--- /dev/null
+# Copyright 2016 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from redisco import containers as cont
+
+
+def get_auto_id(id_type, id_group="auto_id_hash"):
+ auto_id_hash = cont.Hash(id_group)
+ auto_id_hash.hincrby(id_type, 1)
+ return auto_id_hash.hget(id_type)
--- /dev/null
+# Copyright 2016-2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import datetime
+import logging
+import uuid
+import traceback
+
+from catalog.pub.database.models import JobStatusModel, JobModel
+from catalog.pub.utils import idutil
+
+logger = logging.getLogger(__name__)
+
+
+def enum(**enums):
+ return type('Enum', (), enums)
+
+
+JOB_STATUS = enum(PROCESSING=0, FINISH=1)
+JOB_MODEL_STATUS = enum(STARTED='started', PROCESSING='processing', FINISHED='finished', ERROR='error',
+ TIMEOUT='timeout')
+JOB_TYPE = enum(CREATE_VNF="create vnf", TERMINATE_VNF="terminate vnf", GRANT_VNF="grant vnf", MANUAL_SCALE_VNF="manual scale vnf",
+ HEAL_VNF="heal vnf")
+
+
+class JobUtil(object):
+ def __init__(self):
+ pass
+
+ @staticmethod
+ def __gen_job_id(job_name):
+ return "%s-%s" % (job_name if job_name else "UnknownJob", uuid.uuid1())
+
+ @staticmethod
+ def query_job_status(job_id, index_id=-1):
+ #logger.info("Query job status, jobid =[%s], responseid [%d]" % (job_id, index_id))
+ jobs = []
+ if index_id < 0:
+ row = JobStatusModel.objects.filter(jobid=job_id).order_by("-indexid").first()
+ if row:
+ jobs.append(row)
+ else:
+ [jobs.append(job) for job in JobStatusModel.objects.filter(jobid=job_id).order_by("-indexid")
+ if job.indexid > index_id]
+
+ #logger.info("Query job status, rows=%s" % str(jobs))
+ return jobs
+
+ @staticmethod
+ def is_job_exists(job_id):
+ jobs = JobModel.objects.filter(jobid=job_id)
+ return len(jobs) > 0
+
+ @staticmethod
+ def create_job(inst_type, jobaction, inst_id, user='', job_id=None, res_name=''):
+ if job_id is None:
+ job_id = JobUtil.__gen_job_id(
+ '%s-%s-%s' % (str(inst_type).replace(' ', '_'), str(jobaction).replace(' ', '_'), str(inst_id)))
+ job = JobModel()
+ job.jobid = job_id
+ job.jobtype = inst_type
+ job.jobaction = jobaction
+ job.resid = str(inst_id)
+ job.status = JOB_STATUS.PROCESSING
+ job.user = user
+ job.starttime = datetime.datetime.now().strftime('%Y-%m-%d %X')
+ job.progress = 0
+ job.resname = res_name
+ logger.debug("create a new job, jobid=%s, jobtype=%s, jobaction=%s, resid=%s, status=%d" %
+ (job.jobid, job.jobtype, job.jobaction, job.resid, job.status))
+ job.save()
+ return job_id
+
+ @staticmethod
+ def clear_job(job_id):
+ [job.delete() for job in JobModel.objects.filter(jobid=job_id)]
+ logger.debug("Clear job, job_id=%s" % job_id)
+
+ @staticmethod
+ def add_job_status(job_id, progress, status_decs, error_code=""):
+ jobs = JobModel.objects.filter(jobid=job_id)
+ if not jobs:
+ logger.error("Job[%s] is not exists, please create job first." % job_id)
+ raise Exception("Job[%s] is not exists." % job_id)
+ try:
+ int_progress = int(progress)
+ job_status = JobStatusModel()
+ job_status.indexid = int(idutil.get_auto_id(job_id))
+ job_status.jobid = job_id
+ job_status.status = "processing"
+ job_status.progress = int_progress
+
+ if job_status.progress == 0:
+ job_status.status = "started"
+ elif job_status.progress == 100:
+ job_status.status = "finished"
+ elif job_status.progress == 101:
+ job_status.status = "partly_finished"
+ elif job_status.progress > 101:
+ job_status.status = "error"
+
+ if error_code == "255":
+ job_status.status = "error"
+
+ job_status.descp = status_decs
+ job_status.errcode = error_code
+ job_status.addtime = datetime.datetime.now().strftime('%Y-%m-%d %X')
+ job_status.save()
+ logger.debug("Add a new job status, jobid=%s, indexid=%d,"
+ " status=%s, description=%s, progress=%d, errcode=%s, addtime=%r" %
+ (job_status.jobid, job_status.indexid, job_status.status, job_status.descp,
+ job_status.progress, job_status.errcode, job_status.addtime))
+
+ job = jobs[0]
+ job.progress = int_progress
+ if job_status.progress >= 100:
+ job.status = JOB_STATUS.FINISH
+ job.endtime = datetime.datetime.now().strftime('%Y-%m-%d %X')
+ job.save()
+ logger.debug("update job, jobid=%s, progress=%d" % (job_status.jobid, int_progress))
+ except:
+ logger.error(traceback.format_exc())
+
+ @staticmethod
+ def clear_job_status(job_id):
+ [job.delete() for job in JobStatusModel.objects.filter(jobid=job_id)]
+ logger.debug("Clear job status, job_id=%s" % job_id)
+
+ @staticmethod
+ def get_unfinished_jobs(url_prefix, inst_id, inst_type):
+ jobs = JobModel.objects.filter(resid=inst_id, jobtype=inst_type, status=JOB_STATUS.PROCESSING)
+ progresses = reduce(lambda content, job: content + [url_prefix + "/" + job.jobid], jobs, [])
+ return progresses
--- /dev/null
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+import json
+
+from catalog.pub.utils.toscaparser.nsdmodel import EtsiNsdInfoModel
+from catalog.pub.utils.toscaparser.vnfdmodel import EtsiVnfdInfoModel
+
+
+def parse_nsd(path, input_parameters=[]):
+ tosca_obj = EtsiNsdInfoModel(path, input_parameters)
+ strResponse = json.dumps(tosca_obj, default=lambda obj: obj.__dict__)
+ strResponse = strResponse.replace(': null', ': ""')
+ return strResponse
+
+
+def parse_vnfd(path, input_parameters=[]):
+ tosca_obj = EtsiVnfdInfoModel(path, input_parameters)
+ strResponse = json.dumps(tosca_obj, default=lambda obj: obj.__dict__)
+ strResponse = strResponse.replace(': null', ': ""')
+ return strResponse
--- /dev/null
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy
+import json
+import os
+import re
+import shutil
+import urllib
+
+from toscaparser.functions import GetInput
+from toscaparser.tosca_template import ToscaTemplate
+
+from catalog.pub.utils.toscaparser.dataentityext import DataEntityExt
+
+
+class BaseInfoModel(object):
+
+ def buildToscaTemplate(self, path, params):
+ file_name = None
+ try:
+ file_name = self._check_download_file(path)
+ valid_params = self._validate_input_params(file_name, params)
+ return self._create_tosca_template(file_name, valid_params)
+ finally:
+ if file_name != None and file_name != path and os.path.exists(file_name):
+ try:
+ os.remove(file_name)
+ except Exception, e:
+ pass
+
+ def _validate_input_params(self, path, params):
+ valid_params = {}
+ if params and len(params) > 0:
+ tmp = self._create_tosca_template(path, None)
+ for key,value in params.items():
+ if hasattr(tmp, 'inputs') and len(tmp.inputs) > 0:
+ for input_def in tmp.inputs:
+ if (input_def.name == key):
+ valid_params[key] = DataEntityExt.validate_datatype(input_def.type, value)
+
+ return valid_params
+
+ def _create_tosca_template(self, file_name, valid_params):
+ tosca_tpl = None
+ try:
+ tosca_tpl = ToscaTemplate(file_name, valid_params)
+ print "-----------------------------"
+ print '\n'.join(['%s:%s' % item for item in tosca_tpl.__dict__.items()])
+ print "-----------------------------"
+ return tosca_tpl
+ finally:
+ if tosca_tpl != None and hasattr(tosca_tpl, "temp_dir") and os.path.exists(tosca_tpl.temp_dir):
+ try:
+ shutil.rmtree(tosca_tpl.temp_dir)
+ except Exception, e:
+ pass
+
+ def _check_download_file(self, path):
+ if (path.startswith("ftp") or path.startswith("sftp")):
+ return self.downloadFileFromFtpServer(path)
+ elif (path.startswith("http")):
+ return self.download_file_from_httpserver(path)
+ return path
+
+ def download_file_from_httpserver(self, path):
+ path = path.encode("utf-8")
+ tmps = str.split(path, '/')
+ localFileName = tmps[len(tmps) - 1]
+ urllib.urlretrieve(path, localFileName)
+ return localFileName
+
+ def downloadFileFromFtpServer(self, path):
+ path = path.encode("utf-8")
+ tmp = str.split(path, '://')
+ protocol = tmp[0]
+ tmp = str.split(tmp[1], ':')
+ if len(tmp) == 2:
+ userName = tmp[0]
+ tmp = str.split(tmp[1], '@')
+ userPwd = tmp[0]
+ index = tmp[1].index('/')
+ hostIp = tmp[1][0:index]
+ remoteFileName = tmp[1][index:len(tmp[1])]
+ if protocol.lower() == 'ftp':
+ hostPort = 21
+ else:
+ hostPort = 22
+
+ if len(tmp) == 3:
+ userName = tmp[0]
+ userPwd = str.split(tmp[1], '@')[0]
+ hostIp = str.split(tmp[1], '@')[1]
+ index = tmp[2].index('/')
+ hostPort = tmp[2][0:index]
+ remoteFileName = tmp[2][index:len(tmp[2])]
+
+ localFileName = str.split(remoteFileName, '/')
+ localFileName = localFileName[len(localFileName) - 1]
+
+ if protocol.lower() == 'sftp':
+ self.sftp_get(userName, userPwd, hostIp, hostPort, remoteFileName, localFileName)
+ else:
+ self.ftp_get(userName, userPwd, hostIp, hostPort, remoteFileName, localFileName)
+ return localFileName
+
+ def buidMetadata(self, tosca):
+ if 'metadata' in tosca.tpl:
+ self.metadata = copy.deepcopy(tosca.tpl['metadata'])
+
+ def buildProperties(self, nodeTemplate, parsed_params):
+ properties = {}
+ isMappingParams = parsed_params and len(parsed_params) > 0
+ for k, item in nodeTemplate.get_properties().items():
+ properties[k] = item.value
+ if isinstance(item.value, GetInput):
+ if item.value.result() and isMappingParams:
+ properties[k] = DataEntityExt.validate_datatype(item.type, item.value.result())
+ else:
+ tmp = {}
+ tmp[item.value.name] = item.value.input_name
+ properties[k] = tmp
+ if 'attributes' in nodeTemplate.entity_tpl:
+ for k, item in nodeTemplate.entity_tpl['attributes'].items():
+ properties[k] = str(item)
+ return properties
+
+
+ def verify_properties(self, props, inputs, parsed_params):
+ ret_props = {}
+ if (props and len(props) > 0):
+ for key, value in props.items():
+ ret_props[key] = self._verify_value(value, inputs, parsed_params)
+ # if isinstance(value, str):
+ # ret_props[key] = self._verify_string(inputs, parsed_params, value);
+ # continue
+ # if isinstance(value, list):
+ # ret_props[key] = map(lambda x: self._verify_dict(inputs, parsed_params, x), value)
+ # continue
+ # if isinstance(value, dict):
+ # ret_props[key] = self._verify_map(inputs, parsed_params, value)
+ # continue
+ # ret_props[key] = value
+ return ret_props
+
+ def build_requirements(self, node_template):
+ rets = []
+ for req in node_template.requirements:
+ for req_name, req_value in req.items():
+ if (isinstance(req_value, dict)):
+ if ('node' in req_value and req_value['node'] not in node_template.templates):
+ continue # No target requirement for aria parser, not add to result.
+ rets.append({req_name : req_value})
+ return rets
+
+ def buildCapabilities(self, nodeTemplate, inputs, ret):
+ capabilities = json.dumps(nodeTemplate.entity_tpl.get('capabilities', None))
+ match = re.findall(r'\{"get_input":\s*"([\w|\-]+)"\}',capabilities)
+ for m in match:
+ aa= [input_def for input_def in inputs
+ if m == input_def.name][0]
+ capabilities = re.sub(r'\{"get_input":\s*"([\w|\-]+)"\}', json.dumps(aa.default), capabilities,1)
+ if capabilities != 'null':
+ ret['capabilities'] = json.loads(capabilities)
+
+ def buildArtifacts(self, nodeTemplate, inputs, ret):
+ artifacts = json.dumps(nodeTemplate.entity_tpl.get('artifacts', None))
+ match = re.findall(r'\{"get_input":\s*"([\w|\-]+)"\}',artifacts)
+ for m in match:
+ aa= [input_def for input_def in inputs
+ if m == input_def.name][0]
+ artifacts = re.sub(r'\{"get_input":\s*"([\w|\-]+)"\}', json.dumps(aa.default), artifacts,1)
+ if artifacts != 'null':
+ ret['artifacts'] = json.loads(artifacts)
+
+ def build_interfaces(self, node_template):
+ if 'interfaces' in node_template.entity_tpl:
+ return node_template.entity_tpl['interfaces']
+ return None
+
+ def isVnf(self, node):
+ return node['nodeType'].upper().find('.VNF.') >= 0 or node['nodeType'].upper().endswith('.VNF')
+
+ def isPnf(self, node):
+ return node['nodeType'].upper().find('.PNF.') >= 0 or node['nodeType'].upper().endswith('.PNF')
+
+ def isCp(self, node):
+ return node['nodeType'].upper().find('.CP.') >= 0 or node['nodeType'].upper().endswith('.CP')
+
+ def isVl(self, node):
+ return node['nodeType'].upper().find('.VIRTUALLINK.') >= 0 or node['nodeType'].upper().find('.VL.') >= 0 or \
+ node['nodeType'].upper().endswith('.VIRTUALLINK') or node['nodeType'].upper().endswith('.VL')
+
+ def get_requirement_node_name(self, req_value):
+ return self.get_prop_from_obj(req_value, 'node')
+
+ def get_prop_from_obj(self, obj, prop):
+ if isinstance(obj, str):
+ return obj
+ if (isinstance(obj, dict) and prop in obj):
+ return obj[prop]
+ return None
+
+ def getNodeDependencys(self, node):
+ return self.getRequirementByName(node, 'dependency')
+
+ def getVirtualLinks(self, node):
+ return self.getRequirementByName(node, 'virtualLink')
+
+ def getVirtualbindings(self, node):
+ return self.getRequirementByName(node, 'virtualbinding')
+
+
+ def getRequirementByName(self, node, requirementName):
+ requirements = []
+ if 'requirements' in node:
+ for item in node['requirements']:
+ for key, value in item.items():
+ if key == requirementName:
+ requirements.append(value)
+ return requirements
+
+ def get_networks(self, node):
+ rets = []
+ if 'requirements' in node:
+ for item in node['requirements']:
+ for key, value in item.items():
+ if key.upper().find('VIRTUALLINK') >=0:
+ rets.append({"key_name":key, "vl_id":self.get_requirement_node_name(value)})
+ return rets
+
+ def _verify_value(self, value, inputs, parsed_params):
+ if isinstance(value, str):
+ return self._verify_string(inputs, parsed_params, value)
+ if isinstance(value, list) or isinstance(value, dict):
+ return self._verify_object(value, inputs, parsed_params)
+ return value
+
+ def _verify_object(self, value, inputs, parsed_params):
+ s = self._verify_string(inputs, parsed_params, json.dumps(value))
+ return json.loads(s)
+
+ def _get_input_name(self, getInput):
+ input_name = getInput.split(':')[1]
+ input_name = input_name.strip()
+ return input_name.replace('"', '').replace('}', '')
+
+ def _verify_string(self, inputs, parsed_params, value):
+ getInputs = re.findall(r'{"get_input": "[a-zA-Z_0-9]+"}', value)
+ for getInput in getInputs:
+ input_name = self._get_input_name(getInput)
+ if parsed_params and input_name in parsed_params:
+ value = value.replace(getInput, json.dumps(parsed_params[input_name]))
+ else:
+ for input_def in inputs:
+ if input_def.default and input_name == input_def.name:
+ value = value.replace(getInput, json.dumps(input_def.default))
+ return value
+
+ def get_node_vl_id(self, node):
+ vl_ids = map(lambda x: self.get_requirement_node_name(x), self.getVirtualLinks(node))
+ if len(vl_ids) > 0:
+ return vl_ids[0]
+ return ""
+
+ def get_node_by_name(self, node_templates, name):
+ for node in node_templates:
+ if node['name'] == name:
+ return node
+ return None
\ No newline at end of file
--- /dev/null
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+def convert_nsd(nsd_object):
+ pass
+
+def convert_vnfd(vnfd_object):
+ pass
\ No newline at end of file
--- /dev/null
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+from toscaparser.dataentity import DataEntity
+from toscaparser.elements.constraints import Schema
+from toscaparser.common.exception import ExceptionCollector
+
+class DataEntityExt(object):
+ '''A complex data value entity ext.'''
+
+ @staticmethod
+ def validate_datatype(type, value, entry_schema=None, custom_def=None):
+ if value:
+ if (type == Schema.STRING):
+ return str(value)
+ elif type == Schema.FLOAT:
+ try:
+ return float(value)
+ except Exception:
+ ExceptionCollector.appendException(ValueError(('"%s" is not an float.') % value))
+
+ return DataEntity.validate_datatype(type, value, entry_schema, custom_def)
+ return value
+
--- /dev/null
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import functools
+
+from catalog.pub.utils.toscaparser.basemodel import BaseInfoModel
+
+
+class EtsiNsdInfoModel(BaseInfoModel):
+
+ def __init__(self, path, params):
+ tosca = self.buildToscaTemplate(path, params)
+ self.parseModel(tosca)
+
+ def parseModel(self, tosca):
+ self.buidMetadata(tosca)
+ if hasattr(tosca, 'topology_template') and hasattr(tosca.topology_template, 'inputs'):
+ self.inputs = self.buildInputs(tosca.topology_template.inputs)
+
+ nodeTemplates = map(functools.partial(self.buildNode, inputs=tosca.inputs, parsed_params=tosca.parsed_params),
+ tosca.nodetemplates)
+
+ self.vnfs = self._get_all_vnf(nodeTemplates)
+ self.pnfs = self._get_all_pnf(nodeTemplates)
+ self.vls = self.get_all_vl(nodeTemplates)
+ self.cps = self.get_all_cp(nodeTemplates)
+ self.routers = self.get_all_router(nodeTemplates)
+ self.fps = self._get_all_fp(nodeTemplates)
+ self.vnffgs = self._get_all_vnffg(tosca.topology_template.groups)
+ self.server_groups = self.get_all_server_group(tosca.topology_template.groups)
+
+
+ def buildInputs(self, top_inputs):
+ ret = {}
+ for tmpinput in top_inputs:
+ tmp = {}
+ tmp['type'] = tmpinput.type
+ tmp['description'] = tmpinput.description
+ tmp['default'] = tmpinput.default
+
+ ret[tmpinput.name] = tmp
+ return ret
+
+ def buildNode(self, nodeTemplate, inputs, parsed_params):
+ ret ={}
+ ret['name'] = nodeTemplate.name
+ ret['nodeType'] = nodeTemplate.type
+ if 'description' in nodeTemplate.entity_tpl:
+ ret['description'] = nodeTemplate.entity_tpl['description']
+ else:
+ ret['description'] = ''
+ props = self.buildProperties(nodeTemplate, parsed_params)
+ ret['properties'] = self.verify_properties(props, inputs, parsed_params)
+ ret['requirements'] = self.build_requirements(nodeTemplate)
+ self.buildCapabilities(nodeTemplate, inputs, ret)
+ self.buildArtifacts(nodeTemplate, inputs, ret)
+ interfaces = self.build_interfaces(nodeTemplate)
+ if interfaces: ret['interfaces'] = interfaces
+ return ret
+
+ def _get_all_vnf(self, nodeTemplates):
+ vnfs = []
+ for node in nodeTemplates:
+ if self.isVnf(node):
+ vnf = {}
+ vnf['vnf_id'] = node['name']
+ vnf['description'] = node['description']
+ vnf['properties'] = node['properties']
+ vnf['dependencies'] = map(lambda x: self.get_requirement_node_name(x), self.getNodeDependencys(node))
+ vnf['networks'] = self.get_networks(node)
+
+ vnfs.append(vnf)
+ return vnfs
+
+ def _get_all_pnf(self, nodeTemplates):
+ pnfs = []
+ for node in nodeTemplates:
+ if self.isPnf(node):
+ pnf = {}
+ pnf['pnf_id'] = node['name']
+ pnf['description'] = node['description']
+ pnf['properties'] = node['properties']
+ pnf['cps'] = self.getVirtalBindingCpIds(node, nodeTemplates)
+
+ pnfs.append(pnf)
+ return pnfs
+
+ def getVirtalBindingCpIds(self, node, nodeTemplates):
+ return map(lambda x: x['name'], self.getVirtalBindingCps(node, nodeTemplates))
+
+ def getVirtalBindingCps(self, node, nodeTemplates):
+ cps = []
+ for tmpnode in nodeTemplates:
+ if 'requirements' in tmpnode:
+ for item in tmpnode['requirements']:
+ for key, value in item.items():
+ if key.upper().startswith('VIRTUALBINDING'):
+ req_node_name = self.get_requirement_node_name(value)
+ if req_node_name != None and req_node_name == node['name']:
+ cps.append(tmpnode)
+ return cps
+
+ def get_all_vl(self, nodeTemplates):
+ vls = []
+ for node in nodeTemplates:
+ if self.isVl(node):
+ vl = {}
+ vl['vl_id'] = node['name']
+ vl['description'] = node['description']
+ vl['properties'] = node['properties']
+ vl['route_external'] = False
+ vl['route_id'] = self._get_vl_route_id(node)
+ vls.append(vl)
+ if self._isExternalVL(node):
+ vl = {}
+ vl['vl_id'] = node['name']
+ vl['description'] = node['description']
+ vl['properties'] = node['properties']
+ vl['route_external'] = True
+ vls.append(vl)
+ return vls
+
+ def _get_vl_route_id(self, node):
+ route_ids = map(lambda x: self.get_requirement_node_name(x),
+ self.getRequirementByName(node, 'virtual_route'))
+ if len(route_ids) > 0:
+ return route_ids[0]
+ return ""
+
+ def _isExternalVL(self, node):
+ return node['nodeType'].upper().find('.ROUTEEXTERNALVL') >= 0
+
+ def get_all_cp(self, nodeTemplates):
+ cps = []
+ for node in nodeTemplates:
+ if self.isCp(node):
+ cp = {}
+ cp['cp_id'] = node['name']
+ cp['cpd_id'] = node['name']
+ cp['description'] = node['description']
+ cp['properties'] = node['properties']
+ cp['vl_id'] = self.get_node_vl_id(node)
+ binding_node_ids = map(lambda x: self.get_requirement_node_name(x), self.getVirtualbindings(node))
+ # cp['vnf_id'] = self._filter_vnf_id(binding_node_ids, nodeTemplates)
+ cp['pnf_id'] = self._filter_pnf_id(binding_node_ids, nodeTemplates)
+ vls = self.buil_cp_vls(node)
+ if len(vls) > 1:
+ cp['vls'] = vls
+ cps.append(cp)
+ return cps
+
+ def buil_cp_vls(self, node):
+ return map(lambda x: self._build_cp_vl(x), self.getVirtualLinks(node))
+
+ def _build_cp_vl(self, req):
+ cp_vl = {}
+ cp_vl['vl_id'] = self.get_prop_from_obj(req, 'node')
+ relationship = self.get_prop_from_obj(req, 'relationship')
+ if relationship != None:
+ properties = self.get_prop_from_obj(relationship, 'properties')
+ if properties != None and isinstance(properties, dict):
+ for key, value in properties.items():
+ cp_vl[key] = value
+ return cp_vl
+
+ def _filter_pnf_id(self, node_ids, node_templates):
+ for node_id in node_ids:
+ node = self.get_node_by_name(node_templates, node_id)
+ if self.isPnf(node):
+ return node_id
+ return ""
+
+ def get_all_router(self, nodeTemplates):
+ rets = []
+ for node in nodeTemplates:
+ if self._isRouter(node):
+ ret = {}
+ ret['router_id'] = node['name']
+ ret['description'] = node['description']
+ ret['properties'] = node['properties']
+ ret['external_vl_id'] = self._get_router_external_vl_id(node)
+ ret['external_ip_addresses'] = self._get_external_ip_addresses(node)
+
+ rets.append(ret)
+ return rets
+
+ def _isRouter(self, node):
+ return node['nodeType'].upper().find('.ROUTER.') >= 0 or node['nodeType'].upper().endswith('.ROUTER')
+
+ def _get_router_external_vl(self, node):
+ return self.getRequirementByName(node, 'external_virtual_link')
+
+ def _get_router_external_vl_id(self, node):
+ ids = map(lambda x: self.get_requirement_node_name(x), self._get_router_external_vl(node))
+ if len(ids) > 0:
+ return ids[0]
+ return ""
+
+ def _get_external_ip_addresses(self, node):
+ external_vls = self._get_router_external_vl(node)
+ if len(external_vls) > 0:
+ if 'relationship' in external_vls[0] and 'properties' in external_vls[0]['relationship'] and 'router_ip_address' in external_vls[0]['relationship']['properties']:
+ return external_vls[0]['relationship']['properties']['router_ip_address']
+ return []
+
+ def _get_all_fp(self, nodeTemplates):
+ fps = []
+ for node in nodeTemplates:
+ if self._isFp(node):
+ fp = {}
+ fp['fp_id'] = node['name']
+ fp['description'] = node['description']
+ fp['properties'] = node['properties']
+ fp['forwarder_list'] = self._getForwarderList(node, nodeTemplates)
+
+ fps.append(fp)
+ return fps
+
+ def _isFp(self, node):
+ return node['nodeType'].upper().find('.FP.') >= 0 or node['nodeType'].upper().find('.SFP.') >= 0 or node[
+ 'nodeType'].upper().endswith('.FP') or node['nodeType'].upper().endswith('.SFP')
+
+ def _getForwarderList(self, node, node_templates):
+ forwarderList = []
+ if 'requirements' in node:
+ for item in node['requirements']:
+ for key, value in item.items():
+ if key == 'forwarder':
+ tmpnode = self.get_node_by_req(node_templates, value)
+ type = 'cp' if self.isCp(tmpnode) else 'vnf'
+ req_node_name = self.get_requirement_node_name(value)
+ if isinstance(value, dict) and 'capability' in value:
+ forwarderList.append(
+ {"type": type, "node_name": req_node_name, "capability": value['capability']})
+ else:
+ forwarderList.append({"type": type, "node_name": req_node_name, "capability": ""})
+
+ return forwarderList
+
+ def get_node_by_req(self, node_templates, req):
+ req_node_name = self.get_requirement_node_name(req)
+ return self.get_node_by_name(node_templates, req_node_name)
+
+ def _get_all_vnffg(self, groups):
+ vnffgs = []
+ for group in groups:
+ if self._isVnffg(group):
+ vnffg = {}
+ vnffg['vnffg_id'] = group.name
+ vnffg['description'] = group.description
+ if 'properties' in group.tpl:
+ vnffg['properties'] = group.tpl['properties']
+ vnffg['members'] = group.members
+
+ vnffgs.append(vnffg)
+ return vnffgs
+
+ def _isVnffg(self, group):
+ return group.type.upper().find('.VNFFG.') >= 0 or group.type.upper().find(
+ '.SFC.') >= 0 or group.type.upper().endswith('.VNFFG') or group.type.upper().endswith('.SFC')
+
+ def get_all_server_group(self, groups):
+ rets = []
+ for group in groups:
+ if self._isServerGroup(group):
+ ret = {}
+ ret['group_id'] = group.name
+ ret['description'] = group.description
+ if 'properties' in group.tpl:
+ ret['properties'] = group.tpl['properties']
+ ret['members'] = group.members
+
+ rets.append(ret)
+ return rets
+
+ def _isServerGroup(self, group):
+ return group.type.upper().find('.AFFINITYORANTIAFFINITYGROUP.') >= 0 or group.type.upper().endswith(
+ '.AFFINITYORANTIAFFINITYGROUP')
--- /dev/null
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from os import R_OK, access
+
+from catalog.pub.exceptions import NSLCMException
+from toscaparser.tosca_template import ToscaTemplate
+
+def parse_nsd_model(path, input_parameters):
+ isexist = check_file_exist(path)
+ if isexist:
+ nsd_tpl = parse_nsd_csar(path, input_parameters)
+ else:
+ raise NSLCMException('%s is not exist.' % path)
+ return nsd_tpl
+
+
+def parse_vnfd_model(path, input_parameters):
+ isexist = check_file_exist(path)
+ if isexist:
+ vnfd_tpl = parse_vnfd_csar(path, input_parameters)
+ else:
+ raise NSLCMException('%s is not exist.' % path)
+ return vnfd_tpl
+
+def check_file_exist(path):
+ if path.exists(path) and path.isfile(path) and access(path, R_OK):
+ return True
+ else:
+ return False
+
+def parse_nsd_csar(path, input_parameters=[], a_file=True):
+ nsd_object = None
+ nsd_object = ToscaTemplate(path, input_parameters)
+ return nsd_object
+
+
+def parse_vnfd_csar(path, input_parameters=[], a_file=True):
+ vnfd_object = None
+ vnfd_object = ToscaTemplate(path, input_parameters)
+ return vnfd_object
\ No newline at end of file
--- /dev/null
+# Copyright 2017 ZTE Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from catalog.pub.utils.toscaparser import EtsiNsdInfoModel
+
+
+class EtsiVnfdInfoModel(EtsiNsdInfoModel):
+
+ def __init__(self, path, params):
+ super(EtsiVnfdInfoModel, self).__init__(path, params)