diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index 14fdee8..6db029f 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -31,6 +31,7 @@ | **Logging** | Loki + Fluent-Bit | | **Tracing** | Tempo (OTLP) | | **Container Scanning** | Trivy | +| **Version Control** | Gitea | ### Network Architecture @@ -85,6 +86,7 @@ sturdy-adventure/ │ ├── tempo.yaml │ ├── fluent-bit.yaml │ ├── trivy.yaml +│ ├── gitea.yaml │ ├── sealedsecrets.yaml │ ├── secrets.yaml │ └── values/ @@ -93,6 +95,7 @@ sturdy-adventure/ │ ├── grafana-values.yaml │ ├── loki-values.yaml │ ├── tempo-values.yaml +│ ├── gitea-values.yaml │ └── fluent-bit-values.yaml │ ├── apps/ # Business applications @@ -121,6 +124,7 @@ sturdy-adventure/ ├── secrets/ # Application secrets (sealed) │ ├── argocd-mcp-credentials.yaml │ ├── dot-ai-secrets.yaml +│ ├── gitea-credentials-sealed.yaml │ ├── mcp10x-credentials-sealed.yaml │ └── musicman-credentials.yaml │ @@ -770,6 +774,49 @@ persistence: **Output**: Loki +### Gitea + +**Chart**: `gitea/gitea` +**Version**: 12.5.0 (app v1.25.4) +**Namespace**: `gitea` + +**Purpose**: Self-hosted Git repository hosting with pull requests, issues, CI/CD (Gitea Actions), container registry, and package registry. + +**Configuration**: +```yaml +# infra/gitea.yaml + infra/values/gitea-values.yaml +ingress: + host: git.forteapps.net + tls: cert-manager (letsencrypt-prod) + +gitea: + admin: + existingSecret: gitea-credentials + config: + service: + DISABLE_REGISTRATION: true + ALLOW_ONLY_EXTERNAL_REGISTRATION: true + actions: + ENABLED: true + packages: + ENABLED: true + metrics: + ENABLED: true + +postgresql: + enabled: true + persistence: 8Gi (upcloud-block-storage-maxiops) +``` + +**Authentication**: Keycloak OIDC via `forte` realm (client ID: `gitea`) + +**Endpoints**: +- Web UI: `https://git.forteapps.net` +- SSH: port 22 (ClusterIP) +- Metrics: `/metrics` (Prometheus scrape) + +**Secrets**: `gitea-credentials` (SealedSecret) containing `admin-password`, `postgres-password`, `secret` (OIDC client secret) + --- ## Kyverno Policies @@ -1373,6 +1420,7 @@ team: platform | **Loki** | 2.9.0+ | Latest | | **Tempo** | 2.6.0+ | 1.24.4 | | **Fluent-Bit** | 2.1.0+ | Latest | +| **Gitea** | 1.25.4 | 12.5.0 | | **PostgreSQL** | 16-alpine | N/A | | **Trivy** | Latest | Latest | @@ -1384,6 +1432,6 @@ team: platform --- -**Last Updated**: 2026-03-16 +**Last Updated**: 2026-04-08 **Maintained By**: Platform Team **Version**: 1.0.0 diff --git a/infra/gitea.yaml b/infra/gitea.yaml new file mode 100644 index 0000000..317193f --- /dev/null +++ b/infra/gitea.yaml @@ -0,0 +1,42 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: gitea + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "1" + labels: + app.kubernetes.io/name: gitea + app.kubernetes.io/part-of: platform + app.kubernetes.io/managed-by: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + + sources: + - repoURL: https://dl.gitea.com/charts + chart: gitea + targetRevision: "12.5.0" + helm: + releaseName: gitea + valueFiles: + - $values/infra/values/gitea-values.yaml + + - repoURL: git@github.com:fortedigital/sturdy-adventure.git + targetRevision: HEAD + ref: values + + destination: + server: https://kubernetes.default.svc + namespace: gitea + + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: false + syncOptions: + - CreateNamespace=true + - Validate=true + - ServerSideApply=true diff --git a/infra/values/gitea-values.yaml b/infra/values/gitea-values.yaml new file mode 100644 index 0000000..de2490f --- /dev/null +++ b/infra/values/gitea-values.yaml @@ -0,0 +1,152 @@ +# Gitea Helm Chart Values +# Host: git.forteapps.net +# Chart: gitea v12.5.0 (app v1.25.4) +# Repo: https://dl.gitea.com/charts + +# -- Admin account (password from sealed secret) +gitea: + admin: + existingSecret: gitea-credentials + email: admin@forteapps.net + + # -- Gitea app.ini configuration + config: + APP_NAME: "Forte Git" + + server: + DOMAIN: git.forteapps.net + ROOT_URL: https://git.forteapps.net + SSH_DOMAIN: git.forteapps.net + SSH_PORT: 22 + LFS_START_SERVER: true + + service: + DISABLE_REGISTRATION: true + REQUIRE_SIGNIN_VIEW: false + ALLOW_ONLY_EXTERNAL_REGISTRATION: true + + openid: + ENABLE_OPENID_SIGNIN: true + ENABLE_OPENID_SIGNUP: true + + oauth2: + ENABLED: true + + session: + PROVIDER: db + + cache: + ADAPTER: memory + + database: + DB_TYPE: postgres + + metrics: + ENABLED: true + + repository: + DEFAULT_BRANCH: main + DEFAULT_PRIVATE: last + + actions: + ENABLED: true + + packages: + ENABLED: true + + indexer: + ISSUE_INDEXER_TYPE: bleve + REPO_INDEXER_ENABLED: true + + # -- OIDC authentication via Keycloak + oauth: + - name: "Keycloak" + provider: "openidConnect" + existingSecret: gitea-credentials + key: gitea + autoDiscoverUrl: "https://id.forteapps.net/realms/forte/.well-known/openid-configuration" + scopes: "openid email profile" + groupClaimName: "" + adminGroup: "" + restrictedGroup: "" + + # -- Prometheus metrics (scraped via annotations, no ServiceMonitor CRD needed) + metrics: + enabled: true + serviceMonitor: + enabled: false + +# -- Ingress via Traefik with Let's Encrypt TLS +ingress: + enabled: true + className: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + hosts: + - host: git.forteapps.net + paths: + - path: / + pathType: Prefix + tls: + - secretName: gitea-tls + hosts: + - git.forteapps.net + +# -- Git repository storage +persistence: + enabled: true + size: 10Gi + accessModes: + - ReadWriteOnce + storageClass: upcloud-block-storage-maxiops + +# -- Pod resources +resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +# -- Embedded PostgreSQL (Bitnami subchart) +# Password auto-generated by the subchart; Gitea chart auto-wires the connection. +postgresql: + enabled: true + auth: + existingSecret: gitea-credentials + secretKeys: + adminPasswordKey: postgres-password + userPasswordKey: postgres-password + username: gitea + database: gitea + primary: + persistence: + enabled: true + size: 8Gi + storageClass: upcloud-block-storage-maxiops + resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +# -- Disable PostgreSQL HA (using single-instance postgresql above) +postgresql-ha: + enabled: false + +# -- Disable Redis cluster (use in-memory cache instead) +redis-cluster: + enabled: false + +# -- Disable test pod +test: + enabled: false + +# -- SSH service (ClusterIP for now; enable NodePort if SSH access needed) +service: + ssh: + type: ClusterIP + port: 22 diff --git a/infra/values/keycloak-values.yaml b/infra/values/keycloak-values.yaml index bed8038..c3eaa8d 100644 --- a/infra/values/keycloak-values.yaml +++ b/infra/values/keycloak-values.yaml @@ -64,5 +64,21 @@ keycloakConfigCli: "registrationAllowed": false, "loginWithEmailAllowed": true, "resetPasswordAllowed": true, - "rememberMe": true + "rememberMe": true, + "clients": [ + { + "clientId": "gitea", + "name": "Gitea", + "enabled": true, + "protocol": "openid-connect", + "clientAuthenticatorType": "client-secret", + "secret": "382ed413580cb79d0f54813e5da87007b28fe766a8903d378b9e1c266405a784", + "standardFlowEnabled": true, + "directAccessGrantsEnabled": false, + "publicClient": false, + "redirectUris": ["https://git.forteapps.net/*"], + "webOrigins": ["https://git.forteapps.net"], + "defaultClientScopes": ["openid", "email", "profile"] + } + ] } diff --git a/secrets/gitea-credentials-sealed.yaml b/secrets/gitea-credentials-sealed.yaml new file mode 100644 index 0000000..e13a349 --- /dev/null +++ b/secrets/gitea-credentials-sealed.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: bitnami.com/v1alpha1 +kind: SealedSecret +metadata: + creationTimestamp: null + name: gitea-credentials + namespace: gitea +spec: + encryptedData: + key: AgAN7QteEqfzTrlCRR4Hi50nPJ6GGktFqOJIMgYvAL+es3ELUy9KLGtcyaC+Bf+b9lmG5+UgiCdz8jWbnVI7xEhDKXx8+3KzLw3nPAhYPO3j4XSi3FhbHwE0p5IGlZ0/XdXP5SRr/X0P6wQewapLSClGoya/ErY549ORfL0KgbcUrPE4ReSKbER6R/biRzSpkngxljf0rw4uruhNTlmBvnL/0nRSdZGtww7fLhcQceARutGihKHjOTkzmv0d39hHJA+4xNTi4PCbfOUJBkKwriy7NTi6AZkGRH2b06m+/IGfYYvTp/2gdtf/omS0ZhIoEVeRLhupiwkRAlclOSk3EXRsCcMiH8Gp5Mp4lUuc6yYHwM9ONAbq+P2OlUTjNDOntgH4Z6p02D3pIUf6nterSTuga7haGr5Ph0OCYBk/V6KkswwuTsSBAv7EI5TXrZoALp0xxXBXS459sc21UCgp2K5Xdhb3K92KwtcQDND7qAdIVZXAgf1wahm2svjRWhvjnRVLqChbb8MvkEQC+queHvQvIW+/5mCEb/hAEY/nAHJqTqQhsHnpPxzMhLvxN+7S2zvqSC48zSVAbKvwNjJcaiZ3s4dTjgCaryT307Gg4FI9bHixtk30fB9ZUkMu1cm51QC8ld5CBVKLMi8mHSezshiZ1n2PVYMiOivbghDZQxJ+uutZVOlrF65uAtgnQgmm9q/fTD7FWQ== + password: AgBdnjk041bBX2rwz+q1G6QDk+QrHfvuzoTo1pCRE1w7NLACFgGwzeSTS7gjPXwtjIkgganpZYgT9ZwWK8+gcT6Sae/CBTcDPgE6Y7FtfpG244wgp+mn891TDQXONW/OBAYk+706YDbHfqqz5AQxKAEorJ74RZuLTAo6kB85A/eveEnQqq4cByJaInz0eprB1A4hGfBLF3XArjiVdL7f4X33mR4scH80GozJiqUnG6ruVv5jcEBXnzySVrnCaq4VgmgJTu5Lsjz+AyH7niGTGFIsVBeOnVyeodKwgDk4N3HeSj4w9No3ileZELD5nLZh+/OqdQHw2niBz5/hPjDyXw/p96PfLM3CFygXfs/Au1DqdDf8ccZufhF9OK9CCQqlIgCWK3W7lhsdhcgK65XisRG+hh37Vcxke+A9ZoLGMjIT43KejTqwE8r3wRxPrmejBUcVHohiD7L60dFbcUp64hSBktcIGwEAWn89gmD7Ar1gCoCUmFCBCTVD8c5LQ2W2xeeZ1OrtDpMkOustzXUkzqkqiCB6TPMqDQ4J5FXCyoTuHrBnieLWaKL82kdUohF1+Jak3UGe0rSpOxBmoNC/17yVXyiwBGOUZZP+DJyvwiJu1jc7j3USQ0HRCcR7af96IcwGxge4yWbR268oI53yiJlwh46JFcc8RkxQQaq3Nh3RoiGJohqx/or8JOIFsXEtUW4WSLNQa2tZ4dxRI8F83JnBCo2W+zvL2yXKRP/LLMXfF7nAOuXPrYKrRcdnnRhP1cdDUSIQk8c6gzvKJrsEkt/j + secret: AgAR/5Tj79Rk4fgvPwvRU63q2xF0fokEe0/KWQG9CGiYWwut8wB8PlST5WEcKWIjwNfGpSsyHRQHywIVwDT3m+3/wxfQ5eOtlHIfMuglSymqeLHvj9tuM2EWabd4o9frKHHJigNojXS42JZ1jVSW+PeEfNrGFBARWWaDYSA5586/M8U5qi6UOBIkdyG+796wqqIeUM52d+/lwHHcETQOdhwa5/B4IrbRB33CSv0UHmfM+MeNtUWEnza5+8tm+1mPFyBJ2N9isXxMeyHXWutwOJVsAjEe+X35mC1C03eIsDjpmpjQ+hweUhinu6zse7CsIwcBDuq4/+1xd8xaQ/lmYc01FophuAcVRqDZIhlaAjCLI7gCfX2fliluVuaUbZ/A4DY8Q/psOteODeI0kVEMCaL13T1j6tZZWyDqDAB91xKFh2ne4DOOTwkZLP2StMt7rAENy/eMld+VNrfNliHJUVJGMoPTzCxPaZQxJfRYIbpE5uGGA2fWkteuX5VJRqZ/8JshdBAUVG1XOSXlvM1zlW9KlyvO3j3KhekKG7bY+NndIwFMNhujG3FGWCA+k3MYQfAks3FWhW+ZXA0vYZpnPOJuYO5tqqDO4GLsrdJc5GaXMC7kcey90PqkwzkwhpxX7/X414w3bHWoYttmFCcQwSyA+S029gSFBIleNTKkjpXsNl8qB2NDJR1lf2kufO016WP07PB1NK0hGjvI0isz0uHZILrAD0i55t858/EjWsD2gg7jK2ww69vVxi2c2o6k370YVv92qoZCayTuYsXF0Ay6 + username: AgAmO891YOV8ZtWTNjOF+ZA+6yG69Jdvozq49/XCQabuVXSqoESWA/V/6RPL8+up8dFa+c/u0J+s+Pu1cJL5zjZmJtXStOIuhoIGBTkWBPgHQ11hp/5apkR4nt0gWR3fWQtz1v/073WsaQGhEyKHB4ZsxAXbwEQ41f+TQzdkvxu2DT07Kc4O0jN+QsAl/YtPLk2YW2WaiY/Q7dDq5+LKAbKVRR4Aa03OuMVDapPGOEogu3wC8vl9lkYMhPBrIosq9ycqk4roenKbtmFSIkzytLOLRKSNEmPUSklDMrO8HEGSByASxJP10jgUZW9wY4lE/DmsjuS2CQsGLXhZAye2S3hgGyewnIA1ZfsnJTb7jSsnQ0BVxm6HL9lKy/1PqDzMuE0Ou+LHiIt5DLbCrDmn0F+n8jhNlpCbtiZXVL/Tvo7SAruBe858CYXc2StFHNi5hA1dRP2CCGklY2Wmi8u5JeOdi8RXdhw8deZtI0G+I1NltqzhXdDR55kMWahy2BTImJrGj8owrdg5bFz1Ne63P7jiS80BeUfDKffYAWuslDEiKkhO8YSoVj7ixeWIfXvZRyaecaCMcZ+VuNlZy3R5CbFTcIyZkfotK0+aA9S/q+iM6K36ghTxpQv6WSecnHpeR8mkVckCGVo+iiCPIFfQw2VwOHn+BtvbH8pfr0McKoGHAvoDGGH9sjgDbjAGwCYFYr7qHTKaFc1vbVcUNw== + template: + metadata: + creationTimestamp: null + name: gitea-credentials + namespace: gitea