7d8389d21681f146a4d9dba6c42a53c9a73afe65
[vfc/nfvo/lcm.git] / lcm / pub / utils / toscaparser / basemodel.py
1 import copy
2 import json
3 import os
4 import re
5 import shutil
6 import urllib
7
8 from toscaparser.functions import GetInput
9 from toscaparser.tosca_template import ToscaTemplate
10
11 from lcm.pub.utils.toscaparser.dataentityext import DataEntityExt
12
13
14 class BaseInfoModel(object):
15
16     def buildToscaTemplate(self, path, params):
17         file_name = None
18         try:
19             file_name = self._check_download_file(path)
20             valid_params = self._validate_input_params(file_name, params)
21             return self._create_tosca_template(file_name, valid_params)
22         finally:
23             if file_name != None and file_name != path and os.path.exists(file_name):
24                 try:
25                     os.remove(file_name)
26                 except Exception, e:
27                     pass
28
29     def _validate_input_params(self, path, params):
30         valid_params = {}
31         if params and len(params) > 0:
32             tmp = self._create_tosca_template(path, None)
33             for key,value in params.items():
34                 if hasattr(tmp, 'inputs') and len(tmp.inputs) > 0:
35                     for input_def in tmp.inputs:
36                         if (input_def.name == key):
37                             valid_params[key] = DataEntityExt.validate_datatype(input_def.type, value)
38
39         return valid_params
40
41     def _create_tosca_template(self, file_name, valid_params):
42         tosca_tpl = None
43         try:
44             tosca_tpl = ToscaTemplate(file_name, valid_params)
45             print "-----------------------------"
46             print '\n'.join(['%s:%s' % item for item in tosca_tpl.__dict__.items()])
47             print "-----------------------------"
48             return tosca_tpl
49         finally:
50             if tosca_tpl != None and hasattr(tosca_tpl, "temp_dir") and os.path.exists(tosca_tpl.temp_dir):
51                 try:
52                     shutil.rmtree(tosca_tpl.temp_dir)
53                 except Exception, e:
54                     pass
55
56     def _check_download_file(self, path):
57         if (path.startswith("ftp") or path.startswith("sftp")):
58             return self.downloadFileFromFtpServer(path)
59         elif (path.startswith("http")):
60             return self.download_file_from_httpserver(path)
61         return path
62
63     def download_file_from_httpserver(self, path):
64         path = path.encode("utf-8")
65         tmps = str.split(path, '/')
66         localFileName = tmps[len(tmps) - 1]
67         urllib.urlretrieve(path, localFileName)
68         return localFileName
69
70     def downloadFileFromFtpServer(self, path):
71         path = path.encode("utf-8")
72         tmp = str.split(path, '://')
73         protocol = tmp[0]
74         tmp = str.split(tmp[1], ':')
75         if len(tmp) == 2:
76             userName = tmp[0]
77             tmp = str.split(tmp[1], '@')
78             userPwd = tmp[0]
79             index = tmp[1].index('/')
80             hostIp = tmp[1][0:index]
81             remoteFileName = tmp[1][index:len(tmp[1])]
82             if protocol.lower() == 'ftp':
83                 hostPort = 21
84             else:
85                 hostPort = 22
86
87         if len(tmp) == 3:
88             userName = tmp[0]
89             userPwd = str.split(tmp[1], '@')[0]
90             hostIp = str.split(tmp[1], '@')[1]
91             index = tmp[2].index('/')
92             hostPort = tmp[2][0:index]
93             remoteFileName = tmp[2][index:len(tmp[2])]
94
95         localFileName = str.split(remoteFileName, '/')
96         localFileName = localFileName[len(localFileName) - 1]
97
98         if protocol.lower() == 'sftp':
99             self.sftp_get(userName, userPwd, hostIp, hostPort, remoteFileName, localFileName)
100         else:
101             self.ftp_get(userName, userPwd, hostIp, hostPort, remoteFileName, localFileName)
102         return localFileName
103
104     def buidMetadata(self, tosca):
105         if 'metadata' in tosca.tpl:
106             self.metadata = copy.deepcopy(tosca.tpl['metadata'])
107
108     def buildProperties(self, nodeTemplate, parsed_params):
109         properties = {}
110         isMappingParams = parsed_params and len(parsed_params) > 0
111         for k, item in nodeTemplate.get_properties().items():
112             properties[k] = item.value
113             if isinstance(item.value, GetInput):
114                 if item.value.result() and isMappingParams:
115                     properties[k] = DataEntityExt.validate_datatype(item.type, item.value.result())
116                 else:
117                     tmp = {}
118                     tmp[item.value.name] = item.value.input_name
119                     properties[k] = tmp
120         if 'attributes' in nodeTemplate.entity_tpl:
121             for k, item in nodeTemplate.entity_tpl['attributes'].items():
122                 properties[k] = str(item)
123         return properties
124
125
126     def verify_properties(self, props, inputs, parsed_params):
127         ret_props = {}
128         if (props and len(props) > 0):
129             for key, value in props.items():
130                 ret_props[key] = self._verify_value(value, inputs, parsed_params)
131                 #                 if isinstance(value, str):
132                 #                     ret_props[key] = self._verify_string(inputs, parsed_params, value);
133                 #                     continue
134                 #                 if isinstance(value, list):
135                 #                     ret_props[key] = map(lambda x: self._verify_dict(inputs, parsed_params, x), value)
136                 #                     continue
137                 #                 if isinstance(value, dict):
138                 #                     ret_props[key] = self._verify_map(inputs, parsed_params, value)
139                 #                     continue
140                 #                 ret_props[key] = value
141         return ret_props
142
143     def build_requirements(self, node_template):
144         rets = []
145         for req in node_template.requirements:
146             for req_name, req_value in req.items():
147                 if (isinstance(req_value, dict)):
148                     if ('node' in req_value and req_value['node'] not in node_template.templates):
149                         continue  # No target requirement for aria parser, not add to result.
150                 rets.append({req_name : req_value})
151         return rets
152
153     def buildCapabilities(self, nodeTemplate, inputs, ret):
154         capabilities = json.dumps(nodeTemplate.entity_tpl.get('capabilities', None))
155         match = re.findall(r'\{"get_input":\s*"([\w|\-]+)"\}',capabilities)
156         for m in match:
157             aa= [input_def for input_def in inputs
158                  if m == input_def.name][0]
159             capabilities = re.sub(r'\{"get_input":\s*"([\w|\-]+)"\}', json.dumps(aa.default), capabilities,1)
160         if capabilities != 'null':
161             ret['capabilities'] = json.loads(capabilities)
162
163     def buildArtifacts(self, nodeTemplate, inputs, ret):
164         artifacts = json.dumps(nodeTemplate.entity_tpl.get('artifacts', None))
165         match = re.findall(r'\{"get_input":\s*"([\w|\-]+)"\}',artifacts)
166         for m in match:
167             aa= [input_def for input_def in inputs
168                  if m == input_def.name][0]
169             artifacts = re.sub(r'\{"get_input":\s*"([\w|\-]+)"\}', json.dumps(aa.default), artifacts,1)
170         if artifacts != 'null':
171             ret['artifacts'] = json.loads(artifacts)
172
173     def build_interfaces(self, node_template):
174         if 'interfaces' in node_template.entity_tpl:
175             return node_template.entity_tpl['interfaces']
176         return None
177
178     def isVnf(self, node):
179         return node['nodeType'].upper().find('.VNF.') >= 0 or node['nodeType'].upper().endswith('.VNF')
180
181     def isPnf(self, node):
182         return node['nodeType'].upper().find('.PNF.') >= 0 or node['nodeType'].upper().endswith('.PNF')
183
184     def isCp(self, node):
185         return node['nodeType'].upper().find('.CP.') >= 0 or node['nodeType'].upper().endswith('.CP')
186
187     def isVl(self, node):
188         return node['nodeType'].upper().find('.VIRTUALLINK.') >= 0 or node['nodeType'].upper().find('.VL.') >= 0 or \
189                node['nodeType'].upper().endswith('.VIRTUALLINK') or node['nodeType'].upper().endswith('.VL')
190
191     def isService(self, node):
192         return node['nodeType'].upper().find('.SERVICE.') >= 0 or node['nodeType'].upper().endswith('.SERVICE')
193
194     def get_requirement_node_name(self, req_value):
195         return self.get_prop_from_obj(req_value, 'node')
196
197     def get_prop_from_obj(self, obj, prop):
198         if isinstance(obj, str):
199             return obj
200         if (isinstance(obj, dict) and prop in obj):
201             return obj[prop]
202         return None
203
204     def getNodeDependencys(self, node):
205         return self.getRequirementByName(node, 'dependency')
206
207     def getVirtualLinks(self, node):
208         return self.getRequirementByName(node, 'virtualLink')
209
210     def getVirtualbindings(self, node):
211         return self.getRequirementByName(node, 'virtualbinding')
212
213
214     def getRequirementByName(self, node, requirementName):
215         requirements = []
216         if 'requirements' in node:
217             for item in node['requirements']:
218                 for key, value in item.items():
219                     if key == requirementName:
220                         requirements.append(value)
221         return requirements
222
223     def get_networks(self, node):
224         rets = []
225         if 'requirements' in node:
226             for item in node['requirements']:
227                 for key, value in item.items():
228                     if key.upper().find('VIRTUALLINK') >=0:
229                         rets.append({"key_name":key, "vl_id":self.get_requirement_node_name(value)})
230         return rets
231
232     def _verify_value(self, value, inputs, parsed_params):
233         if isinstance(value, str):
234             return self._verify_string(inputs, parsed_params, value)
235         if isinstance(value, list) or isinstance(value, dict):
236             return self._verify_object(value, inputs, parsed_params)
237         return value
238
239     def _verify_object(self, value, inputs, parsed_params):
240         s = self._verify_string(inputs, parsed_params, json.dumps(value))
241         return json.loads(s)
242
243     def _get_input_name(self, getInput):
244         input_name = getInput.split(':')[1]
245         input_name = input_name.strip()
246         return input_name.replace('"', '').replace('}', '')
247
248     def _verify_string(self, inputs, parsed_params, value):
249         getInputs = re.findall(r'{"get_input": "[a-zA-Z_0-9]+"}', value)
250         for getInput in getInputs:
251             input_name = self._get_input_name(getInput)
252             if parsed_params and input_name in parsed_params:
253                 value = value.replace(getInput, json.dumps(parsed_params[input_name]))
254             else:
255                 for input_def in inputs:
256                     if input_def.default and input_name == input_def.name:
257                         value = value.replace(getInput, json.dumps(input_def.default))
258         return value
259
260     def get_node_vl_id(self, node):
261         vl_ids = map(lambda x: self.get_requirement_node_name(x), self.getVirtualLinks(node))
262         if len(vl_ids) > 0:
263             return vl_ids[0]
264         return ""
265
266     def get_node_by_name(self, node_templates, name):
267         for node in node_templates:
268             if node['name'] == name:
269                 return node
270         return None
271