From c7756e8088e66c8b983f0bac45e14ff60042ac26 Mon Sep 17 00:00:00 2001 From: Benjamin Dauvergne Date: Fri, 21 May 2021 08:34:06 +0200 Subject: [PATCH] add script to analyze a2 ldap settings on all hosts --- a2-analyze-ldap-auth-settings/Makefile | 6 ++++ a2-analyze-ldap-auth-settings/README | 6 ++++ a2-analyze-ldap-auth-settings/analyze.py | 35 +++++++++++++++++++ a2-analyze-ldap-auth-settings/functions.py | 33 +++++++++++++++++ .../harvest-settings.py | 20 +++++++++++ .../print_ldap_auth_settings.py | 10 ++++++ 6 files changed, 110 insertions(+) create mode 100644 a2-analyze-ldap-auth-settings/Makefile create mode 100644 a2-analyze-ldap-auth-settings/README create mode 100644 a2-analyze-ldap-auth-settings/analyze.py create mode 100644 a2-analyze-ldap-auth-settings/functions.py create mode 100644 a2-analyze-ldap-auth-settings/harvest-settings.py create mode 100644 a2-analyze-ldap-auth-settings/print_ldap_auth_settings.py diff --git a/a2-analyze-ldap-auth-settings/Makefile b/a2-analyze-ldap-auth-settings/Makefile new file mode 100644 index 0000000..7c2c7ed --- /dev/null +++ b/a2-analyze-ldap-auth-settings/Makefile @@ -0,0 +1,6 @@ +SSH_CONFIG = ~/wd/eo/puppet/data/ssh_config/*.conf + +all: + cat $(SSH_CONFIG) >eo.conf + python3 harvest-settings.py + python3 analyze.py diff --git a/a2-analyze-ldap-auth-settings/README b/a2-analyze-ldap-auth-settings/README new file mode 100644 index 0000000..15ce632 --- /dev/null +++ b/a2-analyze-ldap-auth-settings/README @@ -0,0 +1,6 @@ +You need fabric to run the Makefile : + + apt install python3-fabric + + +the run `make`. diff --git a/a2-analyze-ldap-auth-settings/analyze.py b/a2-analyze-ldap-auth-settings/analyze.py new file mode 100644 index 0000000..0f4e40d --- /dev/null +++ b/a2-analyze-ldap-auth-settings/analyze.py @@ -0,0 +1,35 @@ +import collections +import json + +with open('tenants.json') as fd: + tenants = json.load(fd) + +key_counters = collections.Counter() +values = collections.defaultdict(set) + + +def immutable(d): + if isinstance(d, list): + return tuple(immutable(x) for x in d) + if isinstance(d, dict): + return tuple((k, immutable(v)) for k, v in d.items()) + return d + + +for tenant, ldap_settings in tenants.items(): + for block in ldap_settings: + url = block.get('url') + if not isinstance(url, list): + url = [url] + if any('entrouvert' in x for x in url) or any('libre-entr' in x for x in url): + continue + key_counters.update(collections.Counter(list(block))) + for key, value in block.items(): + if not hasattr(value, '__len__') or isinstance(value, str) and key not in ('url', 'bindpw', 'user_filter', 'basedn', 'binddn') or key == 'external_id_tuples': + values[key].add(immutable(value)) + + +for key, count in key_counters.most_common(len(key_counters)): + v = str(values.get(key) or '') + print(f'{key:30s} {count:>4d} {v:>30s}') + diff --git a/a2-analyze-ldap-auth-settings/functions.py b/a2-analyze-ldap-auth-settings/functions.py new file mode 100644 index 0000000..e9eb0f9 --- /dev/null +++ b/a2-analyze-ldap-auth-settings/functions.py @@ -0,0 +1,33 @@ +import json +import os +import traceback + + +def list_ldap_settings(c): + result = c.run('which authentic2-multitenant-manage', hide=True, warn=True) + if result.exited: + return {} + c.put('print_ldap_auth_settings.py', '/tmp/') + result = c.run( + 'authentic2-multitenant-manage tenant_command runscript --all-tenants /tmp/print_ldap_auth_settings.py', + hide=True, warn=True) + tenants = {} + if not result.exited and result.stdout.strip(): + for line in result.stdout.splitlines(): + try: + tenant, data = line.strip().split(' ', 1) + tenants[tenant] = json.loads(data) + except Exception: + traceback.print_exc() + c.run('rm /tmp/print_ldap_auth_settings.py') + return tenants + + +def run(host): + from fabric import Config, Connection + try: + config = Config(runtime_ssh_path='eo.conf') + return host, list_ldap_settings(Connection(host, config=config)) + except Exception: + traceback.print_exc() + return host, {} diff --git a/a2-analyze-ldap-auth-settings/harvest-settings.py b/a2-analyze-ldap-auth-settings/harvest-settings.py new file mode 100644 index 0000000..73ab5c1 --- /dev/null +++ b/a2-analyze-ldap-auth-settings/harvest-settings.py @@ -0,0 +1,20 @@ +import json +import multiprocessing +import subprocess + +import functions + + +hosts = [x.decode() for x in subprocess.check_output('eoptasks -k test,prod -l', shell=True).split()] + +tenants = {} + +pool = multiprocessing.Pool(8) + + +for host, partial_tenants in pool.imap_unordered(functions.run, hosts): + print('Host', host, 'finished, found', len(partial_tenants), 'tenants.') + tenants.update(partial_tenants) + +with open('tenants.json', 'w') as fd: + json.dump(tenants, fd, indent=2) diff --git a/a2-analyze-ldap-auth-settings/print_ldap_auth_settings.py b/a2-analyze-ldap-auth-settings/print_ldap_auth_settings.py new file mode 100644 index 0000000..56fe2c1 --- /dev/null +++ b/a2-analyze-ldap-auth-settings/print_ldap_auth_settings.py @@ -0,0 +1,10 @@ +import json + +from django.db import connection +from django.conf import settings + +auth_settings = getattr(settings, 'LDAP_AUTH_SETTINGS', None) + +if auth_settings: + print(connection.tenant.domain_url, end=' ') + print(json.dumps(auth_settings))