From 274bfc7019af82dac67bbbeb121ef45739a45e4e Mon Sep 17 00:00:00 2001 From: tierno Date: Thu, 24 Sep 2020 12:31:36 +0000 Subject: [PATCH] fix 1223. Increment ip address on scaling vdus Change-Id: I18f11bbf6d20b78b3811e5e39daa1ad10af57e3d Signed-off-by: tierno --- RO-plugin/osm_ro_plugin/vim_dummy.py | 27 ++++++++-- RO/osm_ro/nfvo.py | 80 ++++++++++++++++------------ 2 files changed, 67 insertions(+), 40 deletions(-) diff --git a/RO-plugin/osm_ro_plugin/vim_dummy.py b/RO-plugin/osm_ro_plugin/vim_dummy.py index 8e8afd16..31892399 100644 --- a/RO-plugin/osm_ro_plugin/vim_dummy.py +++ b/RO-plugin/osm_ro_plugin/vim_dummy.py @@ -24,6 +24,7 @@ import yaml from osm_ro_plugin import vimconn from uuid import uuid4 from copy import deepcopy +import logging __author__ = "Alfonso Tierno" __date__ = "2020-04-20" @@ -39,6 +40,9 @@ class VimDummyConnector(vimconn.VimConnector): config={}, persistent_info={}): super().__init__(uuid, name, tenant_id, tenant_name, url, url_admin, user, passwd, log_level, config, persistent_info) + self.logger = logging.getLogger('openmano.vim.dummy') + if log_level: + self.logger.setLevel(getattr(logging, log_level)) self.nets = { "mgmt": { "id": "mgmt", @@ -91,6 +95,8 @@ class VimDummyConnector(vimconn.VimConnector): def new_network(self, net_name, net_type, ip_profile=None, shared=False, provider_network_profile=None): net_id = str(uuid4()) + self.logger.debug("new network id={}, name={}, net_type={}, ip_profile={}, provider_network_profile={}". + format(net_id, net_name, net_type, ip_profile, provider_network_profile)) net = { "id": net_id, "name": net_name, @@ -120,6 +126,7 @@ class VimDummyConnector(vimconn.VimConnector): def delete_network(self, net_id, created_items=None): if net_id not in self.nets: raise vimconn.VimConnNotFoundException("network with id {} not found".format(net_id)) + self.logger.debug("delete network id={}, created_items={}".format(net_id, created_items)) self.nets.pop(net_id) return net_id @@ -143,6 +150,7 @@ class VimDummyConnector(vimconn.VimConnector): def new_flavor(self, flavor_data): flavor_id = str(uuid4()) + self.logger.debug("new flavor id={}, flavor_data={}".format(flavor_id, flavor_data)) flavor = deepcopy(flavor_data) flavor["id"] = flavor_id if "name" not in flavor: @@ -153,8 +161,9 @@ class VimDummyConnector(vimconn.VimConnector): def delete_flavor(self, flavor_id): if flavor_id not in self.flavors: raise vimconn.VimConnNotFoundException("flavor with id {} not found".format(flavor_id)) - return flavor_id + self.logger.debug("delete flavor id={}".format(flavor_id)) self.flavors.pop(flavor_id) + return flavor_id def get_flavor_id_from_data(self, flavor_dict): for flavor_id, flavor_data in self.flavors.items(): @@ -169,6 +178,7 @@ class VimDummyConnector(vimconn.VimConnector): def new_tenant(self, tenant_name, tenant_description): tenant_id = str(uuid4()) + self.logger.debug("new tenant id={}, description={}".format(tenant_id, tenant_description)) tenant = {'name': tenant_name, 'description': tenant_description, 'id': tenant_id} self.tenants[tenant_id] = tenant return tenant_id @@ -176,8 +186,9 @@ class VimDummyConnector(vimconn.VimConnector): def delete_tenant(self, tenant_id): if tenant_id not in self.tenants: raise vimconn.VimConnNotFoundException("tenant with id {} not found".format(tenant_id)) - return tenant_id self.tenants.pop(tenant_id) + self.logger.debug("delete tenant id={}".format(tenant_id)) + return tenant_id def get_tenant_list(self, filter_dict=None): tenants = [] @@ -193,6 +204,7 @@ class VimDummyConnector(vimconn.VimConnector): def new_image(self, image_dict): image_id = str(uuid4()) + self.logger.debug("new image id={}, iamge_dict={}".format(image_id, image_dict)) image = deepcopy(image_dict) image["id"] = image_id if "name" not in image: @@ -203,8 +215,9 @@ class VimDummyConnector(vimconn.VimConnector): def delete_image(self, image_id): if image_id not in self.images: raise vimconn.VimConnNotFoundException("image with id {} not found".format(image_id)) - return image_id + self.logger.debug("delete image id={}".format(image_id)) self.images.pop(image_id) + return image_id def get_image_list(self, filter_dict=None): images = [] @@ -225,10 +238,13 @@ class VimDummyConnector(vimconn.VimConnector): availability_zone_index=None, availability_zone_list=None): vm_id = str(uuid4()) interfaces = [] + self.logger.debug("new vm id={}, name={}, image_id={}, flavor_id={}, net_list={}, cloud_config={}". + format(vm_id, name, image_id, flavor_id, net_list, cloud_config)) for iface_index, iface in enumerate(net_list): iface["vim_id"] = str(iface_index) interface = { - "ip_address": self.config.get("vm_ip") or "192.168.4.2", + "ip_address": iface.get("ip_address") or self.config.get("vm_ip") or "192.168.4.2", + "mac_address": iface.get("mac_address") or self.config.get("vm_mac") or "00:11:22:33:44:55", "vim_interface_id": str(iface_index), "vim_net_id": iface["net_id"], } @@ -257,8 +273,9 @@ class VimDummyConnector(vimconn.VimConnector): def delete_vminstance(self, vm_id, created_items=None): if vm_id not in self.vms: raise vimconn.VimConnNotFoundException("vm with id {} not found".format(vm_id)) - return vm_id self.vms.pop(vm_id) + self.logger.debug("delete vm id={}, created_items={}".format(vm_id, created_items)) + return vm_id def refresh_vms_status(self, vm_list): vms = {} diff --git a/RO/osm_ro/nfvo.py b/RO/osm_ro/nfvo.py index 3e1f377e..e346699a 100644 --- a/RO/osm_ro/nfvo.py +++ b/RO/osm_ro/nfvo.py @@ -3803,6 +3803,25 @@ def create_instance(mydb, tenant_id, instance_dict): logger.exception(e) raise NfvoException(error_text, e.http_code) +def increment_ip_mac(ip_mac, vm_index=1): + if not isinstance(ip_mac, str): + return ip_mac + try: + # try with ipv4 look for last dot + i = ip_mac.rfind(".") + if i > 0: + i += 1 + return "{}{}".format(ip_mac[:i], int(ip_mac[i:]) + vm_index) + # try with ipv6 or mac look for last colon. Operate in hex + i = ip_mac.rfind(":") + if i > 0: + i += 1 + # format in hex, len can be 2 for mac or 4 for ipv6 + return ("{}{:0" + str(len(ip_mac) - i) + "x}").format(ip_mac[:i], int(ip_mac[i:], 16) + vm_index) + except: + pass + return None + def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): default_datacenter_id = params["default_datacenter_id"] @@ -4161,16 +4180,11 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): av_index = None for vm_index in range(0, vm.get('count', 1)): vm_name = myVMDict['name'] + "-" + str(vm_index+1) + vm_networks = deepcopy(myVMDict['networks']) task_params = (vm_name, myVMDict['description'], myVMDict.get('start', None), - myVMDict['imageRef'], myVMDict['flavorRef'], myVMDict['networks'], cloud_config_vm, + myVMDict['imageRef'], myVMDict['flavorRef'], vm_networks, cloud_config_vm, myVMDict['disks'], av_index, vnf_availability_zones) - # put interface uuid back to scenario[vnfs][vms[[interfaces] - for net in myVMDict['networks']: - if "vim_id" in net: - for iface in vm['interfaces']: - if net["name"] == iface["internal_name"]: - iface["vim_id"] = net["vim_id"] - break + vm_uuid = str(uuid4()) uuid_list.append(vm_uuid) db_vm = { @@ -4184,28 +4198,32 @@ def instantiate_vnf(mydb, sce_vnf, params, params_out, rollbackList): } db_instance_vms.append(db_vm) - iface_index = 0 - for db_vm_iface in db_vm_ifaces: + # put interface uuid back to scenario[vnfs][vms[[interfaces] + for net in vm_networks: + if "vim_id" in net: + for iface in vm['interfaces']: + if net["name"] == iface["internal_name"]: + iface["vim_id"] = net["vim_id"] + break + + if vm_index > 0: + if net.get("ip_address"): + net["ip_address"] = increment_ip_mac(net.get("ip_address"), vm_index) + if net.get("mac_address"): + net["mac_address"] = increment_ip_mac(net.get("mac_address"), vm_index) + + for iface_index, db_vm_iface in enumerate(db_vm_ifaces): iface_uuid = str(uuid4()) uuid_list.append(iface_uuid) db_vm_iface_instance = { "uuid": iface_uuid, - "instance_vm_id": vm_uuid + "instance_vm_id": vm_uuid, + "ip_address": vm_networks[iface_index].get("ip_address"), + "mac_address": vm_networks[iface_index].get("mac_address") } db_vm_iface_instance.update(db_vm_iface) - if db_vm_iface_instance.get("ip_address"): # increment ip_address - ip = db_vm_iface_instance.get("ip_address") - try: - i = ip.rfind(".") - if i > 0: - i += 1 - ip = ip[:i] + str(int(ip[i:]) + 1) - db_vm_iface_instance["ip_address"] = ip - except: - db_vm_iface_instance["ip_address"] = None db_instance_interfaces.append(db_vm_iface_instance) - myVMDict['networks'][iface_index]["uuid"] = iface_uuid - iface_index += 1 + vm_networks[iface_index]["uuid"] = iface_uuid db_vim_action = { "instance_action_id": instance_action_id, @@ -4862,7 +4880,6 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): # TODO do the same for flavor and image when available task_depends_on = [] task_params = extra["params"] - task_params_networks = deepcopy(task_params[5]) for iface in task_params[5]: if iface["net_id"].startswith("TASK-"): if "." not in iface["net_id"]: @@ -4872,8 +4889,6 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): iface["net_id"][5:]) else: task_depends_on.append(iface["net_id"][5:]) - if "mac_address" in iface: - del iface["mac_address"] vm_ifaces_to_clone = mydb.get_rows(FROM="instance_interfaces", WHERE={"instance_vm_id": target_vm["uuid"]}) for index in range(0, vdu_count): @@ -4916,15 +4931,10 @@ def instance_action(mydb,nfvo_tenant,instance_id, action_dict): iface["uuid"] = iface2iface[iface["uuid"]] # increment ip_address if iface.get("ip_address"): - try: - ip = iface["ip_address"] - i = ip.rfind(".") - if i > 0: - i += 1 - ip = ip[:i] + str(int(ip[i:]) + 1) - iface["ip_address"] = ip - except: - iface["ip_address"] = None + iface["ip_address"] = increment_ip_mac(iface.get("ip_address"), index+1) + if iface.get("mac_address"): + iface["mac_address"] = increment_ip_mac(iface.get("mac_address"), index+1) + if vm_name: task_params_copy[0] = vm_name db_vim_action = { -- 2.17.1