1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Cleanup and enhancements for ansible-test. (#37142)

* Fix type hint typos.
* Add one-time cloud env setup after delegation.
* Add generate_password to util.
* Add username/password support to HttpClient.
* Avoid pip requirement for ansible-test shell.
* Support provisioning Tower instances.
This commit is contained in:
Matt Clay 2018-03-07 14:02:31 -08:00 committed by GitHub
parent 5de7c9ce8f
commit b9b8081a87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 82 additions and 13 deletions

View file

@ -164,6 +164,7 @@ class CloudBase(ABC):
_CONFIG_PATH = 'config_path' _CONFIG_PATH = 'config_path'
_RESOURCE_PREFIX = 'resource_prefix' _RESOURCE_PREFIX = 'resource_prefix'
_MANAGED = 'managed' _MANAGED = 'managed'
_SETUP_EXECUTED = 'setup_executed'
def __init__(self, args): def __init__(self, args):
""" """
@ -172,6 +173,20 @@ class CloudBase(ABC):
self.args = args self.args = args
self.platform = self.__module__.split('.')[2] self.platform = self.__module__.split('.')[2]
@property
def setup_executed(self):
"""
:rtype: bool
"""
return self._get_cloud_config(self._SETUP_EXECUTED, False)
@setup_executed.setter
def setup_executed(self, value):
"""
:type value: bool
"""
self._set_cloud_config(self._SETUP_EXECUTED, value)
@property @property
def config_path(self): def config_path(self):
""" """
@ -214,11 +229,15 @@ class CloudBase(ABC):
""" """
self._set_cloud_config(self._MANAGED, value) self._set_cloud_config(self._MANAGED, value)
def _get_cloud_config(self, key): def _get_cloud_config(self, key, default=None):
""" """
:type key: str :type key: str
:type default: str | int | bool | None
:rtype: str | int | bool :rtype: str | int | bool
""" """
if default is not None:
return self.args.metadata.cloud_config[self.platform].get(key, default)
return self.args.metadata.cloud_config[self.platform][key] return self.args.metadata.cloud_config[self.platform][key]
def _set_cloud_config(self, key, value): def _set_cloud_config(self, key, value):
@ -357,9 +376,21 @@ class CloudProvider(CloudBase):
class CloudEnvironment(CloudBase): class CloudEnvironment(CloudBase):
"""Base class for cloud environment plugins. Updates integration test environment after delegation.""" """Base class for cloud environment plugins. Updates integration test environment after delegation."""
def setup_once(self):
"""Run setup if it has not already been run."""
if self.setup_executed:
return
self.setup()
self.setup_executed = True
def setup(self):
"""Setup which should be done once per environment instead of once per test target."""
pass
@abc.abstractmethod @abc.abstractmethod
def configure_environment(self, env, cmd): def configure_environment(self, env, cmd):
""" """Configuration which should be done once for each test target.
:type env: dict[str, str] :type env: dict[str, str]
:type cmd: list[str] :type cmd: list[str]
""" """

View file

@ -171,8 +171,8 @@ class AzureCloudEnvironment(CloudEnvironment):
def get_config(config_path): def get_config(config_path):
""" """
:param config_path: str :type config_path: str
:return: dict[str, str] :rtype: dict[str, str]
""" """
with open(config_path, 'r') as config_fd: with open(config_path, 'r') as config_fd:
lines = [line for line in config_fd.read().splitlines() if ':' in line and line.strip() and not line.strip().startswith('#')] lines = [line for line in config_fd.read().splitlines() if ':' in line and line.strip() and not line.strip().startswith('#')]

View file

@ -69,6 +69,7 @@ class AnsibleCoreCI(object):
'vyos', 'vyos',
'junos', 'junos',
'ios', 'ios',
'tower',
), ),
azure=( azure=(
'azure', 'azure',

View file

@ -140,6 +140,9 @@ def install_command_requirements(args):
if not args.requirements: if not args.requirements:
return return
if isinstance(args, ShellConfig):
return
packages = [] packages = []
if isinstance(args, TestConfig): if isinstance(args, TestConfig):
@ -720,6 +723,9 @@ def command_integration_filtered(args, targets, all_targets):
tries -= 1 tries -= 1
try: try:
if cloud_environment:
cloud_environment.setup_once()
run_setup_targets(args, test_dir, target.setup_once, all_targets_dict, setup_targets_executed, False) run_setup_targets(args, test_dir, target.setup_once, all_targets_dict, setup_targets_executed, False)
start_time = time.time() start_time = time.time()
@ -808,12 +814,12 @@ def command_integration_filtered(args, targets, all_targets):
def run_setup_targets(args, test_dir, target_names, targets_dict, targets_executed, always): def run_setup_targets(args, test_dir, target_names, targets_dict, targets_executed, always):
""" """
:param args: IntegrationConfig :type args: IntegrationConfig
:param test_dir: str :type test_dir: str
:param target_names: list[str] :type target_names: list[str]
:param targets_dict: dict[str, IntegrationTarget] :type targets_dict: dict[str, IntegrationTarget]
:param targets_executed: set[str] :type targets_executed: set[str]
:param always: bool :type always: bool
""" """
for target_name in target_names: for target_name in target_names:
if not always and target_name in targets_executed: if not always and target_name in targets_executed:

View file

@ -42,6 +42,9 @@ class HttpClient(object):
self.always = always self.always = always
self.insecure = insecure self.insecure = insecure
self.username = None
self.password = None
def get(self, url): def get(self, url):
""" """
:type url: str :type url: str
@ -83,6 +86,13 @@ class HttpClient(object):
headers['Expect'] = '' # don't send expect continue header headers['Expect'] = '' # don't send expect continue header
if self.username:
if self.password:
display.sensitive.add(self.password)
cmd += ['-u', '%s:%s' % (self.username, self.password)]
else:
cmd += ['-u', self.username]
for header in headers.keys(): for header in headers.keys():
cmd += ['-H', '%s: %s' % (header, headers[header])] cmd += ['-H', '%s: %s' % (header, headers[header])]

View file

@ -135,6 +135,8 @@ class ManagePosixCI(object):
self.become = ['sudo', '-in', 'PATH=/usr/local/bin:$PATH'] self.become = ['sudo', '-in', 'PATH=/usr/local/bin:$PATH']
elif self.core_ci.platform == 'rhel': elif self.core_ci.platform == 'rhel':
self.become = ['sudo', '-in', 'bash', '-c'] self.become = ['sudo', '-in', 'bash', '-c']
elif self.core_ci.platform == 'tower':
self.become = ['sudo', '-in', 'bash', '-c']
def setup(self): def setup(self):
"""Start instance and wait for it to become ready and respond to an ansible ping.""" """Start instance and wait for it to become ready and respond to an ansible ping."""

View file

@ -231,9 +231,9 @@ class PylintTest(SanitySingleVersion):
def pylint(self, args, context, paths): def pylint(self, args, context, paths):
""" """
:type args: SanityConfig :type args: SanityConfig
:param context: str :type context: str
:param paths: list[str] :type paths: list[str]
:return: list[dict[str, str]] :rtype: list[dict[str, str]]
""" """
rcfile = 'test/sanity/pylint/config/%s' % context rcfile = 'test/sanity/pylint/config/%s' % context

View file

@ -466,6 +466,25 @@ def is_binary_file(path):
return b'\0' in path_fd.read(1024) return b'\0' in path_fd.read(1024)
def generate_password():
"""Generate a random password.
:rtype: str
"""
chars = [
string.ascii_letters,
string.digits,
string.ascii_letters,
string.digits,
'-',
] * 4
password = ''.join([random.choice(char) for char in chars[:-1]])
display.sensitive.add(password)
return password
class Display(object): class Display(object):
"""Manages color console output.""" """Manages color console output."""
clear = '\033[0m' clear = '\033[0m'