From 91f5443b01fbca4237f285f5b6d6d38a8a64e114 Mon Sep 17 00:00:00 2001 From: Peter Ondrejka Date: Wed, 2 Oct 2024 11:02:19 +0200 Subject: [PATCH] test rex using values from global parameters --- conftest.py | 1 + pytest_fixtures/component/global_params.py | 33 ++++ pytest_fixtures/component/settings.py | 23 +++ tests/foreman/cli/test_remoteexecution.py | 193 ++++++++++++++++++++- 4 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 pytest_fixtures/component/global_params.py diff --git a/conftest.py b/conftest.py index af150454d82..a4aa7d6e479 100644 --- a/conftest.py +++ b/conftest.py @@ -43,6 +43,7 @@ 'pytest_fixtures.component.contentview', 'pytest_fixtures.component.domain', 'pytest_fixtures.component.discovery', + 'pytest_fixtures.component.global_params', 'pytest_fixtures.component.host', 'pytest_fixtures.component.hostgroup', 'pytest_fixtures.component.http_proxy', diff --git a/pytest_fixtures/component/global_params.py b/pytest_fixtures/component/global_params.py new file mode 100644 index 00000000000..05900661c97 --- /dev/null +++ b/pytest_fixtures/component/global_params.py @@ -0,0 +1,33 @@ +# Settings Fixtures +import pytest + + +@pytest.fixture +def multi_global_param_update(request, target_sat): + """ + This fixture is used to alter multiple global parameters in one batch. + """ + key_vals = request.param + param_objects = [] + for key_val in key_vals: + param, new_value = tuple(key_val.split('=')) if '=' in key_val else (key_val, None) + existing_params = target_sat.api.CommonParameter().search(query={'search': f'name={param}'}) + if len(existing_params) > 0: + assert len(existing_params) == 1, 'Unexpected number of parameters returned' + param_object = existing_params[0] + cleanup = False + default_param_value = param_object.value + else: + param_object = target_sat.api.CommonParameter(name=param, value=new_value).create() + cleanup = True + default_param_value = new_value + param_objects.append( + {'object': param_object, 'default': default_param_value, 'cleanup': cleanup} + ) + yield [item['object'] for item in param_objects] + for item in param_objects: + if item['cleanup']: + item['object'].delete() + else: + item['object'].value = item['default'] + item['object'].update({'value'}) diff --git a/pytest_fixtures/component/settings.py b/pytest_fixtures/component/settings.py index b541e703733..79159254ef1 100644 --- a/pytest_fixtures/component/settings.py +++ b/pytest_fixtures/component/settings.py @@ -19,3 +19,26 @@ def setting_update(request, target_sat): yield setting_object setting_object.value = default_setting_value setting_object.update({'value'}) + + +@pytest.fixture +def multi_setting_update(request, target_sat): + """ + This fixture is used to alter multiple settings in one batch. + """ + key_vals = request.param + setting_objects = [] + for key_val in key_vals: + setting, new_value = tuple(key_val.split('=')) if '=' in key_val else (key_val, None) + setting_object = target_sat.api.Setting().search(query={'search': f'name={setting}'})[0] + default_setting_value = ( + '' if setting_object.value in [None, '*****'] else setting_object.value + ) + if new_value is not None: + setting_object.value = new_value + setting_object.update({'value'}) + setting_objects.append({'object': setting_object, 'original': default_setting_value}) + yield [item['object'] for item in setting_objects] + for item in setting_objects: + item['object'].value = item['original'] + item['object'].update({'value'}) diff --git a/tests/foreman/cli/test_remoteexecution.py b/tests/foreman/cli/test_remoteexecution.py index 1fac4a2f71d..6b125e67971 100644 --- a/tests/foreman/cli/test_remoteexecution.py +++ b/tests/foreman/cli/test_remoteexecution.py @@ -245,9 +245,9 @@ def test_positive_run_job_effective_user(self, rex_contenthost, module_target_sa """ client = rex_contenthost # create a user on client via remote job - ssh_username = gen_string('alpha') + ssh_username = f"sshuser_{gen_string('alpha')}" ssh_password = gen_string('alpha') - username = gen_string('alpha') + username = f"effuser_{gen_string('alpha')}" password = gen_string('cjk') filename = gen_string('alpha') make_user_job = module_target_sat.cli_factory.job_invocation( @@ -258,8 +258,8 @@ def test_positive_run_job_effective_user(self, rex_contenthost, module_target_sa 'description-format': 'adding users', } ) - client.execute('echo "Defaults targetpw" >> /etc/sudoers') assert_job_invocation_result(module_target_sat, make_user_job['id'], client.hostname) + client.execute('echo "Defaults targetpw" >> /etc/sudoers') # create a file as new user invocation_command = module_target_sat.cli_factory.job_invocation( { @@ -329,6 +329,193 @@ def test_positive_run_job_effective_user(self, rex_contenthost, module_target_sa ) assert 'Permission denied' in out + @pytest.mark.tier3 + @pytest.mark.parametrize( + 'multi_global_param_update', + [ + [ + 'remote_execution_ssh_user', + 'remote_execution_effective_user_method', + ], + ], + ids=["global-param-sudo"], + indirect=True, + ) + @pytest.mark.rhel_ver_list([9]) + def test_positive_run_job_ssh_user_from_global_param( + self, + rex_contenthost, + module_target_sat, + multi_global_param_update, + module_org, + module_ak_with_cv, + ): + """Run default job template with global ssh user, effective user and sudo + + :id: 0adaf5a2-930a-4050-863b-62456234ce8c + + :verifies: SAT-28443 + + :steps: + 1. set global parameters for rex + 2. re-register the client to check that sudo setup was performed based on parameters + 3. run rex to see that sudo was configured correctly + + :expectedresults: Verify global paremeters are used to set up rex during registration + + :parametrized: yes + """ + client = rex_contenthost + + # configure global settings + ssh_username = f"sshuser_{gen_string('alpha')}" + ssh_password = gen_string('alpha') + username = f"effuser_{gen_string('alpha')}" + password = gen_string('alpha') + filename = gen_string('alpha') + multi_global_param_update[0].value = ssh_username + multi_global_param_update[1].value = 'sudo' + for param in multi_global_param_update: + param.update({'value'}) + + # add users to the host + make_user_job = module_target_sat.cli_factory.job_invocation( + { + 'job-template': 'Run Command - Script Default', + 'inputs': f"command=useradd {ssh_username}; echo {ssh_username}:{ssh_password} | chpasswd; useradd {username}; echo {username}:{password} | chpasswd", + 'search-query': f"name ~ {client.hostname}", + 'effective-user': 'root', + 'ssh-user': 'root', + 'description-format': 'adding users', + } + ) + assert_job_invocation_result(module_target_sat, make_user_job['id'], client.hostname) + + # re-register host to run the remote_execution_ssh_keys snippet with new defaults + client.register(module_org, None, module_ak_with_cv.name, module_target_sat, force=True) + + # check the sudoers.d entry was created by the snippet + result = client.execute(f'''stat -c "%a %n" /etc/sudoers.d/{ssh_username}''') + assert '440' in result.stdout + + client.execute('echo "Defaults targetpw" >> /etc/sudoers') + + # create a file as new user + invocation_command = module_target_sat.cli_factory.job_invocation( + { + 'job-template': 'Run Command - Script Default', + 'inputs': f"command=touch /home/{username}/{filename}", + 'search-query': f"name ~ {client.hostname}", + 'ssh-user': f'{ssh_username}', + 'password': f'{ssh_password}', + 'effective-user': f'{username}', + 'effective-user-password': f'{password}', + } + ) + assert_job_invocation_result(module_target_sat, invocation_command['id'], client.hostname) + # check the file owner + result = client.execute( + f'''stat -c '%U' /home/{username}/{filename}''', + ) + # assert the file is owned by the effective user + assert username == result.stdout.strip('\n') + result = client.execute( + f'''stat -c '%G' /home/{username}/{filename}''', + ) + + @pytest.mark.tier3 + @pytest.mark.parametrize( + 'multi_setting_update', + [ + [ + 'remote_execution_effective_user', + 'remote_execution_effective_user_password', + 'remote_execution_effective_user_method', + 'remote_execution_ssh_user', + 'remote_execution_ssh_password', + ], + ], + ids=["settings"], + indirect=True, + ) + @pytest.mark.rhel_ver_list([9]) + def test_positive_run_job_effective_user_from_settings( + self, + rex_contenthost, + module_target_sat, + multi_setting_update, + module_org, + module_ak_with_cv, + ): + """Run default job template with ssh user, effective user and method defined in settings + + :id: 689e20c3-558a-47dc-a4dc-c067d1fb33fe + + :expectedresults: Verify the job uses default values from settings + + :BlockedBy: SAT-30443 + + :steps: + 1. set global settings + 2. create users on a client via rex overriding the global setinggs + 3. run another rex checking that global settings are used + + :parametrized: yes + """ + client = rex_contenthost + + # configure global settings + ssh_username = f"sshuser_{gen_string('alpha')}" + ssh_password = gen_string('alpha') + username = f"effuser_{gen_string('alpha')}" + password = gen_string('alpha') + filename = gen_string('alpha') + multi_setting_update[0].value = username + multi_setting_update[1].value = password + multi_setting_update[2].value = 'sudo' + multi_setting_update[3].value = ssh_username + multi_setting_update[4].value = ssh_password + for param in multi_setting_update: + param.update({'value'}) + + # add users to the host + make_user_job = module_target_sat.cli_factory.job_invocation( + { + 'job-template': 'Run Command - Script Default', + 'inputs': f"command=useradd {ssh_username} -G wheel; echo {ssh_username}:{ssh_password} | chpasswd; useradd {username}; echo {username}:{password} | chpasswd", + 'search-query': f"name ~ {client.hostname}", + 'effective-user': 'root', + 'ssh-user': 'root', + 'description-format': 'adding users', + 'password': '', + 'effective-user-password': '', + } + ) + assert_job_invocation_result(module_target_sat, make_user_job['id'], client.hostname) + client.execute('echo "Defaults targetpw" >> /etc/sudoers') + + # create a file using global ssh-user and effective-user settings + invocation_command = module_target_sat.cli_factory.job_invocation( + { + 'job-template': 'Run Command - Script Default', + 'inputs': f"command=touch /home/{username}/{filename}", + 'search-query': f"name ~ {client.hostname}", + } + ) + assert_job_invocation_result(module_target_sat, invocation_command['id'], client.hostname) + + # check the file owner + result = client.execute( + f'''stat -c '%U' /home/{username}/{filename}''', + ) + # assert the file is owned by the effective user + assert username == result.stdout.strip('\n') + result = client.execute( + f'''stat -c '%G' /home/{username}/{filename}''', + ) + # assert the file is in the effective user's group + assert username == result.stdout.strip('\n') + @pytest.mark.tier3 @pytest.mark.e2e @pytest.mark.rhel_ver_match('[^6].*')