Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Query all usernames and group names #711

Merged
merged 1 commit into from
Mar 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions test/test_modules.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,13 @@ def test_user(host):
assert user.password == "!"


def test_user_get_all_users(host):
user_list = host.user("root").get_all_users
assert "root" in user_list
assert "man" in user_list
assert "nobody" in user_list


def test_user_password_days(host):
assert host.user("root").password_max_days == 99999
assert host.user("root").password_min_days == 0
Expand Down Expand Up @@ -266,6 +273,12 @@ def test_current_user(host):
def test_group(host):
assert host.group("root").exists
assert host.group("root").gid == 0
group_list = host.group("root").get_all_groups
assert "root" in group_list
assert "bin" in group_list
group_list = host.group("root").get_local_groups
assert "root" in group_list
assert "bin" in group_list


def test_empty_command_output(host):
Expand Down
26 changes: 26 additions & 0 deletions testinfra/modules/group.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,32 @@ def exists(self):
"""
return self.run_expect([0, 2], "getent group %s", self.name).rc == 0

@property
def get_all_groups(self):
"""Returns a list of local and remote group names

>>> host.group("anyname").get_all_groups
["root", "wheel", "man", "tty", <...>]
"""
all_groups = [
line.split(":")[0]
for line in self.check_output("getent group").splitlines()
]
return all_groups

@property
def get_local_groups(self):
"""Returns a list of local group names

>>> host.group("anyname").get_local_groups
["root", "wheel", "man", "tty", <...>]
"""
local_groups = [
line.split(":")[0]
for line in self.check_output("cat /etc/group").splitlines()
]
return local_groups

@property
def gid(self):
return int(self.check_output("getent group %s | cut -d':' -f3", self.name))
Expand Down
28 changes: 28 additions & 0 deletions testinfra/modules/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,34 @@ def expiration_date(self):
epoch = datetime.datetime.utcfromtimestamp(0)
return epoch + datetime.timedelta(days=int(days))

@property
def get_all_users(self):
"""Returns a list of local and remote user names

>>> host.user().get_all_users
["root", "bin", "daemon", "lp", <...>]
"""
all_users = [
line.split(":")[0]
for line in self.check_output("getent passwd").splitlines()
Copy link
Contributor

@martinhoyer martinhoyer Jun 12, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we could use pwd?

import pwd
all_users = [pw.pw_name for pw in pwd.getpwall()]

(same with grp for groups)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, this is not possible because testinfra only executes Unix commands on the remote host.

]
return all_users

@property
def get_local_users(self):
"""Returns a list of local user names

>>> host.user().get_local_users
["root", "bin", "daemon", "lp", <...>]
"""
local_users = [
line.split(":")[0]
for line in self.check_output("cat /etc/passwd").splitlines()
]
# strip NIS compat mode entries
local_users = [i for i in local_users if not i.startswith("+")]
return local_users

@classmethod
def get_module_class(cls, host):
if host.system_info.type.endswith("bsd"):
Expand Down