From e73aec1409543e9e62abfab9dfaa2a14967f2035 Mon Sep 17 00:00:00 2001 From: Dalton Bohning Date: Wed, 8 Jan 2025 23:26:05 +0000 Subject: [PATCH] DAOS-15268 test: handle errors in add_del_user Replace security_test_base.py:add_del_user with calls to individual functions and handle errors. Test-tag: SecurityPoolACLTest SecurityPoolGroupsTest DaosContainerSecurityTest Skip-unit-tests: true Skip-fault-injection-test: true Signed-off-by: Dalton Bohning --- src/tests/ftest/security/cont_acl.py | 10 +---- src/tests/ftest/security/cont_acl.yaml | 4 +- .../ftest/util/pool_security_test_base.py | 28 +++++++----- src/tests/ftest/util/security_test_base.py | 21 +-------- src/tests/ftest/util/user_utils.py | 43 +++++++++++++++++++ utils/cq/words.dict | 2 + 6 files changed, 66 insertions(+), 42 deletions(-) diff --git a/src/tests/ftest/security/cont_acl.py b/src/tests/ftest/security/cont_acl.py index 74c4ae34124..7bb8783520c 100644 --- a/src/tests/ftest/security/cont_acl.py +++ b/src/tests/ftest/security/cont_acl.py @@ -1,12 +1,12 @@ """ (C) Copyright 2020-2024 Intel Corporation. + (C) Copyright 2025 Hewlett Packard Enterprise Development LP SPDX-License-Identifier: BSD-2-Clause-Patent """ import os import security_test_base as secTestBase -from agent_utils import include_local_host from cont_security_test_base import ContSecurityTestBase from pool_security_test_base import PoolSecurityTestBase @@ -74,10 +74,6 @@ def test_container_user_acl(self): "attribute", "/run/container_acl/*") property_name, property_value = self.params.get( "property", "/run/container_acl/*") - secTestBase.add_del_user( - include_local_host(self.hostlist_clients), "useradd", new_test_user) - secTestBase.add_del_user( - include_local_host(self.hostlist_clients), "groupadd", new_test_group) acl_file_name = self._get_acl_file_name() test_user = self.params.get( "testuser", "/run/container_acl/daos_user/*") @@ -204,7 +200,3 @@ def test_container_user_acl(self): # Restore pool permissions in case they were altered self.update_pool_acl_entry( "update", secTestBase.acl_entry("user", "OWNER", "rctd")) - secTestBase.add_del_user( - self.hostlist_clients, "userdel", new_test_user) - secTestBase.add_del_user( - self.hostlist_clients, "groupdel", new_test_group) diff --git a/src/tests/ftest/security/cont_acl.yaml b/src/tests/ftest/security/cont_acl.yaml index 799a0eddc6f..a767b32a63a 100644 --- a/src/tests/ftest/security/cont_acl.yaml +++ b/src/tests/ftest/security/cont_acl.yaml @@ -24,8 +24,8 @@ container: control_method: daos container_acl: acl_file_name: cont_test_acl1.txt - new_user: daos_ci_tester_1 - new_group: daos_ci_test_grp_1 + new_user: root + new_group: root attribute: - container_name - Container1 diff --git a/src/tests/ftest/util/pool_security_test_base.py b/src/tests/ftest/util/pool_security_test_base.py index ac7de7db866..383d315b96a 100644 --- a/src/tests/ftest/util/pool_security_test_base.py +++ b/src/tests/ftest/util/pool_security_test_base.py @@ -1,5 +1,6 @@ """ (C) Copyright 2020-2024 Intel Corporation. + (C) Copyright 2025 Hewlett Packard Enterprise Development LP SPDX-License-Identifier: BSD-2-Clause-Patent """ @@ -11,6 +12,7 @@ import agent_utils as agu import security_test_base as secTestBase from apricot import TestWithServers +from user_utils import groupadd, groupdel, useradd, userdel, usermod PERMISSIONS = ["", "r", "w", "rw"] DENY_ACCESS = "-1001" @@ -362,13 +364,14 @@ def create_pool_acl(self, num_user, num_group, current_user_acl, acl_file): for uid in range(num_user): username = user_prefix + "_tester_" + str(uid + 1) new_user = "A::" + username + "@:" + PERMISSIONS[uid % 4] - secTestBase.add_del_user(self.hostlist_clients, "useradd", username) + if not useradd(self.log, self.hostlist_clients, username, sudo=True).passed: + self.fail(f"Failed to useradd {username}") user_list.append(new_user) for gid in range(num_group): groupname = user_prefix + "_testGrp_" + str(gid + 1) new_group = "A:G:" + groupname + "@:" + PERMISSIONS[(gid + 2) % 4] - secTestBase.add_del_user(self.hostlist_clients, "groupadd", - groupname) + if not groupadd(self.log, self.hostlist_clients, groupname, sudo=True).passed: + self.fail(f"Failed to groupadd {groupname}") group_list.append(new_group) permission_list = group_list + user_list + current_user_acl random.shuffle(permission_list) @@ -386,11 +389,12 @@ def cleanup_user_group(self, num_user, num_group): user_prefix = self.params.get("user_prefix", "/run/pool_acl/*") for uid in range(num_user): username = user_prefix + "_tester_" + str(uid + 1) - secTestBase.add_del_user(self.hostlist_clients, "userdel", username) + if not userdel(self.log, self.hostlist_clients, username, sudo=True).passed: + self.log.error("Failed to userdel %s", username) for gid in range(num_group): groupname = user_prefix + "_testGrp_" + str(gid + 1) - secTestBase.add_del_user(self.hostlist_clients, "groupdel", - groupname) + if not groupdel(self.log, self.hostlist_clients, groupname, sudo=True).passed: + self.log.error("Failed to groupdel %s", groupname) def verify_pool_acl_prim_sec_groups(self, pool_acl_list, acl_file): """Verify daos pool acl access. @@ -417,10 +421,11 @@ def verify_pool_acl_prim_sec_groups(self, pool_acl_list, acl_file): "sg_read_write", "/run/pool_acl/primary_secondary_group_test/*") l_group = grp.getgrgid(os.getegid())[0] for group in sec_group: - secTestBase.add_del_user(self.hostlist_clients, "groupadd", group) - cmd = "usermod -G " + ",".join(sec_group) - self.log.info(" (8-1)verify_pool_acl_prim_sec_groups, cmd= %s", cmd) - secTestBase.add_del_user(self.hostlist_clients, cmd, l_group) + if not groupadd(self.log, self.hostlist_clients, group, sudo=True).passed: + self.fail(f"Failed to groupadd {group}") + self.log.info(" (8-1)verify_pool_acl_prim_sec_groups, cmd=usermod") + if not usermod(self.log, self.hostlist_clients, l_group, sec_group, sudo=True).passed: + self.fail(f"Failed to usermod {l_group}") self.log.info( " (8-2)Before update sec_group permission, pool_acl_list= %s", @@ -465,7 +470,8 @@ def verify_pool_acl_prim_sec_groups(self, pool_acl_list, acl_file): self.verify_pool_readwrite(self.pool, "write", expect=exp_write) for group in sec_group: - secTestBase.add_del_user(self.hostlist_clients, "groupdel", group) + if not groupdel(self.log, self.hostlist_clients, group, sudo=True).passed: + self.log.error("Failed to groupdel %s", group) def pool_acl_verification(self, current_user_acl, read, write, secondary_grp_test=False): diff --git a/src/tests/ftest/util/security_test_base.py b/src/tests/ftest/util/security_test_base.py index a0b83426777..64a3ef3cd59 100644 --- a/src/tests/ftest/util/security_test_base.py +++ b/src/tests/ftest/util/security_test_base.py @@ -1,5 +1,6 @@ """ (C) Copyright 2020-2023 Intel Corporation. + (C) Copyright 2025 Hewlett Packard Enterprise Development LP SPDX-License-Identifier: BSD-2-Clause-Patent """ @@ -7,8 +8,6 @@ import os import random -from general_utils import pcmd - class DaosTestError(Exception): """DAOS API exception class.""" @@ -71,24 +70,6 @@ def get_user_type(test_user): return user_type -def add_del_user(hosts, bash_cmd, user): - """Add or delete the daos user and group on host by sudo command. - - Args: - hosts (NodeSet): hosts on which to add/delete the user. - bash_cmd (str): Linux bash command to create user or group. - user (str): user or group name to be created or cleaned. - - """ - bash_cmd = os.path.join("/usr/sbin", bash_cmd) - homedir = "" - if "usermod" not in bash_cmd and "user" in bash_cmd: - homedir = "-r" - cmd = " ".join(("sudo", bash_cmd, homedir, user)) - print(" =Clients/hosts {0}, exec cmd: {1}".format(hosts, cmd)) - pcmd(hosts, cmd, False) - - def create_acl_file(file_name, permissions): """Create a acl_file with permissions. diff --git a/src/tests/ftest/util/user_utils.py b/src/tests/ftest/util/user_utils.py index ce5a58ed4f7..4350e231607 100644 --- a/src/tests/ftest/util/user_utils.py +++ b/src/tests/ftest/util/user_utils.py @@ -1,5 +1,6 @@ """ (C) Copyright 2018-2024 Intel Corporation. + (C) Copyright 2025 Hewlett Packard Enterprise Development LP SPDX-License-Identifier: BSD-2-Clause-Patent """ @@ -113,6 +114,27 @@ def groupadd(log, hosts, group, force=False, sudo=False): return run_remote(log, hosts, command) +def groupdel(log, hosts, group, force=False, sudo=False): + """Run groupdel remotely. + + Args: + log (logger): logger for the messages produced by this method + hosts (NodeSet): hosts on which to run the command + group (str): the group to delete + force (bool, optional): whether to use the force option. Default is False + sudo (bool, optional): whether to execute commands with sudo. Default is False + + Returns: + CommandResult: groups of command results from the same hosts with the same return status + """ + command = ' '.join(filter(None, [ + 'sudo -n' if sudo else None, + 'groupdel', + '-f' if force else None, + group])) + return run_remote(log, hosts, command) + + def useradd(log, hosts, user, group=None, parent_dir=None, sudo=False): """Run useradd remotely. @@ -158,6 +180,27 @@ def userdel(log, hosts, user, sudo=False): return run_remote(log, hosts, command) +def usermod(log, hosts, login, groups, sudo=False): + """Run usermod remotely. + + Args: + log (logger): logger for the messages produced by this method + hosts (NodeSet): hosts on which to run the command + login (str): login username + groups (list): list of new groups + sudo (bool): whether to execute commands with sudo. Default is False + + Returns: + CommandResult: groups of command results from the same hosts with the same return status + """ + command = ' '.join(filter(None, [ + 'sudo -n' if sudo else None, + 'usermod', + f'-G {",".join(groups)}', + login])) + return run_remote(log, hosts, command) + + def get_group_id(log, hosts, group, sudo=False): """Get a group's id on remote nodes. diff --git a/utils/cq/words.dict b/utils/cq/words.dict index 102ca21a882..cd882cf8848 100644 --- a/utils/cq/words.dict +++ b/utils/cq/words.dict @@ -204,6 +204,7 @@ getfattr getxattr gid groupadd +groupdel groupname grp hackery @@ -498,6 +499,7 @@ uri url useradd userdel +usermod username ushort usr