From 08323a11b631b9e24ada40aed70af36915dd20a4 Mon Sep 17 00:00:00 2001 From: Dave Lewis Date: Thu, 23 Apr 2020 11:24:51 +0100 Subject: [PATCH 1/4] Addition of project domain name to OpenStack Credential Keystone v3 requires user_domain_id and project_domain_name to authenticate, but AWX openstack credential only requests the user_domain_id. Added in project_domain_name into the credential templating. Not added as a required field as this is only needed when using Keystone v3. --- awx/main/models/credential/__init__.py | 4 ++++ awx/main/models/credential/injectors.py | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/awx/main/models/credential/__init__.py b/awx/main/models/credential/__init__.py index 1701c1fb24..85800b4029 100644 --- a/awx/main/models/credential/__init__.py +++ b/awx/main/models/credential/__init__.py @@ -799,6 +799,10 @@ ManagedCredentialType( 'id': 'project', 'label': ugettext_noop('Project (Tenant Name)'), 'type': 'string', + }, { + 'id': 'project_domain_name', + 'label': ugettext_noop('Project (Domain Name)'), + 'type': 'string', }, { 'id': 'domain', 'label': ugettext_noop('Domain Name'), diff --git a/awx/main/models/credential/injectors.py b/awx/main/models/credential/injectors.py index cdf193f8e9..3dd3838cc4 100644 --- a/awx/main/models/credential/injectors.py +++ b/awx/main/models/credential/injectors.py @@ -76,7 +76,8 @@ def _openstack_data(cred): openstack_auth = dict(auth_url=cred.get_input('host', default=''), username=cred.get_input('username', default=''), password=cred.get_input('password', default=''), - project_name=cred.get_input('project', default='')) + project_name=cred.get_input('project', default=''), + project_domain_name=cred.get_input('project_domain_name')) if cred.has_input('domain'): openstack_auth['domain_name'] = cred.get_input('domain', default='') verify_state = cred.get_input('verify_ssl', default=True) From 92b74266ca8988e3b657eb6a58dcdff929dd490f Mon Sep 17 00:00:00 2001 From: Dave Lewis Date: Thu, 23 Apr 2020 11:33:24 +0100 Subject: [PATCH 2/4] Correct missing "default=''" On previous commit missed "default=''" so changing: project_domain_name=cred.get_input('project_domain_name')) to project_domain_name=cred.get_input('project_domain_name', default='')) --- awx/main/models/credential/injectors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/awx/main/models/credential/injectors.py b/awx/main/models/credential/injectors.py index 3dd3838cc4..0e8debdd30 100644 --- a/awx/main/models/credential/injectors.py +++ b/awx/main/models/credential/injectors.py @@ -77,7 +77,7 @@ def _openstack_data(cred): username=cred.get_input('username', default=''), password=cred.get_input('password', default=''), project_name=cred.get_input('project', default=''), - project_domain_name=cred.get_input('project_domain_name')) + project_domain_name=cred.get_input('project_domain_name', default='')) if cred.has_input('domain'): openstack_auth['domain_name'] = cred.get_input('domain', default='') verify_state = cred.get_input('verify_ssl', default=True) From 952c91dea523acac7b67f1176fb3afc1563d1c40 Mon Sep 17 00:00:00 2001 From: Dave Lewis Date: Fri, 24 Apr 2020 14:06:13 +0100 Subject: [PATCH 3/4] Updated injector.py and added new test into test_tasks.py --- awx/main/models/credential/injectors.py | 5 +-- awx/main/tests/unit/test_tasks.py | 45 +++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/awx/main/models/credential/injectors.py b/awx/main/models/credential/injectors.py index 0e8debdd30..15b8229ea2 100644 --- a/awx/main/models/credential/injectors.py +++ b/awx/main/models/credential/injectors.py @@ -76,8 +76,9 @@ def _openstack_data(cred): openstack_auth = dict(auth_url=cred.get_input('host', default=''), username=cred.get_input('username', default=''), password=cred.get_input('password', default=''), - project_name=cred.get_input('project', default=''), - project_domain_name=cred.get_input('project_domain_name', default='')) + project_name=cred.get_input('project', default='')) + if cred.has_input('project_domain_name'): + openstack_auth['project_domain_name'] = cred.get_input('project_domain_name', default='') if cred.has_input('domain'): openstack_auth['domain_name'] = cred.get_input('domain', default='') verify_state = cred.get_input('verify_ssl', default=True) diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index 78852cbbf2..8d229129ff 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -183,6 +183,51 @@ def test_openstack_client_config_generation(mocker, source, expected, private_da } +@pytest.mark.parametrize("source,expected", [ + (None, True), (False, False), (True, True) +]) +def test_openstack_client_config_generation_with_project_domain_name(mocker, source, expected, private_data_dir): + update = tasks.RunInventoryUpdate() + credential_type = CredentialType.defaults['openstack']() + inputs = { + 'host': 'https://keystone.openstack.example.org', + 'username': 'demo', + 'password': 'secrete', + 'project': 'demo-project', + 'domain': 'my-demo-domain', + 'project_domain_name': 'project-domain', + } + if source is not None: + inputs['verify_ssl'] = source + credential = Credential(pk=1, credential_type=credential_type, inputs=inputs) + + inventory_update = mocker.Mock(**{ + 'source': 'openstack', + 'source_vars_dict': {}, + 'get_cloud_credential': mocker.Mock(return_value=credential), + 'get_extra_credentials': lambda x: [], + 'ansible_virtualenv_path': '/venv/foo' + }) + cloud_config = update.build_private_data(inventory_update, private_data_dir) + cloud_credential = yaml.safe_load( + cloud_config.get('credentials')[credential] + ) + assert cloud_credential['clouds'] == { + 'devstack': { + 'auth': { + 'auth_url': 'https://keystone.openstack.example.org', + 'password': 'secrete', + 'project_name': 'demo-project', + 'username': 'demo', + 'domain_name': 'my-demo-domain', + 'project_domain_name': 'project-domain', + }, + 'verify': expected, + 'private': True, + } + } + + @pytest.mark.parametrize("source,expected", [ (False, False), (True, True) ]) From c86692784eb06f7d14928fe41de3810860fa7509 Mon Sep 17 00:00:00 2001 From: Dave Lewis Date: Fri, 24 Apr 2020 15:11:49 +0100 Subject: [PATCH 4/4] Updated data/inventory/scripts/openstack/files/file_reference Update file_references due to the inclution of project_domain_name in the openstack credentails. --- .../tests/data/inventory/plugins/openstack/files/file_reference | 1 + .../tests/data/inventory/scripts/openstack/files/file_reference | 1 + 2 files changed, 2 insertions(+) diff --git a/awx/main/tests/data/inventory/plugins/openstack/files/file_reference b/awx/main/tests/data/inventory/plugins/openstack/files/file_reference index daf13976f4..895a1eb8a8 100644 --- a/awx/main/tests/data/inventory/plugins/openstack/files/file_reference +++ b/awx/main/tests/data/inventory/plugins/openstack/files/file_reference @@ -8,6 +8,7 @@ clouds: auth_url: https://foo.invalid domain_name: fooo password: fooo + project_domain_name: fooo project_name: fooo username: fooo private: false diff --git a/awx/main/tests/data/inventory/scripts/openstack/files/file_reference b/awx/main/tests/data/inventory/scripts/openstack/files/file_reference index 92a624965e..57b5f18197 100644 --- a/awx/main/tests/data/inventory/scripts/openstack/files/file_reference +++ b/awx/main/tests/data/inventory/scripts/openstack/files/file_reference @@ -10,6 +10,7 @@ clouds: auth_url: https://foo.invalid domain_name: fooo password: fooo + project_domain_name: fooo project_name: fooo username: fooo private: false