diff --git a/clusters/cl01tl/platform/gitea/Chart.yaml b/clusters/cl01tl/platform/gitea/Chart.yaml new file mode 100644 index 000000000..144180b19 --- /dev/null +++ b/clusters/cl01tl/platform/gitea/Chart.yaml @@ -0,0 +1,37 @@ +apiVersion: v2 +name: gitea +version: 1.0.0 +description: Gitea +keywords: + - gitea + - git + - code +home: https://wiki.alexlebens.dev/doc/gitea-OgqW6bQWrW +sources: + - https://github.com/go-gitea/gitea + - https://github.com/cloudflare/cloudflared + - https://github.com/cloudnative-pg/cloudnative-pg + - https://hub.docker.com/r/gitea/gitea + - https://gitea.com/gitea/helm-chart + - https://github.com/alexlebens/helm-charts/tree/main/charts/cloudflared + - https://github.com/alexlebens/helm-charts/tree/main/charts/postgres-cluster +maintainers: + - name: alexlebens +dependencies: + - name: gitea + version: 10.6.0 + repository: https://dl.gitea.io/charts/ + - name: cloudflared + alias: cloudflared + repository: http://alexlebens.github.io/helm-charts + version: 1.14.0 + # - name: app-template + # alias: backup + # repository: https://bjw-s.github.io/helm-charts/ + # version: 3.7.1 + - name: postgres-cluster + alias: postgres-17-cluster + version: 4.2.0 + repository: http://alexlebens.github.io/helm-charts +icon: https://raw.githubusercontent.com/walkxcode/dashboard-icons/main/png/gitea.png +appVersion: 1.22.4 diff --git a/clusters/cl01tl/platform/gitea/templates/external-secret.yaml b/clusters/cl01tl/platform/gitea/templates/external-secret.yaml new file mode 100644 index 000000000..f7e49dd6b --- /dev/null +++ b/clusters/cl01tl/platform/gitea/templates/external-secret.yaml @@ -0,0 +1,176 @@ +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-admin-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-admin-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: username + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/gitea/auth/admin + metadataPolicy: None + property: username + - secretKey: password + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/gitea/auth/admin + metadataPolicy: None + property: password + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-oidc-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-oidc-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: secret + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/gitea + metadataPolicy: None + property: secret + - secretKey: key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /authentik/oidc/gitea + metadataPolicy: None + property: client + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-cloudflared-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-cloudflared-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: cf-tunnel-token + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cloudflare/tunnels/gitea + metadataPolicy: None + property: token + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-backup-s3 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-backup-s3 + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: AWS_ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /digital-ocean/home-infra/gitea-backup + metadataPolicy: None + property: AWS_ACCESS_KEY_ID + - secretKey: AWS_SECRET_ACCESS_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /digital-ocean/home-infra/gitea-backup + metadataPolicy: None + property: AWS_SECRET_ACCESS_KEY + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-s3cmd-config + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-s3cmd-s3 + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: .s3cfg + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/gitea/backup + metadataPolicy: None + property: s3cfg + +--- +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: gitea-postgresql-17-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-postgresql-17-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: database + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /digital-ocean/home-infra/postgres-backups + metadataPolicy: None + property: access + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /digital-ocean/home-infra/postgres-backups + metadataPolicy: None + property: secret diff --git a/clusters/cl01tl/platform/gitea/templates/http-route.yaml b/clusters/cl01tl/platform/gitea/templates/http-route.yaml new file mode 100644 index 000000000..6d5ace299 --- /dev/null +++ b/clusters/cl01tl/platform/gitea/templates/http-route.yaml @@ -0,0 +1,30 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-route-gitea + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: http-route-gitea + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: web + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: traefik-gateway + namespace: traefik + hostnames: + - gitea.alexlebens.net + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - group: '' + kind: Service + name: gitea-http + port: 3000 + weight: 100 diff --git a/clusters/cl01tl/platform/gitea/templates/ingress.yaml b/clusters/cl01tl/platform/gitea/templates/ingress.yaml new file mode 100644 index 000000000..473208441 --- /dev/null +++ b/clusters/cl01tl/platform/gitea/templates/ingress.yaml @@ -0,0 +1,32 @@ +# apiVersion: networking.k8s.io/v1 +# kind: Ingress +# metadata: +# name: gitea-tailscale +# namespace: {{ .Release.Namespace }} +# labels: +# app.kubernetes.io/name: gitea-tailscale +# app.kubernetes.io/instance: {{ .Release.Name }} +# app.kubernetes.io/version: {{ .Chart.AppVersion }} +# app.kubernetes.io/component: web +# app.kubernetes.io/part-of: {{ .Release.Name }} +# labels: +# tailscale.com/proxy-class: no-metrics +# annotations: +# tailscale.com/experimental-forward-cluster-traffic-via-ingress: "true" +# spec: +# ingressClassName: tailscale +# tls: +# - hosts: +# - gitea-cl01tl +# secretName: gitea-cl01tl +# rules: +# - host: gitea-cl01tl +# http: +# paths: +# - path: / +# pathType: ImplementationSpecific +# backend: +# service: +# name: gitea-http +# port: +# name: http diff --git a/clusters/cl01tl/platform/gitea/templates/persistent-volume-claim.yaml b/clusters/cl01tl/platform/gitea/templates/persistent-volume-claim.yaml new file mode 100644 index 000000000..e3c2e4704 --- /dev/null +++ b/clusters/cl01tl/platform/gitea/templates/persistent-volume-claim.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: gitea-nfs-storage-backup + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-nfs-storage-backup + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: storage + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + volumeMode: Filesystem + storageClassName: nfs-client + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi diff --git a/clusters/cl01tl/platform/gitea/templates/role-binding.yaml b/clusters/cl01tl/platform/gitea/templates/role-binding.yaml new file mode 100644 index 000000000..527cf0f94 --- /dev/null +++ b/clusters/cl01tl/platform/gitea/templates/role-binding.yaml @@ -0,0 +1,19 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: gitea-backup + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-backup + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: {{ .Release.Name }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: gitea-backup +subjects: + - kind: ServiceAccount + name: gitea-backup + namespace: {{ .Release.Namespace }} diff --git a/clusters/cl01tl/platform/gitea/templates/role.yaml b/clusters/cl01tl/platform/gitea/templates/role.yaml new file mode 100644 index 000000000..56908b3c8 --- /dev/null +++ b/clusters/cl01tl/platform/gitea/templates/role.yaml @@ -0,0 +1,27 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: gitea-backup + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: gitea-backup + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/version: {{ .Chart.AppVersion }} + app.kubernetes.io/component: backup + app.kubernetes.io/part-of: {{ .Release.Name }} +rules: + - apiGroups: + - "" + resources: + - pods + - pods/exec + verbs: + - create + - list + - apiGroups: + - apps + resources: + - deployments + verbs: + - get + - list diff --git a/clusters/cl01tl/platform/gitea/values.yaml b/clusters/cl01tl/platform/gitea/values.yaml new file mode 100644 index 000000000..f8a7cdebe --- /dev/null +++ b/clusters/cl01tl/platform/gitea/values.yaml @@ -0,0 +1,198 @@ +gitea: + image: + repository: gitea/gitea + tag: 1.23.4 + service: + http: + type: ClusterIP + port: 3000 + clusterIP: 10.103.160.139 + ssh: + type: ClusterIP + port: 2222 + clusterIP: 10.103.160.140 + ingress: + enabled: false + persistence: + storageClass: ceph-block + extraVolumes: + - name: gitea-nfs-storage-backup + persistentVolumeClaim: + claimName: gitea-nfs-storage-backup + extraVolumeMounts: + - mountPath: /opt/backup + name: gitea-nfs-storage-backup + readOnly: false + gitea: + # admin: + # existingSecret: gitea-admin-secret + metrics: + enabled: true + serviceMonitor: + enabled: true + oauth: + - name: Authentik + provider: openidConnect + existingSecret: gitea-oidc-secret + autoDiscoverUrl: https://auth.alexlebens.dev/application/o/gitea/.well-known/openid-configuration + iconUrl: https://goauthentik.io/img/icon.png + scopes: "email profile" + config: + APP_NAME: Gitea + server: + PROTOCOL: http + DOMAIN: gitea.alexlebens.dev + ROOT_URL: https://gitea.alexlebens.dev + LOCAL_ROOT_URL: http://gitea-http.gitea.svc.cluster.local:3000 + START_SSH_SERVER: true + SSH_DOMAIN: gitea-ssh.gitea + SSH_PORT: 2222 + SSH_LISTEN_PORT: 2222 + ENABLE_PPROF: true + LANDING_PAGE: explore + database: + DB_TYPE: postgres + SCHEMA: public + oauth2_client: + ENABLE_AUTO_REGISTRATION: true + service: + REGISTER_MANUAL_CONFIRM: true + SHOW_REGISTRATION_BUTTON: false + ALLOW_ONLY_EXTERNAL_REGISTRATION: true + explore: + REQUIRE_SIGNIN_VIEW: true + webhook: + ALLOWED_HOST_LIST: private + mirror: + DEFAULT_INTERVAL: 10m + additionalConfigFromEnvs: + - name: GITEA__DATABASE__HOST + valueFrom: + secretKeyRef: + name: gitea-postgresql-17-cluster-app + key: host + - name: GITEA__DATABASE__NAME + valueFrom: + secretKeyRef: + name: gitea-postgresql-17-cluster-app + key: dbname + - name: GITEA__DATABASE__USER + valueFrom: + secretKeyRef: + name: gitea-postgresql-17-cluster-app + key: user + - name: GITEA__DATABASE__PASSWD + valueFrom: + secretKeyRef: + name: gitea-postgresql-17-cluster-app + key: password + memcached: + enabled: true + redis: + enabled: false + redis-cluster: + enabled: false + postgresql: + enabled: false + postgresql-ha: + enabled: false + mysql: + enabled: false + mariadb: + enabled: false +cloudflared: + existingSecretName: gitea-cloudflared-secret +backup: + global: + fullnameOverride: gitea-backup + controllers: + backup: + type: cronjob + cronjob: + suspend: false + concurrencyPolicy: Forbid + timeZone: US/Central + schedule: 0 4 * * * + startingDeadlineSeconds: 90 + successfulJobsHistory: 3 + failedJobsHistory: 3 + backoffLimit: 3 + parallelism: 1 + initContainers: + backup: + image: + repository: bitnami/kubectl + tag: 1.32.2 + pullPolicy: IfNotPresent + command: + - sh + args: + - -ec + - | + kubectl exec -it deploy/gitea -n gitea -- rm -f /opt/backup/gitea-backup.zip; + kubectl exec -it deploy/gitea -n gitea -- /app/gitea/gitea dump -c /data/gitea/conf/app.ini --file /opt/backup/gitea-backup.zip; + resources: + requests: + cpu: 100m + memory: 128Mi + containers: + s3: + image: + repository: d3fk/s3cmd + tag: latest@sha256:4bdc8e5817cbdd048e6dc487f42e3d96a6b58af69b4be6f256de5e2416da90e9 + pullPolicy: IfNotPresent + command: + - /bin/sh + args: + - -ec + - | + s3cmd put --no-check-md5 --no-check-certificate /opt/backup/gitea-backup.zip s3://gitea-backups-8ba8dae3674a2f53354c600e/cl01tl/cl01tl-gitea-backups/gitea-backup-$(date +"%Y%m%d-%H-%M").zip; + mv /opt/backup/gitea-backup.zip /opt/backup/gitea-backup-$(date +"%Y%m%d-%H-%M").zip; + envFrom: + - secretRef: + name: gitea-backup-s3 + resources: + requests: + cpu: 100m + memory: 128Mi + serviceAccount: + create: true + persistence: + config: + existingClaim: gitea-nfs-storage-backup + advancedMounts: + backup: + s3: + - path: /opt/backup + readOnly: false + s3cmd-config: + enabled: true + type: secret + name: gitea-s3cmd-config + advancedMounts: + backup: + s3: + - path: /root/.s3cfg + readOnly: true + mountPropagation: None + subPath: .s3cfg +postgres-17-cluster: + mode: recovery + cluster: + walStorage: + storageClass: local-path + storage: + storageClass: local-path + monitoring: + enabled: true + recovery: + endpointURL: https://nyc3.digitaloceanspaces.com + destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/gitea/gitea-postgresql-17-cluster + endpointCredentials: gitea-postgresql-17-cluster-backup-secret + recoveryIndex: 2 + backup: + enabled: false + endpointURL: https://nyc3.digitaloceanspaces.com + destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/gitea/gitea-postgresql-17-cluster + endpointCredentials: gitea-postgresql-17-cluster-backup-secret + backupIndex: 3