From 422f568c8e1ced3d08b829a1e9f75b6b6e4a0cf8 Mon Sep 17 00:00:00 2001 From: Automated pipeline Date: Mon, 8 Jun 2026 12:15:27 +0000 Subject: [PATCH] Automated upload for dev.t09.de --- .../stacks/ci-sizer/gitlab-webhook.yaml | 29 ++++ .../ci-sizer/gitlab-webhook/certificates.yaml | 27 ++++ .../ci-sizer/gitlab-webhook/deployment.yaml | 141 ++++++++++++++++++ .../gitlab-webhook/webhook-config.yaml | 30 ++++ .../stacks/ci-sizer/sizer-receiver.yaml | 4 + .../ci-sizer/sizer-receiver/deployment.yaml | 2 +- .../ci-sizer/sizer-receiver/ingress.yaml | 10 ++ otc/dev.t09.de/stacks/core/argocd/values.yaml | 4 +- otc/dev.t09.de/stacks/core/dex/values.yaml | 2 +- .../stacks/core/secrets-backup.yaml | 23 +++ .../manifests/secrets-backup-cronjob.yaml | 129 ++++++++++++++++ .../forgejo/forgejo-runner/dind-docker.yaml | 2 +- .../manifests/forgejo-s3-backup-cronjob.yaml | 2 +- .../stacks/forgejo/forgejo-server/values.yaml | 2 +- otc/dev.t09.de/stacks/garm/garm.yaml | 6 +- otc/dev.t09.de/stacks/garm/garm/values.yaml | 11 +- 16 files changed, 407 insertions(+), 17 deletions(-) create mode 100644 otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook.yaml create mode 100644 otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/certificates.yaml create mode 100644 otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/deployment.yaml create mode 100644 otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/webhook-config.yaml create mode 100644 otc/dev.t09.de/stacks/core/secrets-backup.yaml create mode 100644 otc/dev.t09.de/stacks/core/secrets-backup/manifests/secrets-backup-cronjob.yaml diff --git a/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook.yaml b/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook.yaml new file mode 100644 index 0000000..c02e1cc --- /dev/null +++ b/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook.yaml @@ -0,0 +1,29 @@ +# Optional: GitLab CI integration +# Only hydrate this app for clusters that run GitLab Runner. +# For Forgejo/GitHub-only deployments, omit this app from stacks-instances. +# See: ci-sizer/docs/deployment-modes.md +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: gitlab-sizer-webhook + namespace: argocd + labels: + env: dev + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + syncPolicy: + automated: + selfHeal: true + syncOptions: + - CreateNamespace=true + retry: + limit: -1 + destination: + name: in-cluster + namespace: ci-sizer + source: + repoURL: https://edp.buildth.ing/DevFW-CICD/stacks-instances + targetRevision: HEAD + path: "otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook" diff --git a/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/certificates.yaml b/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/certificates.yaml new file mode 100644 index 0000000..ee1fece --- /dev/null +++ b/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/certificates.yaml @@ -0,0 +1,27 @@ +# Self-signed Issuer for webhook TLS. +# For production, replace with a ClusterIssuer backed by a real CA. +apiVersion: cert-manager.io/v1 +kind: Issuer +metadata: + name: selfsigned-issuer +spec: + selfSigned: {} +--- +# cert-manager Certificate for the webhook TLS. +# The resulting Secret (gitlab-sizer-webhook-tls) is mounted into the webhook pod. +# cert-manager also injects the CA into the MutatingWebhookConfiguration via the +# cert-manager.io/inject-ca-from annotation. +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: gitlab-sizer-webhook-cert +spec: + secretName: gitlab-sizer-webhook-tls + issuerRef: + name: selfsigned-issuer + kind: Issuer + dnsNames: + - gitlab-sizer-webhook.ci-sizer.svc + - gitlab-sizer-webhook.ci-sizer.svc.cluster.local + duration: 8760h + renewBefore: 720h diff --git a/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/deployment.yaml b/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/deployment.yaml new file mode 100644 index 0000000..0b99859 --- /dev/null +++ b/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/deployment.yaml @@ -0,0 +1,141 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: gitlab-sizer-webhook +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: gitlab-sizer-webhook +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: gitlab-sizer-webhook +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: gitlab-sizer-webhook +subjects: + - kind: ServiceAccount + name: gitlab-sizer-webhook + namespace: ci-sizer +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gitlab-sizer-webhook + labels: + app: gitlab-sizer-webhook +spec: + replicas: 2 + selector: + matchLabels: + app: gitlab-sizer-webhook + template: + metadata: + labels: + app: gitlab-sizer-webhook + spec: + serviceAccountName: gitlab-sizer-webhook + securityContext: + runAsNonRoot: true + runAsUser: 65534 + runAsGroup: 65534 + seccompProfile: + type: RuntimeDefault + containers: + - name: webhook + image: edp.buildth.ing/devfw-cicd/gitlab-webhook-edge-connect:latest + imagePullPolicy: Always + securityContext: + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + capabilities: + drop: + - ALL + ports: + - containerPort: 8443 + protocol: TCP + args: + - --listen-addr=:8443 + - --tls-cert-file=/etc/webhook/tls/tls.crt + - --tls-key-file=/etc/webhook/tls/tls.key + - --sizer-url=http://sizer-receiver.ci-sizer.svc:8080 + - --sizer-sidecar-image=edp.buildth.ing/devfw-cicd/ci-sizer-collector:latest + env: + - name: WEBHOOK_SIZER_READ_TOKEN + valueFrom: + secretKeyRef: + name: gitlab-sizer-webhook-tokens + key: sizer-read-token + - name: WEBHOOK_SIZER_PUSH_TOKEN + valueFrom: + secretKeyRef: + name: gitlab-sizer-webhook-tokens + key: sizer-push-token + - name: HTTP_PROXY + valueFrom: + configMapKeyRef: + name: gitlab-sizer-webhook-config + key: HTTP_PROXY + optional: true + - name: HTTPS_PROXY + valueFrom: + configMapKeyRef: + name: gitlab-sizer-webhook-config + key: HTTPS_PROXY + optional: true + - name: NO_PROXY + valueFrom: + configMapKeyRef: + name: gitlab-sizer-webhook-config + key: NO_PROXY + optional: true + volumeMounts: + - name: webhook-tls + mountPath: /etc/webhook/tls + readOnly: true + livenessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /healthz + port: 8443 + scheme: HTTPS + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + requests: + cpu: 100m + memory: 128Mi + limits: + cpu: 200m + memory: 128Mi + volumes: + - name: webhook-tls + secret: + secretName: gitlab-sizer-webhook-tls +--- +apiVersion: v1 +kind: Service +metadata: + name: gitlab-sizer-webhook + labels: + app: gitlab-sizer-webhook +spec: + selector: + app: gitlab-sizer-webhook + ports: + - port: 443 + targetPort: 8443 + protocol: TCP diff --git a/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/webhook-config.yaml b/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/webhook-config.yaml new file mode 100644 index 0000000..72aea4a --- /dev/null +++ b/otc/dev.t09.de/stacks/ci-sizer/gitlab-webhook/webhook-config.yaml @@ -0,0 +1,30 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + name: gitlab-sizer-webhook + annotations: + cert-manager.io/inject-ca-from: ci-sizer/gitlab-sizer-webhook-cert +webhooks: + - name: gitlab-sizer-webhook.ci-sizer.svc + admissionReviewVersions: ["v1"] + sideEffects: NoneOnDryRun + failurePolicy: Ignore + timeoutSeconds: 5 + reinvocationPolicy: Never + clientConfig: + service: + name: gitlab-sizer-webhook + namespace: ci-sizer + path: /mutate + rules: + - apiGroups: [""] + apiVersions: ["v1"] + operations: ["CREATE"] + resources: ["pods"] + namespaceSelector: + matchLabels: + ci-sizer.devfw.io/watch: "true" + objectSelector: + matchExpressions: + - key: job.runner.gitlab.com/pod + operator: Exists diff --git a/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver.yaml b/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver.yaml index 4f1b6bc..1f56541 100644 --- a/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver.yaml +++ b/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver.yaml @@ -1,3 +1,7 @@ +# Required: CI Sizer receiver +# Always deploy this — it stores metrics and computes sizing recommendations. +# Works standalone or with GARM (Forgejo/GitHub) and/or GitLab webhook. +# See: ci-sizer/docs/deployment-modes.md apiVersion: argoproj.io/v1alpha1 kind: Application metadata: diff --git a/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver/deployment.yaml b/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver/deployment.yaml index ccb6a86..3cbfb4c 100644 --- a/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver/deployment.yaml +++ b/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver/deployment.yaml @@ -62,7 +62,7 @@ spec: - name: RECEIVER_SESSION_TTL value: "12h" - name: RECEIVER_ALLOWED_ORG - value: "DevFW" + value: "DevFW-CICD" - name: RECEIVER_CPU_SIZING_MODE value: "observe" - name: RECEIVER_MEMORY_QOS diff --git a/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver/ingress.yaml b/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver/ingress.yaml index 9a28977..1bd81a9 100644 --- a/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver/ingress.yaml +++ b/otc/dev.t09.de/stacks/ci-sizer/sizer-receiver/ingress.yaml @@ -20,6 +20,16 @@ spec: number: 8080 path: / pathType: Prefix + - host: ci-sizer.dev.t09.de + http: + paths: + - backend: + service: + name: sizer-receiver + port: + number: 8080 + path: / + pathType: Prefix tls: - hosts: - sizer.dev.t09.de diff --git a/otc/dev.t09.de/stacks/core/argocd/values.yaml b/otc/dev.t09.de/stacks/core/argocd/values.yaml index 53cac97..dd5b83d 100644 --- a/otc/dev.t09.de/stacks/core/argocd/values.yaml +++ b/otc/dev.t09.de/stacks/core/argocd/values.yaml @@ -30,9 +30,7 @@ configs: - "*" url: https://argocd.dev.t09.de rbac: - policy.csv: | - g, DevFW, role:admin - g, DevFW-CICD, role:admin + policy.csv: 'g, DevFW, role:admin' tls: certificates: diff --git a/otc/dev.t09.de/stacks/core/dex/values.yaml b/otc/dev.t09.de/stacks/core/dex/values.yaml index c3e842a..6f4955b 100644 --- a/otc/dev.t09.de/stacks/core/dex/values.yaml +++ b/otc/dev.t09.de/stacks/core/dex/values.yaml @@ -37,7 +37,7 @@ envVars: - name: FORGEJO_RUNNER_SIZER_CLIENT_SECRET valueFrom: secretKeyRef: - name: dex-runner-sizer-client + name: dex-sizer-client key: clientSecret - name: LOG_LEVEL value: debug diff --git a/otc/dev.t09.de/stacks/core/secrets-backup.yaml b/otc/dev.t09.de/stacks/core/secrets-backup.yaml new file mode 100644 index 0000000..1f33c8d --- /dev/null +++ b/otc/dev.t09.de/stacks/core/secrets-backup.yaml @@ -0,0 +1,23 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: secrets-backup + namespace: argocd + labels: + env: dev +spec: + project: default + syncPolicy: + automated: + selfHeal: true + syncOptions: + - CreateNamespace=true + retry: + limit: -1 + destination: + name: in-cluster + namespace: gitea + sources: + - repoURL: https://edp.buildth.ing/DevFW-CICD/stacks-instances + targetRevision: HEAD + path: "otc/dev.t09.de/stacks/core/secrets-backup/manifests" diff --git a/otc/dev.t09.de/stacks/core/secrets-backup/manifests/secrets-backup-cronjob.yaml b/otc/dev.t09.de/stacks/core/secrets-backup/manifests/secrets-backup-cronjob.yaml new file mode 100644 index 0000000..bd1f913 --- /dev/null +++ b/otc/dev.t09.de/stacks/core/secrets-backup/manifests/secrets-backup-cronjob.yaml @@ -0,0 +1,129 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: secrets-backup + namespace: gitea +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: secrets-backup-reader +rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list"] + - apiGroups: [""] + resources: ["namespaces"] + verbs: ["get", "list"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: secrets-backup-reader +subjects: + - kind: ServiceAccount + name: secrets-backup + namespace: gitea +roleRef: + kind: ClusterRole + name: secrets-backup-reader + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: v1 +kind: Secret +metadata: + name: secrets-backup-config + namespace: gitea +type: Opaque +stringData: + # IMPORTANT: Replace this placeholder with a strong passphrase per environment. + # This secret should be managed via external-secrets or manually set after initial deploy. + encryption-passphrase: "CHANGE-ME-SET-PER-ENVIRONMENT" +--- +apiVersion: batch/v1 +kind: CronJob +metadata: + name: secrets-backup + namespace: gitea +spec: + schedule: "30 3 * * *" + concurrencyPolicy: "Forbid" + successfulJobsHistoryLimit: 5 + failedJobsHistoryLimit: 5 + startingDeadlineSeconds: 600 # 10 minutes + jobTemplate: + spec: + activeDeadlineSeconds: 900 + backoffLimit: 2 + ttlSecondsAfterFinished: 259200 + template: + spec: + serviceAccountName: secrets-backup + containers: + - name: secrets-backup + image: alpine/k8s:1.28.0 + imagePullPolicy: IfNotPresent + env: + - name: AWS_ACCESS_KEY_ID + valueFrom: + secretKeyRef: + name: forgejo-cloud-credentials + key: access-key + - name: AWS_SECRET_ACCESS_KEY + valueFrom: + secretKeyRef: + name: forgejo-cloud-credentials + key: secret-key + - name: ENCRYPTION_PASSPHRASE + valueFrom: + secretKeyRef: + name: secrets-backup-config + key: encryption-passphrase + - name: SOURCE_BUCKET + valueFrom: + secretKeyRef: + name: forgejo-cloud-credentials + key: bucket-name + - name: OBS_ENDPOINT + value: "obs.eu-de.otc.t-systems.com" + command: + - /bin/sh + - -c + - | + set -euo pipefail + + TIMESTAMP=$(date +%Y%m%d-%H%M%S) + BACKUP_DIR="/tmp/secrets-backup-${TIMESTAMP}" + NAMESPACES="argocd cert-manager external-secrets" + + mkdir -p "${BACKUP_DIR}" + + echo "=== Exporting secrets from critical namespaces ===" + for NS in ${NAMESPACES}; do + echo "Exporting namespace: ${NS}" + kubectl get secrets -n "${NS}" \ + -o json \ + --field-selector type!=kubernetes.io/service-account-token \ + > "${BACKUP_DIR}/${NS}-secrets.json" + done + + echo "=== Encrypting backup with AES-256-CBC ===" + ARCHIVE="${BACKUP_DIR}/secrets-backup-${TIMESTAMP}.tar.gz" + tar -czf "${ARCHIVE}" -C "${BACKUP_DIR}" \ + $(ls "${BACKUP_DIR}"/*.json 2>/dev/null | xargs -n1 basename) + + ENCRYPTED="${BACKUP_DIR}/secrets-backup-${TIMESTAMP}.tar.gz.enc" + openssl enc -aes-256-cbc -salt -pbkdf2 -iter 100000 \ + -in "${ARCHIVE}" \ + -out "${ENCRYPTED}" \ + -pass env:ENCRYPTION_PASSPHRASE + + echo "=== Uploading to OBS ===" + aws s3 cp "${ENCRYPTED}" \ + "s3://${SOURCE_BUCKET}/cluster-secrets-backup/${TIMESTAMP}/secrets-backup.tar.gz.enc" \ + --endpoint-url "https://${OBS_ENDPOINT}" + + echo "=== Cleanup ===" + rm -rf "${BACKUP_DIR}" + echo "Backup completed: ${TIMESTAMP}" + restartPolicy: OnFailure diff --git a/otc/dev.t09.de/stacks/forgejo/forgejo-runner/dind-docker.yaml b/otc/dev.t09.de/stacks/forgejo/forgejo-runner/dind-docker.yaml index 093a819..bcdb719 100644 --- a/otc/dev.t09.de/stacks/forgejo/forgejo-runner/dind-docker.yaml +++ b/otc/dev.t09.de/stacks/forgejo/forgejo-runner/dind-docker.yaml @@ -7,7 +7,7 @@ metadata: namespace: gitea spec: # Two replicas means that if one is busy, the other can pick up jobs. - replicas: 0 + replicas: 3 selector: matchLabels: app: forgejo-runner diff --git a/otc/dev.t09.de/stacks/forgejo/forgejo-server/manifests/forgejo-s3-backup-cronjob.yaml b/otc/dev.t09.de/stacks/forgejo/forgejo-server/manifests/forgejo-s3-backup-cronjob.yaml index 1251a81..de14801 100644 --- a/otc/dev.t09.de/stacks/forgejo/forgejo-server/manifests/forgejo-s3-backup-cronjob.yaml +++ b/otc/dev.t09.de/stacks/forgejo/forgejo-server/manifests/forgejo-s3-backup-cronjob.yaml @@ -72,7 +72,7 @@ spec: - ReadWriteOnce resources: requests: - storage: 100Gi + storage: 500Gi --- apiVersion: v1 kind: Secret diff --git a/otc/dev.t09.de/stacks/forgejo/forgejo-server/values.yaml b/otc/dev.t09.de/stacks/forgejo/forgejo-server/values.yaml index ec901a0..a8a173e 100644 --- a/otc/dev.t09.de/stacks/forgejo/forgejo-server/values.yaml +++ b/otc/dev.t09.de/stacks/forgejo/forgejo-server/values.yaml @@ -178,6 +178,6 @@ image: #tag: "8.0.3" # Adds -rootless suffix to image name # rootless: true - fullOverride: edp.buildth.ing/devfw-cicd/edp-forgejo:workflow-webhook-20260305 + fullOverride: edp.buildth.ing/devfw-cicd/edp-forgejo:14.0.2-edp1-rootless forgejo: {} diff --git a/otc/dev.t09.de/stacks/garm/garm.yaml b/otc/dev.t09.de/stacks/garm/garm.yaml index 911f2cf..a0bbd69 100644 --- a/otc/dev.t09.de/stacks/garm/garm.yaml +++ b/otc/dev.t09.de/stacks/garm/garm.yaml @@ -1,3 +1,7 @@ +# Default: Forgejo/GitHub Actions runner manager +# Deploys GARM with the ci-sizer provider for automatic sizing + collector injection. +# For GitLab-only deployments, omit this and use gitlab-webhook instead. +# See: ci-sizer/docs/deployment-modes.md apiVersion: argoproj.io/v1alpha1 kind: Application metadata: @@ -20,7 +24,7 @@ spec: sources: - repoURL: https://edp.buildth.ing/DevFW-CICD/garm-helm path: charts/garm - targetRevision: v0.0.17 + targetRevision: v0.0.16 helm: valueFiles: - $values/otc/dev.t09.de/stacks/garm/garm/values.yaml diff --git a/otc/dev.t09.de/stacks/garm/garm/values.yaml b/otc/dev.t09.de/stacks/garm/garm/values.yaml index e1ee11d..827e495 100644 --- a/otc/dev.t09.de/stacks/garm/garm/values.yaml +++ b/otc/dev.t09.de/stacks/garm/garm/values.yaml @@ -26,7 +26,7 @@ credentials: image: repository: edp.buildth.ing/devfw-cicd/garm-forgejo - tag: v0.1.7-forgejo-22 + tag: v0.1.7-forgejo-23 providerConfig: edgeConnect: @@ -37,14 +37,9 @@ providerConfig: name: Hamburg organization: TelekomOP edgeConnectK8s: - pendingTimeout: "5m" sizer: - sidecarImage: edp.buildth.ing/devfw-cicd/ci-sizer-collector:latest - sidecarPushEndpoint: https://sizer.dev.t09.de/api/v1/metrics - baseUrl: "https://sizer.dev.t09.de" - readToken: - existingSecretName: sizer-tokens + sidecarImage: edp.buildth.ing/devfw-cicd/ci-sizer-collector:0.0.4 garm: logging: - logLevel: debug + logLevel: info