feat(eso): chart 0.7.0 — migrate all 4 remaining Tower-stamped Secrets to ExternalSecret

Phase 2 of Item #9. Adds ExternalSecret manifests for:
  - docker-mirror-pull (×2 namespaces, dockerconfigjson template)
  - cloudflare-api-token-<slug> (per-tenant, gated on tenant.id+slug)
  - s3-backup-creds (per-tenant, in tenants ns)
  - longhorn-s3-creds (per-tenant, gated on tenant.s3Endpoint)

New helm values: tenant.id, tenant.slug, tenant.s3Endpoint. Tower must
pass these per-cluster (next ship). All manifests gated on
externalSecrets.enabled + mountPath set + tenant.id set, so old apps
without the new params remain on the legacy Tower-stamped path until
the operator opts them in.
This commit is contained in:
OdooSky v3
2026-05-07 21:25:41 +03:00
parent 52a157f187
commit c26ee5b3c6
6 changed files with 185 additions and 2 deletions

View File

@@ -23,8 +23,8 @@ description: |
Git). Git).
type: application type: application
version: 0.6.2 version: 0.7.0
appVersion: "0.6.2" appVersion: "0.7.0"
dependencies: dependencies:
- name: cert-manager - name: cert-manager

View File

@@ -0,0 +1,32 @@
{{- if .Values.externalSecrets.enabled }}
{{- if .Values.externalSecrets.openbao.mountPath }}
{{- if and .Values.tenant.id .Values.tenant.slug }}
# cloudflare-api-token-<slug> — per-tenant CF token used by cert-manager's
# DNS-01 solver. Pulled from OpenBao path v3/tenants/<id>/cloudflare-token,
# field api_token, exposed as Secret key "api-token" (matches what the
# ClusterIssuer references via secretKeyRef.key in cluster-issuer.yaml).
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: cloudflare-api-token-{{ .Values.tenant.slug }}
namespace: odoosky-system
labels:
app.kubernetes.io/managed-by: cluster-platform-v3
odoosky.io/tenant: {{ .Values.tenant.id | quote }}
spec:
refreshInterval: "1h"
secretStoreRef:
name: openbao-platform
kind: ClusterSecretStore
target:
name: cloudflare-api-token-{{ .Values.tenant.slug }}
creationPolicy: Owner
deletionPolicy: Retain
data:
- secretKey: api-token
remoteRef:
key: tenants/{{ .Values.tenant.id }}/cloudflare-token
property: api_token
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,46 @@
{{- if .Values.externalSecrets.enabled }}
{{- if .Values.externalSecrets.openbao.mountPath }}
# docker-mirror-pull — platform-wide registry credential. Two ExternalSecrets
# (one per namespace the chart consumes the Secret in) sourced from the same
# OpenBao path. Type kubernetes.io/dockerconfigjson rendered via ESO template
# from the registry/username/password fields stored in OpenBao.
{{- range $ns := list "odoosky-system" "tenants" }}
---
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: docker-mirror-pull
namespace: {{ $ns }}
labels:
app.kubernetes.io/managed-by: cluster-platform-v3
spec:
refreshInterval: "1h"
secretStoreRef:
name: openbao-platform
kind: ClusterSecretStore
target:
name: docker-mirror-pull
creationPolicy: Owner
deletionPolicy: Retain
template:
type: kubernetes.io/dockerconfigjson
engineVersion: v2
data:
.dockerconfigjson: |
{{ `{"auths":{"{{ .registry }}":{"username":"{{ .username }}","password":"{{ .password }}","auth":"{{ printf "%s:%s" .username .password | b64enc }}"}}}` }}
data:
- secretKey: registry
remoteRef:
key: platform/docker-mirror-pull
property: registry
- secretKey: username
remoteRef:
key: platform/docker-mirror-pull
property: username
- secretKey: password
remoteRef:
key: platform/docker-mirror-pull
property: password
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,47 @@
{{- if .Values.externalSecrets.enabled }}
{{- if .Values.externalSecrets.openbao.mountPath }}
{{- if and .Values.tenant.id .Values.tenant.s3Endpoint }}
# longhorn-s3-creds — per-tenant credentials for Longhorn's async S3 backup
# target. Same access_key/secret_key as s3-backup-creds (sourced from
# tenants/<id>/s3-credentials in OpenBao) but lives in odoosky-system
# (Longhorn's namespace) and includes AWS_ENDPOINTS for S3-compatible
# providers. AWS_ENDPOINTS comes from a chart helm value (tenant settings,
# not Vault) since it's a static config tied to the tenant's S3 provider
# choice rather than rotated credential material. Gated on s3Endpoint
# being set — empty endpoint = no Longhorn S3 backup configured.
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: longhorn-s3-creds
namespace: odoosky-system
labels:
app.kubernetes.io/managed-by: cluster-platform-v3
odoosky.io/tenant: {{ .Values.tenant.id | quote }}
spec:
refreshInterval: "1h"
secretStoreRef:
name: openbao-platform
kind: ClusterSecretStore
target:
name: longhorn-s3-creds
creationPolicy: Owner
deletionPolicy: Retain
template:
type: Opaque
engineVersion: v2
data:
AWS_ACCESS_KEY_ID: "{{ `{{ .access_key }}` }}"
AWS_SECRET_ACCESS_KEY: "{{ `{{ .secret_key }}` }}"
AWS_ENDPOINTS: {{ .Values.tenant.s3Endpoint | quote }}
data:
- secretKey: access_key
remoteRef:
key: tenants/{{ .Values.tenant.id }}/s3-credentials
property: access_key
- secretKey: secret_key
remoteRef:
key: tenants/{{ .Values.tenant.id }}/s3-credentials
property: secret_key
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,43 @@
{{- if .Values.externalSecrets.enabled }}
{{- if .Values.externalSecrets.openbao.mountPath }}
{{- if .Values.tenant.id }}
# s3-backup-creds — per-tenant S3 backup credentials consumed by the
# instance-template-v3 backup-cronjob (env: AWS_ACCESS_KEY_ID +
# AWS_SECRET_ACCESS_KEY). Source: v3/tenants/<id>/s3-credentials in
# OpenBao with fields access_key + secret_key. Lives in the `tenants`
# namespace where the per-instance backup CronJobs run.
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: s3-backup-creds
namespace: tenants
labels:
app.kubernetes.io/managed-by: cluster-platform-v3
odoosky.io/tenant: {{ .Values.tenant.id | quote }}
spec:
refreshInterval: "1h"
secretStoreRef:
name: openbao-platform
kind: ClusterSecretStore
target:
name: s3-backup-creds
creationPolicy: Owner
deletionPolicy: Retain
template:
type: Opaque
engineVersion: v2
data:
AWS_ACCESS_KEY_ID: "{{ `{{ .access_key }}` }}"
AWS_SECRET_ACCESS_KEY: "{{ `{{ .secret_key }}` }}"
data:
- secretKey: access_key
remoteRef:
key: tenants/{{ .Values.tenant.id }}/s3-credentials
property: access_key
- secretKey: secret_key
remoteRef:
key: tenants/{{ .Values.tenant.id }}/s3-credentials
property: secret_key
{{- end }}
{{- end }}
{{- end }}

View File

@@ -19,6 +19,21 @@ cluster:
# but a real deploy MUST set domain + wildcardHost (the Certificate # but a real deploy MUST set domain + wildcardHost (the Certificate
# template fails with `required` on an empty value). # template fails with `required` on an empty value).
tenant: tenant:
# Tenant UUID — used by ESO ExternalSecrets to construct the
# OpenBao path `v3/tenants/<id>/{cloudflare-token,s3-credentials}`.
# Empty default = ESO ExternalSecret manifests skip rendering (chart
# remains usable for non-ESO clusters during transition).
id: ""
# Tenant slug — used as the per-tenant Secret name suffix
# (e.g., `cloudflare-api-token-<slug>`). Must match the slug
# cert-manager's ClusterIssuer references via secrets.cloudflareTokenSecret.
slug: ""
# S3-compatible endpoint for the tenant's backup target. When set,
# the longhorn-s3-creds ExternalSecret manifest renders with
# AWS_ENDPOINTS literal alongside the access_key+secret_key from
# OpenBao. Empty = no Longhorn S3 backup wired (instance-level
# backups still work via s3-backup-creds + the per-tenant CronJob).
s3Endpoint: ""
# Domain the Cloudflare zone covers, e.g. "acme-erp.com". # Domain the Cloudflare zone covers, e.g. "acme-erp.com".
# Mirror of domains[primary].root — kept for legacy chart consumers. # Mirror of domains[primary].root — kept for legacy chart consumers.
domain: "" domain: ""