From c944a307109788c5ab26fc33e6c7e86932189b4a Mon Sep 17 00:00:00 2001 From: micafer Date: Wed, 21 Apr 2021 17:10:26 +0200 Subject: [PATCH] Fix errors --- IM/AppDB.py | 6 ++- IM/connectors/EGI.py | 88 +++++++++++++++++++++---------------- IM/connectors/OpenStack.py | 12 ++++- test/unit/connectors/EGI.py | 1 + 4 files changed, 65 insertions(+), 42 deletions(-) diff --git a/IM/AppDB.py b/IM/AppDB.py index a9113b466..59cf30898 100644 --- a/IM/AppDB.py +++ b/IM/AppDB.py @@ -102,7 +102,7 @@ def get_image_id(site_id, image_name, vo_name): return None @staticmethod - def get_image_data(str_url, stype="occi"): + def get_image_data(str_url, stype="occi", vo=None): """ The url has this format: appdb://UPV-GRyCAP/egi.docker.ubuntu.16.04?fedcloud.egi.eu or this one appdb://UPV-GRyCAP/83d5e854-a128-5b1f-9457-d32e10a720a6:8135 @@ -130,6 +130,8 @@ def get_image_data(str_url, stype="occi"): return None, None, "No image ID returned from EGI AppDB for image: %s/%s." % (site_id, image_name) else: + if not vo_name: + vo_name = vo image_id = AppDB.get_image_id(site_id, image_name, vo_name) if not image_id: return None, None, "No image ID returned from EGI AppDB for image: %s/%s/%s." % (site_id, @@ -181,4 +183,4 @@ def get_project_ids(site_id): for vo in shares: projects[vo["#text"]] = vo['@projectid'] - return projects \ No newline at end of file + return projects diff --git a/IM/connectors/EGI.py b/IM/connectors/EGI.py index 3185d4bba..a86ec03b5 100644 --- a/IM/connectors/EGI.py +++ b/IM/connectors/EGI.py @@ -24,6 +24,7 @@ except ImportError: from urllib.parse import urlparse + class EGICloudConnector(OpenStackCloudConnector): """ Cloud Launcher to EGI using LibCloud @@ -32,6 +33,10 @@ class EGICloudConnector(OpenStackCloudConnector): type = "EGI" """str with the name of the provider.""" + def __init__(self, cloud_info, inf): + self.egi_auth = None + OpenStackCloudConnector.__init__(self, cloud_info, inf) + def get_driver(self, auth_data): """ Get the driver from the auth data @@ -47,53 +52,58 @@ def get_driver(self, auth_data): else: auth = auths[0] - if 'host' in auth and 'vo' in auth and 'token' in auth: - ost_auth = {'id': auth['id'], 'type': 'OpenStack', 'username': 'egi.eu', 'tenant': 'openid', - 'password': auth['token'], 'auth_version': '3.x_oidc_access_token'} - site_id = AppDB.get_site_id(auth["host"]) - site_url = AppDB.get_site_url(site_id) - ost_auth['host'] = site_url - projects = AppDB.get_project_ids(site_id) - # If the VO does not appear in the project IDs - if auth['vo'] in projects: - ost_auth['domain'] = projects[auth['vo']] - else: - # let's use the VO name directly - ost_auth['domain'] = auth['vo'] - - new_auth = Authentication([ost_auth]) - - orig_cloud = self.cloud - self.cloud = CloudInfo.get_cloud_list(new_auth)[0] - self.type = OpenStackCloudConnector.type - driver = OpenStackCloudConnector.get_driver(self, new_auth) - self.type = EGICloudConnector.type - self.cloud = orig_cloud - return driver + if self.driver and self.egi_auth.compare(auth_data, self.type, self.cloud.server): + return self.driver else: - self.log_error("No correct auth data has been specified to EGI: host, vo, and token") - raise Exception("No correct auth data has been specified to EG: host, vo, and token") + self.egi_auth = auth_data + + if 'host' in auth and 'vo' in auth and 'token' in auth: + ost_auth = {'id': auth['id'], 'type': 'OpenStack', 'username': 'egi.eu', 'tenant': 'openid', + 'password': auth['token'], 'auth_version': '3.x_oidc_access_token', 'vo': auth['vo']} + site_id = AppDB.get_site_id(auth["host"], stype="openstack") + site_url = AppDB.get_site_url(site_id) + if not site_url: + raise Exception("Invalid site name '%s'. Not found at AppDB." % auth['host']) + ost_auth['host'] = site_url + projects = AppDB.get_project_ids(site_id) + # If the VO does not appear in the project IDs + if auth['vo'] in projects: + ost_auth['domain'] = projects[auth['vo']] + else: + # let's use the VO name directly + ost_auth['domain'] = auth['vo'] + + if 'api_version' in auth: + ost_auth['api_version'] = auth['api_version'] + + new_auth = Authentication([ost_auth]) + + orig_cloud = self.cloud + self.cloud = CloudInfo.get_cloud_list(new_auth)[0] + self.type = OpenStackCloudConnector.type + driver = OpenStackCloudConnector.get_driver(self, new_auth) + self.type = EGICloudConnector.type + self.cloud = orig_cloud + + self.driver = driver + return driver + else: + self.log_error("No correct auth data has been specified to EGI: host, vo, and token") + raise Exception("No correct auth data has been specified to EG: host, vo, and token") def concrete_system(self, radl_system, str_url, auth_data): url = urlparse(str_url) protocol = url[0] src_host = url[1].split(':')[0] - if protocol == "appdb": - site_url, image_id, msg = AppDB.get_image_data(str_url, "openstack") - if not image_id or not site_url: - self.log_error(msg) - return None - - protocol = "ost" - url = urlparse(site_url) - src_host = url[1].split(':')[0] - - if protocol == "ost" and self.cloud.server and not self.cloud.protocol: - site_url = AppDB.get_site_url(self.cloud.server) - site_host = urlparse(str_url)[1].split(':')[0] + if protocol in ["ost", "appdb"] and self.cloud.server and not self.cloud.protocol: + site_host = "" + if protocol == "ost": + site_url = AppDB.get_site_url(self.cloud.server) + site_host = urlparse(site_url)[1].split(':')[0] - if protocol == "ost" and site_host == src_host: + if ((protocol == "ost" and site_host == src_host) or + (protocol == "appdb" and src_host == self.cloud.server)): driver = self.get_driver(auth_data) res_system = radl_system.clone() diff --git a/IM/connectors/OpenStack.py b/IM/connectors/OpenStack.py index 030c86b63..4d5fd13ee 100644 --- a/IM/connectors/OpenStack.py +++ b/IM/connectors/OpenStack.py @@ -1052,6 +1052,15 @@ def get_volumes(driver, image, radl): return res + def get_vo_name(self, auth_data): + """Get vo field from auth data if present""" + auths = auth_data.getAuthInfo(self.type, self.cloud.server) + if auths: + auth = auths[0] + if 'vo' in auth and auth['vo']: + return auth['vo'] + return None + def launch(self, inf, radl, requested_radl, num_vm, auth_data): driver = self.get_driver(auth_data) @@ -1059,7 +1068,8 @@ def launch(self, inf, radl, requested_radl, num_vm, auth_data): image_url = system.getValue("disk.0.image.url") if urlparse(image_url)[0] == "appdb": - _, image_id, msg = AppDB.get_image_data(image_url, "openstack") + vo = self.get_vo_name(auth_data) + _, image_id, msg = AppDB.get_image_data(image_url, "openstack", vo) if not image_id: self.log_error(msg) raise Exception("Error in appdb image: %s" % msg) diff --git a/test/unit/connectors/EGI.py b/test/unit/connectors/EGI.py index a76ea5b4a..8e6457aac 100644 --- a/test/unit/connectors/EGI.py +++ b/test/unit/connectors/EGI.py @@ -233,5 +233,6 @@ def test_20_launch(self, appdb, get_image_data, save_data, get_driver): self.assertEqual(driver.create_node.call_args_list[0][1]['ex_blockdevicemappings'], mappings) self.assertEqual(driver.ex_create_subnet.call_args_list[0][0][2], "10.0.1.0/24") + if __name__ == '__main__': unittest.main()