X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=RO-VIM-azure%2Fosm_rovim_azure%2Fvimconn_azure.py;h=967eb3dd4e045822fd3512285f59c1fb293bb076;hb=refs%2Fchanges%2F26%2F11526%2F9;hp=71c7f5926b653f4593f4f0ad47c62b92483f1620;hpb=c8138e84753752ccebda0e41b6a972184abe4abc;p=osm%2FRO.git diff --git a/RO-VIM-azure/osm_rovim_azure/vimconn_azure.py b/RO-VIM-azure/osm_rovim_azure/vimconn_azure.py index 71c7f592..967eb3dd 100755 --- a/RO-VIM-azure/osm_rovim_azure/vimconn_azure.py +++ b/RO-VIM-azure/osm_rovim_azure/vimconn_azure.py @@ -14,28 +14,27 @@ ## import base64 -from osm_ro_plugin import vimconn import logging -import netaddr +from os import getenv import re -from os import getenv +from azure.core.exceptions import ResourceNotFoundError 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.core.exceptions import ResourceNotFoundError +from azure.mgmt.network import NetworkManagementClient +from azure.mgmt.resource import ResourceManagementClient from azure.profiles import ProfileDefinition -from msrestazure.azure_exceptions import CloudError +from cryptography.hazmat.backends import default_backend as crypto_default_backend +from cryptography.hazmat.primitives import serialization as crypto_serialization +from cryptography.hazmat.primitives.asymmetric import rsa from msrest.exceptions import AuthenticationError +from msrestazure.azure_exceptions import CloudError import msrestazure.tools as azure_tools +import netaddr +from osm_ro_plugin import vimconn from requests.exceptions import ConnectionError -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$" @@ -49,6 +48,14 @@ if getenv("OSMRO_PDB_DEBUG"): 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 @@ -221,14 +228,6 @@ class vimconnector(vimconn.VimConnector): else: raise vimconn.VimConnException("Subscription not specified") - # REGION - if "region_name" in config: - self.region = config.get("region_name") - else: - raise vimconn.VimConnException( - "Azure region_name is not specified at config" - ) - # RESOURCE_GROUP if "resource_group" in config: self.resource_group = config.get("resource_group") @@ -237,10 +236,21 @@ class vimconnector(vimconn.VimConnector): "Azure resource_group is not specified at config" ) + # REGION + if "region_name" in config: + self.region = config.get("region_name") + else: + raise vimconn.VimConnException( + "Azure region_name is not specified at config" + ) + # VNET_NAME if "vnet_name" in config: self.vnet_name = config["vnet_name"] + # VNET_RESOURCE_GROUP + self.vnet_resource_group = config.get("vnet_resource_group") + # TODO - not used, do anything about it? # public ssh key self.pub_key = config.get("pub_key") @@ -253,6 +263,13 @@ class vimconnector(vimconn.VimConnector): 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 @@ -390,7 +407,7 @@ class vimconnector(vimconn.VimConnector): """ try: vnet = self.conn_vnet.virtual_networks.get( - self.resource_group, self.vnet_name + self.vnet_resource_group or self.resource_group, self.vnet_name ) self.vnet_address_space = vnet.address_space.address_prefixes[0] self.vnet_id = vnet.id @@ -413,10 +430,12 @@ class vimconnector(vimconn.VimConnector): self.logger.debug("create base vnet: %s", self.vnet_name) self.conn_vnet.virtual_networks.begin_create_or_update( - self.resource_group, self.vnet_name, vnet_params + self.vnet_resource_group or self.resource_group, + self.vnet_name, + vnet_params, ) vnet = self.conn_vnet.virtual_networks.get( - self.resource_group, self.vnet_name + self.vnet_resource_group or self.resource_group, self.vnet_name ) self.vnet_id = vnet.id except Exception as e: @@ -496,7 +515,10 @@ class vimconnector(vimconn.VimConnector): self.logger.debug("creating subnet_name: {}".format(subnet_name)) async_creation = self.conn_vnet.subnets.begin_create_or_update( - self.resource_group, self.vnet_name, subnet_name, subnet_params + self.vnet_resource_group or self.resource_group, + self.vnet_name, + subnet_name, + subnet_params, ) async_creation.wait() # TODO - do not wait here, check where it is used @@ -511,7 +533,9 @@ class vimconnector(vimconn.VimConnector): Adds a prefix to the subnet_name with a number in case the indicated name is repeated Checks subnets with the indicated name (without suffix) and adds a suffix with a number """ - all_subnets = self.conn_vnet.subnets.list(self.resource_group, self.vnet_name) + all_subnets = self.conn_vnet.subnets.list( + self.vnet_resource_group or self.resource_group, self.vnet_name + ) # Filter to subnets starting with the indicated name subnets = list( filter(lambda subnet: (subnet.name.startswith(subnet_name)), all_subnets) @@ -528,12 +552,15 @@ class vimconnector(vimconn.VimConnector): return name - def _create_nic(self, net, nic_name, static_ip=None, created_items={}): + def _create_nic(self, net, nic_name, region=None, static_ip=None, created_items={}): self.logger.debug("create nic name %s, net_name %s", nic_name, net) self._reload_connection() subnet_id = net["net_id"] - location = self._get_location_from_resource_group(self.resource_group) + location = self.region or self._get_location_from_resource_group( + self.resource_group + ) + try: net_ifz = {"location": location} net_ip_config = { @@ -799,7 +826,7 @@ class vimconnector(vimconn.VimConnector): self._reload_connection() vnet = self.conn_vnet.virtual_networks.get( - self.resource_group, self.vnet_name + self.vnet_resource_group or self.resource_group, self.vnet_name ) subnet_list = [] @@ -888,7 +915,7 @@ class vimconnector(vimconn.VimConnector): # subnet_id=net["net_id"] nic_name = vm_name + "-nic-" + str(idx) vm_nic, nic_items = self._create_nic( - net, nic_name, net.get("ip_address"), created_items + net, nic_name, self.region, net.get("ip_address"), created_items ) vm_nics.append({"id": str(vm_nic.id)}) net["vim_id"] = vm_nic.id @@ -1223,9 +1250,9 @@ class vimconnector(vimconn.VimConnector): try: self._reload_connection() vm_sizes_list = [ - vm_size.serialize() + vm_size.as_dict() for vm_size in self.conn_compute.resource_skus.list( - "location={}".format(self.region) + "location eq '{}'".format(self.region) ) ] @@ -1234,31 +1261,56 @@ class vimconnector(vimconn.VimConnector): numberInterfaces = len(filter_dict.get("interfaces", [])) or 0 # Filter - if self._config.get("flavors_pattern"): - filtered_sizes = [ - size - for size in vm_sizes_list - if size["capabilities"]["vCPUs"] >= cpus - and size["capabilities"]["MemoryGB"] >= memMB / 1024 - and size["capabilities"]["MaxNetworkInterfaces"] >= numberInterfaces - and re.search(self._config.get("flavors_pattern"), size["name"]) - ] - else: - filtered_sizes = [ - size - for size in vm_sizes_list - if size["capabilities"]["vCPUs"] >= cpus - and size["capabilities"]["MemoryGB"] >= memMB / 1024 - and size["capabilities"]["MaxNetworkInterfaces"] >= numberInterfaces - ] + 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: ( - k["numberOfCores"], - k["memoryInMB"], - k["resourceDiskSizeInMB"], + int(k["vCPUs"]), + float(k["MemoryGB"]), + int(k["MaxNetworkInterfaces"]), + int(k["MaxResourceVolumeMB"]), ), ) @@ -1276,9 +1328,9 @@ class vimconnector(vimconn.VimConnector): try: self._reload_connection() vm_sizes_list = [ - vm_size.serialize() + vm_size.as_dict() for vm_size in self.conn_compute.resource_skus.list( - "location={}".format(self.region) + "location eq '{}'".format(self.region) ) ] @@ -1318,7 +1370,9 @@ class vimconnector(vimconn.VimConnector): def delete_network(self, net_id, created_items=None): self.logger.debug( - "deleting network {} - {}".format(self.resource_group, net_id) + "deleting network {} - {}".format( + self.vnet_resource_group or self.resource_group, net_id + ) ) self._reload_connection() @@ -1327,7 +1381,9 @@ class vimconnector(vimconn.VimConnector): try: # Obtain subnets ant try to delete nic first subnet = self.conn_vnet.subnets.get( - self.resource_group, self.vnet_name, res_name + self.vnet_resource_group or self.resource_group, + self.vnet_name, + res_name, ) if not subnet: raise vimconn.VimConnNotFoundException( @@ -1346,7 +1402,9 @@ class vimconnector(vimconn.VimConnector): # Subnet API fails (CloudError: Azure Error: ResourceNotFound) # Put the initial virtual_network API async_delete = self.conn_vnet.subnets.begin_delete( - self.resource_group, self.vnet_name, res_name + self.vnet_resource_group or self.resource_group, + self.vnet_name, + res_name, ) async_delete.wait() @@ -1759,7 +1817,9 @@ class vimconnector(vimconn.VimConnector): netName = self._get_net_name_from_resource_id(net_id) resName = self._get_resource_name_from_resource_id(net_id) - net = self.conn_vnet.subnets.get(self.resource_group, netName, resName) + net = self.conn_vnet.subnets.get( + self.vnet_resource_group or self.resource_group, netName, resName + ) out_nets[net_id] = { "status": self.provision_state2osm[net.provisioning_state], @@ -2004,7 +2064,7 @@ if __name__ == "__main__": logger.debug("Network_list: {}".format(network_list)) logger.debug("List flavors") - flavors = azure.get_flavor_id_from_data({"vcpu": "2"}) + flavors = azure.get_flavor_id_from_data({"vcpus": 2}) logger.debug("flavors: {}".format(flavors)) """ @@ -2025,7 +2085,7 @@ if __name__ == "__main__": 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" @@ -2034,10 +2094,12 @@ if __name__ == "__main__": 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 @@ -2047,7 +2109,7 @@ if __name__ == "__main__": "/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"])