From df108b4cce50c32fdcbfaa15586138ea462802e4 Mon Sep 17 00:00:00 2001 From: Jacob Callahan Date: Thu, 21 Nov 2024 10:46:16 -0500 Subject: [PATCH] Add a contenthost_factory to perform post-deploy actions The intent of this change is to enable us to add post-deploy actions when requesting specific types of content hosts, like fips-enabled. Users can define a set of host_post_configs in conf/content_host.yaml file. They can then add the post config action under the host definition. --- conf/content_host.yaml.template | 130 ++++++++++++++++---------- pytest_fixtures/core/contenthosts.py | 86 ++++++++++------- tests/new_upgrades/test_repository.py | 10 +- tests/upgrades/test_repository.py | 10 +- 4 files changed, 147 insertions(+), 89 deletions(-) diff --git a/conf/content_host.yaml.template b/conf/content_host.yaml.template index c04f9382f64..06707613587 100644 --- a/conf/content_host.yaml.template +++ b/conf/content_host.yaml.template @@ -1,80 +1,114 @@ content_host: - default_rhel_version: 7 - rhel6: + centos7: vm: - workflow: deploy-base-rhel - deploy_rhel_version: '6' + deploy_rhel_version: '7' + deploy_scenario: centos + target_cores: 1 + target_memory: 1GiB + workflow: deploy-centos + centos8: + vm: + deploy_rhel_version: '8.5' + deploy_scenario: centos + target_cores: 1 + target_memory: 1536 MiB + workflow: deploy-centos + default_rhel_version: 8 + oracle7: + vm: + deploy_rhel_version: '7.9' + deploy_scenario: oracle + target_cores: 1 target_memory: 1GiB + workflow: deploy-oracle-linux + oracle8: + vm: + deploy_rhel_version: '8.9' + deploy_scenario: oracle target_cores: 1 + target_memory: 1536 MiB + workflow: deploy-oracle-linux + rhel6: container: container_host: rhel6:latest - rhel7: vm: - workflow: deploy-base-rhel - deploy_rhel_version: '7' - target_memory: 1GiB + cores: 1 + deploy_rhel_version: '6' + memory: 1GiB + release: '6.10' target_cores: 1 + target_memory: 1GiB + workflow: deploy-rhel + rhel7: container: container_host: ubi7:latest - rhel7_fips: vm: - workflow: deploy-base-rhel-fips + cores: 1 deploy_rhel_version: '7' + memory: 1GiB + release: '7.9' + target_cores: 1 target_memory: 1GiB + workflow: deploy-rhel + rhel7_fips: + vm: + cores: 1 + deploy_rhel_version: '7' + memory: 1GiB + release: '7.9' target_cores: 1 + target_memory: 1GiB + workflow: deploy-rhel + post_configs: + - fips rhel8: + container: + container_host: ubi8:latest vm: - workflow: deploy-base-rhel + cores: 1 deploy_rhel_version: '8' - target_memory: 1536 MiB + memory: 1536 MiB + release: '8.5' target_cores: 1 - container: - container_host: ubi8:latest + target_memory: 1536 MiB + workflow: deploy-rhel rhel8_fips: vm: - workflow: deploy-base-rhel-fips + cores: 1 deploy_rhel_version: '8' - target_memory: 1536 MiB + memory: 1536 MiB + release: '8.5' target_cores: 1 - rhel9: - vm: - workflow: deploy-base-rhel - deploy_rhel_version: '9' target_memory: 1536 MiB - target_cores: 1 + workflow: deploy-rhel + post_configs: + - fips + rhel9: container: container_host: ubi9:latest - rhel9_fips: vm: - workflow: deploy-base-rhel-fips + cores: 1 deploy_rhel_version: '9' - target_memory: 1536 MiB - target_cores: 1 - centos7: - vm: - workflow: deploy-centos - deploy_scenario: centos - deploy_rhel_version: '7' - target_memory: 1GiB + memory: 1536 MiB + release: '9.0' target_cores: 1 - centos8: - vm: - workflow: deploy-centos - deploy_scenario: centos - deploy_rhel_version: '8.6' target_memory: 1536 MiB - target_cores: 1 - oracle7: + workflow: deploy-rhel + rhel9_fips: vm: - workflow: deploy-oracle-linux - deploy_scenario: oracle - deploy_rhel_version: '7.9' - target_memory: 1GiB + cores: 1 + deploy_rhel_version: '9' + memory: 1536 MiB + release: '9.0' target_cores: 1 - oracle8: - vm: - workflow: deploy-oracle-linux - deploy_scenario: oracle - deploy_rhel_version: '8.6' target_memory: 1536 MiB - target_cores: 1 + workflow: deploy-rhel + post_configs: + - fips +host_post_configs: + fips: + workflow: enable-fips + target_vm: "{vm.name}" + fapolicyd: + workflow: enable-fapolicyd + target_vm: "{vm.name}" diff --git a/pytest_fixtures/core/contenthosts.py b/pytest_fixtures/core/contenthosts.py index fc34a22f80c..b942a9fa58f 100644 --- a/pytest_fixtures/core/contenthosts.py +++ b/pytest_fixtures/core/contenthosts.py @@ -5,6 +5,8 @@ All functions in this module will be treated as fixtures that apply the contenthost mark """ +from contextlib import contextmanager + from broker import Broker import pytest @@ -41,12 +43,35 @@ def host_conf(request): return conf +def host_post_config(hosts, config_name): + """A function that runs a specified post config on a list of content hosts.""" + broker_args = settings.content_host.host_post_configs.get(config_name).to_dict() + for host in hosts: + for key, val in broker_args.items(): + if "{" in val: + broker_args[key] = val.format(host=host) + Broker(**broker_args).execute() + + +@contextmanager +def contenthost_factory(request, **kwargs): + """A factory function that checks out and (optionally) configures a content host.""" + host_params = host_conf(request) + post_configs = host_params.pop("post_configs", []) + host_class = kwargs.pop("host_class", ContentHost) + with Broker(**host_params, host_class=host_class, **kwargs) as host: + if post_configs: + hosts = host if isinstance(host, list) else [host] + for config_name in post_configs: + host_post_config(hosts, config_name) + yield host + + @pytest.fixture def rhel_contenthost(request): """A function-level fixture that provides a content host object parametrized""" # Request should be parametrized through pytest_fixtures.fixture_markers - # unpack params dict - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @@ -54,64 +79,63 @@ def rhel_contenthost(request): def module_rhel_contenthost(request): """A module-level fixture that provides a content host object parametrized""" # Request should be parametrized through pytest_fixtures.fixture_markers - # unpack params dict - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture(params=[{'rhel_version': '7'}]) def rhel7_contenthost(request): """A function-level fixture that provides a rhel7 content host object""" - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture(scope="class", params=[{'rhel_version': '7'}]) def rhel7_contenthost_class(request): """A fixture for use with unittest classes. Provides a rhel7 Content Host object""" - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture(scope='module', params=[{'rhel_version': '7'}]) def rhel7_contenthost_module(request): """A module-level fixture that provides a rhel7 content host object""" - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture(params=[{'rhel_version': '8'}]) def rhel8_contenthost(request): """A fixture that provides a rhel8 content host object""" - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture(scope='module', params=[{'rhel_version': '8'}]) def rhel8_contenthost_module(request): """A module-level fixture that provides a rhel8 content host object""" - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture(params=[{'rhel_version': 6}]) def rhel6_contenthost(request): """A function-level fixture that provides a rhel6 content host object""" - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture(params=[{'rhel_version': '9'}]) def rhel9_contenthost(request): """A fixture that provides a rhel9 content host object""" - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture def content_hosts(request): """A function-level fixture that provides two rhel content hosts object""" - with Broker(**host_conf(request), host_class=ContentHost, _count=2) as hosts: + with contenthost_factory(request=request, _count=2) as hosts: hosts[0].set_infrastructure_type('physical') yield hosts @@ -119,7 +143,7 @@ def content_hosts(request): @pytest.fixture(scope='module') def mod_content_hosts(request): """A module-level fixture that provides two rhel content hosts object""" - with Broker(**host_conf(request), host_class=ContentHost, _count=2) as hosts: + with contenthost_factory(request=request, _count=2) as hosts: hosts[0].set_infrastructure_type('physical') yield hosts @@ -127,7 +151,7 @@ def mod_content_hosts(request): @pytest.fixture def registered_hosts(request, target_sat, module_org, module_ak_with_cv): """Fixture that registers content hosts to Satellite, based on rh_cloud setup""" - with Broker(**host_conf(request), host_class=ContentHost, _count=2) as hosts: + with contenthost_factory(request=request, _count=2) as hosts: for vm in hosts: repo = settings.repos['SATCLIENT_REPO'][f'RHEL{vm.os_version.major}'] vm.register( @@ -171,7 +195,7 @@ def cockpit_host(class_target_sat, class_org, rhel_contenthost): @pytest.fixture def rex_contenthost(request, module_org, target_sat, module_ak_with_cv): request.param['no_containers'] = True - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: repo = settings.repos['SATCLIENT_REPO'][f'RHEL{host.os_version.major}'] host.register( module_org, None, module_ak_with_cv.name, target_sat, repo_data=f'repo={repo}' @@ -182,7 +206,7 @@ def rex_contenthost(request, module_org, target_sat, module_ak_with_cv): @pytest.fixture def rex_contenthosts(request, module_org, target_sat, module_ak_with_cv): request.param['no_containers'] = True - with Broker(**host_conf(request), host_class=ContentHost, _count=2) as hosts: + with contenthost_factory(request=request, _count=2) as hosts: for host in hosts: repo = settings.repos['SATCLIENT_REPO'][f'RHEL{host.os_version.major}'] host.register( @@ -193,8 +217,7 @@ def rex_contenthosts(request, module_org, target_sat, module_ak_with_cv): @pytest.fixture def katello_host_tools_tracer_host(rex_contenthost, target_sat): - """Install katello-host-tools-tracer, create custom - repositories on the host""" + """Install katello-host-tools-tracer, create custom repositories on the host""" # create a custom, rhel version-specific OS repo rhelver = rex_contenthost.os_version.major if rhelver > 7: @@ -215,7 +238,7 @@ def module_container_contenthost(request, module_target_sat, module_org, module_ "distro": "rhel", "no_containers": True, } - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: host.register_to_cdn() for client in constants.CONTAINER_CLIENTS: assert ( @@ -239,7 +262,7 @@ def centos_host(request, version): "distro": "centos", "no_containers": True, } - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @@ -250,16 +273,14 @@ def oracle_host(request, version): "distro": "oracle", "no_containers": True, } - with Broker(**host_conf(request), host_class=ContentHost) as host: + with contenthost_factory(request=request) as host: yield host @pytest.fixture(scope='module', params=[{'rhel_version': 8, 'no_containers': True}]) def external_puppet_server(request): - deploy_args = host_conf(request) - deploy_args['target_cores'] = 2 - deploy_args['target_memory'] = '4GiB' - with Broker(**deploy_args, host_class=ContentHost) as host: + request.param.update({'target_cores': 2, 'target_memory': '4GiB'}) + with contenthost_factory(request=request) as host: host.register_to_cdn() # Install puppet packages assert ( @@ -290,21 +311,18 @@ def external_puppet_server(request): @pytest.fixture(scope="module") -def sat_upgrade_chost(): +def sat_upgrade_chost(request): # This leaks! Be sure to clean up manually. """A module-level fixture that provides a UBI_8 content host for upgrade scenario testing""" - return Broker( - container_host=settings.content_host.rhel8.container.container_host, host_class=ContentHost - ).checkout() + request.param = {"container_host": settings.content_host.ubi8.container.container_host} + return contenthost_factory(request=request) @pytest.fixture def custom_host(request): """A rhel content host that passes custom host config through request.param""" - deploy_args = request.param - # if 'deploy_rhel_version' is not set, let's default to what's in content_host.yaml - deploy_args['deploy_rhel_version'] = deploy_args.get( + request.param['deploy_rhel_version'] = request.param.get( 'deploy_rhel_version', settings.content_host.default_rhel_version ) - deploy_args['workflow'] = 'deploy-rhel' - with Broker(**deploy_args, host_class=Satellite) as host: + request.param['workflow'] = 'deploy-rhel' + with contenthost_factory(request=request, host_class=Satellite) as host: yield host diff --git a/tests/new_upgrades/test_repository.py b/tests/new_upgrades/test_repository.py index 50c985164fc..11c2c826913 100644 --- a/tests/new_upgrades/test_repository.py +++ b/tests/new_upgrades/test_repository.py @@ -29,7 +29,7 @@ @pytest.fixture -def custom_repo_check_setup(sat_upgrade_chost, content_upgrade_shared_satellite, upgrade_action): +def custom_repo_check_setup(rhel9_contenthost, content_upgrade_shared_satellite, upgrade_action): """This is pre-upgrade scenario test to verify if we can create a custom repository and consume it via content host. @@ -53,7 +53,7 @@ def custom_repo_check_setup(sat_upgrade_chost, content_upgrade_shared_satellite, test_data = Box( { 'target_sat': target_sat, - 'rhel_client': sat_upgrade_chost, + 'rhel_client': rhel9_contenthost, 'lce': None, 'repo': None, 'content_view': None, @@ -85,11 +85,11 @@ def custom_repo_check_setup(sat_upgrade_chost, content_upgrade_shared_satellite, query={'search': f'name={product.name}'} )[0] ak.add_subscriptions(data={'subscription_id': subscription.id}) - sat_upgrade_chost.api_register( + rhel9_contenthost.api_register( target_sat, organization=org, activation_keys=[ak.name], location=None ) - sat_upgrade_chost.execute('subscription-manager repos --enable=* && yum clean all') - result = sat_upgrade_chost.execute(f'yum install -y {FAKE_0_CUSTOM_PACKAGE_NAME}') + rhel9_contenthost.execute('subscription-manager repos --enable=* && yum clean all') + result = rhel9_contenthost.execute(f'yum install -y {FAKE_0_CUSTOM_PACKAGE_NAME}') assert result.status == 0 sat_upgrade.ready() target_sat._session = None diff --git a/tests/upgrades/test_repository.py b/tests/upgrades/test_repository.py index bb730ca847e..d94492d6d90 100644 --- a/tests/upgrades/test_repository.py +++ b/tests/upgrades/test_repository.py @@ -12,6 +12,7 @@ """ +from broker import Broker import pytest from robottelo import constants @@ -175,7 +176,7 @@ def test_pre_scenario_custom_repo_check(self, target_sat, sat_upgrade_chost, sav ) @pytest.mark.post_upgrade(depend_on=test_pre_scenario_custom_repo_check) - def test_post_scenario_custom_repo_check(self, target_sat, pre_upgrade_data): + def test_post_scenario_custom_repo_check(self, request, target_sat, pre_upgrade_data): """This is post-upgrade scenario test to verify if we can alter the created custom repository and satellite will be able to sync back the repo. @@ -192,6 +193,12 @@ def test_post_scenario_custom_repo_check(self, target_sat, pre_upgrade_data): """ client_hostname = pre_upgrade_data.get('rhel_client') + rhel_client = ContentHost.get_host_by_hostname(client_hostname) + + @request.addfinalizer + def _cleanup(): + Broker(hosts=[rhel_client]).checkin() + content_view_name = pre_upgrade_data.get('content_view_name') lce_id = pre_upgrade_data.get('lce_id') repo_name = pre_upgrade_data.get('repo_name') @@ -208,7 +215,6 @@ def test_post_scenario_custom_repo_check(self, target_sat, pre_upgrade_data): data={'environment_ids': lce_id} ) - rhel_client = ContentHost.get_host_by_hostname(client_hostname) result = rhel_client.execute(f'yum install -y {FAKE_4_CUSTOM_PACKAGE_NAME}') assert result.status == 0