summaryrefslogtreecommitdiff
path: root/tools/sops-inventory/sops_inventory/__main__.py
diff options
context:
space:
mode:
Diffstat (limited to 'tools/sops-inventory/sops_inventory/__main__.py')
-rw-r--r--tools/sops-inventory/sops_inventory/__main__.py34
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
10from operator import attrgetter, itemgetter 10from operator import attrgetter, itemgetter
11 11
12from itertools import chain
13
12from yaml import load, YAMLError 14from yaml import load, YAMLError
13try: 15try:
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
49def main(): 51def 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
88def 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
103if __name__ == '__main__': 107if __name__ == '__main__':
104 os.exit(main()) 108 os.exit(main())