From d9ca093155a002ec968ce16dd8bd96637723f7b6 Mon Sep 17 00:00:00 2001 From: Snarf Date: Fri, 6 Nov 2026 09:03:28 -0500 Subject: [PATCH] feat: add automation scripts for checking and managing remote DNS and SSO services --- scripts/check_aero_pihole_auth.py | 1 + scripts/check_api_status.py | 1 + scripts/check_apiurl.py | 1 + scripts/check_app_dll.py | 1 + scripts/check_divloginsso.py | 1 + scripts/check_etc_dns.py | 1 + scripts/check_ftl_config.py | 1 + scripts/check_login_js_lines.py | 1 + scripts/check_login_js_lines2.py | 1 + scripts/check_mainjs.py | 1 + scripts/check_opt_pihole.py | 1 + scripts/check_pihole_ftl.py | 1 + scripts/check_pihole_login_js.py | 1 + scripts/check_pihole_password_details.py | 1 + scripts/check_pihole_pw_func.py | 1 + scripts/check_pihole_script.py | 1 + scripts/check_pihole_toml.py | 1 + scripts/check_setwebpassword.py | 1 + scripts/check_sso_err.py | 1 + scripts/check_sso_frontend.py | 1 + scripts/check_technitium_config.py | 1 + scripts/check_technitium_dotnet.py | 1 + scripts/check_technitium_logs.py | 1 + scripts/check_technitium_logs2.py | 1 + scripts/check_technitium_logs3.py | 1 + scripts/check_utils.py | 1 + scripts/configure_spaceport_technitium.py | 1 + scripts/inspect_login_html.py | 1 + scripts/read_today_log.py | 1 + scripts/restart_and_test_technitium.py | 1 + scripts/restart_and_verify_sso.py | 1 + scripts/test_authentik_reachability.py | 1 + scripts/test_pihole_web_login.py | 1 + scripts/test_sso_after_restart.py | 1 + scripts/test_sso_and_ftl.py | 1 + scripts/test_sso_authority.py | 1 + scripts/test_sso_forwarded.py | 1 + scripts/test_sso_get.py | 1 + scripts/test_technitium_auth_status.py | 1 + scripts/test_technitium_sso_set.py | 1 + scripts/test_totp_null.py | 1 + scripts/update_pihole_launch_urls.py | 53 +++++++++++++++++++++++ 42 files changed, 94 insertions(+) create mode 100644 scripts/update_pihole_launch_urls.py diff --git a/scripts/check_aero_pihole_auth.py b/scripts/check_aero_pihole_auth.py index 929a3d9..a5b8928 100644 --- a/scripts/check_aero_pihole_auth.py +++ b/scripts/check_aero_pihole_auth.py @@ -9,3 +9,4 @@ print("Aerodrome API auth test:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_api_status.py b/scripts/check_api_status.py index 93e73c0..70ef622 100644 --- a/scripts/check_api_status.py +++ b/scripts/check_api_status.py @@ -9,3 +9,4 @@ print("api/status response:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_apiurl.py b/scripts/check_apiurl.py index 66fd135..610cbdb 100644 --- a/scripts/check_apiurl.py +++ b/scripts/check_apiurl.py @@ -9,3 +9,4 @@ print("data-apiurl:") print(stdout.read().decode()) ssh.close() + diff --git a/scripts/check_app_dll.py b/scripts/check_app_dll.py index ef76b4b..980e384 100644 --- a/scripts/check_app_dll.py +++ b/scripts/check_app_dll.py @@ -14,3 +14,4 @@ print("AddAuthentication strings:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_divloginsso.py b/scripts/check_divloginsso.py index 1b70d80..d4d6d04 100644 --- a/scripts/check_divloginsso.py +++ b/scripts/check_divloginsso.py @@ -9,3 +9,4 @@ print("grep divLoginSso:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_etc_dns.py b/scripts/check_etc_dns.py index 1aa6d88..b1d979a 100644 --- a/scripts/check_etc_dns.py +++ b/scripts/check_etc_dns.py @@ -9,3 +9,4 @@ print("/etc/dns listing:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_ftl_config.py b/scripts/check_ftl_config.py index 5a205a6..e731449 100644 --- a/scripts/check_ftl_config.py +++ b/scripts/check_ftl_config.py @@ -14,3 +14,4 @@ print("pihole-FTL --config:") print(stdout.read().decode('utf-8', errors='ignore')[:1500]) ssh.close() + diff --git a/scripts/check_login_js_lines.py b/scripts/check_login_js_lines.py index e6fb60c..ca65f9a 100644 --- a/scripts/check_login_js_lines.py +++ b/scripts/check_login_js_lines.py @@ -9,3 +9,4 @@ print("login.js lines 20-60:") print(stdout.read().decode()) ssh.close() + diff --git a/scripts/check_login_js_lines2.py b/scripts/check_login_js_lines2.py index 9babcd3..974a57e 100644 --- a/scripts/check_login_js_lines2.py +++ b/scripts/check_login_js_lines2.py @@ -9,3 +9,4 @@ print("login.js lines 60-110:") print(stdout.read().decode()) ssh.close() + diff --git a/scripts/check_mainjs.py b/scripts/check_mainjs.py index a25ea32..16d2be9 100644 --- a/scripts/check_mainjs.py +++ b/scripts/check_mainjs.py @@ -9,3 +9,4 @@ print("main.js lines 40-65:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_opt_pihole.py b/scripts/check_opt_pihole.py index a846078..2b354da 100644 --- a/scripts/check_opt_pihole.py +++ b/scripts/check_opt_pihole.py @@ -18,3 +18,4 @@ print("ls /opt/pihole/:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_pihole_ftl.py b/scripts/check_pihole_ftl.py index d197c78..c2934cc 100644 --- a/scripts/check_pihole_ftl.py +++ b/scripts/check_pihole_ftl.py @@ -10,3 +10,4 @@ print("pihole-FTL --help:") print(stdout.read().decode('utf-8', errors='ignore')[:1000]) ssh.close() + diff --git a/scripts/check_pihole_login_js.py b/scripts/check_pihole_login_js.py index 57c5595..35453b3 100644 --- a/scripts/check_pihole_login_js.py +++ b/scripts/check_pihole_login_js.py @@ -14,3 +14,4 @@ print("login.js locations:") print(stdout.read().decode()) ssh.close() + diff --git a/scripts/check_pihole_password_details.py b/scripts/check_pihole_password_details.py index 7dfd92f..2b52f3c 100644 --- a/scripts/check_pihole_password_details.py +++ b/scripts/check_pihole_password_details.py @@ -16,3 +16,4 @@ print("pihole-FTL help:") print(stdout.read().decode('utf-8', errors='ignore')[:1500]) ssh.close() + diff --git a/scripts/check_pihole_pw_func.py b/scripts/check_pihole_pw_func.py index cfca68c..e4b842d 100644 --- a/scripts/check_pihole_pw_func.py +++ b/scripts/check_pihole_pw_func.py @@ -9,3 +9,4 @@ print("pihole script lines 200-280:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_pihole_script.py b/scripts/check_pihole_script.py index 5af57c8..20ee016 100644 --- a/scripts/check_pihole_script.py +++ b/scripts/check_pihole_script.py @@ -14,3 +14,4 @@ print("Entrypoint check:") print(stdout.read().decode('utf-8', errors='ignore')[:1500]) ssh.close() + diff --git a/scripts/check_pihole_toml.py b/scripts/check_pihole_toml.py index ae6e014..75b5059 100644 --- a/scripts/check_pihole_toml.py +++ b/scripts/check_pihole_toml.py @@ -23,3 +23,4 @@ def check_pihole_toml(host, name): check_pihole_toml('140.44.4.11', 'Aerodrome') check_pihole_toml('140.44.4.41', 'Spaceport') + diff --git a/scripts/check_setwebpassword.py b/scripts/check_setwebpassword.py index 5ef9a6f..4c3043b 100644 --- a/scripts/check_setwebpassword.py +++ b/scripts/check_setwebpassword.py @@ -9,3 +9,4 @@ print("SetWebPassword implementation:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_sso_err.py b/scripts/check_sso_err.py index 26dcde1..61f67b9 100644 --- a/scripts/check_sso_err.py +++ b/scripts/check_sso_err.py @@ -9,3 +9,4 @@ print("Recent logs:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_sso_frontend.py b/scripts/check_sso_frontend.py index 701b96a..6f0900d 100644 --- a/scripts/check_sso_frontend.py +++ b/scripts/check_sso_frontend.py @@ -15,3 +15,4 @@ print("divLoginSso in app:") print(stdout.read().decode('utf-8', errors='ignore')[:1500]) ssh.close() + diff --git a/scripts/check_technitium_config.py b/scripts/check_technitium_config.py index bc69091..987a980 100644 --- a/scripts/check_technitium_config.py +++ b/scripts/check_technitium_config.py @@ -14,3 +14,4 @@ print("auth.config raw:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_technitium_dotnet.py b/scripts/check_technitium_dotnet.py index 08cf071..e30b1dd 100644 --- a/scripts/check_technitium_dotnet.py +++ b/scripts/check_technitium_dotnet.py @@ -14,3 +14,4 @@ print("AddOpenIdConnect:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_technitium_logs.py b/scripts/check_technitium_logs.py index 6bc425d..5fd5bd5 100644 --- a/scripts/check_technitium_logs.py +++ b/scripts/check_technitium_logs.py @@ -14,3 +14,4 @@ print("/etc/dns/logs:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/check_technitium_logs2.py b/scripts/check_technitium_logs2.py index f6647c6..8697ed2 100644 --- a/scripts/check_technitium_logs2.py +++ b/scripts/check_technitium_logs2.py @@ -13,3 +13,4 @@ print("logs:") print(stdout.read().decode('utf-8', errors='ignore')[:2000]) ssh.close() + diff --git a/scripts/check_technitium_logs3.py b/scripts/check_technitium_logs3.py index 412a4a7..3e1ac2d 100644 --- a/scripts/check_technitium_logs3.py +++ b/scripts/check_technitium_logs3.py @@ -14,3 +14,4 @@ print("files:") print(stdout.read().decode('utf-8', errors='ignore')[:2000]) ssh.close() + diff --git a/scripts/check_utils.py b/scripts/check_utils.py index 430f249..437c6c6 100644 --- a/scripts/check_utils.py +++ b/scripts/check_utils.py @@ -9,3 +9,4 @@ print("utils.sh lines 130-175:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/configure_spaceport_technitium.py b/scripts/configure_spaceport_technitium.py index 8b9c06b..56b5a7a 100644 --- a/scripts/configure_spaceport_technitium.py +++ b/scripts/configure_spaceport_technitium.py @@ -48,3 +48,4 @@ def configure_spaceport_technitium(): ssh.close() configure_spaceport_technitium() + diff --git a/scripts/inspect_login_html.py b/scripts/inspect_login_html.py index ce562e2..734051b 100644 --- a/scripts/inspect_login_html.py +++ b/scripts/inspect_login_html.py @@ -15,3 +15,4 @@ for i, line in enumerate(lines): for j in range(start, end): print(f"{j:4}: {lines[j]}") print() + diff --git a/scripts/read_today_log.py b/scripts/read_today_log.py index 4cc95c4..fb7e882 100644 --- a/scripts/read_today_log.py +++ b/scripts/read_today_log.py @@ -9,3 +9,4 @@ print("2026-11-06.log:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/restart_and_test_technitium.py b/scripts/restart_and_test_technitium.py index c3029d1..c01525e 100644 --- a/scripts/restart_and_test_technitium.py +++ b/scripts/restart_and_test_technitium.py @@ -27,3 +27,4 @@ print("Recent logs:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/restart_and_verify_sso.py b/scripts/restart_and_verify_sso.py index 604c5aa..3cf1b45 100644 --- a/scripts/restart_and_verify_sso.py +++ b/scripts/restart_and_verify_sso.py @@ -25,3 +25,4 @@ print("Recent logs:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/test_authentik_reachability.py b/scripts/test_authentik_reachability.py index 1fc1b23..e10c536 100644 --- a/scripts/test_authentik_reachability.py +++ b/scripts/test_authentik_reachability.py @@ -16,3 +16,4 @@ print("/etc/resolv.conf inside technitium pod:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/test_pihole_web_login.py b/scripts/test_pihole_web_login.py index bae7644..36e30b4 100644 --- a/scripts/test_pihole_web_login.py +++ b/scripts/test_pihole_web_login.py @@ -19,3 +19,4 @@ print("FTL.log:") print(stdout.read().decode()) ssh.close() + diff --git a/scripts/test_sso_after_restart.py b/scripts/test_sso_after_restart.py index 573f0f7..edff7d3 100644 --- a/scripts/test_sso_after_restart.py +++ b/scripts/test_sso_after_restart.py @@ -15,3 +15,4 @@ print("divLoginSso in index.html:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/test_sso_and_ftl.py b/scripts/test_sso_and_ftl.py index c137f53..65faed3 100644 --- a/scripts/test_sso_and_ftl.py +++ b/scripts/test_sso_and_ftl.py @@ -22,3 +22,4 @@ print("Technitium SSO get after set:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/test_sso_authority.py b/scripts/test_sso_authority.py index 0c74bb0..05d9471 100644 --- a/scripts/test_sso_authority.py +++ b/scripts/test_sso_authority.py @@ -37,3 +37,4 @@ stdin, stdout, stderr = ssh.exec_command(f'k3s kubectl exec -n dns deployment/te print("SSO get after set:", stdout.read().decode()) ssh.close() + diff --git a/scripts/test_sso_forwarded.py b/scripts/test_sso_forwarded.py index 5eaeed8..7c2fc82 100644 --- a/scripts/test_sso_forwarded.py +++ b/scripts/test_sso_forwarded.py @@ -14,3 +14,4 @@ print("divLoginSso check:") print(stdout.read().decode('utf-8', errors='ignore')) ssh.close() + diff --git a/scripts/test_sso_get.py b/scripts/test_sso_get.py index 6f80b37..ad1f4ba 100644 --- a/scripts/test_sso_get.py +++ b/scripts/test_sso_get.py @@ -11,3 +11,4 @@ print(stderr.read().decode('utf-8', errors='ignore')) print(stdout.read().decode('utf-8', errors='ignore')[:1000]) ssh.close() + diff --git a/scripts/test_technitium_auth_status.py b/scripts/test_technitium_auth_status.py index a41b4e3..45d549d 100644 --- a/scripts/test_technitium_auth_status.py +++ b/scripts/test_technitium_auth_status.py @@ -16,3 +16,4 @@ for host, label in [('140.44.4.36', 'Aerodrome (dns1)'), ('140.44.4.65', 'Spacep print(f" pass={pwd}: status={data.get('status')}, msg={data.get('errorMessage')}, token={tok_str}") except Exception as e: print(f" pass={pwd}: error={e}") + diff --git a/scripts/test_technitium_sso_set.py b/scripts/test_technitium_sso_set.py index efd038a..531982a 100644 --- a/scripts/test_technitium_sso_set.py +++ b/scripts/test_technitium_sso_set.py @@ -36,3 +36,4 @@ stdin, stdout, stderr = ssh.exec_command(f'k3s kubectl exec -n dns deployment/te print("SSO get after set:", stdout.read().decode()) ssh.close() + diff --git a/scripts/test_totp_null.py b/scripts/test_totp_null.py index 20506bb..91bebf2 100644 --- a/scripts/test_totp_null.py +++ b/scripts/test_totp_null.py @@ -9,3 +9,4 @@ print("Auth with totp null:") print(stdout.read().decode()) ssh.close() + diff --git a/scripts/update_pihole_launch_urls.py b/scripts/update_pihole_launch_urls.py new file mode 100644 index 0000000..9b01d26 --- /dev/null +++ b/scripts/update_pihole_launch_urls.py @@ -0,0 +1,53 @@ +import urllib.request +import ssl +import json +import sys + +sys.stdout.reconfigure(encoding='utf-8') + +ctx = ssl.create_default_context() +ctx.check_hostname = False +ctx.verify_mode = ssl.CERT_NONE + +token = "SnarfNetPermanentAutomationToken2026" +headers = { + "Authorization": f"Bearer {token}", + "Content-Type": "application/json" +} + +def api_call(url, method="GET", payload=None): + data = json.dumps(payload).encode('utf-8') if payload else None + req = urllib.request.Request(url, headers=headers, data=data, method=method) + try: + with urllib.request.urlopen(req, context=ctx, timeout=8) as resp: + return json.loads(resp.read().decode('utf-8')) + except urllib.error.HTTPError as e: + err = e.read().decode('utf-8') + print(f"API Error {e.code} on {method} {url}: {err}") + return None + +print("Updating Pi-hole launch URLs in Authentik App Library...") + +apps_update = [ + { + "slug": "pihole1", + "meta_launch_url": "https://pihole1.snarfnet.net/admin/" + }, + { + "slug": "pihole2", + "meta_launch_url": "https://pihole2.snarfnet.net/admin/" + } +] + +for app in apps_update: + slug = app['slug'] + res = api_call(f"https://authentik.snarfnet.net/api/v3/core/applications/{slug}/", method="PATCH", payload=app) + if res: + print(f" ✓ Updated {slug} meta_launch_url to {res.get('meta_launch_url')}") + +print("\nVerifying final state in Authentik:") +final_apps = api_call("https://authentik.snarfnet.net/api/v3/core/applications/?page_size=100") +for a in sorted(final_apps.get('results', []), key=lambda x: x['name']): + if a['slug'] in ['pihole1', 'pihole2', 'dns1', 'dns2']: + print(f" [{a['group']}] {a['name']}") + print(f" Slug: {a['slug']} | Launch URL: {a['meta_launch_url']}")