From f146f810695e83d2a8ce0fcdb94ff32e75ebdb20 Mon Sep 17 00:00:00 2001 From: Martin Kopec Date: Mon, 16 Nov 2020 21:26:58 +0000 Subject: [PATCH] Fix and improve SSL configuration Previously --insecure argument didn't have any effect on discover-tempest-config's behavior which lead to to failing requests due to certificates verify failures. That is fixed now. Due to the change discover-tempest-config can now automatically set the following 2 tempest options: * CONF.identity.disable_ssl_certificate_validation - previously always set to True by default. * CONF.identity.ca_certificates_file - previously not set at all. Change-Id: Iafcc9720e45190e6bd1046540d7c4a640c043023 --- config_tempest/clients.py | 11 +---- config_tempest/credentials.py | 47 +++++++++++++++---- config_tempest/main.py | 11 ++++- config_tempest/tests/test_clients.py | 6 +-- ...ve-SSL-configuration-16f0f06a6ade3a3d.yaml | 17 +++++++ 5 files changed, 67 insertions(+), 25 deletions(-) create mode 100644 releasenotes/notes/Improve-SSL-configuration-16f0f06a6ade3a3d.yaml diff --git a/config_tempest/clients.py b/config_tempest/clients.py index d9cc3b3b..f3d3eba2 100644 --- a/config_tempest/clients.py +++ b/config_tempest/clients.py @@ -88,7 +88,7 @@ class ClientManager(object): self.identity_region = creds.identity_region self.auth_provider = creds.get_auth_provider() - default_params = self._get_default_params(conf) + default_params = creds.get_ssl_certificate_validation() compute_params = self._get_compute_params(conf) compute_params.update(default_params) @@ -177,15 +177,6 @@ class ClientManager(object): project = self.projects.get_project_by_name(creds.project_name) conf.set('auth', 'admin_project_id', project['id']) - def _get_default_params(self, conf): - default_params = { - 'disable_ssl_certificate_validation': - conf.get_defaulted('identity', - 'disable_ssl_certificate_validation'), - 'ca_certs': conf.get_defaulted('identity', 'ca_certificates_file') - } - return default_params - def _get_compute_params(self, conf): compute_params = { 'service': conf.get_defaulted('compute', 'catalog_type'), diff --git a/config_tempest/credentials.py b/config_tempest/credentials.py index 33e0db0b..ff7e0080 100644 --- a/config_tempest/credentials.py +++ b/config_tempest/credentials.py @@ -25,7 +25,7 @@ class Credentials(object): Wrapps credentials obtained from TempestConf object and Tempest credentialsfrom auth library. """ - def __init__(self, conf, admin): + def __init__(self, conf, admin, **kwargs): """Init method of Credentials. :type conf: TempestConf object @@ -34,20 +34,43 @@ class Credentials(object): """ self.admin = admin self._conf = conf + self.verify = kwargs.get('verify', True) + self.cert = kwargs.get('cert', None) self.username = self.get_credential('username') self.password = self.get_credential('password') self.project_name = self.get_credential('project_name') self.identity_version = self._get_identity_version() self.api_version = 3 if self.identity_version == "v3" else 2 self.identity_region = self._conf.get_defaulted('identity', 'region') - self.disable_ssl_certificate_validation = self._conf.get_defaulted( - 'identity', - 'disable_ssl_certificate_validation' - ) - self.ca_certs = self._conf.get_defaulted('identity', - 'ca_certificates_file') + self.set_ssl_certificate_validation() self.set_credentials() + def set_ssl_certificate_validation(self): + # is there a specific CA bundle to use? + # self.verify is either a boolean, in which case it controls whether + # server's TLS certificates are verified, or a string, in which case + # it is a path to a CA bundle to use, default in requests package + # is True. + if isinstance(self.verify, str): + self.disable_ssl_certificate_validation = False + self.ca_certs = self.verify + self._conf.set('identity', 'ca_certificates_file', self.ca_certs) + else: + self.disable_ssl_certificate_validation = self._conf.get_defaulted( + 'identity', 'disable_ssl_certificate_validation' + ) + self.ca_certs = self._conf.get_defaulted('identity', + 'ca_certificates_file') + self._conf.set('identity', 'disable_ssl_certificate_validation', + str(self.disable_ssl_certificate_validation)) + + def get_ssl_certificate_validation(self): + return { + 'disable_ssl_certificate_validation': + self.disable_ssl_certificate_validation, + 'ca_certs': self.ca_certs, + } + def get_credential(self, key): """Helper for getting credential by its name. @@ -65,8 +88,8 @@ class Credentials(object): # tool keeps them in identity section for further usage return self._conf.get_defaulted('identity', key) - def _list_versions(self, base_url): - resp = requests.get(base_url) + def _list_versions(self, base_url, **kwargs): + resp = requests.get(base_url, **kwargs) data = resp.json() return data["versions"]["values"] @@ -77,7 +100,11 @@ class Credentials(object): :rtype: string """ base_url = utils.get_base_url(self._conf.get("identity", "uri")) - versions = self._list_versions(base_url) + kwargs = { + 'verify': self.verify, + 'cert': self.cert, + } + versions = self._list_versions(base_url, **kwargs) for version in versions: if version["status"] == "stable" and "v3" in version["id"]: return "v3" diff --git a/config_tempest/main.py b/config_tempest/main.py index 891dff38..59363e84 100755 --- a/config_tempest/main.py +++ b/config_tempest/main.py @@ -488,10 +488,15 @@ def get_cloud_creds(args_namespace): cloud_creds = cloud.config.get_auth_args() region_name = cloud.config.config['region_name'] - if region_name: cloud_creds['region_name'] = region_name + request_args = cloud.config.get_requests_verify_args() + cloud_creds['request_args'] = { + 'verify': request_args[0], + 'cert': request_args[1], + } + return cloud_creds @@ -512,7 +517,9 @@ def config_tempest(**kwargs): accounts_path, kwargs.get('cloud_creds')) - credentials = Credentials(conf, not kwargs.get('non_admin', False)) + request_args = kwargs.get('cloud_creds', {}).get('request_args', {}) + credentials = Credentials(conf, not kwargs.get('non_admin', False), + **request_args) clients = ClientManager(conf, credentials) if kwargs.get('create', False) and kwargs.get('test_accounts') is None: diff --git a/config_tempest/tests/test_clients.py b/config_tempest/tests/test_clients.py index 69cb87c6..4957bedb 100644 --- a/config_tempest/tests/test_clients.py +++ b/config_tempest/tests/test_clients.py @@ -42,7 +42,7 @@ class TestProjectsClient(BaseConfigTempestTest): self.client_manager.identity_region, 'publicURL', identity_version, - **self.client_manager._get_default_params(self.conf)) + **self.creds.get_ssl_certificate_validation()) def test_init(self): resp = self._get_projects_client('v2') @@ -130,7 +130,7 @@ class TestClientManager(BaseConfigTempestTest): self.creds.identity_version, self.conf.get_defaulted('identity', 'catalog_type'), 'publicURL', - self.client_manager._get_default_params(self.conf)) + self.creds.get_ssl_certificate_validation()) self.assertEqual( type(self.client_manager.users).__name__, 'UsersClient') @@ -142,7 +142,7 @@ class TestClientManager(BaseConfigTempestTest): self.creds.identity_version, self.conf.get_defaulted('identity', 'catalog_type'), 'publicURL', - self.client_manager._get_default_params(self.conf)) + self.creds.get_ssl_certificate_validation()) self.assertEqual( type(self.client_manager.roles).__name__, 'RolesClient') diff --git a/releasenotes/notes/Improve-SSL-configuration-16f0f06a6ade3a3d.yaml b/releasenotes/notes/Improve-SSL-configuration-16f0f06a6ade3a3d.yaml new file mode 100644 index 00000000..fe1f6a18 --- /dev/null +++ b/releasenotes/notes/Improve-SSL-configuration-16f0f06a6ade3a3d.yaml @@ -0,0 +1,17 @@ +--- +features: + - | + discover-tempest-config can now automatically set the following 2 tempest + options: + * CONF.identity.disable_ssl_certificate_validation + * CONF.identity.ca_certificates_file + The mentioned options are set based on cloud's request verify arguments + (verify and cert) read (either set as environent variables or passed via + CLI) by openstack package. +fixes: + - | + Passing a value from --insecure argument is fixed. Previously --insecure + didn't have any effect on discover-tempest-config and its behavior which + lead to failing requests due to certificates verify failures. That is fixed + now. Now the --insecure's value will be stored in the internal Credentials + class and safely pased in requests querying the cloud.