diff --git a/awx/main/models/credential/__init__.py b/awx/main/models/credential/__init__.py index 10c5050440..c487d79fbc 100644 --- a/awx/main/models/credential/__init__.py +++ b/awx/main/models/credential/__init__.py @@ -970,6 +970,10 @@ ManagedCredentialType( 'It is only needed for Keystone v3 authentication ' 'URLs. Refer to Ansible Tower documentation for ' 'common scenarios.') + }, { + 'id': 'verify_ssl', + 'label': ugettext_noop('Verify SSL'), + 'type': 'boolean' }], 'required': ['username', 'password', 'host', 'project'] } diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 8aa80e308c..2532a6c3d6 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -1167,10 +1167,12 @@ class RunJob(BaseTask): project_name=credential.get_input('project', default='')) if credential.has_input('domain'): openstack_auth['domain_name'] = credential.get_input('domain', default='') + verify_state = credential.get_input('verify_ssl', default=True) openstack_data = { 'clouds': { 'devstack': { 'auth': openstack_auth, + 'verify': verify_state, }, }, } @@ -1875,6 +1877,7 @@ class RunInventoryUpdate(BaseTask): openstack_auth['domain_name'] = credential.get_input('domain', default='') private_state = inventory_update.source_vars_dict.get('private', True) + verify_state = credential.get_input('verify_ssl', default=True) # Retrieve cache path from inventory update vars if available, # otherwise create a temporary cache path only for this update. cache = inventory_update.source_vars_dict.get('cache', {}) @@ -1887,6 +1890,7 @@ class RunInventoryUpdate(BaseTask): 'clouds': { 'devstack': { 'private': private_state, + 'verify': verify_state, 'auth': openstack_auth, }, }, diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index b193901a41..a40b235b18 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -105,7 +105,10 @@ def test_safe_env_returns_new_copy(): assert build_safe_env(env) is not env -def test_openstack_client_config_generation(mocker): +@pytest.mark.parametrize("source,expected", [ + (False, False), (True, True) +]) +def test_openstack_client_config_generation(mocker, source, expected): update = tasks.RunInventoryUpdate() credential_type = CredentialType.defaults['openstack']() inputs = { @@ -114,6 +117,7 @@ def test_openstack_client_config_generation(mocker): 'password': 'secrete', 'project': 'demo-project', 'domain': 'my-demo-domain', + 'verify_ssl': source, } credential = Credential(pk=1, credential_type=credential_type, inputs=inputs) @@ -136,7 +140,8 @@ def test_openstack_client_config_generation(mocker): 'username': 'demo', 'domain_name': 'my-demo-domain', }, - 'private': True + 'verify': expected, + 'private': True, } } @@ -153,6 +158,7 @@ def test_openstack_client_config_generation_with_private_source_vars(mocker, sou 'password': 'secrete', 'project': 'demo-project', 'domain': None, + 'verify_ssl': True, } credential = Credential(pk=1, credential_type=credential_type, inputs=inputs) @@ -174,6 +180,7 @@ def test_openstack_client_config_generation_with_private_source_vars(mocker, sou 'project_name': 'demo-project', 'username': 'demo' }, + 'verify': True, 'private': expected } } @@ -1145,6 +1152,7 @@ class TestJobCredentials(TestJobExecution): ' password: secret', ' project_name: tenant-name', ' username: bob', + ' verify: true', '' ]) return ['successful', 0]