update version of lcm
[vfc/nfvo/lcm.git] / lcm / ns_vnfs / biz / heal_vnfs.py
1 # Copyright 2017 Intel Corporation.
2 #
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
6 #
7 #         http://www.apache.org/licenses/LICENSE-2.0
8 #
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.
14
15 import json
16 import logging
17 import threading
18 import traceback
19
20 from lcm.pub.config.config import MR_IP
21 from lcm.pub.config.config import MR_PORT
22 from lcm.pub.database.models import NfInstModel, VNFCInstModel
23 from lcm.pub.exceptions import NSLCMException
24 from lcm.pub.msapi.vnfmdriver import send_nf_heal_request
25 from lcm.pub.utils import restcall
26 from lcm.pub.utils.jobutil import JobUtil, JOB_TYPE, JOB_MODEL_STATUS
27 from lcm.pub.utils.values import ignore_case_get
28 from lcm.ns_vnfs.const import VNF_STATUS
29 from lcm.ns_vnfs.biz.wait_job import wait_job_finish
30
31 JOB_ERROR = 255
32
33 logger = logging.getLogger(__name__)
34
35
36 class NFHealService(threading.Thread):
37     def __init__(self, vnf_instance_id, data):
38         super(NFHealService, self).__init__()
39         self.vnf_instance_id = vnf_instance_id
40         self.data = data
41         self.job_id = JobUtil.create_job("NF", JOB_TYPE.HEAL_VNF, vnf_instance_id)
42
43         self.nf_model = {}
44         self.nf_additional_params = {}
45         self.nf_heal_params = {}
46         self.m_nf_inst_id = ''
47         self.vnfm_inst_id = ''
48
49     def run(self):
50         try:
51             self.do_biz()
52         except NSLCMException as e:
53             JobUtil.add_job_status(self.job_id, JOB_ERROR, e.message)
54         except:
55             logger.error(traceback.format_exc())
56             JobUtil.add_job_status(self.job_id, JOB_ERROR, 'nf heal fail')
57
58     def do_biz(self):
59         self.update_job(1, desc='nf heal start')
60         self.get_and_check_params()
61         self.update_nf_status(VNF_STATUS.HEALING)
62         self.send_nf_healing_request()
63         self.update_nf_status(VNF_STATUS.ACTIVE)
64         self.update_job(100, desc='nf heal success')
65
66     def get_and_check_params(self):
67         nf_info = NfInstModel.objects.filter(nfinstid=self.vnf_instance_id)
68         if not nf_info:
69             logger.error('NF instance[id=%s] does not exist' % self.vnf_instance_id)
70             raise NSLCMException('NF instance[id=%s] does not exist' % self.vnf_instance_id)
71         logger.debug('vnfd_model = %s, vnf_instance_id = %s' % (nf_info[0].vnfd_model, self.vnf_instance_id))
72         self.nf_model = nf_info[0].vnfd_model
73         self.m_nf_inst_id = nf_info[0].mnfinstid
74         self.vnfm_inst_id = nf_info[0].vnfm_inst_id
75         self.nf_additional_params = ignore_case_get(self.data, 'additionalParams')
76
77         if not self.nf_additional_params:
78             logger.error('additionalParams parameter does not exist or value incorrect')
79             raise NSLCMException('additionalParams parameter does not exist or value incorrect')
80
81         actionvminfo = ignore_case_get(self.nf_additional_params, 'actionvminfo')
82         vmid = ignore_case_get(actionvminfo, 'vmid')
83         retry_count = 10
84         while (retry_count > 0):
85             resp = restcall.call_req('http://%s:%s/events' % (MR_IP, MR_PORT),
86                                      '',
87                                      '',
88                                      restcall.rest_no_auth,
89                                      '/test/bins/1?timeout=15000',
90                                      'GET')
91             if resp[2] == '200' and resp[1] != '[]':
92                 for message in eval(resp[1]):
93                     if 'powering-off' in message:
94                         action = "vmReset"
95                         vm_info = json.loads(message)
96                         if vmid == vm_info['instance_id']:
97                             vduid = self.get_vudId(vm_info['instance_id'])
98                             self.nf_heal_params = {
99                                 "action": action,
100                                 "affectedvm": {
101                                     "vmid": vm_info['instance_id'],
102                                     "vduid": vduid,
103                                     "vmname": vm_info['display_name']
104                                 }
105                             }
106                             retry_count = -1
107             retry_count = retry_count - 1
108
109     def send_nf_healing_request(self):
110         req_param = json.JSONEncoder().encode(self.nf_heal_params)
111         rsp = send_nf_heal_request(self.vnfm_inst_id, self.m_nf_inst_id, req_param)
112         vnfm_job_id = ignore_case_get(rsp, 'jobId')
113         ret = wait_job_finish(self.vnfm_inst_id, self.job_id, vnfm_job_id, progress_range=None, timeout=1200,
114                               mode='1')
115         if ret != JOB_MODEL_STATUS.FINISHED:
116             logger.error('[NF heal] nf heal failed')
117             raise NSLCMException("nf heal failed")
118
119     # Gets vdu id according to the given vm id.
120     def get_vudId(self, vmid):
121         vnfcInstances = VNFCInstModel.objects.filter(vmid=vmid, nfinstid=self.vnf_instance_id)
122         if not vnfcInstances:
123             raise NSLCMException('VDU [vmid=%s, vnfInstanceId=%s] does not exist' % (vmid, self.vnf_instance_id))
124
125         vnfcInstance = VNFCInstModel.objects.filter(vmid=vmid, nfinstid=self.vnf_instance_id).first()
126         return vnfcInstance.vduid
127
128     def update_job(self, progress, desc=''):
129         JobUtil.add_job_status(self.job_id, progress, desc)
130
131     def update_nf_status(self, status):
132         NfInstModel.objects.filter(nfinstid=self.vnf_instance_id).update(status=status)