Last active
June 23, 2020 11:56
-
-
Save maxfischer2781/d806f17f66add5725d62602e773e6dda to your computer and use it in GitHub Desktop.
Create a gridmapdir from a groupmap file and accounts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
from typing import NamedTuple, Iterable, Dict, List | |
import argparse | |
import pathlib | |
import re | |
CLI = argparse.ArgumentParser() | |
CLI.add_argument( | |
"--gridmapfile", | |
help="path to gridmapfile", | |
default="/etc/grid-security/grid-mapfile", | |
type=pathlib.Path, | |
) | |
CLI.add_argument( | |
"--gridmapdir", | |
help="path to gridmapdir", | |
default="/etc/grid-security/gridmapdir/", | |
type=pathlib.Path, | |
) | |
CLI.add_argument( | |
"-n", | |
"--no-op", | |
help="only report actions, do not perform them", | |
action="store_true", | |
) | |
class Group(NamedTuple): | |
pattern: str | |
pool_name: str | |
def get_groups(gridmapfile: pathlib.Path) -> Iterable[Group]: | |
with gridmapfile.open() as groupmap: | |
for line in map(str.strip, groupmap): | |
if not line: | |
continue | |
pattern, basename = line.rsplit(None, 1) | |
if basename[0] == '.': | |
yield Group(pattern=pattern, pool_name=basename[1:]) | |
def get_accounts() -> Dict[str, List[str]]: | |
pool_pattern = re.compile(r"^(\w+?)(\d+)$") | |
pools: Dict[str, List[str]] = {} | |
with open("/etc/passwd") as passwd: | |
for line in map(str.strip, passwd): | |
if not line: | |
continue | |
name, *_ = line.split(":", 1) | |
try: | |
pool_name, number = pool_pattern.match(name).groups() | |
except AttributeError: | |
continue | |
else: | |
pools.setdefault(pool_name, []).append(name) | |
return {pool_name: sorted(names) for pool_name, names in pools.items()} | |
def create_accountmap(path: pathlib.Path): | |
try: | |
path.touch(exist_ok=False) | |
except FileExistsError: | |
return False | |
else: | |
return True | |
def create_accountmap_noop(path: pathlib.Path): | |
return not path.exists() | |
def ensure_gridmap(gridmapfile: pathlib.Path, gridmapdir: pathlib.Path, no_op=True): | |
groups = {group.pool_name for group in get_groups(gridmapfile)} | |
accounts = get_accounts() | |
ensure_account = create_accountmap_noop if no_op else create_accountmap | |
for group in groups: | |
created = existed = 0 | |
total = len(accounts.get(group, [])) | |
print("Ensuring", group, f"[{total}]") | |
for account in accounts.get(group, []): | |
path = gridmapdir / account | |
if ensure_account(path): | |
print("++ create:", path) | |
created += 1 | |
else: | |
print("== exists:", path, end="\r") | |
existed += 1 | |
print(f"=============================== [{created} / {total}] ====") | |
def main(): | |
options = CLI.parse_args() | |
ensure_gridmap( | |
gridmapfile=options.gridmapfile, | |
gridmapdir=options.gridmapdir, | |
no_op=options.no_op, | |
) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment