Fix bug 1544 to read properly size capabilities in Azure
[osm/RO.git] / RO-VIM-azure / osm_rovim_azure / vimconn_azure.py
index 485bf05..c78b0f9 100755 (executable)
@@ -20,17 +20,23 @@ import netaddr
 import re
 
 from os import getenv
 import re
 
 from os import getenv
-from azure.common.credentials import ServicePrincipalCredentials
+from azure.identity import ClientSecretCredential
 from azure.mgmt.resource import ResourceManagementClient
 from azure.mgmt.network import NetworkManagementClient
 from azure.mgmt.compute import ComputeManagementClient
 from azure.mgmt.compute.models import DiskCreateOption
 from azure.mgmt.resource import ResourceManagementClient
 from azure.mgmt.network import NetworkManagementClient
 from azure.mgmt.compute import ComputeManagementClient
 from azure.mgmt.compute.models import DiskCreateOption
+from azure.core.exceptions import ResourceNotFoundError
+from azure.profiles import ProfileDefinition
 from msrestazure.azure_exceptions import CloudError
 from msrest.exceptions import AuthenticationError
 import msrestazure.tools as azure_tools
 from requests.exceptions import ConnectionError
 
 from msrestazure.azure_exceptions import CloudError
 from msrest.exceptions import AuthenticationError
 import msrestazure.tools as azure_tools
 from requests.exceptions import ConnectionError
 
-__author__ = "Isabel Lloret, Sergio Gonzalez, Alfonso Tierno"
+from cryptography.hazmat.primitives import serialization as crypto_serialization
+from cryptography.hazmat.primitives.asymmetric import rsa
+from cryptography.hazmat.backends import default_backend as crypto_default_backend
+
+__author__ = "Isabel Lloret, Sergio Gonzalez, Alfonso Tierno, Gerardo Garcia"
 __date__ = "$18-apr-2019 23:59:59$"
 
 
 __date__ = "$18-apr-2019 23:59:59$"
 
 
@@ -43,6 +49,14 @@ if getenv("OSMRO_PDB_DEBUG"):
     pdb.set_trace()
 
 
     pdb.set_trace()
 
 
+def find_in_list(the_list, condition_lambda):
+    for item in the_list:
+        if condition_lambda(item):
+            return item
+    else:
+        return None
+
+
 class vimconnector(vimconn.VimConnector):
 
     # Translate azure provisioning state to OSM provision state
 class vimconnector(vimconn.VimConnector):
 
     # Translate azure provisioning state to OSM provision state
@@ -68,8 +82,84 @@ class vimconnector(vimconn.VimConnector):
         "deallocating": "BUILD",
     }
 
         "deallocating": "BUILD",
     }
 
+    # TODO - review availability zones
     AZURE_ZONES = ["1", "2", "3"]
 
     AZURE_ZONES = ["1", "2", "3"]
 
+    AZURE_COMPUTE_MGMT_CLIENT_API_VERSION = "2021-03-01"
+    AZURE_COMPUTE_MGMT_PROFILE_TAG = "azure.mgmt.compute.ComputeManagementClient"
+    AZURE_COMPUTE_MGMT_PROFILE = ProfileDefinition(
+        {
+            AZURE_COMPUTE_MGMT_PROFILE_TAG: {
+                None: AZURE_COMPUTE_MGMT_CLIENT_API_VERSION,
+                "availability_sets": "2020-12-01",
+                "dedicated_host_groups": "2020-12-01",
+                "dedicated_hosts": "2020-12-01",
+                "disk_accesses": "2020-12-01",
+                "disk_encryption_sets": "2020-12-01",
+                "disk_restore_point": "2020-12-01",
+                "disks": "2020-12-01",
+                "galleries": "2020-09-30",
+                "gallery_application_versions": "2020-09-30",
+                "gallery_applications": "2020-09-30",
+                "gallery_image_versions": "2020-09-30",
+                "gallery_images": "2020-09-30",
+                "gallery_sharing_profile": "2020-09-30",
+                "images": "2020-12-01",
+                "log_analytics": "2020-12-01",
+                "operations": "2020-12-01",
+                "proximity_placement_groups": "2020-12-01",
+                "resource_skus": "2019-04-01",
+                "shared_galleries": "2020-09-30",
+                "shared_gallery_image_versions": "2020-09-30",
+                "shared_gallery_images": "2020-09-30",
+                "snapshots": "2020-12-01",
+                "ssh_public_keys": "2020-12-01",
+                "usage": "2020-12-01",
+                "virtual_machine_extension_images": "2020-12-01",
+                "virtual_machine_extensions": "2020-12-01",
+                "virtual_machine_images": "2020-12-01",
+                "virtual_machine_images_edge_zone": "2020-12-01",
+                "virtual_machine_run_commands": "2020-12-01",
+                "virtual_machine_scale_set_extensions": "2020-12-01",
+                "virtual_machine_scale_set_rolling_upgrades": "2020-12-01",
+                "virtual_machine_scale_set_vm_extensions": "2020-12-01",
+                "virtual_machine_scale_set_vm_run_commands": "2020-12-01",
+                "virtual_machine_scale_set_vms": "2020-12-01",
+                "virtual_machine_scale_sets": "2020-12-01",
+                "virtual_machine_sizes": "2020-12-01",
+                "virtual_machines": "2020-12-01",
+            }
+        },
+        AZURE_COMPUTE_MGMT_PROFILE_TAG + " osm",
+    )
+
+    AZURE_RESOURCE_MGMT_CLIENT_API_VERSION = "2020-10-01"
+    AZURE_RESOURCE_MGMT_PROFILE_TAG = (
+        "azure.mgmt.resource.resources.ResourceManagementClient"
+    )
+    AZURE_RESOURCE_MGMT_PROFILE = ProfileDefinition(
+        {
+            AZURE_RESOURCE_MGMT_PROFILE_TAG: {
+                None: AZURE_RESOURCE_MGMT_CLIENT_API_VERSION,
+            }
+        },
+        AZURE_RESOURCE_MGMT_PROFILE_TAG + " osm",
+    )
+
+    AZURE_NETWORK_MGMT_CLIENT_API_VERSION = "2020-11-01"
+    AZURE_NETWORK_MGMT_PROFILE_TAG = "azure.mgmt.network.NetworkManagementClient"
+    AZURE_NETWORK_MGMT_PROFILE = ProfileDefinition(
+        {
+            AZURE_NETWORK_MGMT_PROFILE_TAG: {
+                None: AZURE_NETWORK_MGMT_CLIENT_API_VERSION,
+                "firewall_policy_rule_groups": "2020-04-01",
+                "interface_endpoints": "2019-02-01",
+                "p2_svpn_server_configurations": "2019-07-01",
+            }
+        },
+        AZURE_NETWORK_MGMT_PROFILE_TAG + " osm",
+    )
+
     def __init__(
         self,
         uuid,
     def __init__(
         self,
         uuid,
@@ -117,11 +207,10 @@ class vimconnector(vimconn.VimConnector):
         self.reload_client = True
 
         self.vnet_address_space = None
         self.reload_client = True
 
         self.vnet_address_space = None
+
         # LOGGER
         self.logger = logging.getLogger("ro.vim.azure")
         # LOGGER
         self.logger = logging.getLogger("ro.vim.azure")
-
         if log_level:
         if log_level:
-            logging.basicConfig()
             self.logger.setLevel(getattr(logging, log_level))
 
         self.tenant = tenant_id or tenant_name
             self.logger.setLevel(getattr(logging, log_level))
 
         self.tenant = tenant_id or tenant_name
@@ -160,13 +249,25 @@ class vimconnector(vimconn.VimConnector):
         if "vnet_name" in config:
             self.vnet_name = config["vnet_name"]
 
         if "vnet_name" in config:
             self.vnet_name = config["vnet_name"]
 
+        # TODO - not used, do anything about it?
         # public ssh key
         self.pub_key = config.get("pub_key")
 
         # public ssh key
         self.pub_key = config.get("pub_key")
 
+        # TODO - check default user for azure
+        # default admin user
+        self._default_admin_user = "azureuser"
+
         # flavor pattern regex
         if "flavors_pattern" in config:
             self._config["flavors_pattern"] = config["flavors_pattern"]
 
         # flavor pattern regex
         if "flavors_pattern" in config:
             self._config["flavors_pattern"] = config["flavors_pattern"]
 
+    def _find_in_capabilities(self, capabilities, name):
+        cap = find_in_list(capabilities, lambda c: c["name"] == name)
+        if cap:
+            return cap.get("value")
+        else:
+            return None
+
     def _reload_connection(self):
         """
         Called before any operation, checks python azure clients
     def _reload_connection(self):
         """
         Called before any operation, checks python azure clients
@@ -175,19 +276,25 @@ class vimconnector(vimconn.VimConnector):
             self.logger.debug("reloading azure client")
 
             try:
             self.logger.debug("reloading azure client")
 
             try:
-                self.credentials = ServicePrincipalCredentials(
+                self.credentials = ClientSecretCredential(
                     client_id=self._config["user"],
                     client_id=self._config["user"],
-                    secret=self._config["passwd"],
-                    tenant=self._config["tenant"],
+                    client_secret=self._config["passwd"],
+                    tenant_id=self._config["tenant"],
                 )
                 self.conn = ResourceManagementClient(
                 )
                 self.conn = ResourceManagementClient(
-                    self.credentials, self._config["subscription_id"]
+                    self.credentials,
+                    self._config["subscription_id"],
+                    profile=self.AZURE_RESOURCE_MGMT_PROFILE,
                 )
                 self.conn_compute = ComputeManagementClient(
                 )
                 self.conn_compute = ComputeManagementClient(
-                    self.credentials, self._config["subscription_id"]
+                    self.credentials,
+                    self._config["subscription_id"],
+                    profile=self.AZURE_COMPUTE_MGMT_PROFILE,
                 )
                 self.conn_vnet = NetworkManagementClient(
                 )
                 self.conn_vnet = NetworkManagementClient(
-                    self.credentials, self._config["subscription_id"]
+                    self.credentials,
+                    self._config["subscription_id"],
+                    profile=self.AZURE_NETWORK_MGMT_PROFILE,
                 )
                 self._check_or_create_resource_group()
                 self._check_or_create_vnet()
                 )
                 self._check_or_create_resource_group()
                 self._check_or_create_vnet()
@@ -248,6 +355,7 @@ class vimconnector(vimconn.VimConnector):
 
     def _check_subnets_for_vm(self, net_list):
         # All subnets must belong to the same resource group and vnet
 
     def _check_subnets_for_vm(self, net_list):
         # All subnets must belong to the same resource group and vnet
+        # All subnets must belong to the same resource group anded vnet
         rg_vnet = set(
             self._get_resource_group_name_from_resource_id(net["net_id"])
             + self._get_net_name_from_resource_id(net["net_id"])
         rg_vnet = set(
             self._get_resource_group_name_from_resource_id(net["net_id"])
             + self._get_net_name_from_resource_id(net["net_id"])
@@ -263,8 +371,9 @@ class vimconnector(vimconn.VimConnector):
         """
         Transforms a generic or azure exception to a vimcommException
         """
         """
         Transforms a generic or azure exception to a vimcommException
         """
+        self.logger.error("Azure plugin error: {}".format(e))
         if isinstance(e, vimconn.VimConnException):
         if isinstance(e, vimconn.VimConnException):
-            raise
+            raise e
         elif isinstance(e, AuthenticationError):
             raise vimconn.VimConnAuthException(type(e).__name__ + ": " + str(e))
         elif isinstance(e, ConnectionError):
         elif isinstance(e, AuthenticationError):
             raise vimconn.VimConnAuthException(type(e).__name__ + ": " + str(e))
         elif isinstance(e, ConnectionError):
@@ -318,7 +427,7 @@ class vimconnector(vimconn.VimConnector):
             self.vnet_address_space = "10.0.0.0/8"
 
             self.logger.debug("create base vnet: %s", self.vnet_name)
             self.vnet_address_space = "10.0.0.0/8"
 
             self.logger.debug("create base vnet: %s", self.vnet_name)
-            self.conn_vnet.virtual_networks.create_or_update(
+            self.conn_vnet.virtual_networks.begin_create_or_update(
                 self.resource_group, self.vnet_name, vnet_params
             )
             vnet = self.conn_vnet.virtual_networks.get(
                 self.resource_group, self.vnet_name, vnet_params
             )
             vnet = self.conn_vnet.virtual_networks.get(
@@ -401,10 +510,11 @@ class vimconnector(vimconn.VimConnector):
             subnet_name = self._get_unused_subnet_name(net_name)
 
             self.logger.debug("creating subnet_name: {}".format(subnet_name))
             subnet_name = self._get_unused_subnet_name(net_name)
 
             self.logger.debug("creating subnet_name: {}".format(subnet_name))
-            async_creation = self.conn_vnet.subnets.create_or_update(
+            async_creation = self.conn_vnet.subnets.begin_create_or_update(
                 self.resource_group, self.vnet_name, subnet_name, subnet_params
             )
             async_creation.wait()
                 self.resource_group, self.vnet_name, subnet_name, subnet_params
             )
             async_creation.wait()
+            # TODO - do not wait here, check where it is used
             self.logger.debug("created subnet_name: {}".format(subnet_name))
 
             return "{}/subnets/{}".format(self.vnet_id, subnet_name), None
             self.logger.debug("created subnet_name: {}".format(subnet_name))
 
             return "{}/subnets/{}".format(self.vnet_id, subnet_name), None
@@ -456,8 +566,10 @@ class vimconnector(vimconn.VimConnector):
             if mac_address:
                 net_ifz["mac_address"] = mac_address
 
             if mac_address:
                 net_ifz["mac_address"] = mac_address
 
-            async_nic_creation = self.conn_vnet.network_interfaces.create_or_update(
-                self.resource_group, nic_name, net_ifz
+            async_nic_creation = (
+                self.conn_vnet.network_interfaces.begin_create_or_update(
+                    self.resource_group, nic_name, net_ifz
+                )
             )
             nic_data = async_nic_creation.result()
             created_items[nic_data.id] = True
             )
             nic_data = async_nic_creation.result()
             created_items[nic_data.id] = True
@@ -470,8 +582,10 @@ class vimconnector(vimconn.VimConnector):
                     "public_ip_allocation_method": "Dynamic",
                 }
                 public_ip_name = nic_name + "-public-ip"
                     "public_ip_allocation_method": "Dynamic",
                 }
                 public_ip_name = nic_name + "-public-ip"
-                async_public_ip = self.conn_vnet.public_ip_addresses.create_or_update(
-                    self.resource_group, public_ip_name, public_ip_address_params
+                async_public_ip = (
+                    self.conn_vnet.public_ip_addresses.begin_create_or_update(
+                        self.resource_group, public_ip_name, public_ip_address_params
+                    )
                 )
                 public_ip = async_public_ip.result()
                 self.logger.debug("created public IP: {}".format(public_ip))
                 )
                 public_ip = async_public_ip.result()
                 self.logger.debug("created public IP: {}".format(public_ip))
@@ -484,7 +598,7 @@ class vimconnector(vimconn.VimConnector):
                 nic_data.ip_configurations[0].public_ip_address = public_ip
                 created_items[public_ip.id] = True
 
                 nic_data.ip_configurations[0].public_ip_address = public_ip
                 created_items[public_ip.id] = True
 
-                self.conn_vnet.network_interfaces.create_or_update(
+                self.conn_vnet.network_interfaces.begin_create_or_update(
                     self.resource_group, nic_name, nic_data
                 )
 
                     self.resource_group, nic_name, nic_data
                 )
 
@@ -558,9 +672,15 @@ class vimconnector(vimconn.VimConnector):
                             # if version is defined get directly version, else list images
                             if len(params) == 4 and params[3]:
                                 version = params[3]
                             # if version is defined get directly version, else list images
                             if len(params) == 4 and params[3]:
                                 version = params[3]
-                                image_list = self._get_version_image_list(
-                                    publisher, offer, sku, version
-                                )
+                                if version == "latest":
+                                    image_list = self._get_sku_image_list(
+                                        publisher, offer, sku
+                                    )
+                                    image_list = [image_list[-1]]
+                                else:
+                                    image_list = self._get_version_image_list(
+                                        publisher, offer, sku, version
+                                    )
                             else:
                                 image_list = self._get_sku_image_list(
                                     publisher, offer, sku
                             else:
                                 image_list = self._get_sku_image_list(
                                     publisher, offer, sku
@@ -788,51 +908,9 @@ class vimconnector(vimconn.VimConnector):
                 vm_nics.append({"id": str(vm_nic.id)})
                 net["vim_id"] = vm_nic.id
 
                 vm_nics.append({"id": str(vm_nic.id)})
                 net["vim_id"] = vm_nic.id
 
-            # cloud-init configuration
-            # cloud config
-            if cloud_config:
-                config_drive, userdata = self._create_user_data(cloud_config)
-                custom_data = base64.b64encode(userdata.encode("utf-8")).decode(
-                    "latin-1"
-                )
-                key_data = None
-                key_pairs = cloud_config.get("key-pairs")
-                if key_pairs:
-                    key_data = key_pairs[0]
-
-                if cloud_config.get("users"):
-                    user_name = cloud_config.get("users")[0].get("name", "osm")
-                else:
-                    user_name = "osm"  # DEFAULT USER IS OSM
-
-                os_profile = {
-                    "computer_name": vm_name,
-                    "admin_username": user_name,
-                    "linux_configuration": {
-                        "disable_password_authentication": True,
-                        "ssh": {
-                            "public_keys": [
-                                {
-                                    "path": "/home/{}/.ssh/authorized_keys".format(
-                                        user_name
-                                    ),
-                                    "key_data": key_data,
-                                }
-                            ]
-                        },
-                    },
-                    "custom_data": custom_data,
-                }
-            else:
-                os_profile = {
-                    "computer_name": vm_name,
-                    "admin_username": "osm",
-                    "admin_password": "Osm4u!",
-                }
-
             vm_parameters = {
                 "location": self.region,
             vm_parameters = {
                 "location": self.region,
-                "os_profile": os_profile,
+                "os_profile": self._build_os_profile(vm_name, cloud_config, image_id),
                 "hardware_profile": {"vm_size": flavor_id},
                 "storage_profile": {"image_reference": image_reference},
             }
                 "hardware_profile": {"vm_size": flavor_id},
                 "storage_profile": {"image_reference": image_reference},
             }
@@ -854,12 +932,14 @@ class vimconnector(vimconn.VimConnector):
                 vm_parameters["zones"] = [vm_zone]
 
             self.logger.debug("create vm name: %s", vm_name)
                 vm_parameters["zones"] = [vm_zone]
 
             self.logger.debug("create vm name: %s", vm_name)
-            creation_result = self.conn_compute.virtual_machines.create_or_update(
-                self.resource_group, vm_name, vm_parameters
+            creation_result = self.conn_compute.virtual_machines.begin_create_or_update(
+                self.resource_group, vm_name, vm_parameters, polling=False
             )
             )
+            self.logger.debug("obtained creation result: %s", creation_result)
             virtual_machine = creation_result.result()
             self.logger.debug("created vm name: %s", vm_name)
 
             virtual_machine = creation_result.result()
             self.logger.debug("created vm name: %s", vm_name)
 
+            """ Por ahora no hacer polling para ver si tarda menos
             # Add disks if they are provided
             if disk_list:
                 for disk_index, disk in enumerate(disk_list):
             # Add disks if they are provided
             if disk_list:
                 for disk_index, disk in enumerate(disk_list):
@@ -875,6 +955,7 @@ class vimconnector(vimconn.VimConnector):
             if start:
                 self.conn_compute.virtual_machines.start(self.resource_group, vm_name)
             # start_result.wait()
             if start:
                 self.conn_compute.virtual_machines.start(self.resource_group, vm_name)
             # start_result.wait()
+            """
 
             return virtual_machine.id, created_items
 
 
             return virtual_machine.id, created_items
 
@@ -900,6 +981,71 @@ class vimconnector(vimconn.VimConnector):
             self.logger.debug("Exception creating new vminstance: %s", e, exc_info=True)
             self._format_vimconn_exception(e)
 
             self.logger.debug("Exception creating new vminstance: %s", e, exc_info=True)
             self._format_vimconn_exception(e)
 
+    def _build_os_profile(self, vm_name, cloud_config, image_id):
+
+        # initial os_profile
+        os_profile = {"computer_name": vm_name}
+
+        # for azure os_profile admin_username is required
+        if cloud_config and cloud_config.get("users"):
+            admin_username = cloud_config.get("users")[0].get(
+                "name", self._get_default_admin_user(image_id)
+            )
+        else:
+            admin_username = self._get_default_admin_user(image_id)
+        os_profile["admin_username"] = admin_username
+
+        # if there is a cloud-init load it
+        if cloud_config:
+            _, userdata = self._create_user_data(cloud_config)
+            custom_data = base64.b64encode(userdata.encode("utf-8")).decode("latin-1")
+            os_profile["custom_data"] = custom_data
+
+        # either password of ssh-keys are required
+        # we will always use ssh-keys, in case it is not available we will generate it
+        if cloud_config and cloud_config.get("key-pairs"):
+            key_data = cloud_config.get("key-pairs")[0]
+        else:
+            _, key_data = self._generate_keys()
+
+        os_profile["linux_configuration"] = {
+            "ssh": {
+                "public_keys": [
+                    {
+                        "path": "/home/{}/.ssh/authorized_keys".format(admin_username),
+                        "key_data": key_data,
+                    }
+                ]
+            },
+        }
+
+        return os_profile
+
+    def _generate_keys(self):
+        """Method used to generate a pair of private/public keys.
+        This method is used because to create a vm in Azure we always need a key or a password
+        In some cases we may have a password in a cloud-init file but it may not be available
+        """
+        key = rsa.generate_private_key(
+            backend=crypto_default_backend(), public_exponent=65537, key_size=2048
+        )
+        private_key = key.private_bytes(
+            crypto_serialization.Encoding.PEM,
+            crypto_serialization.PrivateFormat.PKCS8,
+            crypto_serialization.NoEncryption(),
+        )
+        public_key = key.public_key().public_bytes(
+            crypto_serialization.Encoding.OpenSSH,
+            crypto_serialization.PublicFormat.OpenSSH,
+        )
+        private_key = private_key.decode("utf8")
+        # Change first line because Paramiko needs a explicit start with 'BEGIN RSA PRIVATE KEY'
+        i = private_key.find("\n")
+        private_key = "-----BEGIN RSA PRIVATE KEY-----" + private_key[i:]
+        public_key = public_key.decode("utf8")
+
+        return private_key, public_key
+
     def _get_unused_vm_name(self, vm_name):
         """
         Checks the vm name and in case it is used adds a suffix to the name to allow creation
     def _get_unused_vm_name(self, vm_name):
         """
         Checks the vm name and in case it is used adds a suffix to the name to allow creation
@@ -969,7 +1115,7 @@ class vimconnector(vimconn.VimConnector):
             disk_name = vm_name + "_DataDisk_" + str(disk_index)
             if not disk.get("image_id"):
                 self.logger.debug("create new data disk name: %s", disk_name)
             disk_name = vm_name + "_DataDisk_" + str(disk_index)
             if not disk.get("image_id"):
                 self.logger.debug("create new data disk name: %s", disk_name)
-                async_disk_creation = self.conn_compute.disks.create_or_update(
+                async_disk_creation = self.conn_compute.disks.begin_create_or_update(
                     self.resource_group,
                     disk_name,
                     {
                     self.resource_group,
                     disk_name,
                     {
@@ -993,16 +1139,18 @@ class vimconnector(vimconn.VimConnector):
                     if type == "snapshots" or type == "disks":
                         self.logger.debug("create disk from copy name: %s", image_name)
                         # Â¿Should check that snapshot exists?
                     if type == "snapshots" or type == "disks":
                         self.logger.debug("create disk from copy name: %s", image_name)
                         # Â¿Should check that snapshot exists?
-                        async_disk_creation = self.conn_compute.disks.create_or_update(
-                            self.resource_group,
-                            disk_name,
-                            {
-                                "location": self.region,
-                                "creation_data": {
-                                    "create_option": "Copy",
-                                    "source_uri": image_id,
+                        async_disk_creation = (
+                            self.conn_compute.disks.begin_create_or_update(
+                                self.resource_group,
+                                disk_name,
+                                {
+                                    "location": self.region,
+                                    "creation_data": {
+                                        "create_option": "Copy",
+                                        "source_uri": image_id,
+                                    },
                                 },
                                 },
-                            },
+                            )
                         )
                         data_disk = async_disk_creation.result()
                         created_items[data_disk.id] = True
                         )
                         data_disk = async_disk_creation.result()
                         created_items[data_disk.id] = True
@@ -1026,7 +1174,7 @@ class vimconnector(vimconn.VimConnector):
             }
         )
         self.logger.debug("attach disk name: %s", disk_name)
             }
         )
         self.logger.debug("attach disk name: %s", disk_name)
-        self.conn_compute.virtual_machines.create_or_update(
+        self.conn_compute.virtual_machines.begin_create_or_update(
             self.resource_group, virtual_machine.name, virtual_machine
         )
 
             self.resource_group, virtual_machine.name, virtual_machine
         )
 
@@ -1090,36 +1238,67 @@ class vimconnector(vimconn.VimConnector):
         try:
             self._reload_connection()
             vm_sizes_list = [
         try:
             self._reload_connection()
             vm_sizes_list = [
-                vm_size.serialize()
-                for vm_size in self.conn_compute.virtual_machine_sizes.list(self.region)
+                vm_size.as_dict()
+                for vm_size in self.conn_compute.resource_skus.list(
+                    "location eq '{}'".format(self.region)
+                )
             ]
 
             cpus = filter_dict.get("vcpus") or 0
             memMB = filter_dict.get("ram") or 0
             ]
 
             cpus = filter_dict.get("vcpus") or 0
             memMB = filter_dict.get("ram") or 0
+            numberInterfaces = len(filter_dict.get("interfaces", [])) or 0
 
             # Filter
 
             # Filter
-            if self._config.get("flavors_pattern"):
-                filtered_sizes = [
-                    size
-                    for size in vm_sizes_list
-                    if size["numberOfCores"] >= cpus
-                    and size["memoryInMB"] >= memMB
-                    and re.search(self._config.get("flavors_pattern"), size["name"])
-                ]
-            else:
-                filtered_sizes = [
-                    size
-                    for size in vm_sizes_list
-                    if size["numberOfCores"] >= cpus and size["memoryInMB"] >= memMB
-                ]
+            filtered_sizes = []
+            for size in vm_sizes_list:
+                if size["resource_type"] == "virtualMachines":
+                    size_cpus = int(
+                        self._find_in_capabilities(size["capabilities"], "vCPUs")
+                    )
+                    size_memory = float(
+                        self._find_in_capabilities(size["capabilities"], "MemoryGB")
+                    )
+                    size_interfaces = self._find_in_capabilities(
+                        size["capabilities"], "MaxNetworkInterfaces"
+                    )
+                    if size_interfaces:
+                        size_interfaces = int(size_interfaces)
+                    else:
+                        self.logger.debug(
+                            "Flavor with no defined MaxNetworkInterfaces: {}".format(
+                                size["name"]
+                            )
+                        )
+                        continue
+                    if (
+                        size_cpus >= cpus
+                        and size_memory >= memMB / 1024
+                        and size_interfaces >= numberInterfaces
+                    ):
+                        if self._config.get("flavors_pattern"):
+                            if re.search(
+                                self._config.get("flavors_pattern"), size["name"]
+                            ):
+                                new_size = {
+                                    e["name"]: e["value"] for e in size["capabilities"]
+                                }
+                                new_size["name"] = size["name"]
+                                filtered_sizes.append(new_size)
+                        else:
+                            new_size = {
+                                e["name"]: e["value"] for e in size["capabilities"]
+                            }
+                            new_size["name"] = size["name"]
+                            filtered_sizes.append(new_size)
 
             # Sort
             listedFilteredSizes = sorted(
                 filtered_sizes,
                 key=lambda k: (
 
             # Sort
             listedFilteredSizes = sorted(
                 filtered_sizes,
                 key=lambda k: (
-                    k["numberOfCores"],
-                    k["memoryInMB"],
-                    k["resourceDiskSizeInMB"],
+                    int(k["vCPUs"]),
+                    float(k["MemoryGB"]),
+                    int(k["MaxNetworkInterfaces"]),
+                    int(k["MaxResourceVolumeMB"]),
                 ),
             )
 
                 ),
             )
 
@@ -1137,8 +1316,10 @@ class vimconnector(vimconn.VimConnector):
         try:
             self._reload_connection()
             vm_sizes_list = [
         try:
             self._reload_connection()
             vm_sizes_list = [
-                vm_size.serialize()
-                for vm_size in self.conn_compute.virtual_machine_sizes.list(self.region)
+                vm_size.as_dict()
+                for vm_size in self.conn_compute.resource_skus.list(
+                    "location eq '{}'".format(self.region)
+                )
             ]
 
             output_flavor = None
             ]
 
             output_flavor = None
@@ -1182,22 +1363,39 @@ class vimconnector(vimconn.VimConnector):
 
         self._reload_connection()
         res_name = self._get_resource_name_from_resource_id(net_id)
 
         self._reload_connection()
         res_name = self._get_resource_name_from_resource_id(net_id)
-        filter_dict = {"name": res_name}
-        network_list = self.get_network_list(filter_dict)
-        if not network_list:
-            raise vimconn.VimConnNotFoundException(
-                "network '{}' not found".format(net_id)
-            )
 
         try:
 
         try:
+            # Obtain subnets ant try to delete nic first
+            subnet = self.conn_vnet.subnets.get(
+                self.resource_group, self.vnet_name, res_name
+            )
+            if not subnet:
+                raise vimconn.VimConnNotFoundException(
+                    "network '{}' not found".format(net_id)
+                )
+
+            # TODO - for a quick-fix delete nics sequentially but should not wait
+            # for each in turn
+            if subnet.ip_configurations:
+                for ip_configuration in subnet.ip_configurations:
+                    # obtain nic_name from ip_configuration
+                    parsed_id = azure_tools.parse_resource_id(ip_configuration.id)
+                    nic_name = parsed_id["name"]
+                    self.delete_inuse_nic(nic_name)
+
             # Subnet API fails (CloudError: Azure Error: ResourceNotFound)
             # Put the initial virtual_network API
             # Subnet API fails (CloudError: Azure Error: ResourceNotFound)
             # Put the initial virtual_network API
-            async_delete = self.conn_vnet.subnets.delete(
+            async_delete = self.conn_vnet.subnets.begin_delete(
                 self.resource_group, self.vnet_name, res_name
             )
             async_delete.wait()
                 self.resource_group, self.vnet_name, res_name
             )
             async_delete.wait()
+
             return net_id
 
             return net_id
 
+        except ResourceNotFoundError:
+            raise vimconn.VimConnNotFoundException(
+                "network '{}' not found".format(net_id)
+            )
         except CloudError as e:
             if e.error.error and "notfound" in e.error.error.lower():
                 raise vimconn.VimConnNotFoundException(
         except CloudError as e:
             if e.error.error and "notfound" in e.error.error.lower():
                 raise vimconn.VimConnNotFoundException(
@@ -1208,6 +1406,62 @@ class vimconnector(vimconn.VimConnector):
         except Exception as e:
             self._format_vimconn_exception(e)
 
         except Exception as e:
             self._format_vimconn_exception(e)
 
+    def delete_inuse_nic(self, nic_name):
+
+        # Obtain nic data
+        nic_data = self.conn_vnet.network_interfaces.get(self.resource_group, nic_name)
+
+        # Obtain vm associated to nic in case it exists
+        if nic_data.virtual_machine:
+            vm_name = azure_tools.parse_resource_id(nic_data.virtual_machine.id)["name"]
+            self.logger.debug("vm_name: {}".format(vm_name))
+            virtual_machine = self.conn_compute.virtual_machines.get(
+                self.resource_group, vm_name
+            )
+            self.logger.debug("obtained vm")
+
+            # Deattach nic from vm if it has netwolk machines attached
+            network_interfaces = virtual_machine.network_profile.network_interfaces
+            network_interfaces[:] = [
+                interface
+                for interface in network_interfaces
+                if self._get_resource_name_from_resource_id(interface.id) != nic_name
+            ]
+
+            # TODO - check if there is a public ip to delete and delete it
+            if network_interfaces:
+
+                # Deallocate the vm
+                async_vm_deallocate = (
+                    self.conn_compute.virtual_machines.begin_deallocate(
+                        self.resource_group, vm_name
+                    )
+                )
+                self.logger.debug("deallocating vm")
+                async_vm_deallocate.wait()
+                self.logger.debug("vm deallocated")
+
+                async_vm_update = (
+                    self.conn_compute.virtual_machines.begin_create_or_update(
+                        self.resource_group, vm_name, virtual_machine
+                    )
+                )
+                virtual_machine = async_vm_update.result()
+                self.logger.debug("nic removed from interface")
+
+            else:
+                self.logger.debug("There are no interfaces left, delete vm")
+                self.delete_vminstance(virtual_machine.id)
+                self.logger.debug("Delete vm")
+
+        # Delete nic
+        self.logger.debug("delete NIC name: %s", nic_name)
+        nic_delete = self.conn_vnet.network_interfaces.begin_delete(
+            self.resource_group, nic_name
+        )
+        nic_delete.wait()
+        self.logger.debug("deleted NIC name: %s", nic_name)
+
     def delete_vminstance(self, vm_id, created_items=None):
         """Deletes a vm instance from the vim."""
         self.logger.debug(
     def delete_vminstance(self, vm_id, created_items=None):
         """Deletes a vm instance from the vim."""
         self.logger.debug(
@@ -1228,25 +1482,27 @@ class vimconnector(vimconn.VimConnector):
                 # vm_stop = self.conn_compute.virtual_machines.power_off(self.resource_group, resName)
                 # vm_stop.wait()
 
                 # vm_stop = self.conn_compute.virtual_machines.power_off(self.resource_group, resName)
                 # vm_stop.wait()
 
-                vm_delete = self.conn_compute.virtual_machines.delete(
+                vm_delete = self.conn_compute.virtual_machines.begin_delete(
                     self.resource_group, res_name
                 )
                 vm_delete.wait()
                 self.logger.debug("deleted VM name: %s", res_name)
 
                     self.resource_group, res_name
                 )
                 vm_delete.wait()
                 self.logger.debug("deleted VM name: %s", res_name)
 
-                # Delete OS Disk
-                os_disk_name = vm.storage_profile.os_disk.name
-                self.logger.debug("delete OS DISK: %s", os_disk_name)
-                async_disk_delete = self.conn_compute.disks.delete(
-                    self.resource_group, os_disk_name
-                )
-                async_disk_delete.wait()
-                # os disks are created always with the machine
-                self.logger.debug("deleted OS DISK name: %s", os_disk_name)
+                # Delete OS Disk, check if exists, in case of error creating
+                # it may not be fully created
+                if vm.storage_profile.os_disk:
+                    os_disk_name = vm.storage_profile.os_disk.name
+                    self.logger.debug("delete OS DISK: %s", os_disk_name)
+                    async_disk_delete = self.conn_compute.disks.begin_delete(
+                        self.resource_group, os_disk_name
+                    )
+                    async_disk_delete.wait()
+                    # os disks are created always with the machine
+                    self.logger.debug("deleted OS DISK name: %s", os_disk_name)
 
                 for data_disk in vm.storage_profile.data_disks:
                     self.logger.debug("delete data_disk: %s", data_disk.name)
 
                 for data_disk in vm.storage_profile.data_disks:
                     self.logger.debug("delete data_disk: %s", data_disk.name)
-                    async_disk_delete = self.conn_compute.disks.delete(
+                    async_disk_delete = self.conn_compute.disks.begin_delete(
                         self.resource_group, data_disk.name
                     )
                     async_disk_delete.wait()
                         self.resource_group, data_disk.name
                     )
                     async_disk_delete.wait()
@@ -1280,7 +1536,7 @@ class vimconnector(vimconn.VimConnector):
                         # Public ip must be deleted afterwards of nic that is attached
 
                     self.logger.debug("delete NIC name: %s", nic_name)
                         # Public ip must be deleted afterwards of nic that is attached
 
                     self.logger.debug("delete NIC name: %s", nic_name)
-                    nic_delete = self.conn_vnet.network_interfaces.delete(
+                    nic_delete = self.conn_vnet.network_interfaces.begin_delete(
                         self.resource_group, nic_name
                     )
                     nic_delete.wait()
                         self.resource_group, nic_name
                     )
                     nic_delete.wait()
@@ -1290,7 +1546,7 @@ class vimconnector(vimconn.VimConnector):
                     # Delete list of public ips
                     if public_ip_name:
                         self.logger.debug("delete PUBLIC IP - " + public_ip_name)
                     # Delete list of public ips
                     if public_ip_name:
                         self.logger.debug("delete PUBLIC IP - " + public_ip_name)
-                        ip_delete = self.conn_vnet.public_ip_addresses.delete(
+                        ip_delete = self.conn_vnet.public_ip_addresses.begin_delete(
                             self.resource_group, public_ip_name
                         )
                         ip_delete.wait()
                             self.resource_group, public_ip_name
                         )
                         ip_delete.wait()
@@ -1299,6 +1555,10 @@ class vimconnector(vimconn.VimConnector):
             # Delete created items
             self._delete_created_items(created_items)
 
             # Delete created items
             self._delete_created_items(created_items)
 
+        except ResourceNotFoundError:
+            raise vimconn.VimConnNotFoundException(
+                "No vm instance found '{}'".format(vm_id)
+            )
         except CloudError as e:
             if e.error.error and "notfound" in e.error.error.lower():
                 raise vimconn.VimConnNotFoundException(
         except CloudError as e:
             if e.error.error and "notfound" in e.error.error.lower():
                 raise vimconn.VimConnNotFoundException(
@@ -1319,6 +1579,7 @@ class vimconnector(vimconn.VimConnector):
         virtual machine fails creating or in other cases of error
         """
         self.logger.debug("Created items: %s", created_items)
         virtual machine fails creating or in other cases of error
         """
         self.logger.debug("Created items: %s", created_items)
+        # TODO - optimize - should not wait until it is deleted
         # Must delete in order first nics, then public_ips
         # As dictionaries don't preserve order, first get items to be deleted then delete them
         nics_to_delete = []
         # Must delete in order first nics, then public_ips
         # As dictionaries don't preserve order, first get items to be deleted then delete them
         nics_to_delete = []
@@ -1345,7 +1606,7 @@ class vimconnector(vimconn.VimConnector):
         for item_name in nics_to_delete:
             try:
                 self.logger.debug("deleting nic name %s:", item_name)
         for item_name in nics_to_delete:
             try:
                 self.logger.debug("deleting nic name %s:", item_name)
-                nic_delete = self.conn_vnet.network_interfaces.delete(
+                nic_delete = self.conn_vnet.network_interfaces.begin_delete(
                     self.resource_group, item_name
                 )
                 nic_delete.wait()
                     self.resource_group, item_name
                 )
                 nic_delete.wait()
@@ -1358,7 +1619,7 @@ class vimconnector(vimconn.VimConnector):
         for item_name in publics_ip_to_delete:
             try:
                 self.logger.debug("deleting public ip name %s:", item_name)
         for item_name in publics_ip_to_delete:
             try:
                 self.logger.debug("deleting public ip name %s:", item_name)
-                ip_delete = self.conn_vnet.public_ip_addresses.delete(
+                ip_delete = self.conn_vnet.public_ip_addresses.begin_delete(
                     self.resource_group, name
                 )
                 ip_delete.wait()
                     self.resource_group, name
                 )
                 ip_delete.wait()
@@ -1371,7 +1632,7 @@ class vimconnector(vimconn.VimConnector):
         for item_name in disks_to_delete:
             try:
                 self.logger.debug("deleting data disk name %s:", name)
         for item_name in disks_to_delete:
             try:
                 self.logger.debug("deleting data disk name %s:", name)
-                async_disk_delete = self.conn_compute.disks.delete(
+                async_disk_delete = self.conn_compute.disks.begin_delete(
                     self.resource_group, item_name
                 )
                 async_disk_delete.wait()
                     self.resource_group, item_name
                 )
                 async_disk_delete.wait()
@@ -1392,21 +1653,29 @@ class vimconnector(vimconn.VimConnector):
             resName = self._get_resource_name_from_resource_id(vm_id)
 
             if "start" in action_dict:
             resName = self._get_resource_name_from_resource_id(vm_id)
 
             if "start" in action_dict:
-                self.conn_compute.virtual_machines.start(self.resource_group, resName)
+                self.conn_compute.virtual_machines.begin_start(
+                    self.resource_group, resName
+                )
             elif (
                 "stop" in action_dict
                 or "shutdown" in action_dict
                 or "shutoff" in action_dict
             ):
             elif (
                 "stop" in action_dict
                 or "shutdown" in action_dict
                 or "shutoff" in action_dict
             ):
-                self.conn_compute.virtual_machines.power_off(
+                self.conn_compute.virtual_machines.begin_power_off(
                     self.resource_group, resName
                 )
             elif "terminate" in action_dict:
                     self.resource_group, resName
                 )
             elif "terminate" in action_dict:
-                self.conn_compute.virtual_machines.delete(self.resource_group, resName)
+                self.conn_compute.virtual_machines.begin_delete(
+                    self.resource_group, resName
+                )
             elif "reboot" in action_dict:
             elif "reboot" in action_dict:
-                self.conn_compute.virtual_machines.restart(self.resource_group, resName)
+                self.conn_compute.virtual_machines.begin_restart(
+                    self.resource_group, resName
+                )
 
             return None
 
             return None
+        except ResourceNotFoundError:
+            raise vimconn.VimConnNotFoundException("No vm found '{}'".format(vm_id))
         except CloudError as e:
             if e.error.error and "notfound" in e.error.error.lower():
                 raise vimconn.VimConnNotFoundException("No vm found '{}'".format(vm_id))
         except CloudError as e:
             if e.error.error and "notfound" in e.error.error.lower():
                 raise vimconn.VimConnNotFoundException("No vm found '{}'".format(vm_id))
@@ -1439,6 +1708,10 @@ class vimconnector(vimconn.VimConnector):
         try:
             resName = self._get_resource_name_from_resource_id(vm_id)
             vm = self.conn_compute.virtual_machines.get(self.resource_group, resName)
         try:
             resName = self._get_resource_name_from_resource_id(vm_id)
             vm = self.conn_compute.virtual_machines.get(self.resource_group, resName)
+        except ResourceNotFoundError:
+            raise vimconn.VimConnNotFoundException(
+                "No vminstance found '{}'".format(vm_id)
+            )
         except CloudError as e:
             if e.error.error and "notfound" in e.error.error.lower():
                 raise vimconn.VimConnNotFoundException(
         except CloudError as e:
             if e.error.error and "notfound" in e.error.error.lower():
                 raise vimconn.VimConnNotFoundException(
@@ -1693,15 +1966,32 @@ class vimconnector(vimconn.VimConnector):
             return interface_list
         except Exception as e:
             self.logger.error(
             return interface_list
         except Exception as e:
             self.logger.error(
-                "Exception %s obtaining interface data for vm: %s, error: %s",
-                vm_id,
+                "Exception %s obtaining interface data for vm: %s",
                 e,
                 e,
+                vm_id,
                 exc_info=True,
             )
             self._format_vimconn_exception(e)
 
                 exc_info=True,
             )
             self._format_vimconn_exception(e)
 
+    def _get_default_admin_user(self, image_id):
+        if "ubuntu" in image_id.lower():
+            return "ubuntu"
+        else:
+            return self._default_admin_user
+
 
 if __name__ == "__main__":
 
 if __name__ == "__main__":
+    # Init logger
+    log_format = "%(asctime)s %(levelname)s %(name)s %(filename)s:%(lineno)s %(funcName)s(): %(message)s"
+    log_formatter = logging.Formatter(log_format, datefmt="%Y-%m-%dT%H:%M:%S")
+    handler = logging.StreamHandler()
+    handler.setFormatter(log_formatter)
+    logger = logging.getLogger("ro.vim.azure")
+    # logger.setLevel(level=logging.ERROR)
+    # logger.setLevel(level=logging.INFO)
+    logger.setLevel(level=logging.DEBUG)
+    logger.addHandler(handler)
+
     # Making some basic test
     vim_id = "azure"
     vim_name = "azure"
     # Making some basic test
     vim_id = "azure"
     vim_name = "azure"
@@ -1724,32 +2014,12 @@ if __name__ == "__main__":
         test_params[param] = value
 
     config = {
         test_params[param] = value
 
     config = {
-        "region_name": getenv("AZURE_REGION_NAME", "westeurope"),
+        "region_name": getenv("AZURE_REGION_NAME", "northeurope"),
         "resource_group": getenv("AZURE_RESOURCE_GROUP"),
         "subscription_id": getenv("AZURE_SUBSCRIPTION_ID"),
         "pub_key": getenv("AZURE_PUB_KEY", None),
         "resource_group": getenv("AZURE_RESOURCE_GROUP"),
         "subscription_id": getenv("AZURE_SUBSCRIPTION_ID"),
         "pub_key": getenv("AZURE_PUB_KEY", None),
-        "vnet_name": getenv("AZURE_VNET_NAME", "myNetwork"),
-    }
-
-    virtualMachine = {
-        "name": "sergio",
-        "description": "new VM",
-        "status": "running",
-        "image": {
-            "publisher": "Canonical",
-            "offer": "UbuntuServer",
-            "sku": "16.04.0-LTS",
-            "version": "latest",
-        },
-        "hardware_profile": {"vm_size": "Standard_DS1_v2"},
-        "networks": ["sergio"],
-    }
-
-    vnet_config = {
-        "subnet_address": "10.1.2.0/24",
-        # "subnet_name": "subnet-oam"
+        "vnet_name": getenv("AZURE_VNET_NAME", "osm_vnet"),
     }
     }
-    ###########################
 
     azure = vimconnector(
         vim_id,
 
     azure = vimconnector(
         vim_id,
@@ -1764,18 +2034,127 @@ if __name__ == "__main__":
         config=config,
     )
 
         config=config,
     )
 
-    # azure.get_flavor_id_from_data("here")
-    # subnets=azure.get_network_list()
-    # azure.new_vminstance(virtualMachine["name"], virtualMachine["description"], virtualMachine["status"],
-    #                      virtualMachine["image"], virtualMachine["hardware_profile"]["vm_size"], subnets)
-
-    azure.new_network("mynet", None)
-    net_id = (
-        "/subscriptions/82f80cc1-876b-4591-9911-1fb5788384fd/resourceGroups/osmRG/providers/Microsoft."
-        "Network/virtualNetworks/test"
-    )
-    net_id_not_found = (
-        "/subscriptions/82f80cc1-876b-4591-9911-1fb5788384fd/resourceGroups/osmRG/providers/"
-        "Microsoft.Network/virtualNetworks/testALF"
-    )
-    azure.refresh_nets_status([net_id, net_id_not_found])
+    """
+    logger.debug("List images")
+    image = azure.get_image_list({"name": "Canonical:UbuntuServer:18.04-LTS:18.04.201809110"})
+    logger.debug("image: {}".format(image))
+
+    logger.debug("List networks")
+    network_list = azure.get_network_list({"name": "internal"})
+    logger.debug("Network_list: {}".format(network_list))
+
+    logger.debug("List flavors")
+    flavors = azure.get_flavor_id_from_data({"vcpus": 2})
+    logger.debug("flavors: {}".format(flavors))
+    """
+
+    """
+    # Create network and test machine
+    #new_network_id, _ = azure.new_network("testnet1", "data")
+    new_network_id = ("/subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/resourceGroups/{}/providers")
+                      "/Microsoft.Network/virtualNetworks/osm_vnet/subnets/testnet1"
+                      ).format(test_params["resource_group"])
+    logger.debug("new_network_id: {}".format(new_network_id))
+
+    logger.debug("Delete network")
+    new_network_id = azure.delete_network(new_network_id)
+    logger.debug("deleted network_id: {}".format(new_network_id))
+    """
+
+    """
+    logger.debug("List networks")
+    network_list = azure.get_network_list({"name": "internal"})
+    logger.debug("Network_list: {}".format(network_list))
+    
+    logger.debug("Show machine isabelvm")
+    vmachine = azure.get_vminstance( ("/subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/resourceGroups/{}"
+                                      "/providers/Microsoft.Compute/virtualMachines/isabelVM"
+                                      ).format(test_params["resource_group"])
+                                    )
+    logger.debug("Vmachine: {}".format(vmachine))
+    """
+
+    """
+    logger.debug("List images")
+    image = azure.get_image_list({"name": "Canonical:UbuntuServer:16.04"})
+    # image = azure.get_image_list({"name": "Canonical:UbuntuServer:18.04-LTS"})
+    logger.debug("image: {}".format(image))
+    """
+
+    """
+    # Create network and test machine
+    new_network_id, _ = azure.new_network("testnet1", "data")
+    image_id = ("/Subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/Providers/Microsoft.Compute"
+                "/Locations/northeurope/Publishers/Canonical/ArtifactTypes/VMImage/Offers/UbuntuServer"
+                "/Skus/18.04-LTS/Versions/18.04.201809110")
+    """
+    """
+    
+    network_id = ("subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/resourceGroups/{}
+                  "/providers/Microsoft.Network/virtualNetworks/osm_vnet/subnets/internal"
+                 ).format(test_params["resource_group"])
+    """
+
+    """
+    logger.debug("Create machine")
+    image_id = ("/Subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/Providers/Microsoft.Compute/Locations"
+                "/northeurope/Publishers/Canonical/ArtifactTypes/VMImage/Offers/UbuntuServer/Skus/18.04-LTS"
+                "/Versions/18.04.202103151")
+    cloud_config = {"user-data": (
+                    "#cloud-config\n"
+                    "password: osm4u\n"
+                    "chpasswd: { expire: False }\n"
+                    "ssh_pwauth: True\n\n"
+                    "write_files:\n"
+                    "-   content: |\n"
+                    "        # My new helloworld file\n\n"
+                    "    owner: root:root\n"
+                    "    permissions: '0644'\n"
+                    "    path: /root/helloworld.txt",
+                    "key-pairs": [
+                        ("ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC/p7fuw/W0+6uhx9XNPY4dN/K2cXZweDfjJN8W/sQ1AhKvn"
+                         "j0MF+dbBdsd2tfq6XUhx5LiKoGTunRpRonOw249ivH7pSyNN7FYpdLaij7Krn3K+QRNEOahMI4eoqdglVftA3"
+                         "vlw4Oe/aZOU9BXPdRLxfr9hRKzg5zkK91/LBkEViAijpCwK6ODPZLDDUwY4iihYK9R5eZ3fmM4+3k3Jd0hPRk"
+                         "B5YbtDQOu8ASWRZ9iTAWqr1OwQmvNc6ohSVg1tbq3wSxj/5bbz0J24A7TTpY0giWctne8Qkl/F2e0ZSErvbBB"
+                         "GXKxfnq7sc23OK1hPxMAuS+ufzyXsnL1+fB4t2iF azureuser@osm-test-client\n"
+                        )]
+    }
+    network_id = ("subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/resourceGroups/{}/providers"
+                  "/Microsoft.Network/virtualNetworks/osm_vnet/subnets/internal"
+                 ).format(test_params["resource_group"])
+    vm = azure.new_vminstance(name="isabelvm",
+                            description="testvm",
+                            start=True,
+                            image_id=image_id,
+                            flavor_id="Standard_B1ls",
+                            net_list = [{"net_id": network_id, "name": "internal", "use": "mgmt", "floating_ip":True}],
+                            cloud_config = cloud_config)
+    logger.debug("vm: {}".format(vm))
+    """
+
+    """
+    # Delete nonexistent vm
+    try:
+        logger.debug("Delete machine")
+        vm_id = ("/subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/resourceGroups/{}/providers/Microsoft.Compute/"
+                "virtualMachines/isabelvm"
+                ).format(test_params["resource_group"])
+        created_items = {
+            ("/subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/resourceGroups/{}/providers/Microsoft.Network"
+             "/networkInterfaces/isabelvm-nic-0"
+            ).format(test_params["resource_group"]): True,
+            ("/subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/resourceGroups/{}/providers/Microsoft.Network"
+             "/publicIPAddresses/isabelvm-nic-0-public-ip"
+            ).format(test_params["resource_group"]): True
+        }
+        azure.delete_vminstance(vm_id, created_items)
+    except vimconn.VimConnNotFoundException as e:
+        print("Ok: excepcion no encontrada")
+    """
+
+    """
+    network_id = ("/subscriptions/5c1a2458-dfde-4adf-a4e3-08fa0e21d171/resourceGroups/{}/providers/Microsoft.Network"
+                  "/virtualNetworks/osm_vnet/subnets/hfcloudinit-internal-1"
+                 ).format(test_params["resource_group"])
+    azure.delete_network(network_id)
+    """