fix 1223. Increment ip address on scaling vdus 45/9845/1
authortierno <alfonso.tiernosepulveda@telefonica.com>
Thu, 24 Sep 2020 12:31:36 +0000 (12:31 +0000)
committertierno <alfonso.tiernosepulveda@telefonica.com>
Fri, 16 Oct 2020 09:04:59 +0000 (09:04 +0000)
Change-Id: I18f11bbf6d20b78b3811e5e39daa1ad10af57e3d
Signed-off-by: tierno <alfonso.tiernosepulveda@telefonica.com>
RO-plugin/osm_ro_plugin/vim_dummy.py
RO/osm_ro/nfvo.py

index 8e8afd1..3189239 100644 (file)
@@ -24,6 +24,7 @@ import yaml
 from osm_ro_plugin import vimconn
 from uuid import uuid4
 from copy import deepcopy
 from osm_ro_plugin import vimconn
 from uuid import uuid4
 from copy import deepcopy
+import logging
 
 __author__ = "Alfonso Tierno"
 __date__ = "2020-04-20"
 
 __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)
                  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",
         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())
 
     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,
         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))
     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
 
         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())
 
     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:
         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))
     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)
         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():
 
     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())
 
     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
         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))
     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.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 = []
 
     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())
 
     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:
         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))
     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)
         self.images.pop(image_id)
+        return image_id
 
     def get_image_list(self, filter_dict=None):
         images = []
 
     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 = []
                        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 = {
         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"],
             }
                 "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))
     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.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 = {}
 
     def refresh_vms_status(self, vm_list):
         vms = {}
index 3e1f377..e346699 100644 (file)
@@ -3803,6 +3803,25 @@ def create_instance(mydb, tenant_id, instance_dict):
         logger.exception(e)
         raise NfvoException(error_text, e.http_code)
 
         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"]
 
 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)
             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),
             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)
                            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 = {
             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)
 
             }
             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,
                 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)
                 }
                 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)
                 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,
 
             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"]
                 # 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"]:
                 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:])
                                                                   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):
 
                 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"):
                         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 = {
                     if vm_name:
                         task_params_copy[0] = vm_name
                     db_vim_action = {