+ if flavor_data:
+ flavor = {
+ "id": flavor_id,
+ "name": flavor_id,
+ "ram": flavor_data["memoryInMB"],
+ "vcpus": flavor_data["numberOfCores"],
+ "disk": flavor_data["resourceDiskSizeInMB"] / 1024,
+ }
+
+ return flavor
+ else:
+ raise vimconn.VimConnNotFoundException(
+ "flavor '{}' not found".format(flavor_id)
+ )
+
+ def get_tenant_list(self, filter_dict={}):
+ """Obtains the list of tenants
+ For the azure connector only the azure tenant will be returned if it is compatible
+ with filter_dict
+ """
+ tenants_azure = [{"name": self.tenant, "id": self.tenant}]
+ tenant_list = []
+
+ self.logger.debug("get tenant list: %s", filter_dict)
+ for tenant_azure in tenants_azure:
+ if filter_dict:
+ if (
+ filter_dict.get("id")
+ and str(tenant_azure.get("id")) != filter_dict["id"]
+ ):
+ continue
+
+ if (
+ filter_dict.get("name")
+ and str(tenant_azure.get("name")) != filter_dict["name"]
+ ):
+ continue
+
+ tenant_list.append(tenant_azure)
+
+ return tenant_list
+
+ def refresh_nets_status(self, net_list):
+ """Get the status of the networks
+ Params: the list of network identifiers
+ Returns a dictionary with:
+ net_id: #VIM id of this network
+ status: #Mandatory. Text with one of:
+ # DELETED (not found at vim)
+ # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
+ # OTHER (Vim reported other status not understood)
+ # ERROR (VIM indicates an ERROR status)
+ # ACTIVE, INACTIVE, DOWN (admin down),
+ # BUILD (on building process)
+ #
+ error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
+ vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
+ """
+ out_nets = {}
+ self._reload_connection()
+
+ self.logger.debug("reload nets status net_list: %s", net_list)
+ for net_id in net_list:
+ try:
+ 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.vnet_resource_group or self.resource_group, netName, resName
+ )
+
+ out_nets[net_id] = {
+ "status": self.provision_state2osm[net.provisioning_state],
+ "vim_info": str(net),
+ }
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ self.logger.info(
+ "Not found subnet net_name: %s, subnet_name: %s",
+ netName,
+ resName,
+ )
+ out_nets[net_id] = {"status": "DELETED", "error_msg": str(e)}
+ else:
+ self.logger.error(
+ "CloudError Exception %s when searching subnet", e
+ )
+ out_nets[net_id] = {
+ "status": "VIM_ERROR",
+ "error_msg": str(e),
+ }
+ except vimconn.VimConnNotFoundException as e:
+ self.logger.error(
+ "VimConnNotFoundException %s when searching subnet", e
+ )
+ out_nets[net_id] = {
+ "status": "DELETED",
+ "error_msg": str(e),
+ }
+ except Exception as e:
+ self.logger.error(
+ "Exception %s when searching subnet", e, exc_info=True
+ )
+ out_nets[net_id] = {
+ "status": "VIM_ERROR",
+ "error_msg": str(e),
+ }
+
+ return out_nets
+
+ def refresh_vms_status(self, vm_list):
+ """Get the status of the virtual machines and their interfaces/ports
+ Params: the list of VM identifiers
+ Returns a dictionary with:
+ vm_id: # VIM id of this Virtual Machine
+ status: # Mandatory. Text with one of:
+ # DELETED (not found at vim)
+ # VIM_ERROR (Cannot connect to VIM, VIM response error, ...)
+ # OTHER (Vim reported other status not understood)
+ # ERROR (VIM indicates an ERROR status)
+ # ACTIVE, PAUSED, SUSPENDED, INACTIVE (not running),
+ # BUILD (on building process), ERROR
+ # ACTIVE:NoMgmtIP (Active but none of its interfaces has an IP address
+ # (ACTIVE:NoMgmtIP is not returned for Azure)
+ #
+ error_msg: #Text with VIM error message, if any. Or the VIM connection ERROR
+ vim_info: #Text with plain information obtained from vim (yaml.safe_dump)
+ interfaces: list with interface info. Each item a dictionary with:
+ vim_interface_id - The ID of the interface
+ mac_address - The MAC address of the interface.
+ ip_address - The IP address of the interface within the subnet.
+ """
+ out_vms = {}
+ self._reload_connection()
+
+ self.logger.debug("refresh vm status vm_list: %s", vm_list)
+ search_vm_list = vm_list or {}
+
+ for vm_id in search_vm_list:
+ out_vm = {}
+ try:
+ res_name = self._get_resource_name_from_resource_id(vm_id)
+
+ vm = self.conn_compute.virtual_machines.get(
+ self.resource_group, res_name
+ )
+ img = vm.storage_profile.image_reference
+ images = self._get_version_image_list(
+ img.publisher, img.offer, img.sku, img.version
+ )
+ vim_info = {
+ "id": vm.id,
+ "name": vm.name,
+ "location": vm.location,
+ "provisioning_state": vm.provisioning_state,
+ "vm_id": vm.vm_id,
+ "type": vm.type,
+ "flavor": {"id": vm.hardware_profile.vm_size},
+ "image": images[0],
+ }
+ out_vm["vim_info"] = str(vim_info)
+ out_vm["status"] = self.provision_state2osm.get(
+ vm.provisioning_state, "OTHER"
+ )
+
+ if vm.provisioning_state == "Succeeded":
+ # check if machine is running or stopped
+ instance_view = self.conn_compute.virtual_machines.instance_view(
+ self.resource_group, res_name
+ )
+
+ for status in instance_view.statuses:
+ splitted_status = status.code.split("/")
+ if (
+ len(splitted_status) == 2
+ and splitted_status[0] == "PowerState"
+ ):
+ out_vm["status"] = self.power_state2osm.get(
+ splitted_status[1], "OTHER"
+ )
+
+ network_interfaces = vm.network_profile.network_interfaces
+ out_vm["interfaces"] = self._get_vm_interfaces_status(
+ vm_id, network_interfaces
+ )
+
+ except CloudError as e:
+ if e.error.error and "notfound" in e.error.error.lower():
+ self.logger.debug("Not found vm id: %s", vm_id)
+ out_vm["status"] = "DELETED"
+ out_vm["error_msg"] = str(e)
+ out_vm["vim_info"] = None
+ else:
+ # maybe connection error or another type of error, return vim error
+ self.logger.error("Exception %s refreshing vm_status", e)
+ out_vm["status"] = "VIM_ERROR"
+ out_vm["error_msg"] = str(e)
+ out_vm["vim_info"] = None
+ except Exception as e:
+ self.logger.error("Exception %s refreshing vm_status", e, exc_info=True)
+ out_vm["status"] = "VIM_ERROR"
+ out_vm["error_msg"] = str(e)
+ out_vm["vim_info"] = None
+
+ out_vms[vm_id] = out_vm
+
+ return out_vms
+
+ def _get_vm_interfaces_status(self, vm_id, interfaces):
+ """
+ Gets the interfaces detail for a vm
+ :param interfaces: List of interfaces.
+ :return: Dictionary with list of interfaces including, vim_interface_id, mac_address and ip_address
+ """
+ try:
+ interface_list = []
+ for network_interface in interfaces:
+ interface_dict = {}
+ nic_name = self._get_resource_name_from_resource_id(
+ network_interface.id
+ )
+ interface_dict["vim_interface_id"] = network_interface.id
+
+ nic_data = self.conn_vnet.network_interfaces.get(
+ self.resource_group,
+ nic_name,
+ )
+
+ ips = []
+ if nic_data.ip_configurations[0].public_ip_address:
+ self.logger.debug("Obtain public ip address")
+ public_ip_name = self._get_resource_name_from_resource_id(
+ nic_data.ip_configurations[0].public_ip_address.id
+ )
+ public_ip = self.conn_vnet.public_ip_addresses.get(
+ self.resource_group, public_ip_name
+ )
+ self.logger.debug("Public ip address is: %s", public_ip.ip_address)
+ ips.append(public_ip.ip_address)
+
+ subnet = nic_data.ip_configurations[0].subnet.id
+ if subnet:
+ interface_dict["vim_net_id"] = subnet
+
+ private_ip = nic_data.ip_configurations[0].private_ip_address
+ ips.append(private_ip)
+
+ interface_dict["mac_address"] = nic_data.mac_address
+ interface_dict["ip_address"] = ";".join(ips)
+ interface_list.append(interface_dict)
+
+ return interface_list
+ except Exception as e:
+ self.logger.error(
+ "Exception %s obtaining interface data for vm: %s",
+ e,
+ vm_id,
+ 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
+
+ def migrate_instance(self, vm_id, compute_host=None):
+ """
+ Migrate a vdu
+ param:
+ vm_id: ID of an instance
+ compute_host: Host to migrate the vdu to
+ """
+ # TODO: Add support for migration
+ raise vimconn.VimConnNotImplemented("Not implemented")
+
+ def resize_instance(self, vm_id, flavor_id=None):
+ """
+ resize a vdu
+ param:
+ vm_id: ID of an instance
+ flavor_id: flavor id to resize the vdu
+ """
+ # TODO: Add support for resize
+ raise vimconn.VimConnNotImplemented("Not implemented")