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.
19 from threading import Thread
21 from lcm.pub.database.models import NfInstModel
22 from lcm.pub.database.models import VmInstModel
23 from lcm.pub.database.models import VNFCInstModel
24 from lcm.pub.exceptions import NFLCMException
25 from lcm.pub.utils.jobutil import JobUtil
26 from lcm.pub.utils.timeutil import now_time
27 from lcm.pub.utils.notificationsutil import NotificationsUtil
28 from lcm.pub.utils.values import ignore_case_get
29 from lcm.pub.vimapi import adaptor
30 from lcm.nf.biz.grant_vnf import grant_resource
31 from lcm.nf.const import VNF_STATUS
32 from lcm.nf.const import RESOURCE_MAP
33 from lcm.nf.const import GRANT_TYPE
34 from lcm.nf.const import OPERATION_STATE_TYPE
35 from lcm.nf.const import LCM_NOTIFICATION_STATUS
36 from lcm.nf.const import CHANGE_TYPE
37 from lcm.nf.const import OPERATION_TYPE
38 from lcm.nf.const import OPERATION_TASK
39 from .operate_vnf_lcm_op_occ import VnfLcmOpOcc
41 logger = logging.getLogger(__name__)
44 class OperateVnf(Thread):
45 def __init__(self, data, nf_inst_id, job_id):
46 super(OperateVnf, self).__init__()
48 self.nf_inst_id = nf_inst_id
50 self.grant_type = GRANT_TYPE.OPERATE
51 self.changeStateTo = ignore_case_get(self.data, "changeStateTo")
52 self.stopType = ignore_case_get(self.data, "stopType")
53 self.gracefulStopTimeout = ignore_case_get(self.data, "gracefulStopTimeout")
54 self.inst_resource = {'vm': []}
55 self.lcm_op_occ = VnfLcmOpOcc(
56 vnf_inst_id=nf_inst_id,
58 operation=OPERATION_TYPE.OPERATE,
59 task=OPERATION_TASK.OPERATE
64 self.lcm_op_occ.notify_lcm(OPERATION_STATE_TYPE.STARTING)
66 self.query_inst_resource()
67 self.lcm_op_occ.notify_lcm(OPERATION_STATE_TYPE.PROCESSING)
68 self.operate_resource()
69 JobUtil.add_job_status(self.job_id, 100, "Operate Vnf success.")
70 NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(
71 status='INSTANTIATED',
75 LCM_NOTIFICATION_STATUS.RESULT,
76 OPERATION_STATE_TYPE.COMPLETED
78 except NFLCMException as e:
79 self.vnf_operate_failed_handle(e.message)
80 except Exception as e:
81 logger.error(e.message)
82 logger.error(traceback.format_exc())
83 self.vnf_operate_failed_handle(e.message)
85 def apply_grant(self):
86 vdus = VmInstModel.objects.filter(instid=self.nf_inst_id)
87 apply_result = grant_resource(data=self.data,
88 nf_inst_id=self.nf_inst_id,
90 grant_type=self.grant_type,
92 logger.info("Grant resource, response: %s" % apply_result)
93 JobUtil.add_job_status(self.job_id, 20, 'Nf Operate grant_resource finish')
95 def query_inst_resource(self):
96 logger.info('Query resource begin')
97 # Querying only vm resources now
99 resource_table = globals().get(resource_type + 'InstModel')
100 resource_insts = resource_table.objects.filter(instid=self.nf_inst_id)
101 for resource_inst in resource_insts:
102 if not resource_inst.resourceid:
104 self.inst_resource[RESOURCE_MAP.get(resource_type)].append(self.get_resource(resource_inst))
105 logger.info('Query resource end, resource=%s' % self.inst_resource)
107 def get_resource(self, resource):
109 "vim_id": resource.vimid,
110 "tenant_id": resource.tenant,
111 "id": resource.resourceid
114 def operate_resource(self):
115 logger.info('Operate resource begin')
116 adaptor.operate_vim_res(self.inst_resource,
119 self.gracefulStopTimeout,
121 logger.info('Operate resource complete')
123 def lcm_notify(self, status, opState, err=None):
124 notification_content = self.prepareNotificationData(status, opState, err)
125 logger.info('Notify data = %s' % notification_content)
126 NotificationsUtil().send_notification(notification_content)
127 logger.info('Notify end')
129 def vnf_operate_failed_handle(self, error_msg):
130 logger.error('VNF Operation failed, detail message: %s' % error_msg)
131 NfInstModel.objects.filter(nfinstid=self.nf_inst_id).update(
132 status=VNF_STATUS.FAILED,
133 lastuptime=now_time()
135 self.lcm_op_occ.notify_lcm(OPERATION_STATE_TYPE.FAILED, error_msg)
136 JobUtil.add_job_status(self.job_id, 255, error_msg)
138 def do_notify_op(self, status, resid):
139 logger.error('VNF resource %s updated to: %s' % (resid, status))
141 def prepareNotificationData(self, status, opState, err=None):
143 if status == LCM_NOTIFICATION_STATUS.RESULT and opState == OPERATION_STATE_TYPE.COMPLETED:
144 vnfcs = VNFCInstModel.objects.filter(instid=self.nf_inst_id)
148 vm = VmInstModel.objects.filter(vmid=vnfc.vmid)
151 'vimConnectionId': vm[0].vimid,
152 'resourceId': vm[0].resourceid,
153 'vimLevelResourceType': 'vm'
155 affected_vnfcs.append({
156 'id': vnfc.vnfcinstanceid,
158 'changeType': CHANGE_TYPE.MODIFIED,
159 'computeResource': vm_resource
161 notification_content = {
162 "id": str(uuid.uuid4()),
163 "notificationType": "VnfLcmOperationOccurrenceNotification",
164 "subscriptionId": "",
165 "timeStamp": now_time(),
166 "notificationStatus": status,
167 "operationState": opState,
168 "vnfInstanceId": self.nf_inst_id,
169 "operation": OPERATION_TYPE.OPERATE,
170 "isAutomaticInvocation": "false",
171 "vnfLcmOpOccId": self.job_id,
172 "affectedVnfcs": affected_vnfcs,
173 "affectedVirtualLinks": [],
174 "affectedVirtualStorages": [],
176 "changedExtConnectivity": [],
177 "_links": {"vnfInstance": {"href": ""},
178 "subscription": {"href": ""},
179 "vnfLcmOpOcc": {"href": ""}}
181 if opState in (OPERATION_STATE_TYPE.FAILED, OPERATION_STATE_TYPE.FAILED_TEMP):
182 notification_content["error"] = {"status": 500, "detail": err}
183 notification_content["_links"]["vnfInstance"]["href"] = "/vnf_instances/%s" % self.nf_inst_id
184 notification_content["_links"]["vnfLcmOpOcc"]["href"] = "/vnf_lc_ops/%s" % self.job_id
185 return notification_content