English {#english}
prego-control-plane Deploy and Dashboard
Deploy the Control Plane Worker (prego-control-plane), access internal dashboard URLs, and set INTERNAL_API_KEY. Ref: cloudflare-dashboard-implementation, OPERATIONS.
Access URLs (after deploy)
Worker domain depends on environment (e.g. prego-control-plane.<account>.workers.dev or custom domain).
| Use | URL | Notes |
|---|---|---|
| Dashboard (metrics) | https://<WORKER_DOMAIN>/internal/dashboard | HTML. Enter Bearer to load metrics. |
| Metrics API (JSON) | https://<WORKER_DOMAIN>/internal/metrics/summary | Bearer required. |
| Tenant·billing list (admin test) | https://<WORKER_DOMAIN>/internal/billing-test | Bearer. HTML table. |
| Single tenant billing | https://<WORKER_DOMAIN>/internal/billing?tenant_id=<TENANT_ID> | Bearer. JSON. |
| Onboarding step status API | https://<WORKER_DOMAIN>/internal/onboarding-status?job_id=<JOB_ID> or ?tenant_id=<TENANT_ID> | Bearer. JSON. |
| Onboarding dashboard | https://<WORKER_DOMAIN>/internal/onboarding-dashboard | HTML. Enter job_id/tenant_id for step progress·errors. |
| Trace | https://<WORKER_DOMAIN>/internal/trace/<trace_id> | Bearer. |
| Placement simulation | https://<WORKER_DOMAIN>/internal/placement-simulation | HTML. POST /internal/placement-simulation/run with Bearer. |
| R7 db_host | https://<WORKER_DOMAIN>/internal/db-host?region=sg | Bearer. Region DB host (env DB_HOST_SG/US/EU). |
| Email flow | https://<WORKER_DOMAIN>/internal/email-flow-dashboard | HTML. |
| Health | https://<WORKER_DOMAIN>/ | — |
First deploy (no Worker yet)
- Path: prego-control-plane project root.
- D1·KV:
npx wrangler d1 create prego-d1,npx wrangler kv namespace create "prego-tenant-origins". Putdatabase_idand KVidin wrangler.toml ([[d1_databases]],[[kv_namespaces]]; bindingTENANT_ORIGINS). - Migrations:
npx wrangler d1 migrations apply prego-d1 --remote. - Deploy:
npm run deploy. - Worker appears in Cloudflare Workers & Pages; URLs above work.
Dashboard metrics
- GET /internal/dashboard returns HTML without API key. To load metrics, enter Internal API Key in the page (same key as GET /internal/metrics/summary).
- Set secret once:
npx wrangler secret put INTERNAL_API_KEY. Use that value in the dashboard “Bearer token” field. Same key is used for provision-complete callback and other internal APIs.
Email flow dashboard
- GET /internal/email-flow-dashboard: HTML. Enter Internal API Key and run Flow A (Frappe → POST /email) or Flow B (OTP/Passcode). Optional: set
ZUPLO_BASE_URL,ZUPLO_EMAIL_API_KEYfor live trigger. E2E: set OTP_TEST_EMAILS on Auth Worker; dashboard “테스트 이메일 발송 + OTP 검증 (E2E)” runs send + OTP verify. Ref: otp-and-email-consolidated, otp-verify-consolidated.
Post-deploy verification (R1–R8)
After Control Plane and workflow deploy, verify resource allocation, plan limits, and saturation alerts. Detail: tenant-onboard-resource-allocation-flow-plan §10.
| Check | Method |
|---|---|
| R1 Node get | GET /internal/nodes/<node_id> (Bearer). 200 → host, region, status, role. |
| R2/R4 Placement | Create tenant (free or Stripe); job has target_server_id or create_new_server; capacity·plan role filter. |
| R3 Node register | After one workflow with create_new_server: true, D1 nodes has new row. |
| R5 plan_limits | GET /internal/billing?tenant_id= (Bearer) includes plan_limits. Docker inspect container for memory/CPU limits. |
| R6 Zuplo plan_tier | Zuplo Consumer metadata has planTier. provision-tenant-pipeline §5 for manual Rate Limit. |
| R7 db_host | GET /internal/db-host?region=sg (Bearer). 200 + db_host when DB_HOST_SG/US/EU set; 503 otherwise. db-redis-scaling-policy-r7 §5. |
| R8 Saturation·alert | GET /internal/dashboard → API key → Node health: “saturated” badge, saturated_node_ids. With ALERT_WEBHOOK_URL, Cron POSTs on saturation. |
Quick curl: R1 curl -H "Authorization: Bearer $BEARER" "$CP_URL/internal/nodes/NODE_ID". R5 $CP_URL/internal/billing?tenant_id=, $CP_URL/internal/plan-limits. R7 $CP_URL/internal/db-host?region=sg. Script: Prego scripts/smoke-verify-control-plane.sh (CONTROL_PLANE_URL, INTERNAL_API_KEY; optional NODE_ID). Prereqs: D1 migration 0014_nodes_role; nodes pushing POST /internal/server-metrics. Optional env: PLACEMENT_MEMORY_PCT_MAX, PLACEMENT_MAX_TENANTS_PER_NODE, SATURATION_MEMORY_PCT, SATURATION_MAX_TENANTS (default 85, 10).
Troubleshooting
| Issue | Check |
|---|---|
| 404 / no access | Worker “prego-control-plane” in Workers & Pages; recent npm run deploy. |
| Dashboard metrics not loading | INTERNAL_API_KEY secret set; same value entered in dashboard. |
| 401 (metrics/summary) | Header Authorization: Bearer <INTERNAL_API_KEY> matches secret. |
Full Korean text (incl. E2E OTP, B6 card, exact commands) in the 한국어 section below.
한국어 {#korean}
Runbook: prego-control-plane Deploy and Dashboard
Purpose: Deploy the Control Plane Worker (prego-control-plane), access internal dashboard URLs, and set the metrics API key (INTERNAL_API_KEY).
참조: cloudflare-dashboard-implementation, OPERATIONS.
접속 URL (배포 후)
Worker 도메인은 배포 환경에 따라 다름 (예: prego-control-plane.<account>.workers.dev 또는 커스텀 도메인). 아래는 예시 기준.
| 용도 | URL | 비고 |
|---|---|---|
| 대시보드 (메트릭) | https://<WORKER_DOMAIN>/internal/dashboard | HTML. Bearer 입력 시 메트릭 로드. |
| 메트릭 API (JSON) | https://<WORKER_DOMAIN>/internal/metrics/summary | Bearer 필요. |
| 테넌트·결제 목록 (관리자 테스트) | https://<WORKER_DOMAIN>/internal/billing-test | Bearer 필요. HTML 테이블. |
| 단일 테넌트 결제 | https://<WORKER_DOMAIN>/internal/billing?tenant_id=<TENANT_ID> | Bearer 필요. JSON. |
| 온보딩 단계별 상태 API | https://<WORKER_DOMAIN>/internal/onboarding-status?job_id=<JOB_ID> 또는 ?tenant_id=<TENANT_ID> | Bearer 필요. JSON. |
| 온보딩 단계별 대시보드 | https://<WORKER_DOMAIN>/internal/onboarding-dashboard | HTML. job_id/tenant_id 입력 후 단계별 진행·에러 확인. |
| 트레이스 | https://<WORKER_DOMAIN>/internal/trace/<trace_id> | Bearer 필요. |
| Placement 시뮬레이션 | https://<WORKER_DOMAIN>/internal/placement-simulation | HTML. 시뮬레이션 실행 시 Bearer로 POST /internal/placement-simulation/run 호출. |
| R7 db_host | https://<WORKER_DOMAIN>/internal/db-host?region=sg | Bearer 필요. region별 DB 호스트(env DB_HOST_SG/US/EU). |
| 이메일 플로우 검증 | https://<WORKER_DOMAIN>/internal/email-flow-dashboard | HTML. |
| 헬스 | https://<WORKER_DOMAIN>/ | — |
최초 배포 (Worker가 없을 때)
-
경로:
prego-control-plane프로젝트 루트 (예:/Users/marco/prego-control-plane). -
D1·KV 생성 (이미 있으면 생략):
Terminal window npx wrangler d1 create prego-d1npx wrangler kv namespace create "prego-tenant-origins"출력된
database_id, KVid를wrangler.toml의[[d1_databases]],[[kv_namespaces]]에 넣는다. KV는binding = "TENANT_ORIGINS"유지. -
D1 마이그레이션 적용:
Terminal window npx wrangler d1 migrations apply prego-d1 --remote -
배포:
Terminal window npm run deploy -
Cloudflare Workers & Pages 에 prego-control-plane 이 보이고, 위 URL 로 접속 가능해진다.
대시보드에서 메트릭 보기
- GET /internal/dashboard 는 API 키 없이 HTML 페이지를 준다.
- 페이지에서 메트릭을 불러오기 위해서는 Internal API Key 를 입력해야 한다. (동일 키로 GET /internal/metrics/summary 호출.)
시크릿 설정 (한 번만):
cd /path/to/prego-control-planenpx wrangler secret put INTERNAL_API_KEY프롬프트에 나온 대로 값을 입력한다. 이 값을 대시보드 페이지의 “Bearer token” 입력란에 넣으면 메트릭(테넌트·프로비저닝·노드 등)이 로드된다.
- INTERNAL_API_KEY 는 provision-complete 콜백 등 다른 internal API 호출에도 사용하므로, 이미 설정돼 있을 수 있다. 그 경우 같은 값을 대시보드에 입력하면 된다.
이메일 플로우 검증 대시보드
- GET /internal/email-flow-dashboard 는 API 키 없이 HTML 페이지를 준다.
- 페이지에서 Flow A(Frappe → POST /email) 또는 Flow B(OTP/Passcode 요청) 검증을 실행하려면 Internal API Key 를 입력한 뒤 “검증 실행” 버튼을 누른다. (동일 키로
POST /internal/email-flow/trigger-flow-a,POST /internal/email-flow/trigger-flow-b호출.) - Zuplo 로 실제 트리거를 보내려면 아래 시크릿을 설정한다.
npx wrangler secret put ZUPLO_BASE_URL # 예: https://prego-main-xxx.zuplo.appnpx wrangler secret put ZUPLO_EMAIL_API_KEY # Flow A용 POST /email API 키 (선택)[B6] OTP/KV 검증 결과
- 플로우 B 단계에 [B6] OTP/KV 검증 결과 카드가 추가되어, 이메일 전달 후 코드가 KV와 일치하는지 자동 검증 결과를 표시합니다. 성공 시 초록, 실패 시 빨강, 자동 검증 불가 시 회색(중립). OTP 유형으로 “검증 실행 (Flow B)” 시
otp_for_test가 있으면 자동으로 verify를 호출해 B6에 반영합니다.
E2E: 테스트 이메일 발송 + OTP 검증 자동
-
플로우 B 탭에 「테스트 이메일 발송 + OTP 검증 (E2E)」 버튼이 있다. 이메일 한 번에 발송 → OTP 검증까지 자동 실행하려면:
- Auth Worker(Zuplo 뒤에 붙는 prego auth worker)에 환경 변수 OTP_TEST_EMAILS 설정. 쉼표 구분 이메일(예:
opsfork@gmail.com). 해당 이메일로 OTP 요청 시 응답에otp_for_test가 포함됨. - 대시보드에서 E2E용 이메일 입력(또는 플로우 B 이메일과 동일) 후 「테스트 이메일 발송 + OTP 검증 (E2E)」 클릭.
- Auth Worker(Zuplo 뒤에 붙는 prego auth worker)에 환경 변수 OTP_TEST_EMAILS 설정. 쉼표 구분 이메일(예:
-
OTP_TEST_EMAILS에 없는 이메일이면 OTP는 발송만 되고 자동 검증은 건너뛴다(메시지로 안내). -
계획 문서: otp-and-email-consolidated §5, otp-verify-consolidated §6.
배포 후 검증 (R1–R8)
Control Plane 및 워크플로 배포 후, 리소스 할당·플랜별 한도·포화 알림이 기획대로 동작하는지 아래 순서로 확인한다. 상세: tenant-onboard-resource-allocation-flow-plan §10.
| 확인 항목 | 방법 |
|---|---|
| R1 노드 조회 | GET /internal/nodes/<등록된_node_id> (Bearer). 200 시 host, region, status, role 포함. |
| R2/R4 Placement | 새 테넌트 생성(무료 또는 Stripe 체크아웃) 후 job에 target_server_id 또는 create_new_server 적절히 설정되는지. (용량 여유 노드·플랜별 role 필터) |
| R3 노드 등록 | create_new_server: true 로 워크플로 1회 성공 후, D1 nodes 에 새 행 추가 여부. |
| R5 plan_limits | GET /internal/billing?tenant_id=<id> (Bearer). 응답에 plan_limits 객체. 프로비저닝된 컨테이너 docker inspect 로 메모리/CPU 한도 확인. |
| R6 Zuplo plan_tier | Zuplo Consumer 메타에 planTier 저장 여부. Runbook provision-tenant-pipeline §5 로 수동 Rate Limit 설정 가능. |
| R7 db_host | GET /internal/db-host?region=sg (Bearer). DB_HOST_SG/US/EU 설정 시 200 + { "db_host": "..." }. 미설정 시 503. 워크플로 resolve-server가 이 값을 쓰면 Ansible 인벤토리 db_host로 전달됨. db-redis-scaling-policy-r7 §5. |
| R8 포화·알림 | GET /internal/dashboard → API 키 입력 → Node health 테이블에 포화 시 “포화” 뱃지·saturated_node_ids 요약. ALERT_WEBHOOK_URL 설정 시 매시 Cron으로 포화 시 POST 여부. |
Quick verification (curl) — CP_URL=Worker URL, BEARER=INTERNAL_API_KEY 값으로 치환 후 실행:
# R1 노드 조회 (node_id는 D1 nodes 테이블 또는 워크플로 출력에서 확인)curl -sS -H "Authorization: Bearer $BEARER" "$CP_URL/internal/nodes/NODE_ID"
# R5 plan_limits (테넌트별: billing 응답에 plan_limits 포함)curl -sS -H "Authorization: Bearer $BEARER" "$CP_URL/internal/billing?tenant_id=TENANT_ID"# R5 plan_limits (전체 맵)curl -sS -H "Authorization: Bearer $BEARER" "$CP_URL/internal/plan-limits"
# R7 db_host (region=sg/us/eu, DB_HOST_* 설정 시 200)curl -sS -H "Authorization: Bearer $BEARER" "$CP_URL/internal/db-host?region=sg"동일 검증을 스크립트로 실행: Prego 레포 scripts/smoke-verify-control-plane.sh (CONTROL_PLANE_URL, INTERNAL_API_KEY 설정; 선택 NODE_ID).
사전 조건: D1 마이그레이션 0014_nodes_role 적용, 노드에서 POST /internal/server-metrics 푸시 중.
선택: R2 Placement·R8 포화 기준은 env로 변경 가능. PLACEMENT_MEMORY_PCT_MAX, PLACEMENT_MAX_TENANTS_PER_NODE, SATURATION_MEMORY_PCT, SATURATION_MAX_TENANTS (미설정 시 85%, 10).
문제 해결
| 현상 | 확인 |
|---|---|
| 404 / 접속 안 됨 | Workers & Pages 에 prego-control-plane 이 있는지, 최근에 npm run deploy 했는지 확인. |
| 대시보드에서 메트릭 로드 실패 | INTERNAL_API_KEY 시크릿이 설정돼 있는지, 대시보드 입력값이 동일한지 확인. |
| 401 Unauthorized (metrics/summary) | 요청 헤더 Authorization: Bearer <INTERNAL_API_KEY> 값이 시크릿과 일치하는지 확인. |