1 # Copyright 2016 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.
18 from threading import Thread
19 from lcm.ns.const import OWNER_TYPE
21 from lcm.ns.vnfs.const import VNF_STATUS, NFVO_VNF_INST_TIMEOUT_SECOND, INST_TYPE, INST_TYPE_NAME
22 from lcm.ns.vnfs.wait_job import wait_job_finish
23 from lcm.pub.config.config import REPORT_TO_AAI
24 from lcm.pub.database.models import NfPackageModel, NfInstModel, NSInstModel, VmInstModel, VNFFGInstModel, VLInstModel
25 from lcm.pub.exceptions import NSLCMException
26 from lcm.pub.msapi.aai import create_vnf_aai, create_vserver_aai
27 from lcm.pub.msapi.extsys import get_vnfm_by_id, split_vim_to_owner_region, get_vim_by_id
28 from lcm.pub.msapi.resmgr import create_vnf, create_vnf_creation_info
29 from lcm.pub.msapi.vnfmdriver import send_nf_init_request
30 from lcm.pub.utils.jobutil import JOB_MODEL_STATUS, JobUtil, JOB_TYPE
31 from lcm.pub.utils.share_lock import do_biz_with_share_lock
32 from lcm.pub.utils.timeutil import now_time
33 from lcm.pub.utils.values import ignore_case_get
35 logger = logging.getLogger(__name__)
38 def prepare_create_params():
39 nf_inst_id = str(uuid.uuid4())
40 NfInstModel(nfinstid=nf_inst_id, status=VNF_STATUS.INSTANTIATING, create_time=now_time(),
41 lastuptime=now_time()).save()
42 job_id = JobUtil.create_job(INST_TYPE_NAME.VNF, JOB_TYPE.CREATE_VNF, nf_inst_id)
43 JobUtil.add_job_status(job_id, 0, 'create vnf record in database.', 0)
44 return nf_inst_id, job_id
47 class CreateVnfs(Thread):
48 def __init__(self, data, nf_inst_id, job_id):
49 super(CreateVnfs, self).__init__()
51 self.nf_inst_id = nf_inst_id
56 self.ns_inst_name = ''
59 self.vnf_inst_name = ''
60 self.vnfm_inst_id = ''
62 self.nf_package_info = ''
63 self.vnfm_nf_inst_id = ''
65 self.vnfm_inst_name = ''
71 self.check_nf_name_exist()
73 self.check_nf_package_valid()
74 self.send_nf_init_request_to_vnfm()
75 self.send_get_vnfm_request_to_extsys()
76 self.send_create_vnf_request_to_resmgr()
77 self.wait_vnfm_job_finish()
78 self.write_vnf_creation_info()
79 self.save_info_to_db()
81 self.create_vnf_in_aai()
82 self.create_vserver_in_aai()
83 except NSLCMException as e:
84 self.vnf_inst_failed_handle(e.message)
86 logger.error(traceback.format_exc())
87 self.vnf_inst_failed_handle('unexpected exception')
90 self.ns_inst_id = self.data['ns_instance_id']
91 vnf_index = int(float(self.data['vnf_index'])) - 1
92 additional_vnf_info = self.data['additional_param_for_vnf'][vnf_index]
93 self.vnf_id = ignore_case_get(additional_vnf_info, 'vnfProfileId')
94 additional_param = ignore_case_get(additional_vnf_info, 'additionalParam')
95 self.vnfm_inst_id = ignore_case_get(additional_param, 'vnfmInstanceId')
96 para = ignore_case_get(additional_param, 'inputs')
97 self.inputs = json.loads(para) if isinstance(para, (str, unicode)) else para
98 self.vim_id = ignore_case_get(additional_param, 'vimId')
99 self.vnfd_id = ignore_case_get(additional_param, 'vnfdId')
101 def check_nf_name_exist(self):
102 is_exist = NfInstModel.objects.filter(nf_name=self.vnf_inst_name).exists()
104 logger.error('The name of NF instance already exists.')
105 raise NSLCMException('The name of NF instance already exists.')
107 def get_vnfd_id(self):
109 logger.debug("need not get vnfd_id")
110 self.nsd_model={'vnfs': [], 'vls': [], 'vnffgs': []}
111 self.vnf_inst_name = self.vnfd_id + str(uuid.uuid4())
112 self.vnf_inst_name = self.vnf_inst_name[:30]
114 ns_inst_info = NSInstModel.objects.get(id=self.ns_inst_id)
115 self.ns_inst_name = ns_inst_info.name
116 self.nsd_model = json.loads(ns_inst_info.nsd_model)
117 for vnf_info in self.nsd_model['vnfs']:
118 if self.vnf_id == vnf_info['vnf_id']:
119 self.vnfd_id = vnf_info['properties']['id']
120 if 'name' not in vnf_info['properties']:
121 self.vnf_inst_name = self.vnfd_id + str(uuid.uuid4())
123 self.vnf_inst_name = vnf_info['properties']['name'] + str(uuid.uuid4())
124 self.vnf_inst_name = self.vnf_inst_name[:30]
126 logger.error('Can not found vnf in nsd model')
127 raise NSLCMException('Can not found vnf in nsd model')
129 def check_nf_package_valid(self):
130 nf_package_info = NfPackageModel.objects.filter(vnfdid=self.vnfd_id)
131 if not nf_package_info:
132 logger.info('NF package not exist.')
133 raise NSLCMException('NF package not exist.')
134 self.nf_package_info = nf_package_info[0]
135 self.vnfd_model = json.loads(self.nf_package_info.vnfdmodel)
137 def get_virtual_link_info(self, vnf_id):
138 virtual_link_list, ext_virtual_link = [], []
139 for vnf_info in self.nsd_model['vnfs']:
140 if vnf_info['vnf_id'] != vnf_id:
142 for network_info in vnf_info['networks']:
143 vl_instance = VLInstModel.objects.get(
144 vldid=network_info['vl_id'],
145 ownertype=OWNER_TYPE.NS,
146 ownerid=self.ns_inst_id)
147 vl_instance_id = vl_instance.vlinstanceid
148 network_name, subnet_name = self.get_network_info_of_vl(network_info['vl_id'])
149 virtual_link_list.append({
150 'network_name': network_name,
151 'key_name': network_info['key_name'],
152 'subnetwork_name': subnet_name,
153 'vl_instance_id': vl_instance_id
155 ext_virtual_link.append({
156 "vlInstanceId": vl_instance_id,
157 "resourceId": vl_instance.relatednetworkid,
158 "resourceSubnetId": vl_instance.relatedsubnetworkid,
159 "cpdId": self.get_cpd_id_of_vl(network_info['key_name']),
161 "vimid": vl_instance.vimid
164 return virtual_link_list, ext_virtual_link
166 def get_cpd_id_of_vl(self, vl_key):
167 for cpd in self.vnfd_model["vnf_exposed"]["external_cps"]:
168 if vl_key == cpd["key_name"]:
172 def get_network_info_of_vl(self, vl_id):
173 for vnf_info in self.nsd_model['vls']:
174 if vnf_info['vl_id'] == vl_id:
175 return vnf_info['properties']['network_name'], vnf_info['properties']['name']
178 def send_nf_init_request_to_vnfm(self):
179 virtual_link_list, ext_virtual_link = self.get_virtual_link_info(self.vnf_id)
180 req_param = json.JSONEncoder().encode({
181 'vnfInstanceName': self.vnf_inst_name,
182 'vnfPackageId': self.nf_package_info.nfpackageid,
183 'vnfDescriptorId': self.vnfd_id,
184 'extVirtualLink': ext_virtual_link,
185 'additionalParam': {"inputs": self.inputs,
186 "vimId": self.vim_id,
187 "extVirtualLinks": virtual_link_list}})
188 rsp = send_nf_init_request(self.vnfm_inst_id, req_param)
189 self.vnfm_job_id = ignore_case_get(rsp, 'jobId')
190 self.vnfm_nf_inst_id = ignore_case_get(rsp, 'vnfInstanceId')
192 NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(
193 mnfinstid=self.vnfm_nf_inst_id,
194 nf_name=self.vnf_inst_name,
196 package_id=self.nf_package_info.nfpackageid,
197 vnfm_inst_id=self.vnfm_inst_id,
198 ns_inst_id=self.ns_inst_id,
199 version=self.nf_package_info.vnfversion,
200 vendor=self.nf_package_info.vendor,
201 vnfd_model=self.vnfd_model,
202 input_params=json.JSONEncoder().encode(self.inputs),
203 lastuptime=now_time())
205 def send_get_vnfm_request_to_extsys(self):
206 resp_body = get_vnfm_by_id(self.vnfm_inst_id)
207 self.vnfm_inst_name = ignore_case_get(resp_body, 'name')
209 def send_create_vnf_request_to_resmgr(self):
210 pkg_vnfd = json.loads(self.nf_package_info.vnfdmodel)
212 'nf_inst_id': self.nf_inst_id,
213 'vnfm_nf_inst_id': self.vnfm_nf_inst_id,
214 'vnf_inst_name': self.vnf_inst_name,
215 'ns_inst_id': self.ns_inst_id,
216 'ns_inst_name': self.ns_inst_name,
217 'nf_inst_name': self.vnf_inst_name,
218 'vnfm_inst_id': self.vnfm_inst_id,
219 'vnfm_inst_name': self.vnfm_inst_name,
220 'vnfd_name': pkg_vnfd['metadata'].get('name', 'undefined'),
221 'vnfd_id': self.vnfd_id,
222 'job_id': self.job_id,
223 'nf_inst_status': VNF_STATUS.INSTANTIATING,
224 'vnf_type': pkg_vnfd['metadata'].get('vnf_type', 'undefined'),
225 'nf_package_id': self.nf_package_info.nfpackageid}
228 def wait_vnfm_job_finish(self):
229 ret = wait_job_finish(vnfm_id=self.vnfm_inst_id, vnfo_job_id=self.job_id,
230 vnfm_job_id=self.vnfm_job_id, progress_range=[10, 90],
231 timeout=NFVO_VNF_INST_TIMEOUT_SECOND)
233 if ret != JOB_MODEL_STATUS.FINISHED:
234 logger.error('VNF instantiation failed on VNFM side.')
235 raise NSLCMException('VNF instantiation failed on VNFM side.')
237 def write_vnf_creation_info(self):
238 logger.debug("write_vnf_creation_info start")
239 vm_inst_infos = VmInstModel.objects.filter(insttype=INST_TYPE.VNF, instid=self.nf_inst_id)
241 'nf_inst_id': self.nf_inst_id,
242 'ns_inst_id': self.ns_inst_id,
243 'vnfm_inst_id': self.vnfm_inst_id,
244 'vms': [{'vmId': vm_inst_info.resouceid, 'vmName': vm_inst_info.vmname, 'vmStatus': 'ACTIVE'} for
245 vm_inst_info in vm_inst_infos]}
246 create_vnf_creation_info(data)
247 logger.debug("write_vnf_creation_info end")
249 def save_info_to_db(self):
250 logger.debug("save_info_to_db start")
251 do_biz_with_share_lock("set-vnflist-in-vnffginst-%s" % self.ns_inst_id, self.save_vnf_inst_id_in_vnffg)
252 NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status=VNF_STATUS.ACTIVE, lastuptime=now_time())
253 JobUtil.add_job_status(self.job_id, 100, 'vnf instantiation success', 0)
254 logger.debug("save_info_to_db end")
256 def vnf_inst_failed_handle(self, error_msg):
257 logger.error('VNF instantiation failed, detail message: %s' % error_msg)
258 NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status=VNF_STATUS.FAILED,
259 lastuptime=now_time())
260 JobUtil.add_job_status(self.job_id, 255, 'VNF instantiation failed, detail message: %s' % error_msg, 0)
262 def save_vnf_inst_id_in_vnffg(self):
263 vnffgs = self.nsd_model['vnffgs']
265 if self.vnf_id not in vnffg['members']:
267 vnffg_inst_infos = VNFFGInstModel.objects.filter(vnffgdid=vnffg['vnffg_Id'], nsinstid=self.ns_inst_id)
268 if not vnffg_inst_infos:
269 logger.error('Vnffg instance not exist.')
270 raise NSLCMException('Vnffg instance not exist.')
271 vnf_list = vnffg_inst_infos[0].vnflist
272 vnffg_inst_infos.update(vnf_list=vnf_list + ',' + self.nf_inst_id if vnf_list else self.nf_inst_id)
275 def create_vnf_in_aai(self):
276 logger.debug("CreateVnfs::create_vnf_in_aai::report vnf instance[%s] to aai." % self.nf_inst_id)
278 "vnf-id": self.nf_inst_id,
279 "vnf-name": self.vnf_inst_name,
280 "vnf-type": "vnf-type-test111",
281 "service-id": self.ns_inst_id,
283 "is-closed-loop-disabled": False
285 resp_data, resp_status = create_vnf_aai(self.nf_inst_id, data)
287 logger.debug("Fail to create vnf instance[%s] to aai, resp_status: [%s]." % (self.nf_inst_id, resp_status))
289 logger.debug("Success to create vnf instance[%s] to aai, resp_status: [%s]." % (self.nf_inst_id, resp_status))
291 def create_vserver_in_aai(self):
292 logger.debug("create_vserver_in_aai start!")
293 cloud_owner, cloud_region_id = split_vim_to_owner_region(self.vim_id)
295 # query vim_info from aai
296 vim_info = get_vim_by_id(self.vim_id)
297 tenant_id = vim_info["tenant"]
298 vm_inst_infos = VmInstModel.objects.filter(insttype=INST_TYPE.VNF, instid=self.nf_inst_id)
299 for vm_inst_info in vm_inst_infos:
300 vserver_id = vm_inst_info.resouceid
302 "vserver-id": vm_inst_info.resouceid,
303 "vserver-name": vm_inst_info.vmname,
304 "prov-status": "ACTIVE",
305 "vserver-selflink": "",
307 "is-closed-loop-disabled": False
310 # create vserver instance in aai
311 resp_data, resp_status = create_vserver_aai(cloud_owner, cloud_region_id, tenant_id, vserver_id, data)
314 "Fail to create vserver instance[%s] to aai, resp_status: [%s]." % (vserver_id, resp_status))
317 "Success to create vserver instance[%s] to aai, resp_status: [%s]." % (vserver_id, resp_status))
319 logger.debug("create_vserver_in_aai end!")