96d2f03bc20897d06adcdba3e6c8d0a403b964f4
[sdc/sdc-distribution-client.git] /
1 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
2 #    not use this file except in compliance with the License. You may obtain
3 #    a copy of the License at
4 #
5 #         http://www.apache.org/licenses/LICENSE-2.0
6 #
7 #    Unless required by applicable law or agreed to in writing, software
8 #    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9 #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10 #    License for the specific language governing permissions and limitations
11 #    under the License.
12
13 import copy
14 import logging
15 import os
16 from toscaparser.common.exception import ExceptionCollector
17 from toscaparser.common.exception import ValidationError
18 from toscaparser.extensions.exttools import ExtTools
19 import toscaparser.utils.yamlparser
20
21 log = logging.getLogger('tosca')
22
23
24 class EntityType(object):
25     '''Base class for TOSCA elements.'''
26
27     SECTIONS = (DERIVED_FROM, PROPERTIES, ATTRIBUTES, REQUIREMENTS,
28                 INTERFACES, CAPABILITIES, TYPE, ARTIFACTS) = \
29                ('derived_from', 'properties', 'attributes', 'requirements',
30                 'interfaces', 'capabilities', 'type', 'artifacts')
31
32     TOSCA_DEF_SECTIONS = ['node_types', 'data_types', 'artifact_types',
33                           'group_types', 'relationship_types',
34                           'capability_types', 'interface_types',
35                           'policy_types']
36
37     '''TOSCA definition file.'''
38     TOSCA_DEF_FILE = os.path.join(
39         os.path.dirname(os.path.abspath(__file__)),
40         "TOSCA_definition_1_0.yaml")
41
42     loader = toscaparser.utils.yamlparser.load_yaml
43
44     TOSCA_DEF_LOAD_AS_IS = loader(TOSCA_DEF_FILE)
45
46     # Map of definition with pre-loaded values of TOSCA_DEF_FILE_SECTIONS
47     TOSCA_DEF = {}
48     for section in TOSCA_DEF_SECTIONS:
49         if section in TOSCA_DEF_LOAD_AS_IS.keys():
50             value = TOSCA_DEF_LOAD_AS_IS[section]
51             for key in value.keys():
52                 TOSCA_DEF[key] = value[key]
53
54     RELATIONSHIP_TYPE = (DEPENDSON, HOSTEDON, CONNECTSTO, ATTACHESTO,
55                          LINKSTO, BINDSTO) = \
56                         ('tosca.relationships.DependsOn',
57                          'tosca.relationships.HostedOn',
58                          'tosca.relationships.ConnectsTo',
59                          'tosca.relationships.AttachesTo',
60                          'tosca.relationships.network.LinksTo',
61                          'tosca.relationships.network.BindsTo')
62
63     NODE_PREFIX = 'tosca.nodes.'
64     RELATIONSHIP_PREFIX = 'tosca.relationships.'
65     CAPABILITY_PREFIX = 'tosca.capabilities.'
66     INTERFACE_PREFIX = 'tosca.interfaces.'
67     ARTIFACT_PREFIX = 'tosca.artifacts.'
68     POLICY_PREFIX = 'tosca.policies.'
69     GROUP_PREFIX = 'tosca.groups.'
70     # currently the data types are defined only for network
71     # but may have changes in the future.
72     DATATYPE_PREFIX = 'tosca.datatypes.'
73     DATATYPE_NETWORK_PREFIX = DATATYPE_PREFIX + 'network.'
74     TOSCA = 'tosca'
75
76     def derived_from(self, defs):
77         '''Return a type this type is derived from.'''
78         return self.entity_value(defs, 'derived_from')
79
80     def is_derived_from(self, type_str):
81         '''Check if object inherits from the given type.
82
83         Returns true if this object is derived from 'type_str'.
84         False otherwise.
85         '''
86         if not self.type:
87             return False
88         elif self.type == type_str:
89             return True
90         elif self.parent_type:
91             return self.parent_type.is_derived_from(type_str)
92         else:
93             return False
94
95     def entity_value(self, defs, key):
96         if defs and key in defs:
97             return defs[key]
98
99     def get_value(self, ndtype, defs=None, parent=None):
100         value = None
101         if defs is None:
102             if not hasattr(self, 'defs'):
103                 return None
104             defs = self.defs
105         if ndtype in defs:
106             # copy the value to avoid that next operations add items in the
107             # item definitions
108             value = copy.copy(defs[ndtype])
109         if parent:
110             p = self
111             if p:
112                 while p:
113                     if p.defs and ndtype in p.defs:
114                         # get the parent value
115                         parent_value = p.defs[ndtype]
116                         if value:
117                             if isinstance(value, dict):
118                                 for k, v in parent_value.items():
119                                     if k not in value.keys():
120                                         value[k] = v
121                             if isinstance(value, list):
122                                 for p_value in parent_value:
123                                     if p_value not in value:
124                                         value.append(p_value)
125                         else:
126                             value = copy.copy(parent_value)
127                     p = p.parent_type
128         return value
129
130     def get_definition(self, ndtype):
131         value = None
132         if not hasattr(self, 'defs'):
133             defs = None
134             ExceptionCollector.appendException(
135                 ValidationError(message="defs is " + str(defs)))
136         else:
137             defs = self.defs
138         if defs is not None and ndtype in defs:
139             value = defs[ndtype]
140         p = self.parent_type
141         if p:
142             inherited = p.get_definition(ndtype)
143             if inherited:
144                 inherited = dict(inherited)
145                 if not value:
146                     value = inherited
147                 else:
148                     inherited.update(value)
149                     value.update(inherited)
150         return value
151
152
153 def update_definitions(version):
154     exttools = ExtTools()
155     extension_defs_file = exttools.get_defs_file(version)
156     loader = toscaparser.utils.yamlparser.load_yaml
157     nfv_def_file = loader(extension_defs_file)
158     nfv_def = {}
159     for section in EntityType.TOSCA_DEF_SECTIONS:
160         if section in nfv_def_file.keys():
161             value = nfv_def_file[section]
162             for key in value.keys():
163                 nfv_def[key] = value[key]
164     EntityType.TOSCA_DEF.update(nfv_def)