hswaw/machines/customs: check in code.hackerspace.pl/vuko/customs
Change-Id: Ic698cce2ef0060a54b195cf90574696b8be1eb0f
Reviewed-on: https://gerrit.hackerspace.pl/c/hscloud/+/1162
Reviewed-by: informatic <informatic@hackerspace.pl>
diff --git a/hswaw/machines/customs.hackerspace.pl/update_authorized_keys.py b/hswaw/machines/customs.hackerspace.pl/update_authorized_keys.py
new file mode 100755
index 0000000..2b336f2
--- /dev/null
+++ b/hswaw/machines/customs.hackerspace.pl/update_authorized_keys.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env nix-shell
+#!nix-shell -i python3 -p python3Packages.ldap3
+
+from ldap3 import Server, Connection, LEVEL
+from ldap3.utils.dn import escape_rdn
+import getpass
+import logging
+from pathlib import Path
+import filecmp
+import os
+
+import argparse
+
+parser = argparse.ArgumentParser()
+parser.add_argument("hostname", help="hostname")
+parser.add_argument("ldap_pass_file", type=Path, help="file containing lap password")
+
+header_warning = """
+################################### WARNING ####################################
+# This file was created automatically from LDAP database and *WILL* be
+# overwritten. If you need to add / remove keys make changes to
+# {}-admin group / members sshPublicKey attributes in LDAP and rerun
+# update_authorized_keys script
+################################################################################
+""".lstrip()
+
+def get_keys(connection: Connection, group: str):
+ c = connection
+
+ c.search(
+ search_base="ou=People,dc=hackerspace,dc=pl",
+ search_filter=(
+ "(&"
+ "(objectClass=hsMember)"
+ f"(memberOf=cn={escape_rdn(group)},ou=Group,dc=hackerspace,dc=pl)"
+ ")"
+ ),
+ search_scope=LEVEL,
+ attributes=["sshPublicKey"],
+ )
+
+ admin_keys = []
+ for entry in c.response:
+ attributes = entry["attributes"]
+ for key in entry["attributes"]["sshPublicKey"]:
+ yield key.strip()
+
+
+if __name__ == "__main__":
+ logging.basicConfig(level=logging.INFO)
+ args = parser.parse_args()
+
+ user = f"cn={escape_rdn(args.hostname)},ou=Boxen,dc=hackerspace,dc=pl"
+ password = args.ldap_pass_file.read_text().strip()
+
+ s = Server("ldap.hackerspace.pl", use_ssl=True)
+ with Connection(s, user=user, password=password, raise_exceptions=True) as c:
+ keys = list(get_keys(c, f"{args.hostname}-admin"))
+ if len(keys) < 2:
+ raise Exception("Less then two keys found - aborting")
+
+ ssh_dir = Path("/", "root", ".ssh")
+ ssh_dir.mkdir(mode=700, exist_ok=True)
+ ssh_dir.chmod(0o700)
+ new_file = ssh_dir.joinpath("authorized_keys_new")
+ old_file = ssh_dir.joinpath("authorized_keys")
+ try:
+ new_file.unlink()
+ except FileNotFoundError:
+ pass
+ new_file.write_bytes(
+ header_warning.format(args.hostname).encode() + b"\n".join(keys)
+ )
+ if not old_file.exists():
+ logging.info('Creating new "authorized_keys" file')
+ os.rename(new_file, old_file)
+ elif filecmp.cmp(new_file, old_file, shallow=False):
+ logging.info('Nothing changed - "authorized_keys" file is up to date')
+ new_file.unlink()
+ else:
+ logging.info('Keys changed - overwriting "authorized_keys" file')
+ os.rename(new_file, old_file)