vFW and vDNS support added to azure-plugin
[multicloud/azure.git] / azure / aria / aria-extension-cloudify / src / aria / extensions / aria_extension_tosca / simple_v1_0 / assignments.py
1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements.  See the NOTICE file distributed with
3 # this work for additional information regarding copyright ownership.
4 # The ASF licenses this file to You under the Apache License, Version 2.0
5 # (the "License"); you may not use this file except in compliance with
6 # the License.  You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 from aria.utils.collections import FrozenDict
17 from aria.utils.caching import cachedmethod
18 from aria.parser import implements_specification
19 from aria.parser.presentation import (AsIsPresentation, has_fields, allow_unknown_fields,
20                                       short_form_field, primitive_field, object_field,
21                                       object_dict_field, object_dict_unknown_fields,
22                                       field_validator, type_validator)
23
24 from .filters import NodeFilter
25 from .misc import Description, OperationImplementation
26 from .modeling.parameters import get_assigned_and_defined_parameter_values
27 from .presentation.extensible import ExtensiblePresentation
28 from .presentation.field_validators import (node_template_or_type_validator,
29                                             relationship_template_or_type_validator,
30                                             capability_definition_or_type_validator,
31                                             node_filter_validator)
32 from .presentation.types import (convert_name_to_full_type_name, get_type_by_name)
33
34
35
36 @implements_specification('3.5.9', 'tosca-simple-1.0')
37 class PropertyAssignment(AsIsPresentation):
38     """
39     This section defines the grammar for assigning values to named properties within TOSCA Node and
40     Relationship templates that are defined in their corresponding named types.
41
42     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
43     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
44     #DEFN_ELEMENT_PROPERTY_VALUE_ASSIGNMENT>`__
45     """
46
47
48 @short_form_field('implementation')
49 @has_fields
50 @implements_specification('3.5.13-2', 'tosca-simple-1.0')
51 class OperationAssignment(ExtensiblePresentation):
52     """
53     An operation definition defines a named function or procedure that can be bound to an
54     implementation artifact (e.g., a script).
55
56     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
57     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
58     #DEFN_ELEMENT_OPERATION_DEF>`__
59     """
60
61     @object_field(Description)
62     def description(self):
63         """
64         The optional description string for the associated named operation.
65
66         :type: :class:`Description`
67         """
68
69     @object_field(OperationImplementation)
70     def implementation(self):
71         """
72         The optional implementation artifact name (e.g., a script file name within a TOSCA CSAR
73         file).
74
75         :type: :class:`OperationImplementation`
76         """
77
78     @object_dict_field(PropertyAssignment)
79     def inputs(self):
80         """
81         The optional list of input property assignments (i.e., parameters assignments) for operation
82         definitions that are within TOSCA Node or Relationship Template definitions. This includes
83         when operation definitions are included as part of a Requirement assignment in a Node
84         Template.
85
86         :type: {:obj:`basestring`: :class:`PropertyAssignment`}
87         """
88
89     @cachedmethod
90     def _get_extensions(self, context):
91         def update_inherited_extensions(extensions, interface_type):
92             parent = interface_type._get_parent(context)
93             if parent is not None:
94                 update_inherited_extensions(extensions, parent)
95             operation_definition = interface_type.operations.get(self._name)
96             if operation_definition is not None:
97                 if operation_definition._extensions:
98                     extensions.update(operation_definition._extensions)
99
100         extensions = {}
101         update_inherited_extensions(extensions, self._container._get_type(context))
102         if self._container._extensions:
103             extensions.update(self._container._extensions)
104         if self._extensions:
105             extensions.update(self._extensions)
106         return extensions
107
108
109 @allow_unknown_fields
110 @has_fields
111 @implements_specification('3.5.14-2', 'tosca-simple-1.0')
112 class InterfaceAssignment(ExtensiblePresentation):
113     """
114     An interface definition defines a named interface that can be associated with a Node or
115     Relationship Type.
116
117     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
118     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
119     #DEFN_ELEMENT_INTERFACE_DEF>`__
120     """
121
122     @object_dict_field(PropertyAssignment)
123     def inputs(self):
124         """
125         The optional list of input property assignments (i.e., parameters assignments) for interface
126         definitions that are within TOSCA Node or Relationship Template definitions. This includes
127         when interface definitions are referenced as part of a Requirement assignment in a Node
128         Template.
129
130         :type: {:obj:`basestring`: :class:`PropertyAssignment`}
131         """
132
133     @object_dict_unknown_fields(OperationAssignment)
134     def operations(self):
135         """
136         :type: {:obj:`basestring`: :class:`OperationAssignment`}
137         """
138
139     @cachedmethod
140     def _get_type(self, context):
141         the_type = self._container._get_type(context)
142
143         if isinstance(the_type, tuple):
144             # In RelationshipAssignment
145             the_type = the_type[0] # This could be a RelationshipTemplate
146
147         interface_definitions = the_type._get_interfaces(context) \
148             if the_type is not None else None
149         interface_definition = interface_definitions.get(self._name) \
150             if interface_definitions is not None else None
151         return interface_definition._get_type(context) \
152             if interface_definition is not None else None
153
154     def _validate(self, context):
155         super(InterfaceAssignment, self)._validate(context)
156         if self.operations:
157             for operation in self.operations.itervalues(): # pylint: disable=no-member
158                 operation._validate(context)
159
160
161 @short_form_field('type')
162 @has_fields
163 class RelationshipAssignment(ExtensiblePresentation):
164     """
165     Relationship assignment.
166     """
167
168     @field_validator(relationship_template_or_type_validator)
169     @primitive_field(str)
170     def type(self):
171         """
172         The optional reserved keyname used to provide the name of the Relationship Type for the
173         requirement assignment's relationship keyname.
174
175         :type: :obj:`basestring`
176         """
177
178     @object_dict_field(PropertyAssignment)
179     def properties(self):
180         """
181         ARIA NOTE: This field is not mentioned in the spec, but is implied.
182
183         :type: {:obj:`basestring`: :class:`PropertyAssignment`}
184         """
185
186     @object_dict_field(InterfaceAssignment)
187     def interfaces(self):
188         """
189         The optional reserved keyname used to reference declared (named) interface definitions of
190         the corresponding Relationship Type in order to provide Property assignments for these
191         interfaces or operations of these interfaces.
192
193         :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
194         """
195
196     @cachedmethod
197     def _get_type(self, context):
198         type_name = self.type
199         if type_name is not None:
200             the_type = context.presentation.get_from_dict('service_template', 'topology_template',
201                                                           'relationship_templates', type_name)
202             if the_type is not None:
203                 return the_type, 'relationship_template'
204             the_type = get_type_by_name(context, type_name, 'relationship_types')
205             if the_type is not None:
206                 return the_type, 'relationship_type'
207         return None, None
208
209
210 @short_form_field('node')
211 @has_fields
212 @implements_specification('3.7.2', 'tosca-simple-1.0')
213 class RequirementAssignment(ExtensiblePresentation):
214     """
215     A Requirement assignment allows template authors to provide either concrete names of TOSCA
216     templates or provide abstract selection criteria for providers to use to find matching TOSCA
217     templates that are used to fulfill a named requirement's declared TOSCA Node Type.
218
219     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
220     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
221     #DEFN_ELEMENT_REQUIREMENT_ASSIGNMENT>`__
222     """
223
224     # The example in 3.7.2.2.2 shows unknown fields in addition to these, but is this a mistake?
225
226     @field_validator(capability_definition_or_type_validator)
227     @primitive_field(str)
228     def capability(self):
229         """
230         The optional reserved keyname used to provide the name of either a:
231
232         * Capability definition within a target node template that can fulfill the requirement.
233         * Capability Type that the provider will use to select a type-compatible target node
234           template to fulfill the requirement at runtime.
235
236         :type: :obj:`basestring`
237         """
238
239     @field_validator(node_template_or_type_validator)
240     @primitive_field(str)
241     def node(self):
242         """
243         The optional reserved keyname used to identify the target node of a relationship.
244         Specifically, it is used to provide either a:
245
246         * Node Template name that can fulfill the target node requirement.
247         * Node Type name that the provider will use to select a type-compatible node template to
248           fulfill the requirement at runtime.
249
250         :type: :obj:`basestring`
251         """
252
253     @object_field(RelationshipAssignment)
254     def relationship(self):
255         """
256         The optional reserved keyname used to provide the name of either a:
257
258         * Relationship Template to use to relate the source node to the (capability in the) target
259           node when fulfilling the requirement.
260         * Relationship Type that the provider will use to select a type-compatible relationship
261           template to relate the source node to the target node at runtime.
262
263         :type: :class:`RelationshipAssignment`
264         """
265
266     @field_validator(node_filter_validator)
267     @object_field(NodeFilter)
268     def node_filter(self):
269         """
270         The optional filter definition that TOSCA orchestrators or providers would use to select a
271         type-compatible target node that can fulfill the associated abstract requirement at runtime.
272
273         :type: :class:`NodeFilter`
274         """
275
276     @cachedmethod
277     def _get_node(self, context):
278         node = self.node
279
280         if node is not None:
281             node_template = context.presentation.get_from_dict('service_template',
282                                                                'topology_template',
283                                                                'node_templates', node)
284             if node_template is not None:
285                 return node_template, 'node_template'
286             node_type = get_type_by_name(context, node, 'node_types')
287             if node_type is not None:
288                 return node_type, 'node_type'
289
290         return None, None
291
292     @cachedmethod
293     def _get_capability(self, context):
294         capability = self.capability
295
296         if capability is not None:
297             node, node_variant = self._get_node(context)
298             if node_variant == 'node_template':
299                 capabilities = node._get_capabilities(context)
300                 if capability in capabilities:
301                     return capabilities[capability], 'capability_assignment'
302             capability_type = get_type_by_name(context, capability, 'capability_types')
303             if capability_type is not None:
304                 return capability_type, 'capability_type'
305
306         return None, None
307
308
309 @implements_specification('3.5.11', 'tosca-simple-1.0')
310 class AttributeAssignment(AsIsPresentation):
311     """
312     This section defines the grammar for assigning values to named attributes within TOSCA Node and
313     Relationship templates which are defined in their corresponding named types.
314
315     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
316     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
317     #DEFN_ELEMENT_ATTRIBUTE_VALUE_ASSIGNMENT>`__
318     """
319
320
321 @has_fields
322 @implements_specification('3.7.1', 'tosca-simple-1.0')
323 class CapabilityAssignment(ExtensiblePresentation):
324     """
325     A capability assignment allows node template authors to assign values to properties and
326     attributes for a named capability definition that is part of a Node Template's type definition.
327
328     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
329     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
330     #DEFN_ELEMENT_CAPABILITY_ASSIGNMENT>`__
331     """
332
333     @object_dict_field(PropertyAssignment)
334     def properties(self):
335         """
336         An optional list of property definitions for the Capability definition.
337
338         :type: {:obj:`basestring`: :class:`PropertyAssignment`}
339         """
340
341     @object_dict_field(AttributeAssignment)
342     def attributes(self):
343         """
344         An optional list of attribute definitions for the Capability definition.
345
346         :type: {:obj:`basestring`: :class:`AttributeAssignment`}
347         """
348
349     @cachedmethod
350     def _get_definition(self, context):
351         node_type = self._container._get_type(context)
352         capability_definitions = node_type._get_capabilities(context) \
353             if node_type is not None else None
354         return capability_definitions.get(self._name) \
355             if capability_definitions is not None else None
356
357     @cachedmethod
358     def _get_type(self, context):
359         capability_definition = self._get_definition(context)
360         return capability_definition._get_type(context) \
361             if capability_definition is not None else None
362
363
364 @has_fields
365 @implements_specification('3.5.6', 'tosca-simple-1.0')
366 class ArtifactAssignmentForType(ExtensiblePresentation):
367     """
368     An artifact definition defines a named, typed file that can be associated with Node Type or Node
369     Template and used by orchestration engine to facilitate deployment and implementation of
370     interface operations.
371
372     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
373     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
374     #DEFN_ENTITY_ARTIFACT_DEF>`__
375     """
376
377     @field_validator(type_validator('artifact type', convert_name_to_full_type_name,
378                                     'artifact_types'))
379     @primitive_field(str, required=True)
380     def type(self):
381         """
382         The required artifact type for the artifact definition.
383
384         :type: :obj:`basestring`
385         """
386
387     @primitive_field(str, required=True)
388     def file(self):
389         """
390         The required URI string (relative or absolute) which can be used to locate the artifact's
391         file.
392
393         :type: :obj:`basestring`
394         """
395
396     @field_validator(type_validator('repository', 'repositories'))
397     @primitive_field(str)
398     def repository(self):
399         """
400         The optional name of the repository definition which contains the location of the external
401         repository that contains the artifact. The artifact is expected to be referenceable by its
402         file URI within the repository.
403
404         :type: :obj:`basestring`
405         """
406
407     @object_field(Description)
408     def description(self):
409         """
410         The optional description for the artifact definition.
411
412         :type: :class:`Description`
413         """
414
415     @primitive_field(str)
416     def deploy_path(self):
417         """
418         The file path the associated file would be deployed into within the target node's container.
419
420         :type: :obj:`basestring`
421         """
422
423     @object_dict_field(PropertyAssignment)
424     def properties(self):
425         """
426         ARIA NOTE: This field is not mentioned in the spec, but is implied.
427
428         :type: {:obj:`basestring`: :class:`PropertyAssignment`}
429         """
430
431     @cachedmethod
432     def _get_type(self, context):
433         return get_type_by_name(context, self.type, 'artifact_types')
434
435     @cachedmethod
436     def _get_repository(self, context):
437         return context.presentation.get_from_dict('service_template', 'repositories',
438                                                   self.repository)
439
440     @cachedmethod
441     def _get_property_values(self, context):
442         return FrozenDict(get_assigned_and_defined_parameter_values(context, self, 'property'))
443
444     @cachedmethod
445     def _validate(self, context):
446         super(ArtifactAssignmentForType, self)._validate(context)
447
448
449 class ArtifactAssignment(ArtifactAssignmentForType):
450     @cachedmethod
451     def _validate(self, context):
452         super(ArtifactAssignment, self)._validate(context)
453         self._get_property_values(context)