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" } # 1. Update Provider 12 (Pi-hole 2) p12_payload = { "name": "Pi-hole 2 (Spaceport)", "authorization_flow": "38a86ef3-f43a-4756-8f54-ca008a8eef6e", "mode": "forward_single", "external_host": "https://pihole2.snarfnet.net" } req = urllib.request.Request("https://authentik.snarfnet.net/api/v3/providers/proxy/12/", headers=headers, data=json.dumps(p12_payload).encode('utf-8'), method="PATCH") with urllib.request.urlopen(req, context=ctx, timeout=8) as resp: print("Updated Provider 12 (Pi-hole 2) successfully!") # 2. Check if Pi-hole 1 provider exists, if not create it req_search = urllib.request.Request("https://authentik.snarfnet.net/api/v3/providers/proxy/?search=Pi-hole+1", headers=headers) with urllib.request.urlopen(req_search, context=ctx, timeout=8) as resp: res = json.loads(resp.read().decode('utf-8')) if res.get('results'): p1_pk = res['results'][0]['pk'] print(f"Pi-hole 1 Provider already exists: PK {p1_pk}") else: p1_payload = { "name": "Pi-hole 1 (Aerodrome)", "authorization_flow": "38a86ef3-f43a-4756-8f54-ca008a8eef6e", "invalidation_flow": "7a8145b8-2476-4636-9901-825f826df805", "mode": "forward_single", "external_host": "https://pihole1.snarfnet.net" } req_create = urllib.request.Request("https://authentik.snarfnet.net/api/v3/providers/proxy/", headers=headers, data=json.dumps(p1_payload).encode('utf-8'), method="POST") try: with urllib.request.urlopen(req_create, context=ctx, timeout=8) as resp_c: p1_pk = json.loads(resp_c.read().decode('utf-8'))['pk'] print(f"Created Pi-hole 1 Provider: PK {p1_pk}") except urllib.error.HTTPError as e: print("Create error:", e.code, e.read().decode('utf-8')) sys.exit(1) # 3. Add p1_pk to Embedded Outpost providers req_outpost = urllib.request.Request("https://authentik.snarfnet.net/api/v3/outposts/instances/e68edb7b-4996-438d-9747-e1591b173a66/", headers=headers) with urllib.request.urlopen(req_outpost, context=ctx, timeout=8) as resp: outpost = json.loads(resp.read().decode('utf-8')) current_providers = outpost.get('providers', []) print("Current Outpost providers:", current_providers) if p1_pk not in current_providers: current_providers.append(p1_pk) patch_outpost = urllib.request.Request( "https://authentik.snarfnet.net/api/v3/outposts/instances/e68edb7b-4996-438d-9747-e1591b173a66/", headers=headers, data=json.dumps({"providers": current_providers}).encode('utf-8'), method="PATCH" ) with urllib.request.urlopen(patch_outpost, context=ctx, timeout=8) as resp_p: print("Outpost updated with new provider!") else: print("Provider already in outpost.") # 4. Check/Create Application for Pi-hole 1 req_app_search = urllib.request.Request("https://authentik.snarfnet.net/api/v3/core/applications/?search=Pi-hole+1", headers=headers) with urllib.request.urlopen(req_app_search, context=ctx, timeout=8) as resp: res_app = json.loads(resp.read().decode('utf-8')) if not res_app.get('results'): app_payload = { "name": "Pi-hole 1 (Aerodrome)", "slug": "pihole1", "provider": p1_pk, "group": "Infrastructure & Hypervisors", "meta_launch_url": "https://pihole1.snarfnet.net", "meta_description": "Network-wide Ad and Tracker Blocking (Aerodrome Cluster)", "meta_icon": "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/pi-hole.png", "open_in_new_tab": True } req_app_c = urllib.request.Request("https://authentik.snarfnet.net/api/v3/core/applications/", headers=headers, data=json.dumps(app_payload).encode('utf-8'), method="POST") with urllib.request.urlopen(req_app_c, context=ctx, timeout=8) as resp_ac: print("Created Application Pi-hole 1!") else: print("Application Pi-hole 1 already exists.")