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 / types.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, FrozenList)
17 from aria.utils.caching import cachedmethod
18 from aria.parser import implements_specification
19 from aria.parser.presentation import (has_fields, allow_unknown_fields, primitive_field,
20                                       primitive_list_field, object_field, object_dict_field,
21                                       object_list_field, object_sequenced_list_field,
22                                       object_dict_unknown_fields, field_getter, field_validator,
23                                       list_type_validator, derived_from_validator,
24                                       get_parent_presentation)
25
26 from .assignments import ArtifactAssignmentForType
27 from .data_types import Version
28 from .definitions import (PropertyDefinition, AttributeDefinition, InterfaceDefinition,
29                           RequirementDefinition, CapabilityDefinition, OperationDefinition)
30 from .misc import (Description, ConstraintClause)
31 from .modeling.artifacts import get_inherited_artifact_definitions
32 from .modeling.capabilities import (get_inherited_valid_source_types,
33                                     get_inherited_capability_definitions)
34 from .modeling.data_types import (get_data_type, get_inherited_constraints, coerce_data_type_value,
35                                   validate_data_type_name)
36 from .modeling.interfaces import (get_inherited_interface_definitions, get_inherited_operations)
37 from .modeling.policies import get_inherited_targets
38 from .modeling.parameters import get_inherited_parameter_definitions
39 from .modeling.requirements import get_inherited_requirement_definitions
40 from .presentation.extensible import ExtensiblePresentation
41 from .presentation.field_getters import data_type_class_getter
42 from .presentation.field_validators import (data_type_derived_from_validator,
43                                             data_type_constraints_validator,
44                                             data_type_properties_validator,
45                                             list_node_type_or_group_type_validator)
46 from .presentation.types import convert_name_to_full_type_name
47
48
49
50 @has_fields
51 @implements_specification('3.6.3', 'tosca-simple-1.0')
52 class ArtifactType(ExtensiblePresentation):
53     """
54     An Artifact Type is a reusable entity that defines the type of one or more files that are used
55     to define implementation or deployment artifacts that are referenced by nodes or relationships
56     on their operations.
57
58     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
59     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
60     #DEFN_ENTITY_ARTIFACT_TYPE>`__
61     """
62
63     @field_validator(derived_from_validator(convert_name_to_full_type_name, 'artifact_types'))
64     @primitive_field(str)
65     def derived_from(self):
66         """
67         An optional parent Artifact Type name the Artifact Type derives from.
68
69         :type: :obj:`basestring`
70         """
71
72     @field_getter(data_type_class_getter(Version))
73     @primitive_field()
74     def version(self):
75         """
76         An optional version for the Artifact Type definition.
77
78         :type: :class:`Version`
79         """
80
81     @object_field(Description)
82     def description(self):
83         """
84         An optional description for the Artifact Type.
85
86         :type: :class:`Description`
87         """
88
89     @primitive_field(str)
90     def mime_type(self):
91         """
92         The required mime type property for the Artifact Type.
93
94         :type: :obj:`basestring`
95         """
96
97     @primitive_list_field(str)
98     def file_ext(self):
99         """
100         The required file extension property for the Artifact Type.
101
102         :type: [:obj:`basestring`]
103         """
104
105     @object_dict_field(PropertyDefinition)
106     def properties(self):
107         """
108         An optional list of property definitions for the Artifact Type.
109
110         :type: {:obj:`basestring`: :class:`PropertyDefinition`}
111         """
112
113     @cachedmethod
114     def _get_parent(self, context):
115         return get_parent_presentation(context, self, convert_name_to_full_type_name,
116                                        'artifact_types')
117
118     @cachedmethod
119     def _get_properties(self, context):
120         return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
121
122     def _validate(self, context):
123         super(ArtifactType, self)._validate(context)
124         self._get_properties(context)
125
126     def _dump(self, context):
127         self._dump_content(context, (
128             'description',
129             'version',
130             'derived_from',
131             'mime_type',
132             'file_ext',
133             'properties'))
134
135
136 @has_fields
137 @implements_specification('3.6.5', 'tosca-simple-1.0')
138 class DataType(ExtensiblePresentation):
139     """
140     A Data Type definition defines the schema for new named datatypes in TOSCA.
141
142     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
143     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
144     #DEFN_ENTITY_DATA_TYPE>`__
145     """
146
147     @field_validator(data_type_derived_from_validator)
148     @primitive_field(str)
149     def derived_from(self):
150         """
151         The optional key used when a datatype is derived from an existing TOSCA Data Type.
152
153         :type: :obj:`basestring`
154         """
155
156     @object_field(Version)
157     def version(self):
158         """
159         An optional version for the Data Type definition.
160
161         :type: :class:`Version`
162         """
163
164     @object_field(Description)
165     def description(self):
166         """
167         The optional description for the Data Type.
168
169         :type: :class:`Description`
170         """
171
172     @field_validator(data_type_constraints_validator)
173     @object_list_field(ConstraintClause)
174     def constraints(self):
175         """
176         The optional list of sequenced constraint clauses for the Data Type.
177
178         :type: list of (str, :class:`ConstraintClause`)
179         """
180
181     @field_validator(data_type_properties_validator)
182     @object_dict_field(PropertyDefinition)
183     def properties(self):
184         """
185         The optional list property definitions that comprise the schema for a complex Data Type in
186         TOSCA.
187
188         :type: {:obj:`basestring`: :class:`PropertyDefinition`}
189         """
190
191     @cachedmethod
192     def _get_parent(self, context):
193         return get_data_type(context, self, 'derived_from', allow_none=True)
194
195     @cachedmethod
196     def _is_descendant(self, context, the_type):
197         if the_type is None:
198             return False
199         if not hasattr(the_type, '_name'):
200             # Must be a primitive type
201             return self._get_primitive_ancestor(context) == the_type
202         if the_type._name == self._name:
203             return True
204         return self._is_descendant(context, the_type._get_parent(context))
205
206     @cachedmethod
207     def _get_primitive_ancestor(self, context):
208         parent = self._get_parent(context)
209         if parent is not None:
210             if not isinstance(parent, DataType):
211                 return parent
212             else:
213                 return parent._get_primitive_ancestor(context) # pylint: disable=no-member
214         return None
215
216     @cachedmethod
217     def _get_properties(self, context):
218         return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
219
220     @cachedmethod
221     def _get_constraints(self, context):
222         return get_inherited_constraints(context, self)
223
224     def _validate(self, context):
225         super(DataType, self)._validate(context)
226         validate_data_type_name(context, self)
227         self._get_properties(context)
228
229     def _coerce_value(self, context, presentation, entry_schema, constraints, value, aspect):
230         return coerce_data_type_value(context, presentation, self, entry_schema, constraints, value,
231                                       aspect)
232
233     def _dump(self, context):
234         self._dump_content(context, (
235             'description',
236             'version',
237             'derived_from',
238             'constraints',
239             'properties'))
240
241
242 @has_fields
243 @implements_specification('3.6.6', 'tosca-simple-1.0')
244 class CapabilityType(ExtensiblePresentation):
245     """
246     A Capability Type is a reusable entity that describes a kind of capability that a Node Type can
247     declare to expose. Requirements (implicit or explicit) that are declared as part of one node can
248     be matched to (i.e., fulfilled by) the Capabilities declared by another node.
249
250     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
251     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
252     #DEFN_ENTITY_CAPABILITY_TYPE>`__
253     """
254
255     @field_validator(derived_from_validator(convert_name_to_full_type_name, 'capability_types'))
256     @primitive_field(str)
257     def derived_from(self):
258         """
259         An optional parent capability type name this new Capability Type derives from.
260
261         :type: :obj:`basestring`
262         """
263
264     @object_field(Version)
265     def version(self):
266         """
267         An optional version for the Capability Type definition.
268
269         :type: :class:`Version`
270         """
271
272     @object_field(Description)
273     def description(self):
274         """
275         An optional description for the Capability Type.
276
277         :type: :class:`Description`
278         """
279
280     @object_dict_field(PropertyDefinition)
281     def properties(self):
282         """
283         An optional list of property definitions for the Capability Type.
284
285         ARIA NOTE: The spec says 'list', but the examples are all of dicts.
286
287         :type: {:obj:`basestring`: :class:`PropertyDefinition`}
288         """
289
290     @object_dict_field(AttributeDefinition)
291     def attributes(self):
292         """
293         An optional list of attribute definitions for the Capability Type.
294
295         :type: {:obj:`basestring`: :class:`AttributeDefinition`}
296         """
297
298     @field_validator(list_type_validator('node type', convert_name_to_full_type_name, 'node_types'))
299     @primitive_list_field(str)
300     def valid_source_types(self):
301         """
302         An optional list of one or more valid names of Node Types that are supported as valid
303         sources of any relationship established to the declared Capability Type.
304
305         :type: [:obj:`basestring`]
306         """
307
308     @cachedmethod
309     def _get_parent(self, context):
310         return get_parent_presentation(context, self, convert_name_to_full_type_name,
311                                        'capability_types')
312
313     @cachedmethod
314     def _is_descendant(self, context, other_type):
315         """returns True iff `other_type` is a descendant of the represented capability type"""
316         if other_type is None:
317             return False
318         elif other_type._name == self._name:
319             return True
320         return self._is_descendant(context, other_type._get_parent(context))
321
322     @cachedmethod
323     def _get_properties(self, context):
324         return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
325
326     @cachedmethod
327     def _get_valid_source_types(self, context):
328         return get_inherited_valid_source_types(context, self)
329
330     def _validate(self, context):
331         super(CapabilityType, self)._validate(context)
332         self._get_properties(context)
333
334     def _dump(self, context):
335         self._dump_content(context, (
336             'description',
337             'version',
338             'derived_from',
339             'valid_source_types',
340             'properties',
341             'attributes'))
342
343
344 @allow_unknown_fields
345 @has_fields
346 @implements_specification('3.6.4', 'tosca-simple-1.0')
347 class InterfaceType(ExtensiblePresentation):
348     """
349     An Interface Type is a reusable entity that describes a set of operations that can be used to
350     interact with or manage a node or relationship in a TOSCA topology.
351
352     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
353     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
354     #DEFN_ENTITY_INTERFACE_TYPE>`__
355     """
356
357     @field_validator(derived_from_validator(convert_name_to_full_type_name, 'interface_types'))
358     @primitive_field(str)
359     def derived_from(self):
360         """
361         An optional parent Interface Type name this new Interface Type derives from.
362
363         :type: :obj:`basestring`
364         """
365
366     @object_field(Version)
367     def version(self):
368         """
369         An optional version for the Interface Type definition.
370
371         :type: :class:`Version`
372         """
373
374     @object_field(Description)
375     def description(self):
376         """
377         An optional description for the Interface Type.
378
379         :type: :class:`Description`
380         """
381
382     @object_dict_field(PropertyDefinition)
383     def inputs(self):
384         """
385         The optional list of input parameter definitions.
386
387         :type: {:obj:`basestring`: :class:`PropertyDefinition`}
388         """
389
390     @object_dict_unknown_fields(OperationDefinition)
391     def operations(self):
392         """
393         :type: {:obj:`basestring`: :class:`OperationDefinition`}
394         """
395
396     @cachedmethod
397     def _get_parent(self, context):
398         return get_parent_presentation(context, self, convert_name_to_full_type_name,
399                                        'interface_types')
400
401     @cachedmethod
402     def _is_descendant(self, context, the_type):
403         if the_type is None:
404             return False
405         elif the_type._name == self._name:
406             return True
407         return self._is_descendant(context, the_type._get_parent(context))
408
409     @cachedmethod
410     def _get_inputs(self, context):
411         return FrozenDict(get_inherited_parameter_definitions(context, self, 'inputs'))
412
413     @cachedmethod
414     def _get_operations(self, context):
415         return FrozenDict(get_inherited_operations(context, self))
416
417     def _validate(self, context):
418         super(InterfaceType, self)._validate(context)
419         self._get_inputs(context)
420         for operation in self.operations.itervalues(): # pylint: disable=no-member
421             operation._validate(context)
422
423     def _dump(self, context):
424         self._dump_content(context, (
425             'description',
426             'version',
427             'derived_from',
428             'inputs',
429             'operations'))
430
431
432 @has_fields
433 @implements_specification('3.6.9', 'tosca-simple-1.0')
434 class RelationshipType(ExtensiblePresentation):
435     """
436     A Relationship Type is a reusable entity that defines the type of one or more relationships
437     between Node Types or Node Templates.
438
439     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
440     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
441     #DEFN_ENTITY_RELATIONSHIP_TYPE>`__
442     """
443
444     @field_validator(derived_from_validator(convert_name_to_full_type_name, 'relationship_types'))
445     @primitive_field(str)
446     def derived_from(self):
447         """
448         An optional parent Relationship Type name the Relationship Type derives from.
449
450         :type: :obj:`basestring`
451         """
452
453     @object_field(Version)
454     def version(self):
455         """
456         An optional version for the Relationship Type definition.
457
458         :type: :class:`Version`
459         """
460
461     @object_field(Description)
462     def description(self):
463         """
464         An optional description for the Relationship Type.
465
466         :type: :class:`Description`
467         """
468
469     @object_dict_field(PropertyDefinition)
470     def properties(self):
471         """
472         An optional list of property definitions for the Relationship Type.
473
474         :type: {:obj:`basestring`: :class:`PropertyDefinition`}
475         """
476
477     @object_dict_field(AttributeDefinition)
478     def attributes(self):
479         """
480         An optional list of attribute definitions for the Relationship Type.
481
482         :type: {:obj:`basestring`: :class:`AttributeDefinition`}
483         """
484
485     @object_dict_field(InterfaceDefinition)
486     def interfaces(self):
487         """
488         An optional list of interface definitions interfaces supported by the Relationship Type.
489
490         :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
491         """
492
493     @field_validator(list_type_validator('capability type', convert_name_to_full_type_name,
494                                          'capability_types'))
495     @primitive_list_field(str)
496     def valid_target_types(self):
497         """
498         An optional list of one or more names of Capability Types that are valid targets for this
499         relationship.
500
501         :type: [:obj:`basestring`]
502         """
503
504     @cachedmethod
505     def _get_parent(self, context):
506         return get_parent_presentation(context, self, convert_name_to_full_type_name,
507                                        'relationship_types')
508
509     @cachedmethod
510     def _is_descendant(self, context, the_type):
511         if the_type is None:
512             return False
513         elif the_type._name == self._name:
514             return True
515         return self._is_descendant(context, the_type._get_parent(context))
516
517     @cachedmethod
518     def _get_properties(self, context):
519         return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
520
521     @cachedmethod
522     def _get_attributes(self, context):
523         return FrozenDict(get_inherited_parameter_definitions(context, self, 'attributes'))
524
525     @cachedmethod
526     def _get_interfaces(self, context):
527         return FrozenDict(get_inherited_interface_definitions(context, self, 'relationship type'))
528
529     def _validate(self, context):
530         super(RelationshipType, self)._validate(context)
531         self._get_properties(context)
532         self._get_attributes(context)
533         self._get_interfaces(context)
534
535     def _dump(self, context):
536         self._dump_content(context, (
537             'description',
538             'version',
539             'derived_from',
540             'valid_target_types',
541             'properties',
542             'attributes',
543             'interfaces'))
544
545
546 @has_fields
547 @implements_specification('3.6.8', 'tosca-simple-1.0')
548 class NodeType(ExtensiblePresentation):
549     """
550     A Node Type is a reusable entity that defines the type of one or more Node Templates. As such, a
551     Node Type defines the structure of observable properties via a Properties Definition, the
552     Requirements and Capabilities of the node as well as its supported interfaces.
553
554     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
555     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
556     #DEFN_ENTITY_NODE_TYPE>`__
557     """
558
559     @field_validator(derived_from_validator(convert_name_to_full_type_name, 'node_types'))
560     @primitive_field(str)
561     def derived_from(self):
562         """
563         An optional parent Node Type name this new Node Type derives from.
564
565         :type: :obj:`basestring`
566         """
567
568     @object_field(Version)
569     def version(self):
570         """
571         An optional version for the Node Type definition.
572
573         :type: :class:`Version`
574         """
575
576     @object_field(Description)
577     def description(self):
578         """
579         An optional description for the Node Type.
580
581         :type: :class:`Description`
582         """
583
584     @object_dict_field(PropertyDefinition)
585     def properties(self):
586         """
587         An optional list of property definitions for the Node Type.
588
589         :type: {:obj:`basestring`: :class:`PropertyDefinition`}
590         """
591
592     @object_dict_field(AttributeDefinition)
593     def attributes(self):
594         """
595         An optional list of attribute definitions for the Node Type.
596
597         :type: {:obj:`basestring`: :class:`AttributeDefinition`}
598         """
599
600     @object_sequenced_list_field(RequirementDefinition)
601     def requirements(self):
602         """
603         An optional sequenced list of requirement definitions for the Node Type.
604
605         ARIA NOTE: The spec seems wrong to make this a sequenced list. It seems that when you have
606         more than one requirement of the same name, behavior is undefined. The idea is to use the
607         "occurrences" field if you need to limit the number of requirement assignments.
608
609         :type: list of (str, :class:`RequirementDefinition`)
610         """
611
612     @object_dict_field(CapabilityDefinition)
613     def capabilities(self):
614         """
615         An optional list of capability definitions for the Node Type.
616
617         :type: list of :class:`CapabilityDefinition`
618         """
619
620     @object_dict_field(InterfaceDefinition)
621     def interfaces(self):
622         """
623         An optional list of interface definitions supported by the Node Type.
624
625         :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
626         """
627
628     @object_dict_field(ArtifactAssignmentForType)
629     def artifacts(self):
630         """
631         An optional list of named artifact definitions for the Node Type.
632
633         :type: {:obj:`basestring`: :class:`ArtifactAssignmentForType`}
634         """
635
636     @cachedmethod
637     def _get_parent(self, context):
638         return get_parent_presentation(context, self, convert_name_to_full_type_name, 'node_types')
639
640     @cachedmethod
641     def _is_descendant(self, context, the_type):
642         if the_type is None:
643             return False
644         elif the_type._name == self._name:
645             return True
646         return self._is_descendant(context, the_type._get_parent(context))
647
648     @cachedmethod
649     def _get_properties(self, context):
650         return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
651
652     @cachedmethod
653     def _get_attributes(self, context):
654         return FrozenDict(get_inherited_parameter_definitions(context, self, 'attributes'))
655
656     @cachedmethod
657     def _get_requirements(self, context):
658         return FrozenList(get_inherited_requirement_definitions(context, self))
659
660     @cachedmethod
661     def _get_capabilities(self, context):
662         return FrozenDict(get_inherited_capability_definitions(context, self))
663
664     @cachedmethod
665     def _get_interfaces(self, context):
666         return FrozenDict(get_inherited_interface_definitions(context, self, 'node type'))
667
668     @cachedmethod
669     def _get_artifacts(self, context):
670         return FrozenDict(get_inherited_artifact_definitions(context, self))
671
672     def _validate(self, context):
673         super(NodeType, self)._validate(context)
674         self._get_properties(context)
675         self._get_attributes(context)
676         self._get_requirements(context)
677         self._get_capabilities(context)
678         self._get_interfaces(context)
679         self._get_artifacts(context)
680
681     def _dump(self, context):
682         self._dump_content(context, (
683             'description',
684             'version',
685             'derived_from',
686             'properties',
687             'attributes',
688             'interfaces',
689             'artifacts',
690             'requirements',
691             'capabilities'))
692
693
694 @has_fields
695 @implements_specification('3.6.10', 'tosca-simple-1.0')
696 class GroupType(ExtensiblePresentation):
697     """
698     A Group Type defines logical grouping types for nodes, typically for different management
699     purposes. Groups can effectively be viewed as logical nodes that are not part of the physical
700     deployment topology of an application, yet can have capabilities and the ability to attach
701     policies and interfaces that can be applied (depending on the group type) to its member nodes.
702
703     Conceptually, group definitions allow the creation of logical "membership" relationships to
704     nodes in a service template that are not a part of the application's explicit requirement
705     dependencies in the topology template (i.e. those required to actually get the application
706     deployed and running). Instead, such logical membership allows for the introduction of things
707     such as group management and uniform application of policies (i.e., requirements that are also
708     not bound to the application itself) to the group's members.
709
710     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
711     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
712     #DEFN_ENTITY_GROUP_TYPE>`__
713     """
714
715     @field_validator(derived_from_validator(convert_name_to_full_type_name, 'group_types'))
716     @primitive_field(str)
717     def derived_from(self):
718         """
719         An optional parent Group Type name the Group Type derives from.
720
721         :type: :obj:`basestring`
722         """
723
724     @object_field(Version)
725     def version(self):
726         """
727         An optional version for the Group Type definition.
728
729         :type: :class:`Version`
730         """
731
732     @object_field(Description)
733     def description(self):
734         """
735         The optional description for the Group Type.
736
737         :type: :class:`Description`
738         """
739
740     @object_dict_field(PropertyDefinition)
741     def properties(self):
742         """
743         An optional list of property definitions for the Group Type.
744
745         :type: {:obj:`basestring`: :class:`PropertyDefinition`}
746         """
747
748     @field_validator(list_type_validator('node type', convert_name_to_full_type_name, 'node_types'))
749     @primitive_list_field(str)
750     def members(self):
751         """
752         An optional list of one or more names of Node Types that are valid (allowed) as members of
753         the Group Type.
754
755         Note: This can be viewed by TOSCA Orchestrators as an implied relationship from the listed
756         members nodes to the group, but one that does not have operational lifecycle considerations.
757         For example, if we were to name this as an explicit Relationship Type we might call this
758         "MemberOf" (group).
759
760         :type: [:obj:`basestring`]
761         """
762
763     @object_dict_field(InterfaceDefinition)
764     def interfaces(self):
765         """
766         An optional list of interface definitions supported by the Group Type.
767
768         :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
769         """
770
771     @cachedmethod
772     def _get_parent(self, context):
773         return get_parent_presentation(context, self, convert_name_to_full_type_name,
774                                        'group_types')
775
776     @cachedmethod
777     def _is_descendant(self, context, the_type):
778         if the_type is None:
779             return False
780         elif the_type._name == self._name:
781             return True
782         return self._is_descendant(context, the_type._get_parent(context))
783
784     @cachedmethod
785     def _get_properties(self, context):
786         return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
787
788     @cachedmethod
789     def _get_interfaces(self, context):
790         return FrozenDict(get_inherited_interface_definitions(context, self, 'group type'))
791
792     def _validate(self, context):
793         super(GroupType, self)._validate(context)
794         self._get_properties(context)
795         self._get_interfaces(context)
796
797     def _dump(self, context):
798         self._dump_content(context, (
799             'description',
800             'version',
801             'derived_from',
802             'members',
803             'properties',
804             'interfaces'))
805
806
807 @has_fields
808 @implements_specification('3.6.11', 'tosca-simple-1.0')
809 class PolicyType(ExtensiblePresentation):
810     """
811     A Policy Type defines a type of requirement that affects or governs an application or service's
812     topology at some stage of its lifecycle, but is not explicitly part of the topology itself
813     (i.e., it does not prevent the application or service from being deployed or run if it did not
814     exist).
815
816     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
817     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
818     #DEFN_ENTITY_POLICY_TYPE>`__
819     """
820
821     @field_validator(derived_from_validator(convert_name_to_full_type_name, 'policy_types'))
822     @primitive_field(str)
823     def derived_from(self):
824         """
825         An optional parent Policy Type name the Policy Type derives from.
826
827         :type: :obj:`basestring`
828         """
829
830     @object_field(Version)
831     def version(self):
832         """
833         An optional version for the Policy Type definition.
834
835         :type: :class:`Version`
836         """
837
838     @object_field(Description)
839     def description(self):
840         """
841         The optional description for the Policy Type.
842
843         :type: :class:`Description`
844         """
845
846     @object_dict_field(PropertyDefinition)
847     def properties(self):
848         """
849         An optional list of property definitions for the Policy Type.
850
851         :type: :class:`PropertyDefinition`
852         """
853
854     @field_validator(list_node_type_or_group_type_validator)
855     @primitive_list_field(str)
856     def targets(self):
857         """
858         An optional list of valid Node Types or Group Types the Policy Type can be applied to.
859
860         Note: This can be viewed by TOSCA Orchestrators as an implied relationship to the target
861         nodes, but one that does not have operational lifecycle considerations. For example, if we
862         were to name this as an explicit Relationship Type we might call this "AppliesTo" (node or
863         group).
864
865         :type: [:obj:`basestring`]
866         """
867
868     @cachedmethod
869     def _get_parent(self, context):
870         return get_parent_presentation(context, self, convert_name_to_full_type_name,
871                                        'policy_types')
872
873     @cachedmethod
874     def _get_properties(self, context):
875         return FrozenDict(get_inherited_parameter_definitions(context, self, 'properties'))
876
877     @cachedmethod
878     def _get_targets(self, context):
879         node_types, group_types = get_inherited_targets(context, self)
880         return FrozenList(node_types), FrozenList(group_types)
881
882     def _validate(self, context):
883         super(PolicyType, self)._validate(context)
884         self._get_properties(context)
885
886     def _dump(self, context):
887         self._dump_content(context, (
888             'description',
889             'version',
890             'derived_from',
891             'targets',
892             'properties'))