Adding import/export awx kit features

Changed library structure

Origional TowerModule becomes TowerLegacyModule

TowerModule from tower_api becomes TowerAPIModule

A real base TowerModule is created in tower_module.py

A new TowerAWXKitModule is created in tower_awxkit

TowerAWXKitModule and TowerAPIModule are child classes of TowerModule
This commit is contained in:
John Westcott IV
2020-08-03 12:09:00 -04:00
parent 383f8aa8f9
commit 40f6741474
41 changed files with 652 additions and 315 deletions

View File

@@ -10,7 +10,7 @@ from contextlib import redirect_stdout, suppress
from unittest import mock
import logging
from requests.models import Response
from requests.models import Response, PreparedRequest
import pytest
@@ -23,6 +23,11 @@ try:
except ImportError:
HAS_TOWER_CLI = False
try:
import awxkit
HAS_AWX_KIT = True
except ImportError:
HAS_AWX_KIT = False
logger = logging.getLogger('awx.main.tests')
@@ -90,7 +95,8 @@ def run_module(request, collection_import):
if 'params' in kwargs and method == 'GET':
# query params for GET are handled a bit differently by
# tower-cli and python requests as opposed to REST framework APIRequestFactory
kwargs_copy.setdefault('data', {})
if not kwargs_copy.get('data'):
kwargs_copy['data'] = {}
if isinstance(kwargs['params'], dict):
kwargs_copy['data'].update(kwargs['params'])
elif isinstance(kwargs['params'], list):
@@ -117,6 +123,8 @@ def run_module(request, collection_import):
request_user.username, resp.status_code
)
resp.request = PreparedRequest()
resp.request.prepare(method=method, url=url)
return resp
def new_open(self, method, url, **kwargs):
@@ -142,11 +150,22 @@ def run_module(request, collection_import):
def mock_load_params(self):
self.params = module_params
with mock.patch.object(resource_module.TowerModule, '_load_params', new=mock_load_params):
if getattr(resource_module, 'TowerAWXKitModule', None):
resource_class = resource_module.TowerAWXKitModule
elif getattr(resource_module, 'TowerAPIModule', None):
resource_class = resource_module.TowerAPIModule
elif getattr(resource_module, 'TowerLegacyModule', None):
resource_class = resource_module.TowerLegacyModule
else:
raise("The module has neither a TowerLegacyModule, TowerAWXKitModule or a TowerAPIModule")
with mock.patch.object(resource_class, '_load_params', new=mock_load_params):
# Call the test utility (like a mock server) instead of issuing HTTP requests
with mock.patch('ansible.module_utils.urls.Request.open', new=new_open):
if HAS_TOWER_CLI:
tower_cli_mgr = mock.patch('tower_cli.api.Session.request', new=new_request)
elif HAS_AWX_KIT:
tower_cli_mgr = mock.patch('awxkit.api.client.requests.Session.request', new=new_request)
else:
tower_cli_mgr = suppress()
with tower_cli_mgr:

View File

@@ -30,12 +30,12 @@ def mock_ping_response(self, method, url, **kwargs):
def test_version_warning(collection_import, silence_warning):
TowerModule = collection_import('plugins.module_utils.tower_api').TowerModule
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
cli_data = {'ANSIBLE_MODULE_ARGS': {}}
testargs = ['module_file2.py', json.dumps(cli_data)]
with mock.patch.object(sys, 'argv', testargs):
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_ping_response):
my_module = TowerModule(argument_spec=dict())
my_module = TowerAPIModule(argument_spec=dict())
my_module._COLLECTION_VERSION = "1.0.0"
my_module._COLLECTION_TYPE = "not-junk"
my_module.collection_to_version['not-junk'] = 'not-junk'
@@ -46,12 +46,12 @@ def test_version_warning(collection_import, silence_warning):
def test_type_warning(collection_import, silence_warning):
TowerModule = collection_import('plugins.module_utils.tower_api').TowerModule
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
cli_data = {'ANSIBLE_MODULE_ARGS': {}}
testargs = ['module_file2.py', json.dumps(cli_data)]
with mock.patch.object(sys, 'argv', testargs):
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_ping_response):
my_module = TowerModule(argument_spec={})
my_module = TowerAPIModule(argument_spec={})
my_module._COLLECTION_VERSION = "1.2.3"
my_module._COLLECTION_TYPE = "junk"
my_module.collection_to_version['junk'] = 'junk'
@@ -63,7 +63,7 @@ def test_type_warning(collection_import, silence_warning):
def test_duplicate_config(collection_import, silence_warning):
# imports done here because of PATH issues unique to this test suite
TowerModule = collection_import('plugins.module_utils.tower_api').TowerModule
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
data = {
'name': 'zigzoom',
'zig': 'zoom',
@@ -71,12 +71,12 @@ def test_duplicate_config(collection_import, silence_warning):
'tower_config_file': 'my_config'
}
with mock.patch.object(TowerModule, 'load_config') as mock_load:
with mock.patch.object(TowerAPIModule, 'load_config') as mock_load:
argument_spec = dict(
name=dict(required=True),
zig=dict(type='str'),
)
TowerModule(argument_spec=argument_spec, direct_params=data)
TowerAPIModule(argument_spec=argument_spec, direct_params=data)
assert mock_load.mock_calls[-1] == mock.call('my_config')
silence_warning.assert_called_once_with(
@@ -92,8 +92,8 @@ def test_no_templated_values(collection_import):
Those replacements should happen at build time, so they should not be
checked into source.
"""
TowerModule = collection_import('plugins.module_utils.tower_api').TowerModule
assert TowerModule._COLLECTION_VERSION == "0.0.1-devel", (
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
assert TowerAPIModule._COLLECTION_VERSION == "0.0.1-devel", (
'The collection version is templated when the collection is built '
'and the code should retain the placeholder of "0.0.1-devel".'
)