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.
20 from lcm.pub.database.models import NSInstModel, VLInstModel, FPInstModel, NfInstModel
21 from lcm.pub.exceptions import NSLCMException
22 from lcm.pub.msapi.nslcm import call_from_ns_cancel_resource
23 from lcm.pub.utils.jobutil import JobUtil
24 from lcm.pub.utils.values import ignore_case_get
25 from lcm.pub.utils import restcall
26 from lcm.ns.const import OWNER_TYPE
30 logger = logging.getLogger(__name__)
33 class TerminateNsService(threading.Thread):
34 def __init__(self, ns_inst_id, terminate_type, terminate_timeout, job_id):
35 threading.Thread.__init__(self)
36 self.ns_inst_id = ns_inst_id
37 self.terminate_type = terminate_type
38 self.terminate_timeout = terminate_timeout
43 if not NSInstModel.objects.filter(id=self.ns_inst_id):
44 JobUtil.add_job_status(self.job_id, 100, "Need not terminate.", '')
46 JobUtil.add_job_status(self.job_id, 10, "Starting terminate...", '')
48 self.cancel_sfc_list()
49 self.cancel_vnf_list()
52 NSInstModel.objects.filter(id=self.ns_inst_id).update(status='null')
53 JobUtil.add_job_status(self.job_id, 100, "ns terminate ends.", '')
54 except NSLCMException as e:
55 JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message)
56 except Exception as ex:
57 logger.error(ex.message)
58 logger.error(traceback.format_exc())
59 JobUtil.add_job_status(self.job_id, JOB_ERROR, "ns terminate fail.")
61 def cancel_vl_list(self):
62 array_vlinst = VLInstModel.objects.filter(ownertype=OWNER_TYPE.NS, ownerid=self.ns_inst_id)
64 logger.info("[cancel_vl_list] no vlinst attatch to ns_inst_id: %s" % self.ns_inst_id)
66 step_progress = 20 / len(array_vlinst)
68 for vlinst in array_vlinst:
69 delete_result = "failed"
70 cur_progress += step_progress
72 ret = call_from_ns_cancel_resource('vl', vlinst.vlinstanceid)
74 result = json.JSONDecoder().decode(ret[1]).get("result", "")
75 if str(result) == '0':
76 delete_result = "success"
77 except Exception as e:
78 logger.error("[cancel_vl_list] error[%s]!" % e.message)
79 logger.error(traceback.format_exc())
80 job_msg = "Delete vlinst:[%s] %s." % (vlinst.vlinstanceid, delete_result)
81 JobUtil.add_job_status(self.job_id, cur_progress, job_msg)
83 def cancel_sfc_list(self):
84 array_sfcinst = FPInstModel.objects.filter(nsinstid=self.ns_inst_id)
86 logger.info("[cancel_sfc_list] no sfcinst attatch to ns_inst_id: %s" % self.ns_inst_id)
88 step_progress = 20 / len(array_sfcinst)
90 for sfcinst in array_sfcinst:
91 cur_progress += step_progress
92 delete_result = "failed"
94 ret = call_from_ns_cancel_resource('sfc', sfcinst.sfcid)
96 result = json.JSONDecoder().decode(ret[1]).get("result", "")
97 if str(result) == '0':
98 delete_result = "success"
99 except Exception as e:
100 logger.error("[cancel_sfc_list] error[%s]!" % e.message)
101 logger.error(traceback.format_exc())
102 job_msg = "Delete sfcinst:[%s] %s." % (sfcinst.sfcid, delete_result)
103 JobUtil.add_job_status(self.job_id, cur_progress, job_msg)
105 def cancel_vnf_list(self):
106 array_vnfinst = NfInstModel.objects.filter(ns_inst_id=self.ns_inst_id)
107 if not array_vnfinst:
108 logger.info("[cancel_vnf_list] no vnfinst attatch to ns_inst_id: %s" % self.ns_inst_id)
110 step_progress = 20 / len(array_vnfinst)
112 for vnfinst in array_vnfinst:
113 cur_progress += step_progress
114 delete_result = "failed"
116 if self.delete_vnf(vnfinst.nfinstid):
117 delete_result = "success"
118 except Exception as e:
119 logger.error("[cancel_vnf_list] error[%s]!" % e.message)
120 logger.error(traceback.format_exc())
121 job_msg = "Delete vnfinst:[%s] %s." % (vnfinst.nfinstid, delete_result)
122 JobUtil.add_job_status(self.job_id, cur_progress, job_msg)
124 def delete_vnf(self, nf_instid):
125 ret = call_from_ns_cancel_resource('vnf', nf_instid)
128 job_info = json.JSONDecoder().decode(ret[1])
129 vnf_job_id = ignore_case_get(job_info, "jobid")
130 return self.wait_delete_vnf_job_finish(vnf_job_id)
132 def wait_delete_vnf_job_finish(self, vnf_job_id):
136 response_id, new_response_id = 0, 0
137 job_end_normal, job_timeout = False, True
138 while count < retry_count:
140 time.sleep(interval_second)
141 uri = "/api/nslcm/v1/jobs/%s?responseId=%s" % (vnf_job_id, response_id)
142 ret = restcall.req_by_msb(uri, "GET")
144 logger.error("Failed to query job: %s:%s", ret[2], ret[1])
146 job_result = json.JSONDecoder().decode(ret[1])
147 if "responseDescriptor" not in job_result:
148 logger.error("Job(%s) does not exist.", vnf_job_id)
150 progress = job_result["responseDescriptor"]["progress"]
151 new_response_id = job_result["responseDescriptor"]["responseId"]
152 job_desc = job_result["responseDescriptor"]["statusDescription"]
153 if new_response_id != response_id:
154 logger.debug("%s:%s:%s", progress, new_response_id, job_desc)
155 response_id = new_response_id
157 if progress == JOB_ERROR:
159 logger.error("Job(%s) failed: %s", vnf_job_id, job_desc)
161 elif progress == 100:
162 job_end_normal, job_timeout = True, False
163 logger.info("Job(%s) ended normally", vnf_job_id)
166 logger.error("Job(%s) timeout", vnf_job_id)
167 return job_end_normal