1 # Copyright 2016-2018 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.
20 from lcm.pub.config.config import REPORT_TO_AAI
21 from lcm.pub.database.models import NfInstModel, VmInstModel
22 from lcm.pub.exceptions import NSLCMException
23 from lcm.pub.msapi import resmgr
24 from lcm.pub.msapi.aai import query_vnf_aai, delete_vnf_aai, query_vserver_aai, delete_vserver_aai
25 from lcm.pub.msapi.extsys import split_vim_to_owner_region, get_vim_by_id
26 from lcm.pub.msapi.vnfmdriver import send_nf_terminate_request
27 from lcm.pub.utils.jobutil import JOB_MODEL_STATUS, JobUtil
28 from lcm.pub.utils.values import ignore_case_get
29 from lcm.ns_vnfs.const import VNF_STATUS, NFVO_VNF_INST_TIMEOUT_SECOND, INST_TYPE
30 from lcm.ns_vnfs.biz.wait_job import wait_job_finish
31 from lcm.ns_vnfs.biz.subscribe import SubscriptionDeletion
33 logger = logging.getLogger(__name__)
36 class TerminateVnfs(threading.Thread):
37 def __init__(self, data, vnf_inst_id, job_id):
38 threading.Thread.__init__(self)
39 self.vnf_inst_id = vnf_inst_id
41 self.vnfm_inst_id = ''
44 self.terminationType = data['terminationType']
45 self.gracefulTerminationTimeout = data['gracefulTerminationTimeout']
46 if not self.gracefulTerminationTimeout:
47 self.gracefulTerminationTimeout = 120
49 self.gracefulTerminationTimeout = int(self.gracefulTerminationTimeout)
56 self.send_nf_terminate_to_vnfmDriver()
57 self.wait_vnfm_job_finish()
58 self.send_terminate_vnf_to_resMgr()
60 self.delete_vserver_in_aai()
61 self.delete_vnf_in_aai()
62 self.delete_subscription()
63 self.delete_data_from_db()
64 except NSLCMException as e:
65 self.set_job_err(e.message)
66 except Exception as ex:
67 logger.error(traceback.format_exc())
68 self.set_job_err(ex.message)
70 def set_vnf_status(self, vnf_inst_info):
71 vnf_status = vnf_inst_info.status
72 if (vnf_status == VNF_STATUS.TERMINATING):
73 logger.info('[VNF terminate] VNF is dealing by other application,try again later.')
74 raise NSLCMException('[VNF terminate] VNF is dealing by other application,try again later.')
76 vnf_inst_info.status = VNF_STATUS.TERMINATING
79 def get_vnf_inst(self):
80 vnf_inst = NfInstModel.objects.filter(nfinstid=self.vnf_inst_id)
81 if not vnf_inst.exists():
82 logger.warning('[VNF terminate] Vnf terminate [%s] does not exist.' % self.vnf_inst_id)
86 def add_progress(self, progress, status_decs, error_code=""):
87 JobUtil.add_job_status(self.job_id, progress, status_decs, error_code)
90 vnf_inst_info = self.get_vnf_inst()
92 self.add_progress(100, "TERM_VNF_NOT_EXIST_SUCCESS", "finished")
93 self.add_progress(2, "GET_VNF_INST_SUCCESS")
94 self.vnfm_inst_id = vnf_inst_info.vnfm_inst_id
95 self.vnf_uuid = vnf_inst_info.mnfinstid
97 self.add_progress(100, "TERM_VNF_NOT_EXIST_SUCCESS", "finished")
99 def check_nf_valid(self):
100 vnf_inst = NfInstModel.objects.filter(nfinstid=self.vnf_inst_id)
101 if not vnf_inst.exists():
102 logger.warning('[VNF terminate] Vnf instance [%s] is not exist.' % self.vnf_inst_id)
103 raise NSLCMException('[VNF terminate] Vnf instance is not exist.')
105 self.add_progress(100, "TERM_VNF_NOT_EXIST_SUCCESS", "finished")
106 raise NSLCMException('[VNF terminate] Vnf instance is not exist.')
107 self.set_vnf_status(vnf_inst[0])
109 def set_job_err(self, error_msg):
110 logger.error('VNF Terminate failed, detail message: %s' % error_msg)
111 NfInstModel.objects.filter(nfinstid=self.vnf_inst_id).update(status=VNF_STATUS.FAILED)
112 JobUtil.add_job_status(self.job_id, 255, 'VNF Terminate failed, detail message: %s' % error_msg, 0)
114 def send_nf_terminate_to_vnfmDriver(self):
115 req_param = json.JSONEncoder().encode({
116 'terminationType': self.terminationType,
117 'gracefulTerminationTimeout': self.gracefulTerminationTimeout})
118 rsp = send_nf_terminate_request(self.vnfm_inst_id, self.vnf_uuid, req_param)
119 self.vnfm_job_id = ignore_case_get(rsp, 'jobId')
121 def send_terminate_vnf_to_resMgr(self):
122 resmgr.terminate_vnf(self.vnf_inst_id)
124 def wait_vnfm_job_finish(self):
125 if not self.vnfm_job_id:
126 logger.warn("No Job, need not wait")
128 ret = wait_job_finish(vnfm_id=self.vnfm_inst_id,
129 vnfo_job_id=self.job_id,
130 vnfm_job_id=self.vnfm_job_id,
131 progress_range=[10, 90],
132 timeout=NFVO_VNF_INST_TIMEOUT_SECOND)
134 if ret != JOB_MODEL_STATUS.FINISHED:
135 logger.error('VNF terminate failed on VNFM side.')
136 raise NSLCMException('VNF terminate failed on VNFM side.')
138 def delete_subscription(self):
139 SubscriptionDeletion(self.vnfm_inst_id, self.vnf_inst_id).do_biz()
141 def delete_data_from_db(self):
142 NfInstModel.objects.filter(nfinstid=self.vnf_inst_id).delete()
143 JobUtil.add_job_status(self.job_id, 100, 'vnf terminate success', 0)
145 def delete_vnf_in_aai(self):
146 logger.debug("TerminateVnfs::delete_vnf_in_aai::delete vnf instance[%s] in aai." % self.vnf_inst_id)
148 # query vnf instance in aai, get resource_version
149 customer_info = query_vnf_aai(self.vnf_inst_id)
150 resource_version = customer_info["resource-version"]
152 # delete vnf instance from aai
153 resp_data, resp_status = delete_vnf_aai(self.vnf_inst_id, resource_version)
155 "Success to delete vnf[%s] from aai, resp_status: [%s]." % (self.vnf_inst_id, resp_status))
156 except NSLCMException as e:
157 logger.debug("Fail to delete vnf from aai[%s], detail message: %s" % (self.vnf_inst_id, e.message))
159 logger.error(traceback.format_exc())
161 def delete_vserver_in_aai(self):
162 logger.debug("delete_vserver_in_aai start!")
164 vm_inst_infos = VmInstModel.objects.filter(insttype=INST_TYPE.VNF, instid=self.vnf_inst_id)
165 for vm_inst_info in vm_inst_infos:
166 vserver_id = vm_inst_info.resouceid
167 vim_id = vm_inst_info.vimid
168 cloud_owner, cloud_region_id = split_vim_to_owner_region(vim_id)
169 # query vim_info from aai, get tenant
170 vim_info = get_vim_by_id(vim_id)
171 tenant_id = vim_info["tenantId"]
173 # query vserver instance in aai, get resource_version
174 vserver_info = query_vserver_aai(cloud_owner, cloud_region_id, tenant_id, vserver_id)
175 resource_version = vserver_info["resource-version"]
177 # delete vserver instance from aai
178 resp_data, resp_status = delete_vserver_aai(cloud_owner, cloud_region_id,
179 tenant_id, vserver_id, resource_version)
181 "Success to delete vserver instance[%s] from aai, resp_status: [%s]." %
182 (vserver_id, resp_status))
183 logger.debug("delete_vserver_in_aai end!")
184 except NSLCMException as e:
185 logger.debug("Fail to delete vserver from aai, detail message: %s" % e.message)
187 logger.error(traceback.format_exc())