Bug 1849: LTS Support
[osm/RO.git] / RO-VIM-gcp / osm_rovim_gcp / vimconn_gcp.py
index 73b77ba..e73f278 100644 (file)
 # under the License.
 ##
 
-import base64
-from osm_ro_plugin import vimconn
 import logging
-import time
+from os import getenv
 import random
 from random import choice as random_choice
-from os import getenv
-
-from google.api_core.exceptions import NotFound
-import googleapiclient.discovery
-from google.oauth2 import service_account
+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 cryptography.hazmat.backends import default_backend as crypto_default_backend
-
-import logging
+from google.oauth2 import service_account
+import googleapiclient.discovery
+from osm_ro_plugin import vimconn
 
 __author__ = "Sergio Gallardo Ruiz"
 __date__ = "$11-aug-2021 08:30:00$"
@@ -157,9 +152,7 @@ class vimconnector(vimconn.VimConnector):
         self.logger.debug("Config: %s", config)
         scopes = ["https://www.googleapis.com/auth/cloud-platform"]
         self.credentials = None
-        if (
-            "credentials" in config
-        ):
+        if "credentials" in config:
             self.logger.debug("Setting credentials")
             # Settings Google Cloud credentials dict
             credentials_body = config["credentials"]
@@ -326,7 +319,8 @@ class vimconnector(vimconn.VimConnector):
                 "description": net_name,
                 "network": network,
                 "ipCidrRange": subnet_address,
-                # "autoCreateSubnetworks": True, # The network is created in AUTO mode (one subnet per region is created)
+                # The network is created in AUTO mode (one subnet per region is created)
+                # "autoCreateSubnetworks": True,
                 "autoCreateSubnetworks": False,
             }
 
@@ -339,7 +333,7 @@ class vimconnector(vimconn.VimConnector):
             self.logger.debug("created network_name: {}".format(net_name))
 
             # Adding firewall rules to allow the traffic in the network:
-            rules_list = self._create_firewall_rules(net_name)
+            self._create_firewall_rules(net_name)
 
             # create subnetwork, even if there is no profile
 
@@ -491,9 +485,7 @@ class vimconnector(vimconn.VimConnector):
         if not network_list:
             return []
         else:
-            self.logger.debug(
-                "get_network Return: network_list[0] %s", network_list[0]
-            )
+            self.logger.debug("get_network Return: network_list[0] %s", network_list[0])
             return network_list[0]
 
     def delete_network(self, net_id, created_items=None):
@@ -516,11 +508,9 @@ class vimconnector(vimconn.VimConnector):
             net_name = self._get_resource_name_from_resource_id(net_id)
 
             # Check associated VMs
-            vms = (
-                self.conn_compute.instances()
-                .list(project=self.project, zone=self.zone)
-                .execute()
-            )
+            self.conn_compute.instances().list(
+                project=self.project, zone=self.zone
+            ).execute()
 
             net_id = self.delete_subnet(net_name, created_items)
 
@@ -549,7 +539,8 @@ class vimconnector(vimconn.VimConnector):
         try:
             # If the network has no more subnets, it will be deleted too
             net_info = self.get_network(net_id)
-            # If the subnet is in use by another resource, the deletion will be retried N times before abort the operation
+            # If the subnet is in use by another resource, the deletion will
+            # be retried N times before abort the operation
             created_items = created_items or {}
             created_items[net_id] = False
 
@@ -586,7 +577,7 @@ class vimconnector(vimconn.VimConnector):
 
                 try:
                     # Deletion of the associated firewall rules:
-                    rules_list = self._delete_firewall_rules(network_name)
+                    self._delete_firewall_rules(network_name)
 
                     operation = (
                         self.conn_compute.networks()
@@ -679,9 +670,7 @@ class vimconnector(vimconn.VimConnector):
         return vm_name_aux.lower()
 
     def get_flavor_id_from_data(self, flavor_dict):
-        self.logger.debug(
-            "get_flavor_id_from_data begin: flavor_dict %s", flavor_dict
-        )
+        self.logger.debug("get_flavor_id_from_data begin: flavor_dict %s", flavor_dict)
         filter_dict = flavor_dict or {}
 
         try:
@@ -695,7 +684,8 @@ class vimconnector(vimconn.VimConnector):
 
             cpus = filter_dict.get("vcpus") or 0
             memMB = filter_dict.get("ram") or 0
-            numberInterfaces = len(filter_dict.get("interfaces", [])) or 4 # Workaround (it should be 0)
+            # Workaround (it should be 0)
+            numberInterfaces = len(filter_dict.get("interfaces", [])) or 4
 
             # Filter
             filtered_machines = []
@@ -850,19 +840,20 @@ class vimconnector(vimconn.VimConnector):
                     + "-"
                     + "".join(random_choice("0123456789abcdef") for _ in range(12))
                 )
-                response = (
-                    self.conn_compute.instances()
-                    .get(project=self.project, zone=self.zone, instance=random_name)
-                    .execute()
-                )
-                # If no exception is arisen, the random name exists for an instance, so a new random name must be generated
+                self.conn_compute.instances().get(
+                    project=self.project, zone=self.zone, instance=random_name
+                ).execute()
+                # If no exception is arisen, the random name exists for an instance,
+                # so a new random name must be generated
 
             except Exception as e:
                 if e.args[0]["status"] == "404":
                     self.logger.debug("New random name: %s", random_name)
                     break
                 else:
-                    self.logger.error("Exception generating random name (%s) for the instance", name)
+                    self.logger.error(
+                        "Exception generating random name (%s) for the instance", name
+                    )
                     self._format_vimconn_exception(e)
 
         return random_name
@@ -926,12 +917,14 @@ class vimconnector(vimconn.VimConnector):
                         ] = "regions/%s/subnetworks/" % self.region + net.get("name")
                 else:
                     net_iface["subnetwork"] = net.get("net_id")
-                # According to documentation "type" can be only ONE_TO_ONE_NAT and the recomended value for "name" is "External NAT",
-                # so an external IP will be generated for the instance
-                # TODO: check if it's possible to allow internet access to the instance with no external IP
-                net_iface["accessConfigs"] = [
-                   {"type": "ONE_TO_ONE_NAT", "name": "External NAT"}
-                ]
+                # 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 (
+                    net["use"] == "mgmt" and self.config.get("use_floating_ip")
+                ):
+                    net_iface["accessConfigs"] = [
+                        {"type": "ONE_TO_ONE_NAT", "name": "External NAT"}
+                    ]
 
                 network_interfaces.append(net_iface)
 
@@ -1007,24 +1000,21 @@ class vimconnector(vimconn.VimConnector):
                     self.logger.error("new_vminstance rollback fail {}".format(e2))
 
             else:
-                self.logger.debug("Exception creating new vminstance: %s", e, exc_info=True)
+                self.logger.debug(
+                    "Exception creating new vminstance: %s", e, exc_info=True
+                )
                 self._format_vimconn_exception(e)
 
-
     def _build_metadata(self, vm_name, cloud_config):
-
         # initial metadata
         metadata = {}
         metadata["items"] = []
-        key_pairs = {}
 
         # if there is a cloud-init load it
         if cloud_config:
             self.logger.debug("cloud config: %s", cloud_config)
             _, userdata = self._create_user_data(cloud_config)
-            metadata["items"].append(
-                {"key": "user-data", "value": userdata}
-            )
+            metadata["items"].append({"key": "user-data", "value": userdata})
 
         # either password of ssh-keys are required
         # we will always use ssh-keys, in case it is not available we will generate it
@@ -1057,7 +1047,6 @@ class vimconnector(vimconn.VimConnector):
 
         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
@@ -1083,7 +1072,6 @@ class vimconnector(vimconn.VimConnector):
 
         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
@@ -1156,7 +1144,7 @@ class vimconnector(vimconn.VimConnector):
                     self._get_resource_name_from_resource_id(netIface["subnetwork"])
                     in self.nets_to_be_deleted
                 ):
-                    net_id = self._get_resource_name_from_resource_id(
+                    self._get_resource_name_from_resource_id(
                         self.delete_network(netIface["subnetwork"])
                     )
 
@@ -1226,7 +1214,6 @@ class vimconnector(vimconn.VimConnector):
 
         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 = (
@@ -1338,7 +1325,6 @@ class vimconnector(vimconn.VimConnector):
             interface_list = []
             for network_interface in interfaces:
                 interface_dict = {}
-                nic_name = network_interface["name"]
                 interface_dict["vim_interface_id"] = network_interface["name"]
 
                 ips = []
@@ -1384,11 +1370,9 @@ class vimconnector(vimconn.VimConnector):
                 "network": "global/networks/" + network,
                 "allowed": [{"IPProtocol": "tcp", "ports": ["80"]}],
             }
-            operation_firewall = (
-                self.conn_compute.firewalls()
-                .insert(project=self.project, body=firewall_rule_body)
-                .execute()
-            )
+            self.conn_compute.firewalls().insert(
+                project=self.project, body=firewall_rule_body
+            ).execute()
 
             # Adding firewall rule to allow ssh:
             self.logger.debug("creating firewall rule to allow ssh")
@@ -1397,11 +1381,9 @@ class vimconnector(vimconn.VimConnector):
                 "network": "global/networks/" + network,
                 "allowed": [{"IPProtocol": "tcp", "ports": ["22"]}],
             }
-            operation_firewall = (
-                self.conn_compute.firewalls()
-                .insert(project=self.project, body=firewall_rule_body)
-                .execute()
-            )
+            self.conn_compute.firewalls().insert(
+                project=self.project, body=firewall_rule_body
+            ).execute()
 
             # Adding firewall rule to allow ping:
             self.logger.debug("creating firewall rule to allow ping")
@@ -1410,11 +1392,9 @@ class vimconnector(vimconn.VimConnector):
                 "network": "global/networks/" + network,
                 "allowed": [{"IPProtocol": "icmp"}],
             }
-            operation_firewall = (
-                self.conn_compute.firewalls()
-                .insert(project=self.project, body=firewall_rule_body)
-                .execute()
-            )
+            self.conn_compute.firewalls().insert(
+                project=self.project, body=firewall_rule_body
+            ).execute()
 
             # Adding firewall rule to allow internal:
             self.logger.debug("creating firewall rule to allow internal")
@@ -1427,11 +1407,9 @@ class vimconnector(vimconn.VimConnector):
                     {"IPProtocol": "icmp"},
                 ],
             }
-            operation_firewall = (
-                self.conn_compute.firewalls()
-                .insert(project=self.project, body=firewall_rule_body)
-                .execute()
-            )
+            self.conn_compute.firewalls().insert(
+                project=self.project, body=firewall_rule_body
+            ).execute()
 
             # Adding firewall rule to allow microk8s:
             self.logger.debug("creating firewall rule to allow microk8s")
@@ -1440,11 +1418,9 @@ class vimconnector(vimconn.VimConnector):
                 "network": "global/networks/" + network,
                 "allowed": [{"IPProtocol": "tcp", "ports": ["16443"]}],
             }
-            operation_firewall = (
-                self.conn_compute.firewalls()
-                .insert(project=self.project, body=firewall_rule_body)
-                .execute()
-            )
+            self.conn_compute.firewalls().insert(
+                project=self.project, body=firewall_rule_body
+            ).execute()
 
             # Adding firewall rule to allow rdp:
             self.logger.debug("creating firewall rule to allow rdp")
@@ -1453,11 +1429,9 @@ class vimconnector(vimconn.VimConnector):
                 "network": "global/networks/" + network,
                 "allowed": [{"IPProtocol": "tcp", "ports": ["3389"]}],
             }
-            operation_firewall = (
-                self.conn_compute.firewalls()
-                .insert(project=self.project, body=firewall_rule_body)
-                .execute()
-            )
+            self.conn_compute.firewalls().insert(
+                project=self.project, body=firewall_rule_body
+            ).execute()
 
             # Adding firewall rule to allow osm:
             self.logger.debug("creating firewall rule to allow osm")
@@ -1466,11 +1440,9 @@ class vimconnector(vimconn.VimConnector):
                 "network": "global/networks/" + network,
                 "allowed": [{"IPProtocol": "tcp", "ports": ["9001", "9999"]}],
             }
-            operation_firewall = (
-                self.conn_compute.firewalls()
-                .insert(project=self.project, body=firewall_rule_body)
-                .execute()
-            )
+            self.conn_compute.firewalls().insert(
+                project=self.project, body=firewall_rule_body
+            ).execute()
 
             self.logger.debug(
                 "_create_firewall_rules Return: list_rules %s", rules_list
@@ -1499,11 +1471,9 @@ class vimconnector(vimconn.VimConnector):
             )
             for item in rules_list["items"]:
                 if network == self._get_resource_name_from_resource_id(item["network"]):
-                    operation_firewall = (
-                        self.conn_compute.firewalls()
-                        .delete(project=self.project, firewall=item["name"])
-                        .execute()
-                    )
+                    self.conn_compute.firewalls().delete(
+                        project=self.project, firewall=item["name"]
+                    ).execute()
 
             self.logger.debug("_delete_firewall_rules Return: list_rules %s", 0)
             return rules_list
@@ -1514,4 +1484,3 @@ class vimconnector(vimconn.VimConnector):
                 )
             )
             self._format_vimconn_exception(e)
-