1 # Copyright 2017 ZTE Corporation.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
25 from toscaparser.functions import GetInput
26 from toscaparser.tosca_template import ToscaTemplate
28 from lcm.pub.utils.toscaparser.dataentityext import DataEntityExt
30 logger = logging.getLogger(__name__)
33 class BaseInfoModel(object):
35 def buildToscaTemplate(self, path, params):
38 file_name = self._check_download_file(path)
39 valid_params = self._validate_input_params(file_name, params)
40 return self._create_tosca_template(file_name, valid_params)
42 if file_name is not None and file_name != path and os.path.exists(file_name):
45 except Exception as e:
46 logger.error("Failed to parse package, error: %s", e.message)
48 def _validate_input_params(self, path, params):
50 if params and len(params) > 0:
51 tmp = self._create_tosca_template(path, None)
52 for key, value in params.items():
53 if hasattr(tmp, 'inputs') and len(tmp.inputs) > 0:
54 for input_def in tmp.inputs:
55 if (input_def.name == key):
56 valid_params[key] = DataEntityExt.validate_datatype(input_def.type, value)
60 def _create_tosca_template(self, file_name, valid_params):
63 tosca_tpl = ToscaTemplate(path=file_name,
64 parsed_params=valid_params,
65 no_required_paras_check=True,
67 except Exception as e:
70 if tosca_tpl is not None and hasattr(tosca_tpl, "temp_dir") and os.path.exists(tosca_tpl.temp_dir):
72 shutil.rmtree(tosca_tpl.temp_dir)
74 logger.error("Failed to create tosca template, error: %s", e.message)
75 print "-----------------------------"
76 print '\n'.join(['%s:%s' % item for item in tosca_tpl.__dict__.items()])
77 print "-----------------------------"
80 def _check_download_file(self, path):
81 if (path.startswith("ftp") or path.startswith("sftp")):
82 return self.downloadFileFromFtpServer(path)
83 elif (path.startswith("http")):
84 return self.download_file_from_httpserver(path)
87 def download_file_from_httpserver(self, path):
88 path = path.encode("utf-8")
89 tmps = str.split(path, '/')
90 localFileName = tmps[len(tmps) - 1]
91 urllib.urlretrieve(path, localFileName)
94 def downloadFileFromFtpServer(self, path):
95 path = path.encode("utf-8")
96 tmp = str.split(path, '://')
98 tmp = str.split(tmp[1], ':')
101 tmp = str.split(tmp[1], '@')
103 index = tmp[1].index('/')
104 hostIp = tmp[1][0:index]
105 remoteFileName = tmp[1][index:len(tmp[1])]
106 if protocol.lower() == 'ftp':
113 userPwd = str.split(tmp[1], '@')[0]
114 hostIp = str.split(tmp[1], '@')[1]
115 index = tmp[2].index('/')
116 hostPort = tmp[2][0:index]
117 remoteFileName = tmp[2][index:len(tmp[2])]
119 localFileName = str.split(remoteFileName, '/')
120 localFileName = localFileName[len(localFileName) - 1]
122 if protocol.lower() == 'sftp':
123 self.sftp_get(userName, userPwd, hostIp, hostPort, remoteFileName, localFileName)
125 self.ftp_get(userName, userPwd, hostIp, hostPort, remoteFileName, localFileName)
128 def sftp_get(self, userName, userPwd, hostIp, hostPort, remoteFileName, localFileName):
132 t = paramiko.Transport(hostIp, int(hostPort))
133 t.connect(username=userName, password=userPwd)
134 sftp = paramiko.SFTPClient.from_transport(t)
135 sftp.get(remoteFileName, localFileName)
140 def ftp_get(self, userName, userPwd, hostIp, hostPort, remoteFileName, localFileName):
144 ftp.connect(hostIp, hostPort)
145 ftp.login(userName, userPwd)
146 f = open(localFileName, 'wb')
147 ftp.retrbinary('RETR ' + remoteFileName, f.write, 1024)
153 def buidMetadata(self, tosca):
154 if 'metadata' in tosca.tpl:
155 self.metadata = copy.deepcopy(tosca.tpl['metadata'])
157 def buildProperties(self, nodeTemplate, parsed_params):
159 isMappingParams = parsed_params and len(parsed_params) > 0
160 for k, item in nodeTemplate.get_properties().items():
161 properties[k] = item.value
162 if isinstance(item.value, GetInput):
163 if item.value.result() and isMappingParams:
164 properties[k] = DataEntityExt.validate_datatype(item.type, item.value.result())
167 tmp[item.value.name] = item.value.input_name
169 if 'attributes' in nodeTemplate.entity_tpl:
170 for k, item in nodeTemplate.entity_tpl['attributes'].items():
171 properties[k] = str(item)
174 def verify_properties(self, props, inputs, parsed_params):
176 if (props and len(props) > 0):
177 for key, value in props.items():
178 ret_props[key] = self._verify_value(value, inputs, parsed_params)
179 # if isinstance(value, str):
180 # ret_props[key] = self._verify_string(inputs, parsed_params, value);
182 # if isinstance(value, list):
183 # ret_props[key] = map(lambda x: self._verify_dict(inputs, parsed_params, x), value)
185 # if isinstance(value, dict):
186 # ret_props[key] = self._verify_map(inputs, parsed_params, value)
188 # ret_props[key] = value
191 def build_requirements(self, node_template):
193 for req in node_template.requirements:
194 for req_name, req_value in req.items():
195 if (isinstance(req_value, dict)):
196 if ('node' in req_value and req_value['node'] not in node_template.templates):
197 continue # No target requirement for aria parser, not add to result.
198 rets.append({req_name: req_value})
201 def buildCapabilities(self, nodeTemplate, inputs, ret):
202 capabilities = json.dumps(nodeTemplate.entity_tpl.get('capabilities', None))
203 match = re.findall(r'\{"get_input":\s*"([\w|\-]+)"\}', capabilities)
205 aa = [input_def for input_def in inputs if m == input_def.name][0]
206 capabilities = re.sub(r'\{"get_input":\s*"([\w|\-]+)"\}', json.dumps(aa.default), capabilities, 1)
207 if capabilities != 'null':
208 ret['capabilities'] = json.loads(capabilities)
210 def buildArtifacts(self, nodeTemplate, inputs, ret):
211 artifacts = json.dumps(nodeTemplate.entity_tpl.get('artifacts', None))
212 match = re.findall(r'\{"get_input":\s*"([\w|\-]+)"\}', artifacts)
214 aa = [input_def for input_def in inputs if m == input_def.name][0]
215 artifacts = re.sub(r'\{"get_input":\s*"([\w|\-]+)"\}', json.dumps(aa.default), artifacts, 1)
216 if artifacts != 'null':
217 ret['artifacts'] = json.loads(artifacts)
219 def build_interfaces(self, node_template):
220 if 'interfaces' in node_template.entity_tpl:
221 return node_template.entity_tpl['interfaces']
224 def isVnf(self, node):
225 # return node['nodeType'].upper().find('.VNF.') >= 0 or node['nodeType'].upper().endswith('.VNF')
226 return node['nodeType'].upper().find('.VF.') >= 0 or node['nodeType'].upper().endswith('.VF')
228 def isPnf(self, node):
229 return node['nodeType'].upper().find('.PNF.') >= 0 or node['nodeType'].upper().endswith('.PNF')
231 def isCp(self, node):
232 return node['nodeType'].upper().find('.CP.') >= 0 or node['nodeType'].upper().endswith('.CP')
234 def isVl(self, node):
235 isvl = node['nodeType'].upper().find('.VIRTUALLINK.') >= 0 or node['nodeType'].upper().find('.VL.') >= 0
236 isvl = isvl or node['nodeType'].upper().endswith('.VIRTUALLINK') or node['nodeType'].upper().endswith('.VL')
239 def isService(self, node):
240 return node['nodeType'].upper().find('.SERVICE.') >= 0 or node['nodeType'].upper().endswith('.SERVICE')
242 def get_requirement_node_name(self, req_value):
243 return self.get_prop_from_obj(req_value, 'node')
245 def get_prop_from_obj(self, obj, prop):
246 if isinstance(obj, str):
248 if (isinstance(obj, dict) and prop in obj):
252 def getNodeDependencys(self, node):
253 return self.getRequirementByName(node, 'dependency')
255 def getVirtualLinks(self, node):
256 return self.getRequirementByName(node, 'virtualLink')
258 def getVirtualbindings(self, node):
259 return self.getRequirementByName(node, 'virtualbinding')
261 def getRequirementByName(self, node, requirementName):
263 if 'requirements' in node:
264 for item in node['requirements']:
265 for key, value in item.items():
266 if key == requirementName:
267 requirements.append(value)
270 def get_networks(self, node):
272 if 'requirements' in node:
273 for item in node['requirements']:
274 for key, value in item.items():
275 if key.upper().find('VIRTUALLINK') >= 0:
276 rets.append({"key_name": key, "vl_id": self.get_requirement_node_name(value)})
279 def _verify_value(self, value, inputs, parsed_params):
280 if isinstance(value, str):
281 return self._verify_string(inputs, parsed_params, value)
282 if isinstance(value, list) or isinstance(value, dict):
283 return self._verify_object(value, inputs, parsed_params)
286 def _verify_object(self, value, inputs, parsed_params):
287 s = self._verify_string(inputs, parsed_params, json.dumps(value))
290 def _get_input_name(self, getInput):
291 input_name = getInput.split(':')[1]
292 input_name = input_name.strip()
293 return input_name.replace('"', '').replace('}', '')
295 def _verify_string(self, inputs, parsed_params, value):
296 getInputs = re.findall(r'{"get_input": "[a-zA-Z_0-9]+"}', value)
297 for getInput in getInputs:
298 input_name = self._get_input_name(getInput)
299 if parsed_params and input_name in parsed_params:
300 value = value.replace(getInput, json.dumps(parsed_params[input_name]))
302 for input_def in inputs:
303 if input_def.default and input_name == input_def.name:
304 value = value.replace(getInput, json.dumps(input_def.default))
307 def get_node_vl_id(self, node):
308 vl_ids = map(lambda x: self.get_requirement_node_name(x), self.getVirtualLinks(node))
313 def get_node_by_name(self, node_templates, name):
314 for node in node_templates:
315 if node['name'] == name:
319 def get_all_nested_ns(self, nodes):
322 if self.is_nested_ns(node):
324 ns['ns_id'] = node['name']
325 ns['description'] = node['description']
326 ns['properties'] = node['properties']
327 ns['networks'] = self.get_networks(node)
332 def is_nested_ns(self, node):
333 return node['nodeType'].upper().find('.NS.') >= 0 or node['nodeType'].upper().endswith('.NS')
335 def isVdu(self, node):
336 return node['nodeType'].upper().find('.VDU.') >= 0 or node['nodeType'].upper().endswith('.VDU')
338 def getCapabilityByName(self, node, capabilityName):
339 if 'capabilities' in node and capabilityName in node['capabilities']:
340 return node['capabilities'][capabilityName]
343 def get_node_vdu_id(self, node):
344 vdu_ids = map(lambda x: self.get_requirement_node_name(x), self.getVirtualbindings(node))