Skip to content

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).

UseURLNotes
Dashboard (metrics)https://<WORKER_DOMAIN>/internal/dashboardHTML. Enter Bearer to load metrics.
Metrics API (JSON)https://<WORKER_DOMAIN>/internal/metrics/summaryBearer required.
Tenant·billing list (admin test)https://<WORKER_DOMAIN>/internal/billing-testBearer. HTML table.
Single tenant billinghttps://<WORKER_DOMAIN>/internal/billing?tenant_id=<TENANT_ID>Bearer. JSON.
Onboarding step status APIhttps://<WORKER_DOMAIN>/internal/onboarding-status?job_id=<JOB_ID> or ?tenant_id=<TENANT_ID>Bearer. JSON.
Onboarding dashboardhttps://<WORKER_DOMAIN>/internal/onboarding-dashboardHTML. Enter job_id/tenant_id for step progress·errors.
Tracehttps://<WORKER_DOMAIN>/internal/trace/<trace_id>Bearer.
Placement simulationhttps://<WORKER_DOMAIN>/internal/placement-simulationHTML. POST /internal/placement-simulation/run with Bearer.
R7 db_hosthttps://<WORKER_DOMAIN>/internal/db-host?region=sgBearer. Region DB host (env DB_HOST_SG/US/EU).
Email flowhttps://<WORKER_DOMAIN>/internal/email-flow-dashboardHTML.
Healthhttps://<WORKER_DOMAIN>/

First deploy (no Worker yet)

  1. Path: prego-control-plane project root.
  2. D1·KV: npx wrangler d1 create prego-d1, npx wrangler kv namespace create "prego-tenant-origins". Put database_id and KV id in wrangler.toml ([[d1_databases]], [[kv_namespaces]]; binding TENANT_ORIGINS).
  3. Migrations: npx wrangler d1 migrations apply prego-d1 --remote.
  4. Deploy: npm run deploy.
  5. 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_KEY for 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.

CheckMethod
R1 Node getGET /internal/nodes/<node_id> (Bearer). 200 → host, region, status, role.
R2/R4 PlacementCreate tenant (free or Stripe); job has target_server_id or create_new_server; capacity·plan role filter.
R3 Node registerAfter one workflow with create_new_server: true, D1 nodes has new row.
R5 plan_limitsGET /internal/billing?tenant_id= (Bearer) includes plan_limits. Docker inspect container for memory/CPU limits.
R6 Zuplo plan_tierZuplo Consumer metadata has planTier. provision-tenant-pipeline §5 for manual Rate Limit.
R7 db_hostGET /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·alertGET /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

IssueCheck
404 / no accessWorker “prego-control-plane” in Workers & Pages; recent npm run deploy.
Dashboard metrics not loadingINTERNAL_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/dashboardHTML. Bearer 입력 시 메트릭 로드.
메트릭 API (JSON)https://<WORKER_DOMAIN>/internal/metrics/summaryBearer 필요.
테넌트·결제 목록 (관리자 테스트)https://<WORKER_DOMAIN>/internal/billing-testBearer 필요. HTML 테이블.
단일 테넌트 결제https://<WORKER_DOMAIN>/internal/billing?tenant_id=<TENANT_ID>Bearer 필요. JSON.
온보딩 단계별 상태 APIhttps://<WORKER_DOMAIN>/internal/onboarding-status?job_id=<JOB_ID> 또는 ?tenant_id=<TENANT_ID>Bearer 필요. JSON.
온보딩 단계별 대시보드https://<WORKER_DOMAIN>/internal/onboarding-dashboardHTML. job_id/tenant_id 입력 후 단계별 진행·에러 확인.
트레이스https://<WORKER_DOMAIN>/internal/trace/<trace_id>Bearer 필요.
Placement 시뮬레이션https://<WORKER_DOMAIN>/internal/placement-simulationHTML. 시뮬레이션 실행 시 Bearer로 POST /internal/placement-simulation/run 호출.
R7 db_hosthttps://<WORKER_DOMAIN>/internal/db-host?region=sgBearer 필요. region별 DB 호스트(env DB_HOST_SG/US/EU).
이메일 플로우 검증https://<WORKER_DOMAIN>/internal/email-flow-dashboardHTML.
헬스https://<WORKER_DOMAIN>/

최초 배포 (Worker가 없을 때)

  1. 경로: prego-control-plane 프로젝트 루트 (예: /Users/marco/prego-control-plane).

  2. D1·KV 생성 (이미 있으면 생략):

    Terminal window
    npx wrangler d1 create prego-d1
    npx wrangler kv namespace create "prego-tenant-origins"

    출력된 database_id, KV idwrangler.toml[[d1_databases]], [[kv_namespaces]] 에 넣는다. KV는 binding = "TENANT_ORIGINS" 유지.

  3. D1 마이그레이션 적용:

    Terminal window
    npx wrangler d1 migrations apply prego-d1 --remote
  4. 배포:

    Terminal window
    npm run deploy
  5. Cloudflare Workers & Pagesprego-control-plane 이 보이고, 위 URL 로 접속 가능해진다.


대시보드에서 메트릭 보기

  • GET /internal/dashboard 는 API 키 없이 HTML 페이지를 준다.
  • 페이지에서 메트릭을 불러오기 위해서는 Internal API Key 를 입력해야 한다. (동일 키로 GET /internal/metrics/summary 호출.)

시크릿 설정 (한 번만):

Terminal window
cd /path/to/prego-control-plane
npx 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 로 실제 트리거를 보내려면 아래 시크릿을 설정한다.
Terminal window
npx wrangler secret put ZUPLO_BASE_URL # 예: https://prego-main-xxx.zuplo.app
npx 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 검증까지 자동 실행하려면:

    1. Auth Worker(Zuplo 뒤에 붙는 prego auth worker)에 환경 변수 OTP_TEST_EMAILS 설정. 쉼표 구분 이메일(예: opsfork@gmail.com). 해당 이메일로 OTP 요청 시 응답에 otp_for_test가 포함됨.
    2. 대시보드에서 E2E용 이메일 입력(또는 플로우 B 이메일과 동일) 후 「테스트 이메일 발송 + OTP 검증 (E2E)」 클릭.
  • 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_limitsGET /internal/billing?tenant_id=<id> (Bearer). 응답에 plan_limits 객체. 프로비저닝된 컨테이너 docker inspect 로 메모리/CPU 한도 확인.
R6 Zuplo plan_tierZuplo Consumer 메타에 planTier 저장 여부. Runbook provision-tenant-pipeline §5 로 수동 Rate Limit 설정 가능.
R7 db_hostGET /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 값으로 치환 후 실행:

Terminal window
# 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> 값이 시크릿과 일치하는지 확인.
Help