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 / modeling / substitution_mappings.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.formatting import safe_repr
17 from aria.parser.validation import Issue
18
19
20 def validate_substitution_mappings_requirement(context, presentation):
21
22     # validate that the requirement in substitution_mapping is defined in the substitution node type
23     substitution_node_type = presentation._container._get_type(context)
24     if substitution_node_type is None:
25         return
26     for req_name, req in substitution_node_type._get_requirements(context):
27         if req_name == presentation._name:
28             substitution_type_requirement = req
29             break
30     else:
31         context.validation.report(
32             'substitution mapping requirement "{0}" is not declared in node type "{1}"'.format(
33                 presentation._name, substitution_node_type._name),
34             locator=presentation._locator, level=Issue.BETWEEN_TYPES)
35         return
36
37     if not _validate_mapping_format(presentation):
38         _report_invalid_mapping_format(context, presentation, field='requirement')
39         return
40
41     # validate that the mapped requirement is defined in the corresponding node template
42     node_template = _get_node_template(context, presentation)
43     if node_template is None:
44         _report_missing_node_template(context, presentation, field='requirement')
45         return
46     mapped_requirement_name = presentation._raw[1]
47     for req_name, req in node_template._get_requirements(context):
48         if req_name == mapped_requirement_name:
49             node_template_requirement = req
50             break
51     else:
52         context.validation.report(
53             'substitution mapping requirement "{0}" refers to an unknown requirement of node '
54             'template "{1}": {mapped_requirement_name}'.format(
55                 presentation._name, node_template._name,
56                 mapped_requirement_name=safe_repr(mapped_requirement_name)),
57             locator=presentation._locator, level=Issue.BETWEEN_TYPES)
58         return
59
60     # validate that the requirement's capability type in substitution_mapping is derived from the
61     # requirement's capability type in the corresponding node template
62     substitution_type_requirement_capability_type = \
63         substitution_type_requirement._get_capability_type(context)
64     node_template_requirement_capability_type = \
65         node_template_requirement._get_capability(context)[0]
66     if not node_template_requirement_capability_type._is_descendant(
67             context, substitution_type_requirement_capability_type):
68         context.validation.report(
69             'substitution mapping requirement "{0}" of capability type "{1}" is not a descendant '
70             'of the mapped node template capability type "{2}"'.format(
71                 presentation._name,
72                 substitution_type_requirement_capability_type._name,
73                 node_template_requirement_capability_type._name),
74             locator=presentation._locator, level=Issue.BETWEEN_TYPES)
75
76
77 def validate_substitution_mappings_capability(context, presentation):
78
79     # validate that the capability in substitution_mapping is defined in the substitution node type
80     substitution_node_type = presentation._container._get_type(context)
81     if substitution_node_type is None:
82         return
83     substitution_type_capabilities = substitution_node_type._get_capabilities(context)
84     substitution_type_capability = substitution_type_capabilities.get(presentation._name)
85     if substitution_type_capability is None:
86         context.validation.report(
87             'substitution mapping capability "{0}" '
88             'is not declared in node type "{substitution_type}"'.format(
89                 presentation._name, substitution_type=substitution_node_type._name),
90             locator=presentation._locator, level=Issue.BETWEEN_TYPES)
91         return
92
93     if not _validate_mapping_format(presentation):
94         _report_invalid_mapping_format(context, presentation, field='capability')
95         return
96
97     # validate that the capability in substitution_mapping is declared in the corresponding
98     # node template
99     node_template = _get_node_template(context, presentation)
100     if node_template is None:
101         _report_missing_node_template(context, presentation, field='capability')
102         return
103     mapped_capability_name = presentation._raw[1]
104     node_template_capability = node_template._get_capabilities(context).get(mapped_capability_name)
105
106     if node_template_capability is None:
107         context.validation.report(
108             'substitution mapping capability "{0}" refers to an unknown '
109             'capability of node template "{1}": {mapped_capability_name}'.format(
110                 presentation._name, node_template._name,
111                 mapped_capability_name=safe_repr(mapped_capability_name)),
112             locator=presentation._locator, level=Issue.BETWEEN_TYPES)
113         return
114
115     # validate that the capability type in substitution_mapping is derived from the capability type
116     # in the corresponding node template
117     substitution_type_capability_type = substitution_type_capability._get_type(context)
118     node_template_capability_type = node_template_capability._get_type(context)
119
120     if not substitution_type_capability_type._is_descendant(context, node_template_capability_type):
121         context.validation.report(
122             'node template capability type "{0}" is not a descendant of substitution mapping '
123             'capability "{1}" of type "{2}"'.format(
124                 node_template_capability_type._name,
125                 presentation._name,
126                 substitution_type_capability_type._name),
127             locator=presentation._locator, level=Issue.BETWEEN_TYPES)
128
129
130 #
131 # Utils
132 #
133
134 def _validate_mapping_format(presentation):
135     """Validate that the mapping is a list of 2 strings"""
136     if not isinstance(presentation._raw, list) or \
137             len(presentation._raw) != 2 or \
138             not isinstance(presentation._raw[0], basestring) or \
139             not isinstance(presentation._raw[1], basestring):
140         return False
141     return True
142
143
144 def _get_node_template(context, presentation):
145     node_template_name = presentation._raw[0]
146     node_template = context.presentation.get_from_dict('service_template', 'topology_template',
147                                                        'node_templates', node_template_name)
148     return node_template
149
150
151 def _report_missing_node_template(context, presentation, field):
152     context.validation.report(
153         'substitution mappings {field} "{node_template_mapping}" '
154         'refers to an unknown node template: {node_template_name}'.format(
155             field=field,
156             node_template_mapping=presentation._name,
157             node_template_name=safe_repr(presentation._raw[0])),
158         locator=presentation._locator, level=Issue.FIELD)
159
160
161 def _report_invalid_mapping_format(context, presentation, field):
162     context.validation.report(
163         'substitution mapping {field} "{field_name}" is not a list of 2 strings: {value}'.format(
164             field=field,
165             field_name=presentation._name,
166             value=safe_repr(presentation._raw)),
167         locator=presentation._locator, level=Issue.FIELD)