feat(DIARCHERS-1674): add GKE cluster provisioning REST API (v0) - #637
Open
Jiachen0715 wants to merge 2 commits into
Open
feat(DIARCHERS-1674): add GKE cluster provisioning REST API (v0)#637Jiachen0715 wants to merge 2 commits into
Jiachen0715 wants to merge 2 commits into
Conversation
Introduces a thin REST API to let external CI consumers (e.g. GitHub Actions) dynamically provision ephemeral GKE clusters via InfraBox, without exposing GCP credentials. The API is a thin orchestration layer on top of the existing GCP operator: POST/GET/DELETE against GKECluster CRs in the worker namespace, plus a GET /kubeconfig endpoint that reads the operator-generated Secret. Endpoints (v0): POST /api/v1/projects/<pid>/gke-clusters GET /api/v1/projects/<pid>/gke-clusters/<name> GET /api/v1/projects/<pid>/gke-clusters/<name>/kubeconfig DELETE /api/v1/projects/<pid>/gke-clusters/<name> Changes: - src/api/handlers/projects/gke_clusters.py: new handler (uses requests + the pod's SA token/CA, same pattern as scheduler.py to avoid adding the kubernetes python client dep) - src/api/handlers/projects/__init__.py: register new handler - src/openpolicyagent/policies/projects_gke_clusters.rego: OPA allow rules for the 4 endpoints (default deny -> explicit allow) - deploy/infrabox/templates/api/deployment.yaml: run the API pod under the existing 'infrabox' ServiceAccount (cluster-admin, same as scheduler), and inject INFRABOX_KUBERNETES_MASTER_HOST/PORT so the handler can reach the in-cluster K8s API server
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Background
The dhaas project has migrated from InfraBox to GitHub Actions (PR #4934), but 5 integration test jobs still depend on InfraBox's native
services: [{kind: GKECluster}]mechanism — the platform's GCP operator dynamically creates/destroys ephemeral GKE clusters for each job. GHA has no equivalent, and the interim workaround (reimplementinggcloudin shell, ~130 lines) has three problems:Decision: Since InfraBox remains a long-term platform service, wrap a thin GKE provisioning REST API on the InfraBox backend. GHA (and other external CI) only calls the API and never touches GCP credentials directly.
Approach
The API does NOT reimplement
gcloud— it is a thin orchestration layer that manipulatesGKEClusterCRs in Kubernetes and reads the kubeconfig Secret produced by the operator. All actual cluster provisioning logic is fully reused from the existing GCP operator (src/services/gcp, unchanged).This PR is v0: prove end-to-end feasibility on test-new using user JWT auth. v1 will add list / TTL GC / MCP-token or OIDC auth / audit / rate limiting / production deployment.
API Endpoints
All endpoints under
/api/v1/projects/<project_id>/gke-clusters./202 {name, status:"pending"}/<name>200 {name, status, message, clusterName}/<name>/kubeconfig200 YAML/409 not ready/<name>202 {name, status:"deleting"}Authentication & Authorization
g.tokenmechanism)token.type=userAND the user must be a project collaboratorinfrabox.net/project-idlabel with the URL'sproject_id; mismatch → 403Files Changed
src/api/handlers/projects/gke_clusters.pysrc/api/handlers/projects/__init__.pysrc/openpolicyagent/policies/projects_gke_clusters.regodeploy/infrabox/templates/api/deployment.yamlinfraboxServiceAccount + injectsINFRABOX_KUBERNETES_MASTER_HOST/PORTKey Design Decisions
kubernetespython client dependency — the handler usesrequeststo talk to the K8s API directly, matching the exact pattern ofscheduler.py(reads/var/run/secrets/kubernetes.io/serviceaccount/token+ca.crt). This avoids adding a new binary dependency.INFRABOX_GENERAL_WORKER_NAMESPACE— identical to what scheduler uses, guaranteeing the operator watches and picks up the CR.infraboxServiceAccount (cluster-admin, same as scheduler) — simplified for v0; v1 can tighten togkeclustersCRUD +secretsread only.service.infrabox.net/secret-name(operator uses this to name the output Secret)infrabox.net/created-by: api(distinguishes from scheduler-created CRs, useful for GC scanning)infrabox.net/project-id(ownership check)infrabox.net/created-by-user(audit stub)Known Limitations (explicitly out-of-scope for v0)
GET /gke-clusters(list)kubectl get gkeclusters -l infrabox.net/created-by=api)Testing
Planned end-to-end validation after deploying to test-new (using the
mcp-e2eproject + a user JWT):Passing
kubectl get nodesagainst the API-provisioned cluster proves the end-to-end feasibility target.Related