1313 - DNS A records for api/app subdomains
1414 - TLS certificates via Let's Encrypt (certmgr function)
1515 - CORS and Google OAuth configuration
16- - tmi-tf-wh webhook registration and client credentials
1716
1817Usage:
1918 uv run scripts/setup-oci-public.py all
2019 uv run scripts/setup-oci-public.py verify
2120 uv run scripts/setup-oci-public.py dns
2221 uv run scripts/setup-oci-public.py certs
2322 uv run scripts/setup-oci-public.py configure
24- uv run scripts/setup-oci-public.py webhook
2523"""
2624
2725import base64
@@ -397,31 +395,6 @@ def verify(ctx):
397395 else :
398396 click .echo (" [SKIP] tmi-ux not deployed" )
399397
400- # Check tmi-tf-wh pods (optional)
401- result = kubectl_cmd (
402- cfg , ["get" , "deployment" , "tmi-tf-wh" , "-o" , "name" ], check = False
403- )
404- if result .returncode == 0 :
405- result2 = kubectl_cmd (
406- cfg ,
407- [
408- "get" ,
409- "pods" ,
410- "-l" ,
411- "app=tmi-tf-wh" ,
412- "-o" ,
413- "jsonpath={.items[*].status.phase}" ,
414- ],
415- check = False ,
416- )
417- if result2 .returncode == 0 and "Running" in (result2 .stdout or "" ):
418- click .echo (" [OK] tmi-tf-wh pods running" )
419- else :
420- errors .append ("tmi-tf-wh deployment exists but pods are not running" )
421- click .echo (" [FAIL] tmi-tf-wh pods not running" )
422- else :
423- click .echo (" [SKIP] tmi-tf-wh not deployed" )
424-
425398 # Check ingress LB IP
426399 lb_ip = get_ingress_lb_ip (cfg )
427400 if lb_ip :
@@ -1025,203 +998,6 @@ def configure(ctx):
1025998 click .echo ("\n Configuration complete." )
1026999
10271000
1028- # ---------------------------------------------------------------------------
1029- # Phase 4: webhook
1030- # ---------------------------------------------------------------------------
1031-
1032-
1033- def find_webhook_subscription (token : str , api_url : str , name : str ) -> dict | None :
1034- """Find a webhook subscription by name."""
1035- resp = tmi_api (token , "GET" , f"{ api_url } /webhooks/subscriptions?limit=100" )
1036- if resp .status_code != 200 :
1037- return None
1038- for sub in resp .json ().get ("items" , []):
1039- if sub .get ("name" ) == name :
1040- return sub
1041- return None
1042-
1043-
1044- def wait_for_webhook_active (
1045- token : str , api_url : str , webhook_id : str , timeout : int = 180 , interval : int = 15
1046- ) -> bool :
1047- """Poll webhook subscription status until active."""
1048- deadline = time .time () + timeout
1049- while time .time () < deadline :
1050- resp = tmi_api (token , "GET" , f"{ api_url } /webhooks/subscriptions/{ webhook_id } " )
1051- if resp .status_code == 200 :
1052- status = resp .json ().get ("status" )
1053- if status == "active" :
1054- return True
1055- if status == "pending_delete" :
1056- return False
1057- remaining = int (deadline - time .time ())
1058- click .echo (f" Waiting for challenge verification... ({ remaining } s remaining)" )
1059- time .sleep (interval )
1060- return False
1061-
1062-
1063- @cli .command ()
1064- @click .pass_context
1065- def webhook (ctx ):
1066- """Phase 4: Register tmi-tf-wh webhook and provision client credentials."""
1067- cfg = ctx .obj ["config" ]
1068- dry_run = ctx .obj ["dry_run" ]
1069-
1070- click .echo ("=== Phase 4: Webhook Registration ===\n " )
1071-
1072- result = kubectl_cmd (
1073- cfg , ["get" , "deployment" , "tmi-tf-wh" , "-o" , "name" ], check = False
1074- )
1075- if result .returncode != 0 :
1076- click .echo (" [SKIP] tmi-tf-wh is not deployed. Skipping webhook registration." )
1077- return
1078-
1079- api_url = get_api_url (cfg )
1080- click .echo (f" API URL: { api_url } " )
1081- click .echo (" Authenticating..." )
1082- token = get_tmi_token (cfg , api_url )
1083- click .echo (" [OK] Authenticated" )
1084-
1085- # --- Webhook subscription ---
1086- click .echo ("\n --- Webhook Subscription ---" )
1087- webhook_name = "tmi-tf-wh"
1088- webhook_url = "http://tmi-tf-wh:8080"
1089- webhook_events = ["repository.created" , "repository.updated" , "addon.invoked" ]
1090-
1091- existing = find_webhook_subscription (token , api_url , webhook_name )
1092- if existing and existing .get ("status" ) == "active" :
1093- click .echo (
1094- f" [OK] Webhook '{ webhook_name } ' already exists and is active (id: { existing ['id' ]} )"
1095- )
1096- elif existing and existing .get ("status" ) == "pending_verification" :
1097- click .echo (
1098- f" Webhook '{ webhook_name } ' exists but pending verification. Waiting..."
1099- )
1100- if wait_for_webhook_active (token , api_url , existing ["id" ]):
1101- click .echo (" [OK] Webhook verified and active" )
1102- else :
1103- click .echo ("ERROR: Webhook challenge verification failed." , err = True )
1104- click .echo (
1105- " Check tmi-tf-wh pod logs: kubectl logs -l app=tmi-tf-wh" , err = True
1106- )
1107- sys .exit (1 )
1108- else :
1109- if dry_run :
1110- click .echo (" [DRY RUN] Would create webhook subscription:" )
1111- click .echo (f" name: { webhook_name } " )
1112- click .echo (f" url: { webhook_url } " )
1113- click .echo (f" events: { webhook_events } " )
1114- else :
1115- click .echo (f" Creating webhook subscription '{ webhook_name } '..." )
1116- resp = tmi_api (
1117- token ,
1118- "POST" ,
1119- f"{ api_url } /webhooks/subscriptions" ,
1120- json = {
1121- "name" : webhook_name ,
1122- "url" : webhook_url ,
1123- "events" : webhook_events ,
1124- },
1125- )
1126- if resp .status_code not in (200 , 201 ):
1127- click .echo (
1128- f"ERROR: Failed to create webhook: { resp .status_code } { resp .text } " ,
1129- err = True ,
1130- )
1131- sys .exit (1 )
1132- webhook_data = resp .json ()
1133- webhook_id = webhook_data ["id" ]
1134- click .echo (
1135- f" Created webhook (id: { webhook_id } ), waiting for challenge verification..."
1136- )
1137-
1138- if wait_for_webhook_active (token , api_url , webhook_id ):
1139- click .echo (" [OK] Webhook verified and active" )
1140- else :
1141- click .echo ("ERROR: Webhook challenge verification failed." , err = True )
1142- click .echo (
1143- " Check tmi-tf-wh pod logs: kubectl logs -l app=tmi-tf-wh" ,
1144- err = True ,
1145- )
1146- sys .exit (1 )
1147-
1148- # --- Client credentials for tmi-tf-wh ---
1149- click .echo ("\n --- Client Credentials for tmi-tf-wh ---" )
1150- cred_name = "tmi-tf-wh-service"
1151-
1152- wh_configmap = get_configmap_data (cfg , "tmi-tf-wh-config" )
1153- existing_client_id = wh_configmap .get ("TMI_CLIENT_ID" , "" )
1154- if existing_client_id .startswith ("tmi_cc_" ):
1155- click .echo (
1156- f" [OK] tmi-tf-wh already has client credentials configured ({ existing_client_id } )"
1157- )
1158- else :
1159- if dry_run :
1160- click .echo (
1161- f" [DRY RUN] Would create client credentials '{ cred_name } ' and inject into tmi-tf-wh"
1162- )
1163- else :
1164- click .echo (f" Creating client credentials '{ cred_name } '..." )
1165- resp = tmi_api (
1166- token ,
1167- "POST" ,
1168- f"{ api_url } /me/client_credentials" ,
1169- json = {
1170- "name" : cred_name ,
1171- "description" : "Service credentials for tmi-tf-wh webhook analyzer" ,
1172- },
1173- )
1174- if resp .status_code not in (200 , 201 ):
1175- click .echo (
1176- f"ERROR: Failed to create client credentials: { resp .status_code } { resp .text } " ,
1177- err = True ,
1178- )
1179- sys .exit (1 )
1180- cred_data = resp .json ()
1181- new_client_id = cred_data ["client_id" ]
1182- new_client_secret = cred_data ["client_secret" ]
1183- click .echo (f" [OK] Created credentials: { new_client_id } " )
1184-
1185- click .echo (" Injecting credentials into tmi-tf-wh-config ConfigMap..." )
1186- patch_configmap (
1187- cfg ,
1188- "tmi-tf-wh-config" ,
1189- {
1190- "TMI_CLIENT_ID" : new_client_id ,
1191- "TMI_CLIENT_SECRET" : new_client_secret ,
1192- },
1193- dry_run = False ,
1194- )
1195-
1196- click .echo (" Restarting tmi-tf-wh pods..." )
1197- kubectl_cmd (cfg , ["rollout" , "restart" , "deployment/tmi-tf-wh" ])
1198- wait_for_rollout (cfg , "tmi-tf-wh" )
1199- click .echo (" [OK] tmi-tf-wh restarted with credentials" )
1200-
1201- if not dry_run :
1202- click .echo ("\n Verifying tmi-tf-wh health..." )
1203- result = kubectl_cmd (
1204- cfg ,
1205- [
1206- "get" ,
1207- "pods" ,
1208- "-l" ,
1209- "app=tmi-tf-wh" ,
1210- "-o" ,
1211- "jsonpath={.items[*].status.phase}" ,
1212- ],
1213- check = False ,
1214- )
1215- if result .returncode == 0 and "Running" in (result .stdout or "" ):
1216- click .echo (" [OK] tmi-tf-wh pods running" )
1217- else :
1218- click .echo (
1219- " [WARN] tmi-tf-wh pods may not be healthy. Check pod logs." , err = True
1220- )
1221-
1222- click .echo ("\n Webhook registration complete." )
1223-
1224-
12251001# ---------------------------------------------------------------------------
12261002# All phases
12271003# ---------------------------------------------------------------------------
@@ -1230,13 +1006,12 @@ def webhook(ctx):
12301006@cli .command (name = "all" )
12311007@click .pass_context
12321008def run_all (ctx ):
1233- """Run all phases in order: verify -> dns -> certs -> configure -> webhook ."""
1009+ """Run all phases in order: verify -> dns -> certs -> configure."""
12341010 phases = [
12351011 ("verify" , verify ),
12361012 ("dns" , dns ),
12371013 ("certs" , certs ),
12381014 ("configure" , configure ),
1239- ("webhook" , webhook ),
12401015 ]
12411016
12421017 for name , cmd in phases :
@@ -1254,7 +1029,6 @@ def run_all(ctx):
12541029 click .echo (f"\n API: https://{ cfg .api_hostname } " )
12551030 click .echo (f" App: https://{ cfg .ux_hostname } " )
12561031 click .echo ("\n Google OAuth configured and available." )
1257- click .echo (" tmi-tf-wh webhook registered and active." )
12581032
12591033
12601034if __name__ == "__main__" :
0 commit comments