Fix output format

This commit is contained in:
2026-05-29 10:54:37 +09:00
parent d9dcbbf0db
commit 1bc8e2cce0
2 changed files with 90 additions and 21 deletions
+1 -2
View File
@@ -58,7 +58,7 @@ prometheus-exporter
proxy
rdma
root
runit
# runit
salt
sambashare
saned
@@ -80,7 +80,6 @@ systemd-timesync
tape
tcpdump
tty
uallt_e
users
utempter
utmp
+89 -19
View File
@@ -1,13 +1,13 @@
#!/usr/bin/env python3
from __future__ import annotations
from typing import Any
import argparse
import json
from collections import Counter
from dataclasses import dataclass
from pathlib import Path
from typing import Any
def main():
@@ -78,13 +78,6 @@ def main():
for user in users.values():
user.email = f"{user.name}@{args.email_domain}"
if not args.output_dir.exists():
args.output_dir.mkdir(parents=True)
user_dir = args.output_dir / "users"
user_dir.mkdir(exist_ok=True)
group_dir = args.output_dir / "groups"
group_dir.mkdir(exist_ok=True)
# print_group_stats(groups, users)
for user in users.values():
@@ -94,12 +87,7 @@ def main():
if user.name in shadow:
user.set_shadow_entry(shadow[user.name])
with open(args.output_dir / "users" / f"{user.name}.json", "w") as f:
json.dump(user.to_systemd_user_record(), f, indent=2)
for group in groups.values():
with open(args.output_dir / "groups" / f"{group.name}.json", "w") as f:
json.dump(group.to_systemd_group_record(), f, indent=2)
output_to_directory(users, groups, args.output_dir)
def ensure_no_overlapping_uids(users: dict[str, User]):
@@ -327,13 +315,16 @@ class User:
if self.memberOf:
result["memberOf"] = self.memberOf
if self.password is not None:
result["privileged"] = {
"hashedPassword": self.password,
}
return result
def to_systemd_privileged_user_record(self) -> dict[str, Any] | None:
if self.password is None:
return None
return {
"hashedPassword": self.password,
}
@dataclass
class Group:
@@ -348,6 +339,10 @@ class Group:
"members": self.members,
}
# TODO: parse gshadow
def to_systemd_privileged_group_record(self) -> dict[str, Any] | None:
return None
def print_group_stats(
groups: dict[str, Group],
@@ -373,5 +368,80 @@ def print_group_stats(
)
def output_to_directory(
users: dict[str, User],
groups: dict[str, Group],
output_dir: Path,
):
if not output_dir.exists():
output_dir.mkdir(parents=True)
for user in users.values():
user_record = user.to_systemd_user_record()
with open(output_dir / f"{user.name}.user", "w") as f:
json.dump(user_record, f, indent=2)
symlink_path = output_dir / f"{user.uid}.user"
if symlink_path.exists():
symlink_path.unlink()
symlink_path.symlink_to(f"./{user.name}.user")
privileged_user_record = user.to_systemd_privileged_user_record()
if privileged_user_record:
priv_path = output_dir / f"{user.name}.user-privileged"
priv_path.touch(exist_ok=True)
priv_path.chmod(0o600)
with open(priv_path, "w") as f:
json.dump(privileged_user_record, f, indent=2)
symlink_path = output_dir / f"{user.uid}.user-privileged"
if symlink_path.exists():
symlink_path.unlink()
symlink_path.symlink_to(f"./{user.name}.user-privileged")
for group in groups.values():
group_record = group.to_systemd_group_record()
with open(output_dir / f"{group.name}.group", "w") as f:
json.dump(group_record, f, indent=2)
symlink_path = output_dir / f"{group.gid}.group"
if symlink_path.exists():
symlink_path.unlink()
symlink_path.symlink_to(f"./{group.name}.group")
privileged_group_record = group.to_systemd_privileged_group_record()
if privileged_group_record:
priv_path = output_dir / f"{group.name}.group-privileged"
priv_path.touch(exist_ok=True)
priv_path.chmod(0o600)
with open(priv_path, "w") as f:
json.dump(privileged_group_record, f, indent=2)
symlink_path = output_dir / f"{group.gid}.group-privileged"
if symlink_path.exists():
symlink_path.unlink()
symlink_path.symlink_to(f"./{group.name}.group-privileged")
groups_by_gid = {group.gid: group for group in groups.values()}
for user in users.values():
primary_group = groups_by_gid.get(user.gid)
if not primary_group:
print(
f"Warning: User {user.name} has primary GID {user.gid} which does not correspond to any group"
)
else:
with open(
output_dir / f"{user.name}:{primary_group.name}.membership", "w"
) as f:
json.dump({}, f)
for group in groups.values():
if user.name in group.members:
with open(
output_dir / f"{user.name}:{group.name}.membership", "w"
) as f:
json.dump({}, f)
if __name__ == "__main__":
main()