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)
57 logger.error(traceback.format_exc())
58 JobUtil.add_job_status(self.job_id, JOB_ERROR, "ns terminate fail.")
60 def cancel_vl_list(self):
61 array_vlinst = VLInstModel.objects.filter(ownertype=OWNER_TYPE.NS, ownerid=self.ns_inst_id)
63 logger.info("[cancel_vl_list] no vlinst attatch to ns_inst_id: %s" % self.ns_inst_id)
65 step_progress = 20 / len(array_vlinst)
67 for vlinst in array_vlinst:
68 delete_result = "failed"
69 cur_progress += step_progress
71 ret = call_from_ns_cancel_resource('vl', vlinst.vlinstanceid)
73 result = json.JSONDecoder().decode(ret[1]).get("result", "")
74 if str(result) == '0':
75 delete_result = "success"
76 except Exception as e:
77 logger.error("[cancel_vl_list] error[%s]!" % e.message)
78 logger.error(traceback.format_exc())
79 job_msg = "Delete vlinst:[%s] %s." % (vlinst.vlinstanceid, delete_result)
80 JobUtil.add_job_status(self.job_id, cur_progress, job_msg)
82 def cancel_sfc_list(self):
83 array_sfcinst = FPInstModel.objects.filter(nsinstid=self.ns_inst_id)
85 logger.info("[cancel_sfc_list] no sfcinst attatch to ns_inst_id: %s" % self.ns_inst_id)
87 step_progress = 20 / len(array_sfcinst)
89 for sfcinst in array_sfcinst:
90 cur_progress += step_progress
91 delete_result = "failed"
93 ret = call_from_ns_cancel_resource('sfc', sfcinst.sfcid)
95 result = json.JSONDecoder().decode(ret[1]).get("result", "")
96 if str(result) == '0':
97 delete_result = "success"
98 except Exception as e:
99 logger.error("[cancel_sfc_list] error[%s]!" % e.message)
100 logger.error(traceback.format_exc())
101 job_msg = "Delete sfcinst:[%s] %s." % (sfcinst.sfcid, delete_result)
102 JobUtil.add_job_status(self.job_id, cur_progress, job_msg)
104 def cancel_vnf_list(self):
105 array_vnfinst = NfInstModel.objects.filter(ns_inst_id=self.ns_inst_id)
106 if not array_vnfinst:
107 logger.info("[cancel_vnf_list] no vnfinst attatch to ns_inst_id: %s" % self.ns_inst_id)
109 step_progress = 20 / len(array_vnfinst)
111 for vnfinst in array_vnfinst:
112 cur_progress += step_progress
113 delete_result = "failed"
115 if self.delete_vnf(vnfinst.nfinstid):
116 delete_result = "success"
117 except Exception as e:
118 logger.error("[cancel_vnf_list] error[%s]!" % e.message)
119 logger.error(traceback.format_exc())
120 job_msg = "Delete vnfinst:[%s] %s." % (vnfinst.nfinstid, delete_result)
121 JobUtil.add_job_status(self.job_id, cur_progress, job_msg)
123 def delete_vnf(self, nf_instid):
124 ret = call_from_ns_cancel_resource('vnf', nf_instid)
127 job_info = json.JSONDecoder().decode(ret[1])
128 vnf_job_id = ignore_case_get(job_info, "jobid")
129 return self.wait_delete_vnf_job_finish(vnf_job_id)
131 def wait_delete_vnf_job_finish(self, vnf_job_id):
135 response_id, new_response_id = 0, 0
136 job_end_normal, job_timeout = False, True
137 while count < retry_count:
139 time.sleep(interval_second)
140 uri = "/api/nslcm/v1/jobs/%s?responseId=%s" % (vnf_job_id, response_id)
141 ret = restcall.req_by_msb(uri, "GET")
143 logger.error("Failed to query job: %s:%s", ret[2], ret[1])
145 job_result = json.JSONDecoder().decode(ret[1])
146 if "responseDescriptor" not in job_result:
147 logger.error("Job(%s) does not exist.", vnf_job_id)
149 progress = job_result["responseDescriptor"]["progress"]
150 new_response_id = job_result["responseDescriptor"]["responseId"]
151 job_desc = job_result["responseDescriptor"]["statusDescription"]
152 if new_response_id != response_id:
153 logger.debug("%s:%s:%s", progress, new_response_id, job_desc)
154 response_id = new_response_id
156 if progress == JOB_ERROR:
158 logger.error("Job(%s) failed: %s", vnf_job_id, job_desc)
160 elif progress == 100:
161 job_end_normal, job_timeout = True, False
162 logger.info("Job(%s) ended normally", vnf_job_id)
165 logger.error("Job(%s) timeout", vnf_job_id)
166 return job_end_normal