79 lines
2.5 KiB
Python
Executable File
79 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
from csv import reader
|
|
from pathlib import Path
|
|
from subprocess import run
|
|
from os import environ
|
|
from argparse import ArgumentParser
|
|
from sys import argv
|
|
|
|
hosts_file = "hosts.csv"
|
|
workdir = Path("./workdir")
|
|
|
|
def pull(id):
|
|
run(["scp", f"{id}:~/.ssh/authorized_keys" , str(workdir/Path(id))], check=True, capture_output=True)
|
|
print(id, "pulled.")
|
|
|
|
def push(id):
|
|
run(["scp", str(workdir/Path(id)), f"{id}:~/.ssh/authorized_keys"], check=True, capture_output=True)
|
|
print(id, "pushed.")
|
|
|
|
def compose(id):
|
|
authorized_set = set()
|
|
with open(workdir/Path(id)) as f:
|
|
for line in f:
|
|
authorized_set.add(line)
|
|
print("".join(authorized_set))
|
|
|
|
operations = { "push" : push,
|
|
"pull" : pull,
|
|
"compose" : compose}
|
|
|
|
def construct_predicate(id_list, group_list):
|
|
if "all" in (group_list+id_list):
|
|
return lambda id, groups: True
|
|
def predicate(id, groups):
|
|
return (id in id_list) or set(groups).intersection(group_list)
|
|
return predicate
|
|
|
|
def construct_predicate_for_pushing(id_list, group_list, own_keys):
|
|
def predicate(id, group):
|
|
with open(workdir/Path(id)) as keylist:
|
|
if any(key in own_keys for key in keylist):
|
|
return ("all" in (group_list+id_list) or
|
|
(id in id_list) or
|
|
set(groups).intersection(group_list))
|
|
print(f"None of the local public keys are in the keyfile for {id}")
|
|
return False
|
|
return predicate
|
|
|
|
def execute(operation, predicate):
|
|
with open(hosts_file) as csvfile:
|
|
for row in reader(csvfile, delimiter=","):
|
|
id, *groups = row
|
|
if predicate(id, groups):
|
|
operation(id)
|
|
|
|
parser = ArgumentParser()
|
|
parser.add_argument('-H', '--host', action='append')
|
|
parser.add_argument('-g', '--group', action='append')
|
|
parser.add_argument('-o', '--operation', choices=['pull', 'push', 'compose'])
|
|
args = parser.parse_args(argv[1:])
|
|
|
|
id_list = list() if args.host is None else args.host
|
|
group_list = list() if args.group is None else args.group
|
|
operation = operations[args.operation]
|
|
|
|
if(operation=="push"):
|
|
# collect local public keys
|
|
own_keys=list()
|
|
for keyfile in Path(environ["HOME"]+"/.ssh").glob("id_*.pub"):
|
|
with open(keyfile) as f:
|
|
own_keys.append(next(f))
|
|
pred = construct_predicate_for_pushing(id_list, group_list, own_keys)
|
|
else:
|
|
pred = construct_predicate(id_list, group_list)
|
|
|
|
execute(operation,pred)
|
|
|