chore: import upstream snapshot with attribution
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
Publish CLI Package / publish-npm (push) Waiting to run
Publish Python SDK / publish-pypi (push) Waiting to run
Publish TypeScript SDK / publish-npm (push) Waiting to run
CI / Migrate Dev DB (push) Has been skipped
CI / Detect Version (push) Has been cancelled
CI / Migrate DB (push) Has been cancelled
CI / Build Dev ECR (./docker/app.Dockerfile, ECR_APP) (push) Has been cancelled
CI / Build Dev ECR (./docker/db.Dockerfile, ECR_MIGRATIONS) (push) Has been cancelled
CI / Build Dev ECR (./docker/pii.Dockerfile, ECR_PII) (push) Has been cancelled
CI / Build Dev ECR (./docker/realtime.Dockerfile, ECR_REALTIME) (push) Has been cancelled
CI / Deploy Trigger.dev (Dev) (push) Has been cancelled
CI / Build AMD64 (./docker/app.Dockerfile, ECR_APP, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build AMD64 (./docker/db.Dockerfile, ECR_MIGRATIONS, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build AMD64 (./docker/pii.Dockerfile, ECR_PII, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build AMD64 (./docker/realtime.Dockerfile, ECR_REALTIME, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/app.Dockerfile, ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/db.Dockerfile, ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/pii.Dockerfile, ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Build ARM64 (GHCR Only) (./docker/realtime.Dockerfile, ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/migrations) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/pii) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/realtime) (push) Has been cancelled
CI / Create GHCR Manifests (ghcr.io/simstudioai/simstudio) (push) Has been cancelled
CI / Check Docs Changes (push) Has been cancelled
CI / Process Docs (push) Has been cancelled
CI / Create GitHub Release (push) Has been cancelled
CI / Test and Build (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
suite: chart-computed env keys can't be overridden (round-8 regression net)
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
|
||||
tests:
|
||||
- it: app pod uses chart-computed DATABASE_URL even when user tries to override
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
app.env.DATABASE_URL: "should-be-ignored"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: DATABASE_URL
|
||||
value: "should-be-ignored"
|
||||
|
||||
- it: existingSecret inline path skips DATABASE_URL/SOCKET_SERVER_URL
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-secret
|
||||
app.env.DATABASE_URL: "postgres://evil-1:5432/x"
|
||||
app.env.SOCKET_SERVER_URL: "https://evil-2.example.com"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content: { name: DATABASE_URL, value: "postgres://evil-1:5432/x" }
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content: { name: SOCKET_SERVER_URL, value: "https://evil-2.example.com" }
|
||||
|
||||
- it: realtime pod existingSecret inline path skips chart-computed keys (round-8)
|
||||
template: deployment-realtime.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-secret
|
||||
app.env.DATABASE_URL: "postgres://evil-1:5432/x"
|
||||
app.env.SOCKET_SERVER_URL: "https://evil-2.example.com"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content: { name: SOCKET_SERVER_URL, value: "https://evil-2.example.com" }
|
||||
@@ -0,0 +1,349 @@
|
||||
suite: copilot secret modes — inline / existingSecret / ESO routing (best-practices fix regression net)
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
|
||||
tests:
|
||||
- it: checksum/secret changes when an ESO remoteRefs.copilot mapping changes, forcing a rollout (Cursor round 4 finding)
|
||||
template: deployment-copilot.yaml
|
||||
documentSelector:
|
||||
path: kind
|
||||
value: Deployment
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
externalSecrets.remoteRefs.copilot.AGENT_API_DB_ENCRYPTION_KEY: path/to/agentdbkey
|
||||
externalSecrets.remoteRefs.copilot.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.copilot.LICENSE_KEY: path/to/license-v1
|
||||
externalSecrets.remoteRefs.copilot.SIM_BASE_URL: path/to/baseurl
|
||||
externalSecrets.remoteRefs.copilot.SIM_AGENT_API_KEY: path/to/agentkey
|
||||
externalSecrets.remoteRefs.copilot.REDIS_URL: path/to/redis
|
||||
externalSecrets.remoteRefs.copilot.OPENAI_API_KEY_1: path/to/openai
|
||||
asserts:
|
||||
- isNotEmpty:
|
||||
path: spec.template.metadata.annotations["checksum/secret"]
|
||||
- matchRegex:
|
||||
path: spec.template.metadata.annotations["checksum/secret"]
|
||||
pattern: "^[a-f0-9]{64}$"
|
||||
|
||||
- it: ESO mode with only the required copilot secrets mapped renders cleanly (envDefaults regression net — Greptile round 1 finding)
|
||||
template: deployment-copilot.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
# Only the genuinely-secret keys are mapped — PORT/SERVICE_NAME/ENVIRONMENT/LOG_LEVEL
|
||||
# live in copilot.server.envDefaults now, not copilot.server.env, so they must NOT
|
||||
# need a remoteRefs.copilot entry.
|
||||
externalSecrets.remoteRefs.copilot.AGENT_API_DB_ENCRYPTION_KEY: path/to/agentdbkey
|
||||
externalSecrets.remoteRefs.copilot.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.copilot.LICENSE_KEY: path/to/license
|
||||
externalSecrets.remoteRefs.copilot.SIM_BASE_URL: path/to/baseurl
|
||||
externalSecrets.remoteRefs.copilot.SIM_AGENT_API_KEY: path/to/agentkey
|
||||
externalSecrets.remoteRefs.copilot.REDIS_URL: path/to/redis
|
||||
externalSecrets.remoteRefs.copilot.OPENAI_API_KEY_1: path/to/openai
|
||||
documentSelector:
|
||||
path: kind
|
||||
value: Deployment
|
||||
asserts:
|
||||
- isKind: { of: Deployment }
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PORT
|
||||
value: "8080"
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: SERVICE_NAME
|
||||
value: copilot
|
||||
|
||||
- it: inline mode renders the chart-managed copilot Secret
|
||||
template: secrets-copilot.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: true
|
||||
copilot.postgresql.auth.password: xxxxxxxx
|
||||
copilot.server.env.AGENT_API_DB_ENCRYPTION_KEY: x
|
||||
copilot.server.env.INTERNAL_API_SECRET: x
|
||||
copilot.server.env.LICENSE_KEY: x
|
||||
copilot.server.env.SIM_BASE_URL: x
|
||||
copilot.server.env.SIM_AGENT_API_KEY: x
|
||||
copilot.server.env.REDIS_URL: x
|
||||
copilot.server.env.OPENAI_API_KEY_1: x
|
||||
asserts:
|
||||
- hasDocuments: { count: 1 }
|
||||
- isKind: { of: Secret }
|
||||
- equal: { path: metadata.name, value: t-sim-copilot-env }
|
||||
|
||||
- it: existingSecret mode does not shadow the pre-created Secret's values with envDefaults (Greptile + Cursor round 2 finding)
|
||||
template: deployment-copilot.yaml
|
||||
documentSelector:
|
||||
path: kind
|
||||
value: Deployment
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
copilot.server.secret.create: false
|
||||
copilot.server.secret.name: my-existing-copilot-secret
|
||||
asserts:
|
||||
- notExists:
|
||||
path: spec.template.spec.containers[0].env
|
||||
|
||||
- it: existingSecret mode still renders extraEnv even though envDefaults are skipped
|
||||
template: deployment-copilot.yaml
|
||||
documentSelector:
|
||||
path: kind
|
||||
value: Deployment
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
copilot.server.secret.create: false
|
||||
copilot.server.secret.name: my-existing-copilot-secret
|
||||
copilot.server.extraEnv:
|
||||
- name: CUSTOM_VAR
|
||||
value: custom-value
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: CUSTOM_VAR
|
||||
value: custom-value
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PORT
|
||||
value: "8080"
|
||||
|
||||
- it: copilot's own existingSecret is still the source of truth even when externalSecrets.enabled=true globally for other components (Greptile round 3 finding)
|
||||
template: deployment-copilot.yaml
|
||||
documentSelector:
|
||||
path: kind
|
||||
value: Deployment
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: ""
|
||||
app.env.ENCRYPTION_KEY: ""
|
||||
app.env.INTERNAL_API_SECRET: ""
|
||||
app.env.CRON_SECRET: ""
|
||||
postgresql.auth.password: ""
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
copilot.server.secret.create: false
|
||||
copilot.server.secret.name: my-existing-copilot-secret
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
asserts:
|
||||
- notExists:
|
||||
path: spec.template.spec.containers[0].env
|
||||
- equal:
|
||||
path: spec.template.spec.containers[0].envFrom[0].secretRef.name
|
||||
value: my-existing-copilot-secret
|
||||
|
||||
- it: existingSecret mode skips the chart-managed copilot Secret and the ExternalSecret
|
||||
templates:
|
||||
- secrets-copilot.yaml
|
||||
- external-secret-copilot.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: true
|
||||
copilot.postgresql.auth.password: xxxxxxxx
|
||||
copilot.server.secret.create: false
|
||||
copilot.server.secret.name: my-existing-copilot-secret
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: ESO mode renders an ExternalSecret instead of the chart-managed copilot Secret
|
||||
template: external-secret-copilot.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
externalSecrets.remoteRefs.copilot.PORT: path/to/port
|
||||
externalSecrets.remoteRefs.copilot.SERVICE_NAME: path/to/name
|
||||
externalSecrets.remoteRefs.copilot.ENVIRONMENT: path/to/env
|
||||
externalSecrets.remoteRefs.copilot.LOG_LEVEL: path/to/log
|
||||
externalSecrets.remoteRefs.copilot.AGENT_API_DB_ENCRYPTION_KEY: path/to/agentdbkey
|
||||
externalSecrets.remoteRefs.copilot.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.copilot.LICENSE_KEY: path/to/license
|
||||
externalSecrets.remoteRefs.copilot.SIM_BASE_URL: path/to/baseurl
|
||||
externalSecrets.remoteRefs.copilot.SIM_AGENT_API_KEY: path/to/agentkey
|
||||
externalSecrets.remoteRefs.copilot.REDIS_URL: path/to/redis
|
||||
externalSecrets.remoteRefs.copilot.OPENAI_API_KEY_1: path/to/openai
|
||||
asserts:
|
||||
- isKind: { of: ExternalSecret }
|
||||
- equal: { path: metadata.name, value: t-sim-copilot-env }
|
||||
- equal: { path: spec.secretStoreRef.name, value: sim-store }
|
||||
|
||||
- it: ESO mode skips the chart-managed copilot Secret
|
||||
template: secrets-copilot.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: true
|
||||
copilot.postgresql.auth.password: xxxxxxxx
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
externalSecrets.remoteRefs.copilot.PORT: path/to/port
|
||||
externalSecrets.remoteRefs.copilot.SERVICE_NAME: path/to/name
|
||||
externalSecrets.remoteRefs.copilot.ENVIRONMENT: path/to/env
|
||||
externalSecrets.remoteRefs.copilot.LOG_LEVEL: path/to/log
|
||||
externalSecrets.remoteRefs.copilot.AGENT_API_DB_ENCRYPTION_KEY: path/to/agentdbkey
|
||||
externalSecrets.remoteRefs.copilot.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.copilot.LICENSE_KEY: path/to/license
|
||||
externalSecrets.remoteRefs.copilot.SIM_BASE_URL: path/to/baseurl
|
||||
externalSecrets.remoteRefs.copilot.SIM_AGENT_API_KEY: path/to/agentkey
|
||||
externalSecrets.remoteRefs.copilot.REDIS_URL: path/to/redis
|
||||
externalSecrets.remoteRefs.copilot.OPENAI_API_KEY_1: path/to/openai
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: ESO validator fails when a required copilot key is neither in env nor mapped
|
||||
template: deployment-copilot.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "Required key 'AGENT_API_DB_ENCRYPTION_KEY' is missing"
|
||||
|
||||
- it: ESO validator fails when copilot.server.env contains an unmapped key
|
||||
template: deployment-copilot.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
externalSecrets.remoteRefs.copilot.PORT: path/to/port
|
||||
externalSecrets.remoteRefs.copilot.SERVICE_NAME: path/to/name
|
||||
externalSecrets.remoteRefs.copilot.ENVIRONMENT: path/to/env
|
||||
externalSecrets.remoteRefs.copilot.LOG_LEVEL: path/to/log
|
||||
externalSecrets.remoteRefs.copilot.AGENT_API_DB_ENCRYPTION_KEY: path/to/agentdbkey
|
||||
externalSecrets.remoteRefs.copilot.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.copilot.LICENSE_KEY: path/to/license
|
||||
externalSecrets.remoteRefs.copilot.SIM_BASE_URL: path/to/baseurl
|
||||
externalSecrets.remoteRefs.copilot.SIM_AGENT_API_KEY: path/to/agentkey
|
||||
externalSecrets.remoteRefs.copilot.REDIS_URL: path/to/redis
|
||||
externalSecrets.remoteRefs.copilot.OPENAI_API_KEY_1: path/to/openai
|
||||
copilot.server.env.UNMAPPED_KEY: "would-go-nowhere"
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "Key 'UNMAPPED_KEY' is set in copilot.server.env but externalSecrets.enabled=true"
|
||||
|
||||
- it: non-ESO mode still requires OPENAI_API_KEY_1 or ANTHROPIC_API_KEY_1 directly in env
|
||||
template: deployment-copilot.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
copilot.enabled: true
|
||||
copilot.postgresql.enabled: false
|
||||
copilot.database.url: "postgresql://x:x@x:5432/x"
|
||||
copilot.server.env.AGENT_API_DB_ENCRYPTION_KEY: x
|
||||
copilot.server.env.INTERNAL_API_SECRET: x
|
||||
copilot.server.env.LICENSE_KEY: x
|
||||
copilot.server.env.SIM_BASE_URL: x
|
||||
copilot.server.env.SIM_AGENT_API_KEY: x
|
||||
copilot.server.env.REDIS_URL: x
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "Set at least one of copilot.server.env.OPENAI_API_KEY_1 or copilot.server.env.ANTHROPIC_API_KEY_1"
|
||||
@@ -0,0 +1,101 @@
|
||||
suite: envDefaults — secret-mode-aware inlining (round-9 regression net)
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
defaults: &defaults
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
tests:
|
||||
- it: inline mode renders localhost envDefaults on the app pod
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: BETTER_AUTH_URL
|
||||
value: http://localhost:3000
|
||||
|
||||
- it: inline mode renders localhost envDefaults on the realtime pod
|
||||
template: deployment-realtime.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: BETTER_AUTH_URL
|
||||
value: http://localhost:3000
|
||||
|
||||
- it: existingSecret mode skips envDefaults on the app pod
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-secret
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: BETTER_AUTH_URL
|
||||
value: http://localhost:3000
|
||||
|
||||
- it: existingSecret mode skips envDefaults on the realtime pod
|
||||
template: deployment-realtime.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-secret
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: BETTER_AUTH_URL
|
||||
value: http://localhost:3000
|
||||
|
||||
- it: existingSecret mode inlines user-set app.env values on the app pod
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-secret
|
||||
app.env.NEXT_PUBLIC_APP_URL: "https://prod.example.com"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: NEXT_PUBLIC_APP_URL
|
||||
value: "https://prod.example.com"
|
||||
|
||||
- it: existingSecret mode propagates app.env to the realtime pod (round-7 regression)
|
||||
template: deployment-realtime.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-secret
|
||||
app.env.NEXT_PUBLIC_APP_URL: "https://prod.example.com"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: NEXT_PUBLIC_APP_URL
|
||||
value: "https://prod.example.com"
|
||||
|
||||
- it: realtime.env wins over app.env on the realtime pod in existingSecret mode
|
||||
template: deployment-realtime.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-secret
|
||||
app.env.NEXT_PUBLIC_APP_URL: "https://prod.example.com"
|
||||
realtime.env.NEXT_PUBLIC_APP_URL: "https://realtime.example.com"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: NEXT_PUBLIC_APP_URL
|
||||
value: "https://realtime.example.com"
|
||||
@@ -0,0 +1,54 @@
|
||||
suite: helm test hook (helm test) connectivity probe
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
defaults: &defaults
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
tests:
|
||||
- it: renders the test pod with helm.sh/hook=test by default
|
||||
template: tests/test-connection.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
asserts:
|
||||
- isKind:
|
||||
of: Pod
|
||||
- equal:
|
||||
path: 'metadata.annotations["helm.sh/hook"]'
|
||||
value: test
|
||||
- equal:
|
||||
path: 'metadata.annotations["helm.sh/hook-delete-policy"]'
|
||||
value: before-hook-creation,hook-succeeded
|
||||
- equal:
|
||||
path: spec.restartPolicy
|
||||
value: Never
|
||||
|
||||
- it: applies restricted PSS context to the test pod
|
||||
template: tests/test-connection.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.securityContext.runAsNonRoot
|
||||
value: true
|
||||
- equal:
|
||||
path: spec.containers[0].securityContext.allowPrivilegeEscalation
|
||||
value: false
|
||||
- equal:
|
||||
path: spec.containers[0].securityContext.readOnlyRootFilesystem
|
||||
value: true
|
||||
- contains:
|
||||
path: spec.containers[0].securityContext.capabilities.drop
|
||||
content: ALL
|
||||
|
||||
- it: skips rendering when tests.enabled=false
|
||||
template: tests/test-connection.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
tests.enabled: false
|
||||
asserts:
|
||||
- hasDocuments:
|
||||
count: 0
|
||||
@@ -0,0 +1,178 @@
|
||||
suite: NetworkPolicy — ingressFrom + telemetry egress + egress shape
|
||||
templates:
|
||||
- networkpolicy.yaml
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
defaults: &defaults
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
networkPolicy.enabled: true
|
||||
ingress.enabled: true
|
||||
ingress.app.host: a.test
|
||||
ingress.realtime.host: b.test
|
||||
|
||||
tests:
|
||||
- it: does not render when networkPolicy.enabled=false
|
||||
set:
|
||||
<<: *defaults
|
||||
networkPolicy.enabled: false
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: default ingressFrom is the explicit any-source peer (single empty peer)
|
||||
set:
|
||||
<<: *defaults
|
||||
documentIndex: 0
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.ingress[2].from
|
||||
value:
|
||||
- {}
|
||||
|
||||
- it: ingressFrom is overridable to a namespace selector
|
||||
set:
|
||||
<<: *defaults
|
||||
networkPolicy.ingressFrom:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: ingress-nginx
|
||||
documentIndex: 0
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.ingress[2].from
|
||||
value:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: ingress-nginx
|
||||
|
||||
- it: app NetworkPolicy includes telemetry egress (ports 4317 + 4318) when telemetry enabled (round-5 fix)
|
||||
set:
|
||||
<<: *defaults
|
||||
telemetry.enabled: true
|
||||
documentIndex: 0
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.egress
|
||||
content:
|
||||
to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sim
|
||||
app.kubernetes.io/instance: t
|
||||
app.kubernetes.io/component: telemetry
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 4317
|
||||
- protocol: TCP
|
||||
port: 4318
|
||||
|
||||
- it: realtime NetworkPolicy includes telemetry egress when telemetry enabled
|
||||
set:
|
||||
<<: *defaults
|
||||
telemetry.enabled: true
|
||||
documentIndex: 1
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.egress
|
||||
content:
|
||||
to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sim
|
||||
app.kubernetes.io/instance: t
|
||||
app.kubernetes.io/component: telemetry
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 4317
|
||||
- protocol: TCP
|
||||
port: 4318
|
||||
|
||||
- it: app NetworkPolicy allows ingress from cron pods when cronjobs.enabled=true
|
||||
set:
|
||||
<<: *defaults
|
||||
documentIndex: 0
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.ingress
|
||||
content:
|
||||
from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sim
|
||||
app.kubernetes.io/instance: t
|
||||
simstudio.ai/component-group: cronjob
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 3000
|
||||
|
||||
- it: cron→app ingress rule is omitted when cronjobs.enabled=false
|
||||
set:
|
||||
<<: *defaults
|
||||
cronjobs.enabled: false
|
||||
documentIndex: 0
|
||||
asserts:
|
||||
- notContains:
|
||||
path: spec.ingress
|
||||
content:
|
||||
from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sim
|
||||
app.kubernetes.io/instance: t
|
||||
simstudio.ai/component-group: cronjob
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 3000
|
||||
|
||||
- it: telemetry collector NetworkPolicy renders when telemetry.enabled=true
|
||||
set:
|
||||
<<: *defaults
|
||||
telemetry.enabled: true
|
||||
documentIndex: 3
|
||||
asserts:
|
||||
- equal:
|
||||
path: kind
|
||||
value: NetworkPolicy
|
||||
- equal:
|
||||
path: metadata.name
|
||||
value: t-sim-otel-collector
|
||||
|
||||
- it: networkPolicy.egress (custom rules) are appended to the app NetworkPolicy
|
||||
set:
|
||||
<<: *defaults
|
||||
networkPolicy.egress:
|
||||
- to: []
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5432
|
||||
documentIndex: 0
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.egress
|
||||
content:
|
||||
to: []
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5432
|
||||
|
||||
- it: networkPolicy.egress (custom rules) are appended to the realtime NetworkPolicy
|
||||
set:
|
||||
<<: *defaults
|
||||
networkPolicy.egress:
|
||||
- to: []
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5432
|
||||
documentIndex: 1
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.egress
|
||||
content:
|
||||
to: []
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5432
|
||||
@@ -0,0 +1,72 @@
|
||||
suite: PDB tri-state and HPA conditional rendering
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
defaults: &defaults
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
tests:
|
||||
- it: PDB does not render when replicaCount=1 and HPA is off (tri-state null)
|
||||
template: poddisruptionbudget.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
app.replicaCount: 1
|
||||
realtime.replicaCount: 1
|
||||
autoscaling.enabled: false
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: PDB auto-renders when replicaCount>1 (tri-state null)
|
||||
template: poddisruptionbudget.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
app.replicaCount: 2
|
||||
realtime.replicaCount: 2
|
||||
autoscaling.enabled: false
|
||||
asserts:
|
||||
- hasDocuments: { count: 2 }
|
||||
|
||||
- it: PDB auto-renders when autoscaling.minReplicas>1 (tri-state null)
|
||||
template: poddisruptionbudget.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
app.replicaCount: 1
|
||||
realtime.replicaCount: 1
|
||||
autoscaling.enabled: true
|
||||
autoscaling.minReplicas: 2
|
||||
asserts:
|
||||
- hasDocuments: { count: 2 }
|
||||
|
||||
- it: PDB explicitly disabled stays off even with multiple replicas
|
||||
template: poddisruptionbudget.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
app.replicaCount: 3
|
||||
podDisruptionBudget.enabled: false
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: HPA does not render when autoscaling.enabled=false
|
||||
template: hpa.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
autoscaling.enabled: false
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: HPA renders when autoscaling.enabled=true and uses autoscaling/v2
|
||||
template: hpa.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
autoscaling.enabled: true
|
||||
autoscaling.minReplicas: 2
|
||||
autoscaling.maxReplicas: 10
|
||||
autoscaling.targetCPUUtilizationPercentage: 70
|
||||
asserts:
|
||||
- isKind: { of: HorizontalPodAutoscaler }
|
||||
- equal: { path: apiVersion, value: autoscaling/v2 }
|
||||
- equal: { path: spec.minReplicas, value: 2 }
|
||||
- equal: { path: spec.maxReplicas, value: 10 }
|
||||
@@ -0,0 +1,185 @@
|
||||
suite: pii — optional Presidio service + PII_URL wiring
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
tests:
|
||||
- it: does not render the pii deployment when disabled
|
||||
template: deployment-pii.yaml
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: renders the pii deployment + service when enabled
|
||||
set:
|
||||
pii.enabled: true
|
||||
templates:
|
||||
- deployment-pii.yaml
|
||||
- services.yaml
|
||||
asserts:
|
||||
- template: deployment-pii.yaml
|
||||
isKind: { of: Deployment }
|
||||
- template: deployment-pii.yaml
|
||||
equal: { path: metadata.name, value: t-sim-pii }
|
||||
- template: deployment-pii.yaml
|
||||
equal:
|
||||
path: spec.template.spec.containers[0].ports[0].containerPort
|
||||
value: 5001
|
||||
|
||||
- it: pii pod defaults to the spacy engine
|
||||
template: deployment-pii.yaml
|
||||
set:
|
||||
pii.enabled: true
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_ENGINE
|
||||
value: "spacy"
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_DEVICE
|
||||
value: "cpu"
|
||||
|
||||
- it: pii.engine and pii.device render through to the container env
|
||||
template: deployment-pii.yaml
|
||||
set:
|
||||
pii.enabled: true
|
||||
pii.engine: gliner
|
||||
pii.device: cuda
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_ENGINE
|
||||
value: "gliner"
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_DEVICE
|
||||
value: "cuda"
|
||||
|
||||
- it: user-set pii.env cannot override the chart-owned engine keys
|
||||
template: deployment-pii.yaml
|
||||
set:
|
||||
pii.enabled: true
|
||||
pii.env:
|
||||
PII_ENGINE: evil
|
||||
PII_DEVICE: evil
|
||||
PII_GLINER_MODEL: acme/custom-model
|
||||
asserts:
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_ENGINE
|
||||
value: "evil"
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_DEVICE
|
||||
value: "evil"
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_GLINER_MODEL
|
||||
value: "acme/custom-model"
|
||||
|
||||
- it: app pod gets chart-computed PII_URL pointing at the in-cluster service
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
pii.enabled: true
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_URL
|
||||
value: "http://t-sim-pii:5001"
|
||||
|
||||
- it: app pod gets the localhost PII_URL fallback when service disabled
|
||||
template: deployment-app.yaml
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_URL
|
||||
value: "http://localhost:5001"
|
||||
|
||||
- it: PII_URL is excluded from the chart-managed app secret
|
||||
template: secrets-app.yaml
|
||||
set:
|
||||
pii.enabled: true
|
||||
app.env.PII_URL: "http://should-not-leak:5001"
|
||||
asserts:
|
||||
- notExists:
|
||||
path: stringData.PII_URL
|
||||
|
||||
- it: user-set PII_URL never overrides the chart-computed inline value
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
pii.enabled: true
|
||||
app.env.PII_URL: "http://evil-pii:5001"
|
||||
asserts:
|
||||
- notContains:
|
||||
path: spec.template.spec.containers[0].env
|
||||
content:
|
||||
name: PII_URL
|
||||
value: "http://evil-pii:5001"
|
||||
|
||||
- it: app NetworkPolicy allows egress to the PII service
|
||||
template: networkpolicy.yaml
|
||||
set:
|
||||
networkPolicy.enabled: true
|
||||
pii.enabled: true
|
||||
documentSelector:
|
||||
path: metadata.name
|
||||
value: t-sim-app
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.egress
|
||||
content:
|
||||
to:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sim
|
||||
app.kubernetes.io/instance: t
|
||||
app.kubernetes.io/component: pii
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 5001
|
||||
|
||||
- it: renders a dedicated NetworkPolicy for the PII service
|
||||
template: networkpolicy.yaml
|
||||
set:
|
||||
networkPolicy.enabled: true
|
||||
pii.enabled: true
|
||||
documentSelector:
|
||||
path: metadata.name
|
||||
value: t-sim-pii
|
||||
asserts:
|
||||
- isKind: { of: NetworkPolicy }
|
||||
- equal:
|
||||
path: spec.podSelector.matchLabels["app.kubernetes.io/component"]
|
||||
value: pii
|
||||
|
||||
- it: pii pod inherits global tolerations (not component-scoped)
|
||||
template: deployment-pii.yaml
|
||||
set:
|
||||
pii.enabled: true
|
||||
tolerations:
|
||||
- key: dedicated
|
||||
operator: Equal
|
||||
value: pii
|
||||
effect: NoSchedule
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.tolerations
|
||||
content:
|
||||
key: dedicated
|
||||
operator: Equal
|
||||
value: pii
|
||||
effect: NoSchedule
|
||||
@@ -0,0 +1,86 @@
|
||||
suite: pod rollout — checksum annotations + topology spread
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
defaults: &defaults
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
tests:
|
||||
- it: app pod template has checksum/secret annotation
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
asserts:
|
||||
- isNotEmpty:
|
||||
path: spec.template.metadata.annotations["checksum/secret"]
|
||||
|
||||
- it: realtime pod template has checksum/secret annotation
|
||||
template: deployment-realtime.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
asserts:
|
||||
- isNotEmpty:
|
||||
path: spec.template.metadata.annotations["checksum/secret"]
|
||||
|
||||
- it: changing a secret value changes the app pod checksum (forces rollout)
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
app.env.BETTER_AUTH_SECRET: yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
||||
asserts:
|
||||
- notEqual:
|
||||
path: spec.template.metadata.annotations["checksum/secret"]
|
||||
value: ""
|
||||
|
||||
- it: topologySpreadConstraints render on the app pod when set
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
app.topologySpreadConstraints:
|
||||
- maxSkew: 1
|
||||
topologyKey: topology.kubernetes.io/zone
|
||||
whenUnsatisfiable: ScheduleAnyway
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sim
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.template.spec.topologySpreadConstraints[0].topologyKey
|
||||
value: topology.kubernetes.io/zone
|
||||
- equal:
|
||||
path: spec.template.spec.topologySpreadConstraints[0].whenUnsatisfiable
|
||||
value: ScheduleAnyway
|
||||
|
||||
- it: topologySpreadConstraints render on the realtime pod when set
|
||||
template: deployment-realtime.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
realtime.topologySpreadConstraints:
|
||||
- maxSkew: 1
|
||||
topologyKey: topology.kubernetes.io/zone
|
||||
whenUnsatisfiable: ScheduleAnyway
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sim
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.template.spec.topologySpreadConstraints[0].topologyKey
|
||||
value: topology.kubernetes.io/zone
|
||||
|
||||
- it: app topologySpreadConstraints do not leak onto realtime pod
|
||||
template: deployment-realtime.yaml
|
||||
set:
|
||||
<<: *defaults
|
||||
app.topologySpreadConstraints:
|
||||
- maxSkew: 1
|
||||
topologyKey: topology.kubernetes.io/zone
|
||||
whenUnsatisfiable: ScheduleAnyway
|
||||
labelSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: sim
|
||||
asserts:
|
||||
- isNull:
|
||||
path: spec.template.spec.topologySpreadConstraints
|
||||
@@ -0,0 +1,59 @@
|
||||
suite: values.schema.json — secret length enforcement (blocker fix regression net)
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
|
||||
tests:
|
||||
- it: rejects a BETTER_AUTH_SECRET shorter than 32 characters
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: short
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "BETTER_AUTH_SECRET.*minLength"
|
||||
|
||||
- it: rejects an ENCRYPTION_KEY shorter than 32 characters
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: short
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "ENCRYPTION_KEY.*minLength"
|
||||
|
||||
- it: rejects a postgresql.auth.password shorter than 8 characters
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: short
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "password.*minLength"
|
||||
|
||||
- it: accepts an empty BETTER_AUTH_SECRET (deferred to existingSecret/ESO)
|
||||
templates:
|
||||
- secrets-app.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-existing-secret
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: accepts a valid 32-character BETTER_AUTH_SECRET and ENCRYPTION_KEY
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- isKind: { of: Deployment }
|
||||
@@ -0,0 +1,118 @@
|
||||
suite: secret modes — inline / existingSecret / ESO routing
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
|
||||
tests:
|
||||
- it: inline mode renders the chart-managed Secret
|
||||
template: secrets-app.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- isKind: { of: Secret }
|
||||
- equal: { path: metadata.name, value: t-sim-app-secrets }
|
||||
|
||||
- it: existingSecret mode skips the chart-managed Secret
|
||||
templates:
|
||||
- secrets-app.yaml
|
||||
- external-secret-app.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-existing-secret
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: ESO mode renders an ExternalSecret instead of the chart-managed Secret
|
||||
template: external-secret-app.yaml
|
||||
set:
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.secretStoreRef.kind: ClusterSecretStore
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- isKind: { of: ExternalSecret }
|
||||
- equal: { path: metadata.name, value: t-sim-app-secrets }
|
||||
- equal: { path: spec.secretStoreRef.name, value: sim-store }
|
||||
- equal: { path: spec.secretStoreRef.kind, value: ClusterSecretStore }
|
||||
|
||||
- it: ESO mode skips the chart-managed Secret
|
||||
template: secrets-app.yaml
|
||||
set:
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- hasDocuments: { count: 0 }
|
||||
|
||||
- it: ESO validator fails when app.env contains an unmapped key
|
||||
set:
|
||||
externalSecrets.enabled: true
|
||||
externalSecrets.secretStoreRef.name: sim-store
|
||||
externalSecrets.remoteRefs.app.BETTER_AUTH_SECRET: path/to/auth
|
||||
externalSecrets.remoteRefs.app.ENCRYPTION_KEY: path/to/enc
|
||||
externalSecrets.remoteRefs.app.INTERNAL_API_SECRET: path/to/iapi
|
||||
externalSecrets.remoteRefs.app.CRON_SECRET: path/to/cron
|
||||
externalSecrets.remoteRefs.postgresql.password: path/to/pgpw
|
||||
app.env.UNMAPPED_KEY: "would-go-nowhere"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "Key 'UNMAPPED_KEY' is set in app.env but externalSecrets.enabled=true"
|
||||
|
||||
- it: app deployment envFrom references existingSecret name
|
||||
template: deployment-app.yaml
|
||||
set:
|
||||
app.secrets.existingSecret.enabled: true
|
||||
app.secrets.existingSecret.name: my-existing-secret
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- contains:
|
||||
path: spec.template.spec.containers[0].envFrom
|
||||
content:
|
||||
secretRef:
|
||||
name: my-existing-secret
|
||||
|
||||
- it: realtime.env-only value reaches the Secret when app.env entry is empty (cursor bugbot fix)
|
||||
template: secrets-app.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
app.env.BETTER_AUTH_URL: ""
|
||||
realtime.env.BETTER_AUTH_URL: "https://realtime.example.com"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData.BETTER_AUTH_URL
|
||||
value: "https://realtime.example.com"
|
||||
|
||||
- it: app.env wins over realtime.env on collision when both are non-empty
|
||||
template: secrets-app.yaml
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
app.env.NEXT_PUBLIC_APP_URL: "https://app.example.com"
|
||||
realtime.env.NEXT_PUBLIC_APP_URL: "https://realtime.example.com"
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- equal:
|
||||
path: stringData.NEXT_PUBLIC_APP_URL
|
||||
value: "https://app.example.com"
|
||||
@@ -0,0 +1,33 @@
|
||||
suite: smoke — minimal install renders
|
||||
templates:
|
||||
- deployment-app.yaml
|
||||
- deployment-realtime.yaml
|
||||
- secrets-app.yaml
|
||||
- services.yaml
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: test-better-auth-secret-32-bytes
|
||||
app.env.ENCRYPTION_KEY: test-encryption-key-32-bytes-long
|
||||
app.env.INTERNAL_API_SECRET: test-internal-api-secret-32-bytes
|
||||
app.env.CRON_SECRET: test-cron-secret-32-bytes
|
||||
postgresql.auth.password: testpassword
|
||||
tests:
|
||||
- it: renders the app deployment
|
||||
template: deployment-app.yaml
|
||||
asserts:
|
||||
- isKind: { of: Deployment }
|
||||
- equal: { path: metadata.name, value: t-sim-app }
|
||||
|
||||
- it: renders the realtime deployment
|
||||
template: deployment-realtime.yaml
|
||||
asserts:
|
||||
- isKind: { of: Deployment }
|
||||
- equal: { path: metadata.name, value: t-sim-realtime }
|
||||
|
||||
- it: renders the chart-managed app secret
|
||||
template: secrets-app.yaml
|
||||
asserts:
|
||||
- isKind: { of: Secret }
|
||||
- equal: { path: metadata.name, value: t-sim-app-secrets }
|
||||
@@ -0,0 +1,53 @@
|
||||
suite: telemetry — Restricted Pod Security Standard hardening (best-practices fix regression net)
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
templates:
|
||||
- telemetry.yaml
|
||||
|
||||
tests:
|
||||
- it: pod-level security context preserves the collector's original UID/GID/fsGroup and adds seccompProfile
|
||||
set:
|
||||
telemetry.enabled: true
|
||||
documentSelector:
|
||||
path: kind
|
||||
value: Deployment
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.template.spec.securityContext.runAsUser
|
||||
value: 10001
|
||||
- equal:
|
||||
path: spec.template.spec.securityContext.runAsGroup
|
||||
value: 10001
|
||||
- equal:
|
||||
path: spec.template.spec.securityContext.fsGroup
|
||||
value: 10001
|
||||
- equal:
|
||||
path: spec.template.spec.securityContext.runAsNonRoot
|
||||
value: true
|
||||
- equal:
|
||||
path: spec.template.spec.securityContext.seccompProfile.type
|
||||
value: RuntimeDefault
|
||||
- equal:
|
||||
path: spec.template.spec.automountServiceAccountToken
|
||||
value: false
|
||||
|
||||
- it: container-level security context matches the Restricted profile (same as every other workload)
|
||||
set:
|
||||
telemetry.enabled: true
|
||||
documentSelector:
|
||||
path: kind
|
||||
value: Deployment
|
||||
asserts:
|
||||
- equal:
|
||||
path: spec.template.spec.containers[0].securityContext.allowPrivilegeEscalation
|
||||
value: false
|
||||
- equal:
|
||||
path: spec.template.spec.containers[0].securityContext.capabilities.drop[0]
|
||||
value: ALL
|
||||
- equal:
|
||||
path: spec.template.spec.containers[0].securityContext.runAsNonRoot
|
||||
value: true
|
||||
- equal:
|
||||
path: spec.template.spec.containers[0].securityContext.seccompProfile.type
|
||||
value: RuntimeDefault
|
||||
@@ -0,0 +1,85 @@
|
||||
suite: validators — required secrets fail clearly
|
||||
templates:
|
||||
- deployment-app.yaml
|
||||
release:
|
||||
name: t
|
||||
namespace: sim
|
||||
|
||||
tests:
|
||||
- it: fails when BETTER_AUTH_SECRET is missing
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: ""
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: "app.env.BETTER_AUTH_SECRET is required for production deployment"
|
||||
|
||||
- it: fails when ENCRYPTION_KEY is missing
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: ""
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: "app.env.ENCRYPTION_KEY is required for production deployment"
|
||||
|
||||
- it: fails when INTERNAL_API_SECRET is missing (1.0.0 requirement)
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: ""
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: "app.env.INTERNAL_API_SECRET is required for production deployment (shared auth between sim-app and sim-realtime pods). Generate one with: openssl rand -hex 32"
|
||||
|
||||
- it: fails when cronjobs are enabled but CRON_SECRET is empty
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: ""
|
||||
cronjobs.enabled: true
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: "app.env.CRON_SECRET is required when cronjobs.enabled=true (every cron pod authenticates with this token). Generate one with: openssl rand -hex 32, or set cronjobs.enabled=false."
|
||||
|
||||
- it: fails when postgresql.auth.password is missing
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: ""
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorMessage: "postgresql.auth.password is required when using internal PostgreSQL"
|
||||
|
||||
- it: rejects postgres passwords with URL-unsafe characters
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: "pa$$word"
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "postgresql.auth.password must only contain alphanumeric"
|
||||
|
||||
- it: rejects placeholder BETTER_AUTH_SECRET
|
||||
set:
|
||||
app.env.BETTER_AUTH_SECRET: "CHANGE-ME-32-CHAR-SECRET-FOR-PRODUCTION-USE"
|
||||
app.env.ENCRYPTION_KEY: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||
app.env.INTERNAL_API_SECRET: x
|
||||
app.env.CRON_SECRET: x
|
||||
postgresql.auth.password: xxxxxxxx
|
||||
asserts:
|
||||
- failedTemplate:
|
||||
errorPattern: "must not use the default placeholder value"
|
||||
Reference in New Issue
Block a user