1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
|
# Copyright 2017 Intel 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 threading
import time
import traceback
from lcm.ns.const import NS_INST_STATUS
from lcm.pub.database.models import JobModel, NSInstModel, NfInstModel, VNFCInstModel, VmInstModel
from lcm.pub.exceptions import NSLCMException
from lcm.pub.utils.jobutil import JobUtil, JOB_MODEL_STATUS
from lcm.pub.utils.values import ignore_case_get
from lcm.ns_vnfs.biz.heal_vnfs import NFHealService
from lcm.ns.biz.ns_lcm_op_occ import NsLcmOpOcc
JOB_ERROR = 255
logger = logging.getLogger(__name__)
class NSHealService(threading.Thread):
def __init__(self, ns_instance_id, request_data, job_id):
super(NSHealService, self).__init__()
self.ns_instance_id = ns_instance_id
self.request_data = request_data
self.job_id = job_id
self.occ_id = NsLcmOpOcc.create(ns_instance_id, "HEAL", "PROCESSING", False, request_data)
self.heal_vnf_data = ''
self.heal_ns_data = ''
def run(self):
try:
self.do_biz()
except NSLCMException as e:
JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message)
NsLcmOpOcc.update(self.occ_id, operationState="FAILED", error=e.message)
except Exception as e:
logger.error(traceback.format_exc())
JobUtil.add_job_status(self.job_id, JOB_ERROR, 'ns heal fail')
NsLcmOpOcc.update(self.occ_id, operationState="FAILED", error=e.message)
def do_biz(self):
self.update_job(1, desc='ns heal start')
self.get_and_check_params()
self.update_ns_status(NS_INST_STATUS.HEALING)
self.do_heal()
self.update_ns_status(NS_INST_STATUS.ACTIVE)
self.update_job(100, desc='ns heal success')
NsLcmOpOcc.update(self.occ_id, "COMPLETED")
def get_and_check_params(self):
ns_info = NSInstModel.objects.filter(id=self.ns_instance_id)
if not ns_info:
logger.error('NS [id=%s] does not exist' % self.ns_instance_id)
raise NSLCMException(
'NS [id=%s] does not exist' % self.ns_instance_id)
self.heal_ns_data = ignore_case_get(self.request_data, 'healNsData')
self.heal_vnf_data = ignore_case_get(self.request_data, 'healVnfData')
if self.heal_ns_data and self.heal_vnf_data:
logger.error('healNsData and healVnfData can not exist together')
raise NSLCMException(
'healNsData and healVnfData can not exist together')
if not self.heal_ns_data and not self.heal_vnf_data:
logger.error(
'healNsData and healVnfData parameters does not exist or value is incorrect.')
raise NSLCMException(
'healNsData and healVnfData parameters does not exist or value is incorrect.')
def do_heal(self):
if self.heal_vnf_data:
vnf_heal_params = self.prepare_vnf_heal_params(self.heal_vnf_data)
status = self.do_vnf_or_ns_heal(vnf_heal_params, 15)
if status is JOB_MODEL_STATUS.FINISHED:
logger.info('nf[%s] heal handle end' %
vnf_heal_params.get('vnfInstanceId'))
self.update_job(90,
desc='nf[%s] heal handle end' % vnf_heal_params.get('vnfInstanceId'))
else:
logger.error('nf heal failed')
raise NSLCMException('nf heal failed')
else:
ns_heal_params = self.prepare_ns_heal_params(self.heal_ns_data)
for ns_heal_param in ns_heal_params:
status = self.do_vnf_or_ns_heal(ns_heal_param, 15)
if status is JOB_MODEL_STATUS.FINISHED:
logger.info('nf[%s] heal handle end' %
ns_heal_param.get('vnfInstanceId'))
self.update_job(90,
desc='nf[%s] heal handle end' % ns_heal_param.get('vnfInstanceId'))
else:
logger.error('nf heal failed')
raise NSLCMException('nf heal failed')
def do_vnf_or_ns_heal(self, heal_param, progress):
instance_id = heal_param.get('vnfInstanceId')
nf_service = NFHealService(instance_id, heal_param)
nf_service.start()
self.update_job(
progress, desc='nf[%s] heal handle start' % instance_id)
status = self.wait_job_finish(nf_service.job_id)
return status
def prepare_ns_heal_params(self, ns_data):
degree_healing = ignore_case_get(ns_data, 'degreeHealing')
if not degree_healing:
logger.error('degreeHealing does not exist.')
raise NSLCMException('degreeHealing does not exist.')
ns_instance_id = self.ns_instance_id
cause = ''
action = ignore_case_get(ns_data, 'actionsHealing')
if degree_healing == "HEAL_RESTORE":
ns_inst_infos = NfInstModel.objects.filter(
ns_inst_id=self.ns_instance_id)
if not ns_inst_infos.exists():
raise NSLCMException(
'NSInsts(%s) does not exist' % self.ns_instance_id)
result_arr = []
for ns_inst_info in ns_inst_infos:
vnfc_insts = VNFCInstModel.objects.filter(
nfinstid=ns_inst_info.nfinstid)
# If a condition is not met, will it all terminate?
if not vnfc_insts.exists():
raise NSLCMException(
'vnfcinsts(%s) does not exist' % ns_inst_info.nfinstid)
for vnfc_inst in vnfc_insts:
vm_id = vnfc_inst.vmid
vdu_id = vnfc_inst.vduid
vm_inst_info = VmInstModel.objects.filter(vmid=vm_id)
if not vm_inst_info.exists():
raise NSLCMException(
'vminstinfo(%s) does not exist' % vm_id)
vm_name = vm_inst_info[0].vmname
result = {
"vnfInstanceId": ns_instance_id,
"cause": cause,
"additionalParams": {
"action": action,
"actionvminfo": {
"vmid": vm_id,
"vduid": vdu_id,
"vmname": vm_name
}
}
}
result_arr.append(result)
return result_arr
else:
logger.error(
'The degree of healing dose not exist or value is incorrect.')
raise NSLCMException(
'The degree of healing dose not exist or value is incorrect.')
def prepare_vnf_heal_params(self, vnf_data):
vnf_instance_id = ignore_case_get(vnf_data, 'vnfInstanceId')
if not vnf_instance_id:
logger.error('vnfinstanceid does not exist or value is incorrect.')
raise NSLCMException(
'vnfinstanceid does not exist or value is incorrect.')
cause = ignore_case_get(vnf_data, 'cause')
additional_params = ignore_case_get(vnf_data, 'additionalParams')
action = ignore_case_get(additional_params, 'action')
action_vm_info = ignore_case_get(additional_params, 'actionvminfo')
vm_id = ignore_case_get(action_vm_info, 'vmid')
vdu_id = ignore_case_get(action_vm_info, 'vduid')
vm_name = ignore_case_get(action_vm_info, 'vmname')
result = {
"vnfInstanceId": vnf_instance_id,
"cause": cause,
"additionalParams": {
"action": action,
"actionvminfo": {
"vmid": vm_id,
"vduid": vdu_id,
"vmname": vm_name
}
}
}
return result
@staticmethod
def wait_job_finish(sub_job_id, timeout=3600):
query_interval = 2
start_time = end_time = datetime.datetime.now()
while (end_time - start_time).seconds < timeout:
job_result = JobModel.objects.get(jobid=sub_job_id)
time.sleep(query_interval)
end_time = datetime.datetime.now()
if job_result.progress == 100:
return JOB_MODEL_STATUS.FINISHED
elif job_result.progress > 100:
return JOB_MODEL_STATUS.ERROR
else:
continue
return JOB_MODEL_STATUS.TIMEOUT
def update_job(self, progress, desc=''):
JobUtil.add_job_status(self.job_id, progress, desc)
def update_ns_status(self, status):
NSInstModel.objects.filter(
id=self.ns_instance_id).update(status=status)
|