From f4a21a26506028c8667d52929a0058776899b387 Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Tue, 31 Jan 2017 14:55:21 -0500 Subject: [PATCH] don't stringify source_vars['private'] for Openstack inventory updates shade's OS_CLIENT_CONFIG_FILE expects the generated YAML value to be a boolean, not a stringified boolean Addresses #5030 --- awx/main/tasks.py | 2 +- awx/main/tests/unit/test_tasks.py | 72 +++++++++++++++++++++++++++---- 2 files changed, 64 insertions(+), 10 deletions(-) diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 4f0484f76d..1d41c1dd4e 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -1358,7 +1358,7 @@ class RunInventoryUpdate(BaseTask): project_name=credential.project) if credential.domain not in (None, ''): openstack_auth['domain_name'] = credential.domain - private_state = str(inventory_update.source_vars_dict.get('private', 'true')) + private_state = inventory_update.source_vars_dict.get('private', 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', {}) diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index 2cefe0007b..d8b6469f93 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -1,15 +1,14 @@ -import pytest from contextlib import contextmanager +import pytest +import yaml + from awx.main.models import ( UnifiedJob, Notification, ) -from awx.main.tasks import ( - send_notifications, - run_administrative_checks, -) +from awx.main import tasks from awx.main.task_engine import TaskEnhancer @@ -22,12 +21,12 @@ def apply_patches(_patches): def test_send_notifications_not_list(): with pytest.raises(TypeError): - send_notifications(None) + tasks.send_notifications(None) def test_send_notifications_job_id(mocker): with mocker.patch('awx.main.models.UnifiedJob.objects.get'): - send_notifications([], job_id=1) + tasks.send_notifications([], job_id=1) assert UnifiedJob.objects.get.called assert UnifiedJob.objects.get.called_with(id=1) @@ -42,7 +41,7 @@ def test_send_notifications_list(mocker): patches.append(mocker.patch('awx.main.models.Notification.objects.filter', return_value=mock_notifications)) with apply_patches(patches): - send_notifications([1,2], job_id=1) + tasks.send_notifications([1,2], job_id=1) assert Notification.objects.filter.call_count == 1 assert mock_notifications[0].status == "successful" assert mock_notifications[0].save.called @@ -64,9 +63,64 @@ def test_run_admin_checks_usage(mocker, current_instances, call_count): patches.append(mocker.patch('awx.main.tasks.send_mail', wraps=mock_sm)) with apply_patches(patches): - run_administrative_checks() + tasks.run_administrative_checks() assert mock_sm.called if call_count == 2: assert '90%' in mock_sm.call_args_list[0][0][0] else: assert 'expire' in mock_sm.call_args_list[0][0][0] + + +def test_openstack_client_config_generation(mocker): + update = tasks.RunInventoryUpdate() + inventory_update = mocker.Mock(**{ + 'source': 'openstack', + 'credential.host': 'https://keystone.openstack.example.org', + 'credential.username': 'demo', + 'credential.password': 'secrete', + 'credential.project': 'demo-project', + 'credential.domain': None, + 'source_vars_dict': {} + }) + cloud_config = update.build_private_data(inventory_update) + cloud_credential = yaml.load(cloud_config['cloud_credential']) + assert cloud_credential['clouds'] == { + 'devstack': { + 'auth': { + 'auth_url': 'https://keystone.openstack.example.org', + 'password': 'secrete', + 'project_name': 'demo-project', + 'username': 'demo' + }, + 'private': True + } + } + + +@pytest.mark.parametrize("source,expected", [ + (False, False), (True, True) +]) +def test_openstack_client_config_generation_with_private_source_vars(mocker, source, expected): + update = tasks.RunInventoryUpdate() + inventory_update = mocker.Mock(**{ + 'source': 'openstack', + 'credential.host': 'https://keystone.openstack.example.org', + 'credential.username': 'demo', + 'credential.password': 'secrete', + 'credential.project': 'demo-project', + 'credential.domain': None, + 'source_vars_dict': {'private': source} + }) + cloud_config = update.build_private_data(inventory_update) + cloud_credential = yaml.load(cloud_config['cloud_credential']) + assert cloud_credential['clouds'] == { + 'devstack': { + 'auth': { + 'auth_url': 'https://keystone.openstack.example.org', + 'password': 'secrete', + 'project_name': 'demo-project', + 'username': 'demo' + }, + 'private': expected + } + }