diff options
Diffstat (limited to 'tools/sops-inventory/sops_inventory')
-rw-r--r-- | tools/sops-inventory/sops_inventory/__main__.py | 34 |
1 files changed, 19 insertions, 15 deletions
diff --git a/tools/sops-inventory/sops_inventory/__main__.py b/tools/sops-inventory/sops_inventory/__main__.py index 2ee1b91d..3f694917 100644 --- a/tools/sops-inventory/sops_inventory/__main__.py +++ b/tools/sops-inventory/sops_inventory/__main__.py | |||
@@ -9,6 +9,8 @@ import subprocess | |||
9 | 9 | ||
10 | from operator import attrgetter, itemgetter | 10 | from operator import attrgetter, itemgetter |
11 | 11 | ||
12 | from itertools import chain | ||
13 | |||
12 | from yaml import load, YAMLError | 14 | from yaml import load, YAMLError |
13 | try: | 15 | try: |
14 | from yaml import CLoader as Loader | 16 | from yaml import CLoader as Loader |
@@ -46,16 +48,9 @@ class BooleanAction(argparse.Action): | |||
46 | setattr(namespace, self.dest, False if option_string.startswith('--no') else True) | 48 | setattr(namespace, self.dest, False if option_string.startswith('--no') else True) |
47 | 49 | ||
48 | 50 | ||
49 | def main(): | 51 | def sops_files(path): |
50 | parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) | 52 | with subprocess.Popen(['git', '-C', path, 'ls-files', '-z'], stdin=subprocess.DEVNULL, stdout=subprocess.PIPE) as proc: |
51 | parser.add_argument('--list-files', '--no-list-files', action=BooleanAction, default=False, help='Only list sops files') | 53 | files = sorted(map(lambda child: path / child.decode('utf-8').strip(), readnull(proc.stdout)), key=attrgetter('parts')) |
52 | parser.add_argument('path', metavar='PATH', nargs='?', type=Path, default=Path('.'), help='Base directory to take inventory of') | ||
53 | args = parser.parse_args() | ||
54 | |||
55 | inventory = defaultdict(list) | ||
56 | |||
57 | with subprocess.Popen(['git', '-C', args.path, 'ls-files', '-z'], stdin=subprocess.DEVNULL, stdout=subprocess.PIPE) as proc: | ||
58 | files = sorted(map(lambda child: args.path / child.decode('utf-8').strip(), readnull(proc.stdout)), key=attrgetter('parts')) | ||
59 | for child in files: | 54 | for child in files: |
60 | try: | 55 | try: |
61 | with child.open(mode='r') as fh: | 56 | with child.open(mode='r') as fh: |
@@ -82,7 +77,7 @@ def main(): | |||
82 | key_info.add(r['recipient']) | 77 | key_info.add(r['recipient']) |
83 | case _: | 78 | case _: |
84 | raise NotImplementedError | 79 | raise NotImplementedError |
85 | inventory[frozenset(key_info)].append(child.relative_to(args.path)) | 80 | yield (frozenset(key_info), child.relative_to(path)) |
86 | except (YAMLError, ValueError) as e: | 81 | except (YAMLError, ValueError) as e: |
87 | pass | 82 | pass |
88 | 83 | ||
@@ -90,15 +85,24 @@ def main(): | |||
90 | if proc.returncode != 0: | 85 | if proc.returncode != 0: |
91 | raise RuntimeError(f'git ls-files returned with {proc.returncode}') | 86 | raise RuntimeError(f'git ls-files returned with {proc.returncode}') |
92 | 87 | ||
88 | def main(): | ||
89 | parser = argparse.ArgumentParser(formatter_class=argparse.ArgumentDefaultsHelpFormatter) | ||
90 | parser.add_argument('--list-files', '--no-list-files', action=BooleanAction, default=False, help='Only list sops files') | ||
91 | parser.add_argument('path', metavar='PATH', nargs='?', type=Path, default=Path('.'), help='Base directory to take inventory of') | ||
92 | args = parser.parse_args() | ||
93 | |||
93 | if not args.list_files: | 94 | if not args.list_files: |
94 | for keys, files in sorted(inventory.items(), key=itemgetter(0)): | 95 | inventory = defaultdict(list) |
96 | for key_info, path in sops_files(args.path): | ||
97 | inventory[key_info].append(path) | ||
98 | |||
99 | for keys, files in sorted(inventory.items(), key=lambda kv: sorted(kv[0])): | ||
95 | print(', '.join(sorted(keys)) + ':') | 100 | print(', '.join(sorted(keys)) + ':') |
96 | for file in files: | 101 | for file in files: |
97 | print(' - ' + str(file)) | 102 | print(' - ' + str(file)) |
98 | else: | 103 | else: |
99 | for _, files in inventory.items(): | 104 | for _, file in sorted(sops_files(args.path), key=lambda kv: kv[1].parts): |
100 | for file in files: | 105 | print(file) |
101 | print(file) | ||
102 | 106 | ||
103 | if __name__ == '__main__': | 107 | if __name__ == '__main__': |
104 | os.exit(main()) | 108 | os.exit(main()) |