diff --git a/changelogs/fragments/ansible-test-tower-plugin.yml b/changelogs/fragments/ansible-test-tower-plugin.yml new file mode 100644 index 00000000000..81640efee9c --- /dev/null +++ b/changelogs/fragments/ansible-test-tower-plugin.yml @@ -0,0 +1,2 @@ +minor_changes: + - ansible-test - Removed the obsolete ``tower`` test plugin for testing Tower modules. diff --git a/test/lib/ansible_test/_internal/cloud/tower.py b/test/lib/ansible_test/_internal/cloud/tower.py deleted file mode 100644 index 227d170c78a..00000000000 --- a/test/lib/ansible_test/_internal/cloud/tower.py +++ /dev/null @@ -1,255 +0,0 @@ -"""Tower plugin for integration tests.""" -from __future__ import (absolute_import, division, print_function) -__metaclass__ = type - -import os -import time - -from ..util import ( - display, - ApplicationError, - SubprocessError, - ConfigParser, -) - -from ..util_common import ( - run_command, -) - -from . import ( - CloudProvider, - CloudEnvironment, - CloudEnvironmentConfig, -) - -from ..core_ci import ( - AnsibleCoreCI, -) - - -class TowerCloudProvider(CloudProvider): - """Tower cloud provider plugin. Sets up cloud resources before delegation.""" - def __init__(self, args): - """ - :type args: TestConfig - """ - super(TowerCloudProvider, self).__init__(args) - - self.aci = None - self.version = '' - - def filter(self, targets, exclude): - """Filter out the cloud tests when the necessary config and resources are not available. - :type targets: tuple[TestTarget] - :type exclude: list[str] - """ - if os.path.isfile(self.config_static_path): - return - - aci = get_tower_aci(self.args) - - if aci.available: - return - - super(TowerCloudProvider, self).filter(targets, exclude) - - def setup(self): - """Setup the cloud resource before delegation and register a cleanup callback.""" - super(TowerCloudProvider, self).setup() - - if self._use_static_config(): - self._setup_static() - else: - self._setup_dynamic() - - def check_tower_version(self, fallback=None): - """Check the Tower version being tested and determine the correct CLI version to use. - :type fallback: str | None - """ - tower_cli_version_map = { - '3.1.5': '3.1.8', - '3.2.3': '3.3.0', - '3.3.5': '3.3.3', - '3.4.3': '3.3.3', - '3.6.3': '3.3.8', - } - - cli_version = tower_cli_version_map.get(self.version, fallback) - - if not cli_version: - raise ApplicationError('Mapping to ansible-tower-cli version required for Tower version: %s' % self.version) - - self._set_cloud_config('tower_cli_version', cli_version) - - def cleanup(self): - """Clean up the cloud resource and any temporary configuration files after tests complete.""" - # cleanup on success or failure is not yet supported due to how cleanup is called - if self.aci and self.args.remote_terminate == 'always': - self.aci.stop() - - super(TowerCloudProvider, self).cleanup() - - def _setup_static(self): - config = TowerConfig.parse(self.config_static_path) - - self.version = config.version - self.check_tower_version() - - def _setup_dynamic(self): - """Request Tower credentials through the Ansible Core CI service.""" - display.info('Provisioning %s cloud environment.' % self.platform, verbosity=1) - - # temporary solution to allow version selection - self.version = os.environ.get('TOWER_VERSION', '3.6.3') - self.check_tower_version(os.environ.get('TOWER_CLI_VERSION')) - - aci = get_tower_aci(self.args, self.version) - aci.start() - aci.wait() - - connection = aci.get() - - config = self._read_config_template() - - if not self.args.explain: - self.aci = aci - - values = dict( - VERSION=self.version, - HOST=connection.hostname, - USERNAME=connection.username, - PASSWORD=connection.password, - ) - - display.sensitive.add(values['PASSWORD']) - - config = self._populate_config_template(config, values) - - self._write_config(config) - - -class TowerCloudEnvironment(CloudEnvironment): - """Tower cloud environment plugin. Updates integration test environment after delegation.""" - def setup(self): - """Setup which should be done once per environment instead of once per test target.""" - self.setup_cli() - self.disable_pendo() - - def setup_cli(self): - """Install the correct Tower CLI for the version of Tower being tested.""" - tower_cli_version = self._get_cloud_config('tower_cli_version') - - display.info('Installing Tower CLI version: %s' % tower_cli_version) - - cmd = self.args.pip_command + ['install', '--disable-pip-version-check', 'ansible-tower-cli==%s' % tower_cli_version] - - run_command(self.args, cmd) - - cmd = ['tower-cli', 'config', 'verify_ssl', 'false'] - run_command(self.args, cmd, capture=True) - - def disable_pendo(self): - """Disable Pendo tracking.""" - display.info('Disable Pendo tracking') - - config = TowerConfig.parse(self.config_path) - - # tower-cli does not recognize TOWER_ environment variables - cmd = ['tower-cli', 'setting', 'modify', 'PENDO_TRACKING_STATE', 'off', - '-h', config.host, '-u', config.username, '-p', config.password] - - attempts = 60 - - while True: - attempts -= 1 - - try: - run_command(self.args, cmd, capture=True) - return - except SubprocessError as ex: - if not attempts: - raise ApplicationError('Timed out trying to disable Pendo tracking:\n%s' % ex) - - time.sleep(5) - - def get_environment_config(self): - """ - :rtype: CloudEnvironmentConfig - """ - config = TowerConfig.parse(self.config_path) - - env_vars = config.environment - - ansible_vars = dict((key.lower(), value) for key, value in env_vars.items()) - - return CloudEnvironmentConfig( - env_vars=env_vars, - ansible_vars=ansible_vars, - ) - - -class TowerConfig: - """Tower settings.""" - def __init__(self, values): - self.version = values.get('version') - self.host = values.get('host') - self.username = values.get('username') - self.password = values.get('password') - - if self.password: - display.sensitive.add(self.password) - - @property - def environment(self): - """Tower settings as environment variables. - :rtype: dict[str, str] - """ - env = dict( - TOWER_VERSION=self.version, - TOWER_HOST=self.host, - TOWER_USERNAME=self.username, - TOWER_PASSWORD=self.password, - ) - - return env - - @staticmethod - def parse(path): - """ - :type path: str - :rtype: TowerConfig - """ - parser = ConfigParser() - parser.read(path) - - keys = ( - 'version', - 'host', - 'username', - 'password', - ) - - values = dict((k, parser.get('default', k)) for k in keys) - config = TowerConfig(values) - - missing = [k for k in keys if not values.get(k)] - - if missing: - raise ApplicationError('Missing or empty Tower configuration value(s): %s' % ', '.join(missing)) - - return config - - -def get_tower_aci(args, version=None): - """ - :type args: EnvironmentConfig - :type version: str | None - :rtype: AnsibleCoreCI - """ - if version: - persist = True - else: - version = '' - persist = False - - return AnsibleCoreCI(args, 'tower', version, persist=persist, stage=args.remote_stage, provider=args.remote_provider) diff --git a/test/lib/ansible_test/_internal/core_ci.py b/test/lib/ansible_test/_internal/core_ci.py index da66977c0e3..0c006058d22 100644 --- a/test/lib/ansible_test/_internal/core_ci.py +++ b/test/lib/ansible_test/_internal/core_ci.py @@ -70,7 +70,6 @@ class AnsibleCoreCI: 'freebsd', 'ios', 'rhel', - 'tower', 'vyos', 'windows', ), diff --git a/test/lib/ansible_test/config/cloud-config-tower.ini.template b/test/lib/ansible_test/config/cloud-config-tower.ini.template deleted file mode 100644 index c76740ab687..00000000000 --- a/test/lib/ansible_test/config/cloud-config-tower.ini.template +++ /dev/null @@ -1,18 +0,0 @@ -# This is the configuration template for ansible-test Tower integration tests. -# -# You do not need this template if you are: -# -# 1) Running integration tests without using ansible-test. -# 2) Using the automatically provisioned Tower credentials in ansible-test. -# -# If you do not want to use the automatically provisioned temporary Tower credentials, -# fill in the @VAR placeholders below and save this file without the .template extension. -# This will cause ansible-test to use the given configuration instead of temporary credentials. -# -# NOTE: Automatic provisioning of Tower credentials requires an ansible-core-ci API key. - -[default] -version=@VERSION -host=@HOST -username=@USERNAME -password=@PASSWORD