summaryrefslogtreecommitdiffstats
path: root/azure/aria/aria-extension-cloudify/src/aria/extensions/aria_extension_tosca/simple_v1_0/misc.py
blob: 221163cf6d0cdccf35334fd62154a36bdf35cacb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements.  See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from aria.utils.caching import cachedmethod
from aria.utils.console import puts
from aria.utils.formatting import as_raw
from aria.parser import implements_specification
from aria.parser.presentation import (AsIsPresentation, has_fields, allow_unknown_fields,
                                      short_form_field, primitive_field, primitive_list_field,
                                      primitive_dict_unknown_fields, object_field,
                                      object_list_field, object_dict_field, field_validator,
                                      type_validator)

from .modeling.data_types import (get_data_type, get_data_type_value, get_property_constraints,
                                  apply_constraint_to_value)
from .modeling.substitution_mappings import (validate_substitution_mappings_requirement,
                                             validate_substitution_mappings_capability)
from .presentation.extensible import ExtensiblePresentation
from .presentation.field_validators import (constraint_clause_field_validator,
                                            constraint_clause_in_range_validator,
                                            constraint_clause_valid_values_validator,
                                            constraint_clause_pattern_validator,
                                            data_type_validator)
from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)



@implements_specification('3.5.1', 'tosca-simple-1.0')
class Description(AsIsPresentation):
    """
    Human-readable description.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ELEMENT_DESCRIPTION>`__
    """

    def __init__(self, name=None, raw=None, container=None, cls=None): # pylint: disable=unused-argument
        super(Description, self).__init__(name, raw, container, cls=unicode)

    def _dump(self, context):
        value = as_raw(self.value)
        puts(context.style.meta_style(value))


@allow_unknown_fields
@has_fields
@implements_specification('3.9.3.2', 'tosca-simple-1.0')
class MetaData(ExtensiblePresentation):
    """
    Meta data.
    """

    @primitive_field(str)
    @implements_specification('3.9.3.3', 'tosca-simple-1.0')
    def template_name(self):
        """
        This optional metadata keyname can be used to declare the name of service template as a
        single-line string value.
        """

    @primitive_field(str)
    @implements_specification('3.9.3.4', 'tosca-simple-1.0')
    def template_author(self):
        """
        This optional metadata keyname can be used to declare the author(s) of the service template
        as a single-line string value.
        """

    @primitive_field(str)
    @implements_specification('3.9.3.5', 'tosca-simple-1.0')
    def template_version(self):
        """
        This optional metadata keyname can be used to declare a domain specific version of the
        service template as a single-line string value.
        """

    @primitive_dict_unknown_fields()
    def custom(self):
        """
        :type: dict
        """


@short_form_field('url')
@has_fields
@implements_specification('3.5.5', 'tosca-simple-1.0')
class Repository(ExtensiblePresentation):
    """
    A repository definition defines a named external repository which contains deployment and
    implementation artifacts that are referenced within the TOSCA Service Template.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ELEMENT_REPOSITORY_DEF>`__
    """

    @object_field(Description)
    def description(self):
        """
        The optional description for the repository.

        :type: :class:`Description`
        """

    @primitive_field(str, required=True)
    def url(self):
        """
        The required URL or network address used to access the repository.

        :type: :obj:`basestring`
        """

    @primitive_field()
    def credential(self):
        """
        The optional Credential used to authorize access to the repository.

        :type: tosca.datatypes.Credential
        """

    @cachedmethod
    def _get_credential(self, context):
        return get_data_type_value(context, self, 'credential', 'tosca.datatypes.Credential')


@short_form_field('file')
@has_fields
@implements_specification('3.5.7', 'tosca-simple-1.0')
class Import(ExtensiblePresentation):
    """
    An import definition is used within a TOSCA Service Template to locate and uniquely name another
    TOSCA Service Template file which has type and template definitions to be imported (included)
    and referenced within another Service Template.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ELEMENT_IMPORT_DEF>`__
    """

    @primitive_field(str, required=True)
    def file(self):
        """
        The required symbolic name for the imported file.

        :type: :obj:`basestring`
        """

    @primitive_field(str)
    def repository(self):
        """
        The optional symbolic name of the repository definition where the imported file can be found
        as a string.

        :type: :obj:`basestring`
        """

    @primitive_field(str)
    def namespace_uri(self):
        """
        The optional namespace URI to that will be applied to type definitions found within the
        imported file as a string.

        :type: :obj:`basestring`
        """

    @primitive_field(str)
    def namespace_prefix(self):
        """
        The optional namespace prefix (alias) that will be used to indicate the namespace_uri when
        forming a qualified name (i.e., qname) when referencing type definitions from the imported
        file.

        :type: :obj:`basestring`
        """


@has_fields
@implements_specification('3.5.2-1', 'tosca-simple-1.0')
class ConstraintClause(ExtensiblePresentation):
    """
    A constraint clause defines an operation along with one or more compatible values that can be
    used to define a constraint on a property or parameter's allowed values when it is defined in a
    TOSCA Service Template or one of its entities.

    See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
    /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
    #DEFN_ELEMENT_CONSTRAINTS_CLAUSE>`__
    """

    @field_validator(constraint_clause_field_validator)
    @primitive_field()
    def equal(self):
        """
        Constrains a property or parameter to a value equal to ('=') the value declared.
        """

    @field_validator(constraint_clause_field_validator)
    @primitive_field()
    def greater_than(self):
        """
        Constrains a property or parameter to a value greater than ('>') the value declared.
        """

    @field_validator(constraint_clause_field_validator)
    @primitive_field()
    def greater_or_equal(self):
        """
        Constrains a property or parameter to a value greater than or equal to ('>=') the value
        declared.
        """

    @field_validator(constraint_clause_field_validator)
    @primitive_field()
    def less_than(self):
        """
        Constrains a property or parameter to a value less than ('<') the value declared.
        """

    @field_validator(constraint_clause_field_validator)
    @primitive_field()
    def less_or_equal(self):
        """
        Constrains a property or parameter to a value less than or equal to ('<=') the value
        declared.
        """

    @field_validator(constraint_clause_in_range_validator)
    @primitive_list_field()
    def in_range(self):
        """
        Constrains a property or parameter to a value in range of (inclusive) the two values
        declared.

        Note: subclasses or templates of types that declare a property with the ``in_range``
        constraint MAY only further restrict the range specified by the parent type.
        """

    @field_validator(constraint_clause_valid_values_validator)
    @primitive_list_field()
    def valid_values(self):
        """
        Constrains a property or parameter to a value that is in the list of declared values.
        """

    @primitive_field(int)
    def length(self):
        """
        Constrains the property or parameter to a value of a given length.
        """

    @primitive_field(int)
    def min_length(self):
        """
        Constrains the property or parameter to a value to a minimum length.
        """

    @primitive_field(int)
    def max_length(self):
        """
        Constrains the property or parameter to a value to a maximum length.
        """

    @field_validator(constraint_clause_pattern_validator)
    @primitive_field(str)
    def pattern(self):
        """
        Constrains the property or parameter to a value that is allowed by the provided regular
        expression.

        Note: Future drafts of this specification will detail the use of regular expressions and
        reference an appropriate standardized grammar.
        """

    @cachedmethod
    def _get_type(self, context):
        if hasattr(self._container, '_get_type_for_name'):
            # NodeFilter or CapabilityFilter
            return self._container._get_type_for_name(context, self._name)
        elif hasattr(self._container, '_get_type'):
            # Properties
            return self._container._get_type(context)
        else:
            # DataType (the DataType itself is our type)
            return self._container

    def _apply_to_value(self, context, presentation, value):
        return apply_constraint_to_value(context, presentation, self, value)


@short_form_field('type')
@has_fields
class EntrySchema(ExtensiblePresentation):
    """
    ARIA NOTE: The specification does not properly explain this type, however it is implied by
    examples.
    """

    @field_validator(data_type_validator('entry schema data type'))
    @primitive_field(str, required=True)
    def type(self):
        """
        :type: :obj:`basestring`
        """

    @object_field(Description)
    def description(self):
        """
        :type: :class:`Description`
        """

    @object_list_field(ConstraintClause)
    def constraints(self):
        """
        :type: list of (str, :class:`ConstraintClause`)
        """

    @cachedmethod
    def _get_type(self, context):
        return get_data_type(context, self, 'type')

    @cachedmethod
    def _get_constraints(self, context):
        return get_property_constraints(context, self)


@short_form_field('primary')
@has_fields
class OperationImplementation(ExtensiblePresentation):
    """
    Operation implementation.
    """

    @primitive_field(str)
    def primary(self):
        """
        The optional implementation artifact name (i.e., the primary script file name within a
        TOSCA CSAR file).

        :type: :obj:`basestring`
        """

    @primitive_list_field(str)
    def dependencies(self):
        """
        The optional ordered list of one or more dependent or secondary implementation artifact name
        which are referenced by the primary implementation artifact (e.g., a library the script
        installs or a secondary script).

        :type: [:obj:`basestring`]
        """


class SubstitutionMappingsRequirement(AsIsPresentation):
    """
    Substitution mapping for requirement.
    """

    @property
    @cachedmethod
    def node_template(self):
        return str(self._raw[0])

    @property
    @cachedmethod
    def requirement(self):
        return str(self._raw[1])

    def _validate(self, context):
        super(SubstitutionMappingsRequirement, self)._validate(context)
        validate_substitution_mappings_requirement(context, self)


class SubstitutionMappingsCapability(AsIsPresentation):
    """
    Substitution mapping for capability.
    """

    @property
    @cachedmethod
    def node_template(self):
        return str(self._raw[0])

    @property
    @cachedmethod
    def capability(self):
        return str(self._raw[1])

    def _validate(self, context):
        super(SubstitutionMappingsCapability, self)._validate(context)
        validate_substitution_mappings_capability(context, self)


@has_fields
@implements_specification('2.10', 'tosca-simple-1.0')
class SubstitutionMappings(ExtensiblePresentation):
    """
    Substitution mappings.
    """

    @field_validator(type_validator('node type', convert_name_to_full_type_name, 'node_types'))
    @primitive_field(str, required=True)
    def node_type(self):
        """
        :type: :obj:`basestring`
        """

    @object_dict_field(SubstitutionMappingsRequirement)
    def requirements(self):
        """
        :type: {:obj:`basestring`: :class:`SubstitutionMappingsRequirement`}
        """

    @object_dict_field(SubstitutionMappingsCapability)
    def capabilities(self):
        """
        :type: {:obj:`basestring`: :class:`SubstitutionMappingsCapability`}
        """

    @cachedmethod
    def _get_type(self, context):
        return get_type_by_name(context, self.node_type, 'node_types')

    def _validate(self, context):
        super(SubstitutionMappings, self)._validate(context)
        self._get_type(context)

    def _dump(self, context):
        self._dump_content(context, (
            'node_type',
            'requirements',
            'capabilities'))