X-Git-Url: https://osm.etsi.org/gitweb/?a=blobdiff_plain;f=RO-VIM-gcp%2Fosm_rovim_gcp%2Fvimconn_gcp.py;h=0109bf12ba9232cf189ad2c41619d0cb975fdd6f;hb=aca8cb5e63ebd11cc69373323d8df62b5d8cbfe2;hp=04e459d2bd2dba8658d56632531a255f367f25f9;hpb=6986244790d12f4ce734fd5cd2599e84b29c3f84;p=osm%2FRO.git diff --git a/RO-VIM-gcp/osm_rovim_gcp/vimconn_gcp.py b/RO-VIM-gcp/osm_rovim_gcp/vimconn_gcp.py index 04e459d2..0109bf12 100644 --- a/RO-VIM-gcp/osm_rovim_gcp/vimconn_gcp.py +++ b/RO-VIM-gcp/osm_rovim_gcp/vimconn_gcp.py @@ -19,9 +19,6 @@ import random from random import choice as random_choice import time -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 google.oauth2 import service_account import googleapiclient.discovery from osm_ro_plugin import vimconn @@ -186,7 +183,9 @@ class vimconnector(vimconn.VimConnector): try: # Set to client created - self.conn_compute = googleapiclient.discovery.build("compute", "v1") + self.conn_compute = googleapiclient.discovery.build( + "compute", "v1", credentials=self.credentials + ) except Exception as e: self._format_vimconn_exception(e) @@ -809,9 +808,6 @@ class vimconnector(vimconn.VimConnector): except Exception as e: self._format_vimconn_exception(e) - def delete_inuse_nic(self, nic_name): - raise vimconn.VimConnNotImplemented("Not necessary") - def delete_image(self, image_id): raise vimconn.VimConnNotImplemented("Not implemented") @@ -908,11 +904,14 @@ class vimconnector(vimconn.VimConnector): if not net.get("name"): continue else: - net_iface[ - "subnetwork" - ] = "regions/%s/subnetworks/" % self.region + net.get("name") + net_iface["subnetwork"] = ( + "regions/%s/subnetworks/" % self.region + net.get("name") + ) else: net_iface["subnetwork"] = net.get("net_id") + if net.get("ip_address"): + net_iface["networkIP"] = net.get("ip_address") + # In order to get an external IP address, the key "accessConfigs" must be used # in the interace. It has to be of type "ONE_TO_ONE_NAT" and name "External NAT" if net.get("floating_ip", False) or ( @@ -1014,85 +1013,10 @@ class vimconnector(vimconn.VimConnector): # 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 = "" - key_pairs = {} - if cloud_config.get("key-pairs"): - if isinstance(cloud_config["key-pairs"], list): - # Transform the format " " into ":" - key_data = "" - for key in cloud_config.get("key-pairs"): - key_data = key_data + key + "\n" - key_pairs = { - "key": "ssh-keys", - "value": key_data - } - else: - # If there is no ssh key in cloud config, a new key is generated: - _, key_data = self._generate_keys() - key_pairs = { - "key": "ssh-keys", - "value": "" + key_data - } - self.logger.debug("generated keys: %s", key_data) - - metadata["items"].append(key_pairs) - """ self.logger.debug("metadata: %s", metadata) return metadata - 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 - :return: - """ - all_vms = ( - self.conn_compute.instances() - .list(project=self.project, zone=self.zone) - .execute() - ) - # Filter to vms starting with the indicated name - vms = list(filter(lambda vm: (vm.name.startswith(vm_name)), all_vms)) - vm_names = [str(vm.name) for vm in vms] - - # get the name with the first not used suffix - name_suffix = 0 - # name = subnet_name + "-" + str(name_suffix) - name = vm_name # first subnet created will have no prefix - - while name in vm_names: - name_suffix += 1 - name = vm_name + "-" + str(name_suffix) - - return name - def get_vminstance(self, vm_id): """ Obtaing the vm instance data from v_id @@ -1153,18 +1077,6 @@ class vimconnector(vimconn.VimConnector): else: self._format_vimconn_exception(e) - def _get_net_name_from_resource_id(self, resource_id): - try: - net_name = str(resource_id.split("/")[-1]) - - return net_name - except Exception: - raise vimconn.VimConnException( - "Unable to get google cloud net_name from invalid resource_id format '{}'".format( - resource_id - ) - ) - def _get_resource_name_from_resource_id(self, resource_id): """ Obtains resource_name from the google cloud complete identifier: resource_name will always be last item @@ -1188,6 +1100,20 @@ class vimconnector(vimconn.VimConnector): ) ) + def _get_id_from_image(self, image): + """ + Obtains image_id from the google cloud complete image identifier: image_id will be the last five items + """ + self.logger.debug(f"_get_id_from_image begin: image {image}") + try: + image_id = "/".join(image.split("/")[-5:]) + self.logger.debug(f"_get_id_from_image Return: image_id {image_id}") + return image_id + except Exception as e: + raise vimconn.VimConnException( + f"Unable to get image_id from image '{image}' Error: '{e}'" + ) + def refresh_nets_status(self, net_list): """Get the status of the networks Params: the list of network identifiers @@ -1282,7 +1208,43 @@ class vimconnector(vimconn.VimConnector): .execute() ) - out_vm["vim_info"] = str(vm["name"]) + disk_source = vm["disks"][0]["source"] + self.logger.debug("getting disk information") + disk = ( + self.conn_compute.disks() + .get( + project=self.project, + zone=self.zone, + disk=self._get_resource_name_from_resource_id(disk_source), + ) + .execute() + ) + image = {} + if disk is not None: + self.logger.debug(f"disk: {disk}") + image = { + "id": self._get_id_from_image(disk["sourceImage"]), + "source": disk_source, + } + + vim_info = { + "id": vm_id, + "name": vm["name"], + "creationTimestamp": vm["creationTimestamp"], + "lastStartTimestamp": vm["lastStartTimestamp"], + "vm_id": vm["id"], + "kind": vm["kind"], + "cpuPlatform": vm["cpuPlatform"], + "zone": self._get_resource_name_from_resource_id(vm["zone"]), + "machineType": vm["machineType"], + "flavor": { + "id": self._get_resource_name_from_resource_id( + vm["machineType"] + ) + }, + "image": image, + } + out_vm["vim_info"] = str(vim_info) out_vm["status"] = self.provision_state2osm.get(vm["status"], "OTHER") # In Google Cloud the there is no difference between provision or power status, @@ -1322,6 +1284,7 @@ class vimconnector(vimconn.VimConnector): for network_interface in interfaces: interface_dict = {} interface_dict["vim_interface_id"] = network_interface["name"] + interface_dict["vim_net_id"] = network_interface["subnetwork"] ips = [] ips.append(network_interface["networkIP"]) @@ -1342,12 +1305,6 @@ class vimconnector(vimconn.VimConnector): ) 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 _create_firewall_rules(self, network): """ Creates the necessary firewall rules to allow the traffic in the network