diff --git a/docs/REFERENCE.md b/docs/REFERENCE.md index 04b3d23..4324e06 100644 --- a/docs/REFERENCE.md +++ b/docs/REFERENCE.md @@ -849,8 +849,6 @@ spec: **Chart**: `sealed-secrets/sealed-secrets-controller` **Namespace**: `kube-system` -**Directory Structure**: `secrets/base/` contains all SealedSecrets with a `kustomization.yaml`. Per-cloud overlays in `secrets/overlays//` reference the base via Kustomize. The ArgoCD `secrets` Application points to the active overlay (e.g., `secrets/overlays/upc-dev`), and `infra/overlays/upc-prod` patches the path to `secrets/overlays/upc-prod`. - To add cloud-specific secrets, create a new SealedSecret in the overlay directory and add it to the overlay's `kustomization.yaml`. **Public Certificate**: @@ -1109,6 +1107,41 @@ storage: - `vaultwarden-oidc-credentials` (registrar-managed) — OIDC client ID + secret - `vaultwarden-tls` — auto-managed by cert-manager +### MinIO + +**Chart**: `minio/minio` from `https://charts.min.io/` +**Version**: 5.4.0 +**Namespace**: `minio` + +**Purpose**: S3-compatible object storage with web console and static website hosting. + +**Configuration**: +```yaml +# infra/overlays/upc-dev/minio/ + infra/values/ +mode: standalone +persistence: + size: 50Gi +consoleIngress: + hosts: [minio.forteapps.net] +ingress: + hosts: [s3.forteapps.net] +``` + +**Ports**: API (9000), Console (9001) + +**TLS**: cert-manager auto-provisions Let's Encrypt certificates — `minio-console-tls` for Console, `minio-api-tls` for API. + +**SSO**: Native OIDC via Keycloak `forte` realm (client ID: `minio`). Self-service client config Secret (`keycloak-client-minio`) triggers registrar. Policy claim mapper maps user attributes to MinIO policies. + +**Endpoints**: +- Console: `https://minio.forteapps.net` +- S3 API: `https://s3.forteapps.net` + +**Secrets**: +- `minio-credentials` (SealedSecret) — root user/password +- `minio-oidc-credentials` (registrar-managed) — OIDC client ID + secret +- `minio-console-tls`, `minio-api-tls` — auto-managed by cert-manager + ### AI Code Review (ai-review) **Type**: Gitea Actions workflow (`.gitea/workflows/ai-review.yaml`) @@ -2003,8 +2036,8 @@ To add support for a new cloud (e.g., `oci-dev` for Oracle Cloud): - `opencost-values.yaml` — pricing model or cloud billing integration 3. **Kustomize overlay**: `infra/overlays/oci-dev/kustomization.yaml` — patch `valueFiles[1]` for each Application 4. **App-of-apps**: `_app-of-apps-oci-dev.yaml` — points to `infra/overlays/oci-dev` -5. **Secrets overlay**: `secrets/overlays/oci-dev/kustomization.yaml` — references `../../base`, add cloud-specific SealedSecrets if needed -6. **Secrets patch**: Add patch to `infra/overlays/oci-dev/kustomization.yaml` to swap secrets path to `secrets/overlays/oci-dev` +5. **SealedSecrets**: Add cloud-specific SealedSecrets directly in the relevant app overlay directories (e.g., `infra/overlays/oci-dev//`) and include them in each overlay's `kustomization.yaml` +6. **Sealed Secrets controller**: Include `../../base/sealedsecrets` in `infra/overlays/oci-dev/kustomization.yaml` if the cluster needs the controller 7. **Bootstrap**: `./bootstrap.sh oci-dev` --- diff --git a/infra/overlays/upc-dev/kustomization.yaml b/infra/overlays/upc-dev/kustomization.yaml index fac7510..07c93c6 100644 --- a/infra/overlays/upc-dev/kustomization.yaml +++ b/infra/overlays/upc-dev/kustomization.yaml @@ -4,6 +4,7 @@ resources: - ../../base - vaultwarden-postgresql - vaultwarden +- minio # No patches needed — base already has "upc-dev" paths # upc-dev is the default/base cluster diff --git a/infra/overlays/upc-dev/minio/keycloak-client-config.yaml b/infra/overlays/upc-dev/minio/keycloak-client-config.yaml new file mode 100644 index 0000000..dcd25ad --- /dev/null +++ b/infra/overlays/upc-dev/minio/keycloak-client-config.yaml @@ -0,0 +1,35 @@ +apiVersion: v1 +kind: Secret +metadata: + name: keycloak-client-minio + namespace: minio + labels: + keycloak.forteapps.net/client-config: "true" +stringData: + client.json: | + { + "clientId": "minio", + "name": "MinIO", + "redirectUris": ["https://minio.forteapps.net/oauth_callback"], + "webOrigins": ["https://minio.forteapps.net"], + "protocolMappers": [ + { + "name": "minio-policy-mapper", + "protocol": "openid-connect", + "protocolMapper": "oidc-usermodel-attribute-mapper", + "config": { + "user.attribute": "policy", + "claim.name": "policy", + "jsonType.label": "String", + "id.token.claim": "true", + "access.token.claim": "true", + "userinfo.token.claim": "true" + } + } + ], + "secret": { + "namespace": "minio", + "name": "minio-oidc-credentials", + "keys": { "clientId": "client-id", "clientSecret": "client-secret" } + } + } diff --git a/infra/overlays/upc-dev/minio/kustomization.yaml b/infra/overlays/upc-dev/minio/kustomization.yaml new file mode 100644 index 0000000..8591aff --- /dev/null +++ b/infra/overlays/upc-dev/minio/kustomization.yaml @@ -0,0 +1,6 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: +- minio.yaml +- minio-credentials-sealed.yaml +- keycloak-client-config.yaml diff --git a/infra/overlays/upc-dev/minio/minio-credentials-sealed.yaml b/infra/overlays/upc-dev/minio/minio-credentials-sealed.yaml new file mode 100644 index 0000000..04b37cf --- /dev/null +++ b/infra/overlays/upc-dev/minio/minio-credentials-sealed.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +data: + rootPassword: NTUwYTU2YmRjZjYyY2RlYmE1ZTYwZDAwZjNhYzcxOGM1MGY0NjExNmZkMzdjZWI0MGY4Yzc3NDA1NTM5YWM4Mg== + rootUser: Zm9ydGVtaW5pbw== +kind: Secret +metadata: + creationTimestamp: null + name: minio-credentials + namespace: minio diff --git a/infra/overlays/upc-dev/minio/minio.yaml b/infra/overlays/upc-dev/minio/minio.yaml new file mode 100644 index 0000000..bf182de --- /dev/null +++ b/infra/overlays/upc-dev/minio/minio.yaml @@ -0,0 +1,43 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Application +metadata: + name: minio + namespace: argocd + annotations: + argocd.argoproj.io/sync-wave: "1" + labels: + app.kubernetes.io/name: minio + app.kubernetes.io/part-of: storage + app.kubernetes.io/managed-by: argocd + finalizers: + - resources-finalizer.argocd.argoproj.io +spec: + project: default + + sources: + - repoURL: https://charts.min.io/ + chart: minio + targetRevision: "5.4.0" + helm: + releaseName: minio + valueFiles: + - $values/infra/values/base/minio-values.yaml + - $values/infra/values/upc-dev/minio-values.yaml + + - repoURL: ssh://git@git.forteapps.net:2222/Forte/launchpad.git + targetRevision: HEAD + ref: values + + destination: + server: https://kubernetes.default.svc + namespace: minio + + syncPolicy: + automated: + prune: true + selfHeal: true + allowEmpty: false + syncOptions: + - CreateNamespace=true + - Validate=true + - ServerSideApply=true diff --git a/infra/values/base/minio-values.yaml b/infra/values/base/minio-values.yaml new file mode 100644 index 0000000..d80f797 --- /dev/null +++ b/infra/values/base/minio-values.yaml @@ -0,0 +1,33 @@ +## MinIO base values — cross-cluster constants + +mode: standalone + +image: + repository: quay.io/minio/minio + tag: "RELEASE.2025-05-24T17-08-30Z" + pullPolicy: IfNotPresent + +## Use existing secret for root credentials +## Secret must contain keys: rootUser, rootPassword +existingSecret: "minio-credentials" + +## Single bucket created on startup +buckets: +- name: default + policy: none + purge: false + +resources: + requests: + cpu: 100m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi + +## Service configuration +service: + type: ClusterIP + +consoleService: + type: ClusterIP diff --git a/infra/values/upc-dev/minio-values.yaml b/infra/values/upc-dev/minio-values.yaml new file mode 100644 index 0000000..aa2d421 --- /dev/null +++ b/infra/values/upc-dev/minio-values.yaml @@ -0,0 +1,52 @@ +## MinIO upc-dev overlay values + +## Storage +persistence: + enabled: true + size: 10Gi + accessMode: ReadWriteOnce + +## Console Ingress (Web UI) — port 9001 +consoleIngress: + enabled: true + ingressClassName: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + gethomepage.dev/enabled: "false" + gethomepage.dev/name: "Forte Zipline" + gethomepage.dev/description: "Object storage" + gethomepage.dev/group: "Storage" + gethomepage.dev/icon: "minio" + gethomepage.dev/href: "https://zipline.forteapps.net" + hosts: + - zipline.forteapps.net + tls: + - secretName: minio-console-tls + hosts: + - zipline.forteapps.net + +## API Ingress — port 9000 +ingress: + enabled: true + ingressClassName: traefik + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod + hosts: + - s3.forteapps.net + tls: + - secretName: minio-api-tls + hosts: + - s3.forteapps.net + +## Native OIDC via Keycloak +oidc: + enabled: true + configUrl: "https://id.forteapps.net/realms/forte/.well-known/openid-configuration" + clientId: "minio" + existingClientSecretName: "minio-oidc-credentials" + existingClientSecretKey: "client-secret" + claimName: "policy" + scopes: "openid,email,profile" + redirectUri: "https://zipline.forteapps.net/oauth_callback" + claimPrefix: "" + comment: ""