summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorfujinhua <fu.jinhua@zte.com.cn>2019-04-08 11:19:08 +0800
committerfujinhua <fu.jinhua@zte.com.cn>2019-04-08 11:29:00 +0800
commit14d6913d256ca67e8c8a6b5fd7fddbd40b2f08e9 (patch)
treecfe6f8b8bea23549ae13b40cc74b8c5c3131c603
parente05635e9f9d28c355ac0272e097d700dd87ecf6b (diff)
Add change ext conn biz logic
Change-Id: I79d43be8e3194e293875a8e6aed99ce930ab05d9 Issue-ID: VFC-1306 Signed-off-by: fujinhua <fu.jinhua@zte.com.cn>
-rw-r--r--lcm/lcm/nf/biz/change_ext_conn.py249
-rw-r--r--lcm/lcm/nf/views/change_ext_conn_view.py3
2 files changed, 251 insertions, 1 deletions
diff --git a/lcm/lcm/nf/biz/change_ext_conn.py b/lcm/lcm/nf/biz/change_ext_conn.py
new file mode 100644
index 00000000..b1bc9219
--- /dev/null
+++ b/lcm/lcm/nf/biz/change_ext_conn.py
@@ -0,0 +1,249 @@
+# Copyright 2019 ZTE 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 json
+import logging
+import traceback
+from threading import Thread
+
+from lcm.nf.biz.common import port_save
+from lcm.nf.biz.grant_vnf import grant_resource
+from lcm.nf.const import RESOURCE_MAP, GRANT_TYPE, OPERATION_STATE_TYPE
+from lcm.nf.const import VNF_STATUS
+from lcm.pub.database.models import VmInstModel, NfInstModel, PortInstModel
+from lcm.pub.utils.notificationsutil import NotificationsUtil, prepare_notification
+from lcm.pub.utils.values import ignore_case_get
+from lcm.pub.utils.timeutil import now_time
+from lcm.pub.utils.jobutil import JobUtil
+from lcm.pub.exceptions import NFLCMException
+from lcm.pub.vimapi import adaptor
+
+logger = logging.getLogger(__name__)
+
+
+class ChangeExtConn(Thread):
+ def __init__(self, data, nf_inst_id, job_id):
+ super(ChangeExtConn, self).__init__()
+ self.data = data
+ self.nf_inst_id = nf_inst_id
+ self.job_id = job_id
+ self.vnf_insts = NfInstModel.objects.filter(nfinstid=self.nf_inst_id)
+ self.extVirtualLinks = ignore_case_get(self.data, "extVirtualLinks")
+ self.vimConnectionInfo = ignore_case_get(self.data, "vimConnectionInfo")
+ self.additionalParams = ignore_case_get(self.data, "additionalParams")
+
+ def run(self):
+ try:
+ JobUtil.add_job_status(self.job_id,
+ 10,
+ "Start to apply grant.")
+ self.apply_grant()
+ JobUtil.add_job_status(self.job_id,
+ 50,
+ "Start to change ext conn.")
+ self.do_operation()
+ self.vnf_insts.update(
+ status='INSTANTIATED',
+ lastuptime=now_time()
+ )
+ JobUtil.add_job_status(self.job_id,
+ 100,
+ "Change ext conn success.")
+ except NFLCMException as e:
+ logger.error(e.message)
+ self.change_ext_conn_failed_handle(e.message)
+ except Exception as e:
+ logger.error(e.message)
+ logger.error(traceback.format_exc())
+ self.change_ext_conn_failed_handle(e.message)
+
+ def apply_grant(self):
+ vdus = VmInstModel.objects.filter(instid=self.nf_inst_id)
+ apply_result = grant_resource(data=self.data,
+ nf_inst_id=self.nf_inst_id,
+ job_id=self.job_id,
+ grant_type=GRANT_TYPE.CHANGE_CONNECTIVITY,
+ vdus=vdus)
+ logger.debug("Grant resource end, response: %s" % apply_result)
+
+ def do_operation(self):
+ logger.info('Operation resource begin')
+ logger.debug("self.vimConnectionInfo: %s" % self.vimConnectionInfo)
+ vnfd_info = json.loads(self.vnf_insts[0].vnfd_model)
+ vm_id = ignore_case_get(self.additionalParams, "vmid")
+ if not vm_id:
+ vms = VmInstModel.objects.filter(instid=self.nf_inst_id)
+ vm_id = vms[0].resourceid
+ vim_id = ignore_case_get(self.vimConnectionInfo[0], "vimid")
+ accessInfo = ignore_case_get(self.vimConnectionInfo[0], "accessInfo")
+ tenant = ignore_case_get(accessInfo, "tenant")
+
+ self.vim_cache, self.res_cache = {}, {}
+ for extVirtualLink in self.extVirtualLinks:
+ network_id = ignore_case_get(extVirtualLink, "resourceId")
+ ext_cps = ignore_case_get(extVirtualLink, "extCps")
+ for ext_cp in ext_cps:
+ cpd_id = ignore_case_get(ext_cp, "cpdId")
+ cp_config = ignore_case_get(ext_cp, "cpConfig")
+ # cp_instance_id = ignore_case_get(cp_config[0], "cpInstanceId")
+ cp_protocol_data = ignore_case_get(cp_config[0], "cpProtocolData")
+ # mac_address = ignore_case_get(ignore_case_get(cp_protocol_data[0], "ipOverEthernet"), "macAddress")
+ ip_addresses = ignore_case_get(ignore_case_get(cp_protocol_data[0], "ipOverEthernet"), "ipAddresses")
+ # fixed_addresse = ignore_case_get(ip_addresses[0], "fixedAddresses")[0]
+ # addressRange = ignore_case_get(ip_addresses[0], "addressRange")
+ # minAddress = ignore_case_get(addressRange, "minAddress")
+ # maxAddress = ignore_case_get(addressRange, "maxAddress")
+ subnet_id = ignore_case_get(ip_addresses[0], "subnetId")
+
+ vdu_id = ""
+ cps = ignore_case_get(vnfd_info, "cps")
+ for cp in cps:
+ cpd_id_in_model = ignore_case_get(cp, "cpd_id")
+ if cpd_id == cpd_id_in_model:
+ vdu_id = ignore_case_get(cp, "vdu_id")
+ break
+
+ port = {
+ "cp_id": cpd_id,
+ "cpd_id": cpd_id,
+ "vm_id": vm_id,
+ "description": "",
+ "properties": {
+ # "name": "",
+ # "mac_address": mac_address,
+ # "ip_address:": fixed_addresse,
+ # "ip_range_start": minAddress,
+ # "ip_range_end": maxAddress,
+ "location_info": {
+ "vimid": vim_id,
+ "tenant": tenant
+ }
+ },
+ "vl_id": network_id,
+ "vdu_id": vdu_id,
+ "networkId": network_id,
+ "subnetId": subnet_id
+ }
+ for resource_type in ['vdus', 'vls', 'cps', 'volume_storages']:
+ for resource in ignore_case_get(vnfd_info, resource_type):
+ if "location_info" not in resource["properties"]:
+ resource["properties"]["location_info"] = {}
+ resource["properties"]["location_info"]["vimid"] = vim_id
+ resource["properties"]["location_info"]["tenant"] = tenant
+
+ # if cp_instance_id:
+ # ret = adaptor.get_port_of_vm(self.vim_cache, self.res_cache, vnfd_info, port,
+ # self.do_notify_op, "port")
+ # port_info = ignore_case_get(ret, "interfaceAttachment")
+ # net_id = ignore_case_get(port_info, "net_id")
+ # if network_id == net_id:
+ # adaptor.update_port(self.vim_cache, self.res_cache, vnfd_info, port,
+ # self.do_notify_op, "port")
+ # else:
+ # adaptor.delete_port_of_vm(self.vim_cache, self.res_cache, vnfd_info, port,
+ # self.do_notify_op, "port")
+ # adaptor.create_port_of_vm(self.vim_cache, self.res_cache, vnfd_info, port,
+ # self.do_notify_op, "port")
+ # else:
+ adaptor.create_port(self.vim_cache, self.res_cache, vnfd_info, port, self.do_create_port_notify, "port")
+ port["port_id"] = self.port_id
+ logger.debug('create_port_of_vm request data = %s' % port)
+ adaptor.create_port_of_vm(self.vim_cache, self.res_cache, vnfd_info, port,
+ self.do_notify_op, "port")
+ PortInstModel.objects.filter(resourceid=self.port_id).update(vmid=vm_id)
+ logger.info('Operate resource complete')
+
+ def send_notification(self):
+ data = prepare_notification(nfinstid=self.nf_inst_id,
+ jobid=self.job_id,
+ operation=self.op_type,
+ operation_state=OPERATION_STATE_TYPE.COMPLETED)
+ self.set_ext_connectivity(data['changedExtConnectivity'])
+
+ logger.debug('Notify request data = %s' % data)
+ NotificationsUtil().send_notification(data)
+
+ def rollback_operation(self):
+ pass
+
+ def query_inst_resource(self, inst_resource):
+ logger.debug('Query resource begin')
+ for resource_type in RESOURCE_MAP.keys():
+ resource_table = globals().get(resource_type + 'InstModel')
+ resource_insts = resource_table.objects.filter(instid=self.nf_inst_id)
+ for resource_inst in resource_insts:
+ if not resource_inst.resourceid:
+ continue
+ inst_resource[RESOURCE_MAP.get(resource_type)].append(self.get_resource(resource_inst))
+ logger.debug('Query resource end, resource=%s' % inst_resource)
+
+ def get_resource(self, resource):
+ return {
+ "vim_id": resource.vimid,
+ "tenant_id": resource.tenant,
+ "res_id": resource.resourceid
+ }
+
+ def do_create_port_notify(self, res_type, ret):
+ self.port_id = ignore_case_get(ret, "id")
+ port_save("", self.nf_inst_id, ret)
+
+ def do_notify_op(self, operation_type, status, resid):
+ if operation_type == "delete":
+ PortInstModel.objects.filter()
+ # TODO delete port from table
+ elif operation_type == "create":
+ pass
+ # TODO save port in table
+ else:
+ pass
+ # TODO update port in table
+ logger.info('VNF resource %s updated to: %s' % (resid, status))
+
+ def set_ext_connectivity(self, ext_connectivity):
+ for extVirtualLink in self.extVirtualLinks:
+ vim_connection_id = ignore_case_get(extVirtualLink, "vimConnectionId")
+ network_id = ignore_case_get(extVirtualLink, "resourceId")
+ ext_cps = ignore_case_get(extVirtualLink, "extCps")
+ ext_link_ports = []
+ for ext_cp in ext_cps:
+ cpd_id = ignore_case_get(ext_cp, "cpdId")
+ cp_config = ignore_case_get(ext_cp, "cpConfig")
+ cp_instance_id = ignore_case_get(cp_config[0], "cpInstanceId")
+ ext_link_ports.append({
+ 'id': cp_instance_id,
+ 'resourceHandle': {
+ 'vimConnectionId': vim_connection_id,
+ 'resourceId': self.res_cache.get("port").get(cp_instance_id),
+ 'resourceProviderId': cpd_id,
+ 'vimLevelResourceType': 'port'
+ },
+ 'cpInstanceId': cp_instance_id
+ })
+ network_resource = {
+ 'vimConnectionId': vim_connection_id,
+ 'resourceId': network_id,
+ 'resourceProviderId': "",
+ 'vimLevelResourceType': 'network'
+ }
+ ext_connectivity.append({
+ 'id': network_id,
+ 'resourceHandle': network_resource,
+ 'extLinkPorts': ext_link_ports
+ })
+
+ def change_ext_conn_failed_handle(self, error_msg):
+ logger.error('Chnage ext conn failed, detail message: %s', error_msg)
+ self.vnf_insts.update(status=VNF_STATUS.FAILED,
+ lastuptime=now_time())
+ JobUtil.add_job_status(self.job_id, 255, error_msg)
diff --git a/lcm/lcm/nf/views/change_ext_conn_view.py b/lcm/lcm/nf/views/change_ext_conn_view.py
index bfe0bfa5..41d39d03 100644
--- a/lcm/lcm/nf/views/change_ext_conn_view.py
+++ b/lcm/lcm/nf/views/change_ext_conn_view.py
@@ -27,6 +27,7 @@ from lcm.pub.exceptions import NFLCMExceptionConflict
from lcm.pub.utils.jobutil import JobUtil
from lcm.pub.database.models import NfInstModel
from lcm.nf.const import VNF_STATUS
+from lcm.nf.biz.change_ext_conn import ChangeExtConn
from .common import view_safe_call_with_log
logger = logging.getLogger(__name__)
@@ -54,7 +55,7 @@ class ChangeExtConnView(APIView):
JobUtil.add_job_status(job_id, 0, "CHG_EXT_CONN_READY")
self.chg_ext_conn_pre_check(instanceid, job_id)
- # TODO: call biz logic
+ ChangeExtConn(chg_ext_conn_serializer.data, instanceid, job_id).start()
response = Response(data={"jobId": job_id},
status=status.HTTP_202_ACCEPTED)