From 4a7ca74834ade3bcb7c42ff66327b8f6b1397dbe Mon Sep 17 00:00:00 2001 From: Gaurav Talreja Date: Fri, 15 Dec 2023 15:22:14 +0530 Subject: [PATCH] [6.13.z] Add test coverage for provisioning with fips_enabled (#12787) Add test coverage for provisioning with fips_enabled (#12695) Signed-off-by: Gaurav Talreja (cherry picked from commit c740d61536d47ce1ac732e726b6519a9dd24a1f1) --- tests/foreman/api/test_provisioning.py | 139 ++++++++++++++++++ .../foreman/api/test_provisioningtemplate.py | 47 ++++++ 2 files changed, 186 insertions(+) diff --git a/tests/foreman/api/test_provisioning.py b/tests/foreman/api/test_provisioning.py index f28e1d12730..b0760d3ff1a 100644 --- a/tests/foreman/api/test_provisioning.py +++ b/tests/foreman/api/test_provisioning.py @@ -25,6 +25,7 @@ from robottelo.config import settings from robottelo.logging import logger from robottelo.utils.installer import InstallerCommand +from robottelo.utils.issue_handlers import is_open def _read_log(ch, pattern): @@ -441,3 +442,141 @@ def test_rhel_httpboot_provisioning( # assert that the host is subscribed and consumes # subsctiption provided by the activation key assert provisioning_host.subscribed, 'Host is not subscribed' + + +@pytest.mark.parametrize('pxe_loader', ['bios', 'uefi'], indirect=True) +@pytest.mark.on_premises_provisioning +@pytest.mark.rhel_ver_match('[^6]') +def test_rhel_pxe_provisioning_fips_enabled( + request, + module_provisioning_sat, + module_sca_manifest_org, + module_location, + provisioning_host, + pxe_loader, + module_provisioning_rhel_content, + provisioning_hostgroup, + module_lce_library, + module_default_org_view, +): + """Provision a host with host param fips_enabled set to true + + :id: 9e016e1d-757a-48e7-9159-131bb65dc4ef + + :steps: + 1. Configure satellite for provisioning + 2. Provision a host with host param fips_enabled + 3. Check that resulting host is registered to Satellite + 4. Check host is subscribed to Satellite + + :expectedresults: + 1. Provisioning with host param fips_enabled is successful + 2. Host installs right version of RHEL + 3. Satellite is able to run REX job on the fips_enabled host + 4. Host is registered to Satellite and subscription status is 'Success' + + :parametrized: yes + + :BZ: 2240076 + """ + sat = module_provisioning_sat.sat + host_mac_addr = provisioning_host._broker_args['provisioning_nic_mac_addr'] + # Verify password hashing algorithm SHA256 is set in OS used for provisioning + assert module_provisioning_rhel_content.os.password_hash == 'SHA256' + + host = sat.api.Host( + hostgroup=provisioning_hostgroup, + organization=module_sca_manifest_org, + location=module_location, + name=gen_string('alpha').lower(), + mac=host_mac_addr, + operatingsystem=module_provisioning_rhel_content.os, + subnet=module_provisioning_sat.subnet, + host_parameters_attributes=[ + { + 'name': 'remote_execution_connect_by_ip', + 'value': 'true', + 'parameter_type': 'boolean', + }, + {'name': 'fips_enabled', 'value': 'true', 'parameter_type': 'boolean'}, + ], + build=True, # put the host in build mode + ).create(create_missing=False) + # Clean up the host to free IP leases on Satellite. + # broker should do that as a part of the teardown, putting here just to make sure. + request.addfinalizer(host.delete) + # Start the VM, do not ensure that we can connect to SSHD + provisioning_host.power_control(ensure=False) + + # TODO: Implement Satellite log capturing logic to verify that + # all the events are captured in the logs. + + # Host should do call back to the Satellite reporting + # the result of the installation. Wait until Satellite reports that the host is installed. + wait_for( + lambda: host.read().build_status_label != 'Pending installation', + timeout=1500, + delay=10, + ) + host = host.read() + assert host.build_status_label == 'Installed' + + # Change the hostname of the host as we know it already. + # In the current infra environment we do not support + # addressing hosts using FQDNs, falling back to IP. + provisioning_host.hostname = host.ip + # Host is not blank anymore + provisioning_host.blank = False + + # Wait for the host to be rebooted and SSH daemon to be started. + provisioning_host.wait_for_connection() + + # Perform version check and check if root password is properly updated + host_os = host.operatingsystem.read() + expected_rhel_version = f'{host_os.major}.{host_os.minor}' + + if int(host_os.major) >= 9: + assert ( + provisioning_host.execute( + 'echo -e "\nPermitRootLogin yes" >> /etc/ssh/sshd_config; systemctl restart sshd' + ).status + == 0 + ) + host_ssh_os = sat.execute( + f'sshpass -p {settings.provisioning.host_root_password} ' + 'ssh -o StrictHostKeyChecking=no -o PubkeyAuthentication=no -o PasswordAuthentication=yes ' + f'-o UserKnownHostsFile=/dev/null root@{provisioning_host.hostname} cat /etc/redhat-release' + ) + assert host_ssh_os.status == 0 + assert ( + expected_rhel_version in host_ssh_os.stdout + ), f'The installed OS version differs from the expected version {expected_rhel_version}' + + # Verify FIPS is enabled on host after provisioning is completed sucessfully + if int(host_os.major) >= 8: + result = provisioning_host.execute('fips-mode-setup --check') + fips_status = 'FIPS mode is disabled' if is_open('BZ:2240076') else 'FIPS mode is enabled' + assert fips_status in result.stdout + else: + result = provisioning_host.execute('cat /proc/sys/crypto/fips_enabled') + assert (0 if is_open('BZ:2240076') else 1) == int(result.stdout) + + # Run a command on the host using REX to verify that Satellite's SSH key is present on the host + template_id = ( + sat.api.JobTemplate().search(query={'search': 'name="Run Command - Script Default"'})[0].id + ) + job = sat.api.JobInvocation().run( + data={ + 'job_template_id': template_id, + 'inputs': { + 'command': f'subscription-manager config | grep "hostname = {sat.hostname}"' + }, + 'search_query': f"name = {host.name}", + 'targeting_type': 'static_query', + }, + ) + assert job['result'] == 'success', 'Job invocation failed' + + # assert that the host is subscribed and consumes + # subsctiption provided by the activation key + assert provisioning_host.subscribed, 'Host is not subscribed' diff --git a/tests/foreman/api/test_provisioningtemplate.py b/tests/foreman/api/test_provisioningtemplate.py index ac0567181c5..19c4ad981ae 100644 --- a/tests/foreman/api/test_provisioningtemplate.py +++ b/tests/foreman/api/test_provisioningtemplate.py @@ -561,3 +561,50 @@ def test_positive_template_check_aap_snippet( assert 'systemctl enable ansible-callback' in render assert f'"host_config_key":"{config_key}"' in render assert '{"package_install": "zsh"}' in render + + @pytest.mark.parametrize('module_sync_kickstart_content', [7, 8, 9], indirect=True) + def test_positive_template_check_fips_enabled( + self, + module_sync_kickstart_content, + module_target_sat, + module_sca_manifest_org, + module_location, + module_default_org_view, + module_lce_library, + default_architecture, + default_partitiontable, + ): + """Read provision/PXE templates, verify fips packages to install and kernel cmdline option + fips=1, set by kickstart_kernel_options snippet while using host param fips_enabled + is rendered correctly + + :id: 065ef48f-bec5-4535-8be7-d8527fa21565 + + :expectedresults: Rendered template should contain correct FIPS packages and boot parameter + set by snippet while using host param fips_enabled for rhel host + + :parametrized: yes + """ + host_params = [{'name': 'fips_enabled', 'value': 'true', 'parameter_type': 'boolean'}] + host = module_target_sat.api.Host( + organization=module_sca_manifest_org, + location=module_location, + name=gen_string('alpha').lower(), + operatingsystem=module_sync_kickstart_content.os, + architecture=default_architecture, + domain=module_sync_kickstart_content.domain, + root_pass=settings.provisioning.host_root_password, + ptable=default_partitiontable, + content_facet_attributes={ + 'content_source_id': module_target_sat.nailgun_smart_proxy.id, + 'content_view_id': module_default_org_view.id, + 'lifecycle_environment_id': module_lce_library.id, + }, + host_parameters_attributes=host_params, + ).create() + render = host.read_template(data={'template_kind': 'provision'})['template'] + assert 'dracut-fips' in render + assert '-prelink' in render + for kind in ['PXELinux', 'PXEGrub', 'PXEGrub2', 'iPXE', 'kexec']: + render = host.read_template(data={'template_kind': kind})['template'] + assert 'fips=1' in render