diff --git a/servers/legion/k8s/gitea-runner/deployment.yaml b/servers/legion/k8s/gitea-runner/deployment.yaml index 615ee58..ed9d079 100644 --- a/servers/legion/k8s/gitea-runner/deployment.yaml +++ b/servers/legion/k8s/gitea-runner/deployment.yaml @@ -8,7 +8,7 @@ metadata: labels: app: gitea-runner annotations: - config-version: "2026-05-05-ssh-clone" + config-version: "2026-05-05-gitea-proxy" spec: replicas: 1 selector: @@ -19,7 +19,7 @@ spec: labels: app: gitea-runner annotations: - config-version: "2026-05-05-ssh-clone" + config-version: "2026-05-05-gitea-proxy" spec: securityContext: runAsNonRoot: false @@ -100,7 +100,7 @@ metadata: labels: app: neuron-technologies-runner annotations: - config-version: "2026-05-05-ssh-clone" + config-version: "2026-05-05-gitea-proxy" spec: replicas: 2 selector: @@ -111,7 +111,7 @@ spec: labels: app: neuron-technologies-runner annotations: - config-version: "2026-05-05-ssh-clone" + config-version: "2026-05-05-gitea-proxy" spec: securityContext: runAsNonRoot: false diff --git a/servers/legion/k8s/gitea-runner/external-secrets.yaml b/servers/legion/k8s/gitea-runner/external-secrets.yaml index 553295e..9cc448c 100644 --- a/servers/legion/k8s/gitea-runner/external-secrets.yaml +++ b/servers/legion/k8s/gitea-runner/external-secrets.yaml @@ -13,7 +13,7 @@ metadata: name: gitea-runner-secret namespace: ci annotations: - force-sync: "2026-05-05-ssh-clone" + force-sync: "2026-05-05-gitea-proxy" spec: refreshInterval: 1h secretStoreRef: @@ -24,7 +24,7 @@ spec: creationPolicy: Owner template: data: - GITEA_INSTANCE_URL: "https://git.neuralplatform.ai" + GITEA_INSTANCE_URL: "http://gitea-proxy.ci.svc.cluster.local:3000" GITEA_RUNNER_REGISTRATION_TOKEN: "{{ .runner_token }}" GITEA_SSH_PRIVATE_KEY: "{{ .ci_ssh_private_key }}" data: @@ -44,7 +44,7 @@ metadata: name: neuron-technologies-runner-secret namespace: ci annotations: - force-sync: "2026-05-05-ssh-clone" + force-sync: "2026-05-05-gitea-proxy" spec: refreshInterval: 1h secretStoreRef: @@ -55,7 +55,7 @@ spec: creationPolicy: Owner template: data: - GITEA_INSTANCE_URL: "https://git.neuralplatform.ai" + GITEA_INSTANCE_URL: "http://gitea-proxy.ci.svc.cluster.local:3000" GITEA_RUNNER_REGISTRATION_TOKEN: "{{ .runner_token }}" GITEA_SSH_PRIVATE_KEY: "{{ .ci_ssh_private_key }}" data: diff --git a/servers/legion/k8s/gitea-runner/gitea-proxy.yaml b/servers/legion/k8s/gitea-runner/gitea-proxy.yaml new file mode 100644 index 0000000..00108b9 --- /dev/null +++ b/servers/legion/k8s/gitea-runner/gitea-proxy.yaml @@ -0,0 +1,132 @@ +--- +# gitea-proxy — nginx CF Access header-injecting proxy +# +# act_runner cannot add custom HTTP headers, so it can't send the +# CF-Access-Client-Id / CF-Access-Client-Secret headers that Cloudflare +# Access requires for service-to-service access to git.neuralplatform.ai. +# +# This proxy sits in the ci namespace. Runners use: +# GITEA_INSTANCE_URL: http://gitea-proxy.ci.svc.cluster.local:3000 +# +# nginx:alpine processes *.conf.template files in /etc/nginx/templates/ via +# envsubst at startup — so CF Access credentials come from the Secret as env +# vars and get interpolated into the nginx config before nginx starts. +apiVersion: v1 +kind: ConfigMap +metadata: + name: gitea-proxy-config + namespace: ci +data: + # Placed at /etc/nginx/templates/default.conf.template — nginx:alpine + # runs envsubst on this and writes the result to /etc/nginx/conf.d/default.conf + default.conf.template: | + server { + listen 3000; + + location / { + proxy_pass https://git.neuralplatform.ai; + + # Inject CF Access service-token headers so Cloudflare lets + # the request through without interactive auth. + proxy_set_header CF-Access-Client-Id "${CF_ACCESS_CLIENT_ID}"; + proxy_set_header CF-Access-Client-Secret "${CF_ACCESS_CLIENT_SECRET}"; + + # Preserve Host so Gitea/CF edge routes correctly. + proxy_set_header Host git.neuralplatform.ai; + + # Forward all original request headers (auth tokens, etc). + proxy_pass_request_headers on; + + # Rewrite Location headers in redirects back to the proxy URL. + proxy_redirect https://git.neuralplatform.ai/ + http://gitea-proxy.ci.svc.cluster.local:3000/; + + # Standard proxy headers. + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto http; + + # Allow large request bodies (git push payloads). + client_max_body_size 512m; + } + } +--- +# ExternalSecret — CF Access service token for the proxy +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-proxy-secret + namespace: ci + annotations: + force-sync: "2026-05-05-initial" +spec: + refreshInterval: 1h + secretStoreRef: + name: vault + kind: ClusterSecretStore + target: + name: gitea-proxy-secret + creationPolicy: Owner + data: + - secretKey: CF_ACCESS_CLIENT_ID + remoteRef: + key: secret/data/gitea-runner-cf-access + property: client_id + - secretKey: CF_ACCESS_CLIENT_SECRET + remoteRef: + key: secret/data/gitea-runner-cf-access + property: client_secret +--- +# Deployment +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gitea-proxy + namespace: ci + labels: + app: gitea-proxy +spec: + replicas: 1 + selector: + matchLabels: + app: gitea-proxy + template: + metadata: + labels: + app: gitea-proxy + spec: + containers: + - name: nginx + image: nginx:alpine + ports: + - containerPort: 3000 + volumeMounts: + - name: config-template + mountPath: /etc/nginx/templates + envFrom: + - secretRef: + name: gitea-proxy-secret + resources: + requests: + cpu: 50m + memory: 32Mi + limits: + cpu: 200m + memory: 64Mi + volumes: + - name: config-template + configMap: + name: gitea-proxy-config +--- +# Service — ClusterIP reachable by all runner pods as gitea-proxy.ci:3000 +apiVersion: v1 +kind: Service +metadata: + name: gitea-proxy + namespace: ci +spec: + selector: + app: gitea-proxy + ports: + - port: 3000 + targetPort: 3000