1 # Copyright (C) 2018 Verizon. All Rights Reserved.
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.
18 from threading import Thread
20 from lcm.pub.database.models import NfInstModel, VmInstModel, VNFCInstModel
21 from lcm.pub.exceptions import NFLCMException
22 from lcm.pub.utils.jobutil import JobUtil
23 from lcm.pub.utils.timeutil import now_time
24 from lcm.pub.utils.notificationsutil import NotificationsUtil
25 from lcm.pub.utils.values import ignore_case_get
26 from lcm.pub.vimapi import adaptor
27 from lcm.nf.biz.grant_vnf import grant_resource
28 from lcm.nf.const import VNF_STATUS, RESOURCE_MAP, GRANT_TYPE, OPERATION_STATE_TYPE, LCM_NOTIFICATION_STATUS, CHANGE_TYPE, OPERATION_TYPE
31 logger = logging.getLogger(__name__)
34 class OperateVnf(Thread):
35 def __init__(self, data, nf_inst_id, job_id):
36 super(OperateVnf, self).__init__()
38 self.nf_inst_id = nf_inst_id
40 self.grant_type = GRANT_TYPE.OPERATE
41 self.changeStateTo = ignore_case_get(self.data, "changeStateTo")
42 self.stopType = ignore_case_get(self.data, "stopType")
43 self.gracefulStopTimeout = ignore_case_get(self.data, "gracefulStopTimeout")
44 self.inst_resource = {'vm': []}
48 self.lcm_notify(LCM_NOTIFICATION_STATUS.START, OPERATION_STATE_TYPE.STARTING)
50 self.query_inst_resource()
51 self.lcm_notify(LCM_NOTIFICATION_STATUS.RESULT, OPERATION_STATE_TYPE.PROCESSING)
52 self.operate_resource()
53 JobUtil.add_job_status(self.job_id, 100, "Operate Vnf success.")
54 NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status='INSTANTIATED', lastuptime=now_time())
55 self.lcm_notify(LCM_NOTIFICATION_STATUS.RESULT, OPERATION_STATE_TYPE.COMPLETED)
56 except NFLCMException as e:
57 self.lcm_notify(LCM_NOTIFICATION_STATUS.RESULT, OPERATION_STATE_TYPE.FAILED, str(e))
58 self.vnf_operate_failed_handle(e.message)
59 except Exception as e:
60 logger.error(e.message)
61 self.lcm_notify(LCM_NOTIFICATION_STATUS.RESULT, OPERATION_STATE_TYPE.FAILED, str(e))
62 self.vnf_operate_failed_handle(traceback.format_exc())
64 def apply_grant(self):
65 vdus = VmInstModel.objects.filter(instid=self.nf_inst_id)
66 apply_result = grant_resource(data=self.data, nf_inst_id=self.nf_inst_id, job_id=self.job_id,
67 grant_type=self.grant_type, vdus=vdus)
68 logger.info("Grant resource, response: %s" % apply_result)
69 JobUtil.add_job_status(self.job_id, 20, 'Nf Operate grant_resource finish')
71 def query_inst_resource(self):
72 logger.info('Query resource begin')
73 # Querying only vm resources now
75 resource_table = globals().get(resource_type + 'InstModel')
76 resource_insts = resource_table.objects.filter(instid=self.nf_inst_id)
77 for resource_inst in resource_insts:
78 if not resource_inst.resourceid:
80 self.inst_resource[RESOURCE_MAP.get(resource_type)].append(self.get_resource(resource_inst))
81 logger.info('Query resource end, resource=%s' % self.inst_resource)
83 def get_resource(self, resource):
85 "vim_id": resource.vimid,
86 "tenant_id": resource.tenant,
87 "id": resource.resourceid
90 def operate_resource(self):
91 logger.info('Operate resource begin')
92 adaptor.operate_vim_res(self.inst_resource, self.changeStateTo, self.stopType, self.gracefulStopTimeout, self.do_notify_op)
93 logger.info('Operate resource complete')
95 def lcm_notify(self, status, opState, err=None):
96 notification_content = self.prepareNotificationData(status, opState, err)
97 logger.info('Notify data = %s' % notification_content)
98 NotificationsUtil().send_notification(notification_content)
99 logger.info('Notify end')
101 def vnf_operate_failed_handle(self, error_msg):
102 logger.error('VNF Operation failed, detail message: %s' % error_msg)
103 NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(status=VNF_STATUS.FAILED, lastuptime=now_time())
104 JobUtil.add_job_status(self.job_id, 255, error_msg)
106 def do_notify_op(self, status, resid):
107 logger.error('VNF resource %s updated to: %s' % (resid, status))
109 def prepareNotificationData(self, status, opState, err=None):
111 if status == LCM_NOTIFICATION_STATUS.RESULT and opState == OPERATION_STATE_TYPE.COMPLETED:
112 vnfcs = VNFCInstModel.objects.filter(instid=self.nf_inst_id)
116 vm = VmInstModel.objects.filter(vmid=vnfc.vmid)
119 'vimConnectionId': vm[0].vimid,
120 'resourceId': vm[0].resourceid,
121 'vimLevelResourceType': 'vm'
123 affected_vnfcs.append({
124 'id': vnfc.vnfcinstanceid,
126 'changeType': CHANGE_TYPE.MODIFIED,
127 'computeResource': vm_resource
129 notification_content = {
130 "id": str(uuid.uuid4()),
131 "notificationType": "VnfLcmOperationOccurrenceNotification",
132 "subscriptionId": "",
133 "timeStamp": now_time(),
134 "notificationStatus": status,
135 "operationState": opState,
136 "vnfInstanceId": self.nf_inst_id,
137 "operation": OPERATION_TYPE.OPERATE,
138 "isAutomaticInvocation": "false",
139 "vnfLcmOpOccId": self.job_id,
140 "affectedVnfcs": affected_vnfcs,
141 "affectedVirtualLinks": [],
142 "affectedVirtualStorages": [],
144 "changedExtConnectivity": [],
145 "_links": {"vnfInstance": {"href": ""},
146 "subscription": {"href": ""},
147 "vnfLcmOpOcc": {"href": ""}}
149 if opState in (OPERATION_STATE_TYPE.FAILED, OPERATION_STATE_TYPE.FAILED_TEMP):
150 notification_content["error"] = {"status": 500, "detail": err}
151 notification_content["_links"]["vnfInstance"]["href"] = "/vnf_instances/%s" % self.nf_inst_id
152 notification_content["_links"]["vnfLcmOpOcc"]["href"] = "/vnf_lc_ops/%s" % self.job_id
153 return notification_content