diff --git a/charts/substrate/README.md b/charts/substrate/README.md index 7fd7b09ed1..20727b3888 100644 --- a/charts/substrate/README.md +++ b/charts/substrate/README.md @@ -2,7 +2,7 @@ Helm chart for installing Agent Substrate. -The chart uses mTLS and PostgreSQL by default. It requires the +The chart uses mTLS and requires a prepared PostgreSQL database. It requires the `ClusterTrustBundle`, `ClusterTrustBundleProjection`, and `PodCertificateRequest` feature gates plus the `certificates.k8s.io/v1beta1` API. @@ -11,8 +11,10 @@ API. # CRDs helm upgrade --install substrate-crds ./charts/substrate-crds -# Install Substrate -helm upgrade --install substrate ./charts/substrate +# Install Substrate after creating the database identities and Secrets +helm upgrade --install substrate ./charts/substrate \ + --set postgres.readWriteConnectionStringSecretRef.name=substrate-postgres-readwrite \ + --set postgres.ownerConnectionStringSecretRef.name=substrate-postgres-owner ``` By default, component images are pulled from `ghcr.io/kagent-dev/substrate` @@ -40,10 +42,12 @@ See `values.yaml` for the full set; the important keys: | Key | Default | Notes | |-----|---------|-------| -| `postgres.enabled` | `true` | Deploy the bundled PostgreSQL instance | -| `postgres.connectionString` | `""` (in-cluster) | Override to use external PostgreSQL | -| `postgres.schema` | `public` | Store the Substrate tables in this PostgreSQL schema | -| `postgres.storageSize` | `1Gi` | In-cluster PostgreSQL PVC size | +| `postgres.readWriteConnectionStringSecretRef` | `substrate-postgres-readwrite` | Read the read/write connection from a pre-created Secret | +| `postgres.ownerConnectionStringSecretRef` | `substrate-postgres-owner` | Read the owner connection from a pre-created Secret | +| `postgres.readWriteRole` | `substrate_readwrite` | Role assumed by read/write connections | +| `postgres.ownerRole` | `substrate_owner` | Role assumed by owner connections | +| `postgres.pool.maxConnLifetime` | `""` (pgx default) | Maximum physical connection lifetime; bounds Secret credential turnover | +| `postgres.schema` | `substrate` | Store the Substrate tables in this PostgreSQL schema | | `rustfs.enabled` | `true` | Deploy an in-cluster S3-compatible RustFS bucket for snapshots | | `atelet.storageBackend` | `s3` | Default snapshot backend, wired to RustFS when `rustfs.enabled=true` | | `atelet.gcpAuthForImagePulls` | `false` | Enable only when using GCP registry auth | @@ -57,3 +61,32 @@ See `values.yaml` for the full set; the important keys: | `otel.metrics.endpoint` | `""` | OTLP endpoint for metrics, overriding `otel.endpoint` | | `otel.logs.enabled` | `true` | Set to `false` to export no logs. Gates both OTLP log sources: ateapi's actor lifecycle events and the router access log | | `otel.logs.endpoint` | `""` | OTLP endpoint for logs, overriding `otel.endpoint` | + +## PostgreSQL credential rotation + +The chart does not deploy or initialize PostgreSQL. Prepare the database, +schema, login users, and the configured `readWriteRole` and `ownerRole` before +installing the chart. For development, `ate-setup` and `kagent install` can +create and prepare an in-cluster PostgreSQL instance before they install the +applications. + +Substrate mounts connection Secrets as projected files. Kubernetes updates +these files when the Secret changes. Substrate reads the current value for +each new physical connection. + +`postgres.pool.maxConnLifetime` bounds how long established connections may +continue using an old credential; rotation is not immediate. Keep old and new +credentials valid long enough for Kubernetes projection and connection +turnover. + +When rotation changes a login username, grant the applicable configured group +role before updating its connection Secret. + +Substrate runs `SET ROLE` for each new connection. It rejects a login without +the required membership. + +Create both group roles and all grants before installation, then set +`postgres.readWriteRole` and `postgres.ownerRole` to those names. Use distinct +roles and table schemas for separate installs sharing one database. Give each +install separate logins and grant each login membership only in its install's +roles. diff --git a/charts/substrate/templates/_helpers.tpl b/charts/substrate/templates/_helpers.tpl index 45184413fb..50fc7dd612 100644 --- a/charts/substrate/templates/_helpers.tpl +++ b/charts/substrate/templates/_helpers.tpl @@ -78,6 +78,14 @@ Plaintext HTTP URL that clients use to reach atenet-router. {{- printf "http://%s.%s.svc:80" (include "substrate.fullname" (list "atenet-router" .)) .Release.Namespace -}} {{- end -}} +{{- define "substrate.postgres.readWriteSecretName" -}} +{{- .Values.postgres.readWriteConnectionStringSecretRef.name -}} +{{- end -}} + +{{- define "substrate.postgres.ownerSecretName" -}} +{{- .Values.postgres.ownerConnectionStringSecretRef.name -}} +{{- end -}} + {{/* OTLP endpoint a signal exports to, or empty when the signal is disabled or no endpoint resolves. The per-signal endpoint wins over the generic one, matching @@ -188,7 +196,7 @@ it contains "." or ":" (the containerd rule); otherwise the reference is docker.io-implied and the mirror is prefixed. The repository path is preserved either way, so a mirror copies images under their existing paths. -Usage: {{ include "substrate.thirdPartyImage" (list .Values.images.postgres .) }} +Usage: {{ include "substrate.thirdPartyImage" (list .Values.images.rustfs .) }} */}} {{- define "substrate.thirdPartyImage" -}} {{- $ref := index . 0 -}} diff --git a/charts/substrate/templates/ate-api-server-envvars.yaml b/charts/substrate/templates/ate-api-server-envvars.yaml index ca76ae3ef8..382ce4b9c9 100644 --- a/charts/substrate/templates/ate-api-server-envvars.yaml +++ b/charts/substrate/templates/ate-api-server-envvars.yaml @@ -14,8 +14,11 @@ See the License for the specific language governing permissions and limitations under the License. */}} -{{- if and (not .Values.postgres.enabled) (empty .Values.postgres.connectionString) }} -{{- fail "postgres.connectionString is required when postgres.enabled=false" }} +{{- if not .Values.postgres.readWriteConnectionStringSecretRef.name }} +{{- fail "postgres.readWriteConnectionStringSecretRef.name is required" }} +{{- end }} +{{- if not .Values.postgres.ownerConnectionStringSecretRef.name }} +{{- fail "postgres.ownerConnectionStringSecretRef.name is required" }} {{- end }} apiVersion: v1 kind: ConfigMap @@ -23,5 +26,4 @@ metadata: name: {{ .Values.ateApiServerEnvVarsConfigMap }} namespace: {{ .Release.Namespace }} data: - ATE_API_POSTGRES_CONNECTION_STRING: {{ .Values.postgres.connectionString | default (printf "postgresql://postgres@%s.%s.svc:5432/atepg?sslmode=verify-full&sslrootcert=/run/servicedns.podcert.ate.dev/trust-bundle.pem&sslcert=/run/podidentity.podcert.ate.dev/credential-bundle.pem&sslkey=/run/podidentity.podcert.ate.dev/credential-bundle.pem" (include "substrate.fullname" (list "postgres" .)) .Release.Namespace) | quote }} ATE_API_POSTGRES_SCHEMA: {{ .Values.postgres.schema | quote }} diff --git a/charts/substrate/templates/ate-api-server.yaml b/charts/substrate/templates/ate-api-server.yaml index e8d69e7c04..5e62612c83 100644 --- a/charts/substrate/templates/ate-api-server.yaml +++ b/charts/substrate/templates/ate-api-server.yaml @@ -14,6 +14,9 @@ See the License for the specific language governing permissions and limitations under the License. */}} +{{- $readWriteConnectionStringSecretRef := .Values.postgres.readWriteConnectionStringSecretRef -}} +{{- $ownerConnectionStringSecretRef := .Values.postgres.ownerConnectionStringSecretRef -}} + apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -85,8 +88,14 @@ spec: - "--grpc-listen-addr=0.0.0.0:443" - "--grpc-server-cred-bundle=/run/servicedns.podcert.ate.dev/credential-bundle.pem" - "--authentication-config=/etc/ateapi/authentication/authentication.yaml" - - "--postgres-connection-string=@env" + - "--postgres-read-write-connection-string=@file:/etc/ateapi/postgres/read-write/connection-string" + - "--postgres-owner-connection-string=@file:/etc/ateapi/postgres/owner/connection-string" + - {{ printf "--postgres-read-write-role=%s" .Values.postgres.readWriteRole | quote }} + - {{ printf "--postgres-owner-role=%s" .Values.postgres.ownerRole | quote }} - "--postgres-schema=@env" +{{- with .Values.postgres.pool.maxConnLifetime }} + - {{ printf "--postgres-max-conn-lifetime=%s" . | quote }} +{{- end }} - "--actor-id-jwt-pool=/run/actor-id-jwt-pool/pool.json" - "--actor-id-ca-pool=/run/actor-id-ca-pool/pool.json" - "--default-egress-gateway-address={{ include "substrate.fullname" (list "atenet-egress" .) }}.{{ .Release.Namespace }}.svc:443" @@ -140,6 +149,12 @@ spec: - { name: actor-id-ca-pool, mountPath: /run/actor-id-ca-pool, readOnly: true } - { name: podidentity, mountPath: /run/podidentity.podcert.ate.dev, readOnly: true } - { name: authentication-config, mountPath: /etc/ateapi/authentication, readOnly: true } + - name: postgres-read-write-connection + mountPath: /etc/ateapi/postgres/read-write + readOnly: true + - name: postgres-owner-connection + mountPath: /etc/ateapi/postgres/owner + readOnly: true ports: - containerPort: 443 - name: prometheus @@ -201,6 +216,22 @@ spec: matchLabels: podcert.ate.dev/canarying: live path: trust-bundle.pem + - name: postgres-read-write-connection + projected: + sources: + - secret: + name: {{ include "substrate.postgres.readWriteSecretName" . | quote }} + items: + - key: {{ get $readWriteConnectionStringSecretRef "key" | default "readWriteConnectionString" | quote }} + path: connection-string + - name: postgres-owner-connection + projected: + sources: + - secret: + name: {{ include "substrate.postgres.ownerSecretName" . | quote }} + items: + - key: {{ get $ownerConnectionStringSecretRef "key" | default "ownerConnectionString" | quote }} + path: connection-string --- apiVersion: policy/v1 kind: PodDisruptionBudget diff --git a/charts/substrate/templates/postgres.yaml b/charts/substrate/templates/postgres.yaml deleted file mode 100644 index 77df191879..0000000000 --- a/charts/substrate/templates/postgres.yaml +++ /dev/null @@ -1,237 +0,0 @@ -{{/* -Copyright 2026 Google LLC - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/}} - -{{- if .Values.postgres.enabled }} -{{- $name := include "substrate.fullname" (list "postgres" .) -}} -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ $name }}-config - namespace: {{ .Release.Namespace }} -data: - postgresql.conf: | - listen_addresses = '*' - ssl = on - ssl_cert_file = '/run/servicedns.podcert.ate.dev/credential-bundle.pem' - ssl_key_file = '/run/servicedns.podcert.ate.dev/credential-bundle.pem' - ssl_ca_file = '/run/podidentity.podcert.ate.dev/trust-bundle.pem' - hba_file = '/etc/postgresql/pg_hba.conf' - pg_hba.conf: | - # Local socket access is limited to processes in this pod and is used by - # health checks, the workload's idempotent database bootstrap, and the - # tls-reloader sidecar's configuration reloads. - local all all trust - # PostgreSQL verifies client certificates against the pod-identity CA. It - # does not need its own serving CA because it never verifies its server certificate. - hostssl all all all trust clientcert=verify-ca - reload-tls.sh: | - # PostgreSQL opens ssl_cert_file, ssl_key_file and ssl_ca_file at startup - # and on SIGHUP, and nowhere else. The kubelet replaces the projected pod - # certificate in place about 30 minutes before it expires, so without this - # loop the server keeps presenting the certificate it booted with until it - # expires about a day later and every client stops trusting it. - set -eu - - # As PID 1 this shell only sees SIGTERM if a handler is installed, and only - # acts on it between commands, so the sleep below runs in the background - # and is waited on. Without both halves the pod takes the full termination - # grace period to go away. - trap 'exit 0' TERM INT - - CERT=/run/servicedns.podcert.ate.dev/credential-bundle.pem - CA=/run/podidentity.podcert.ate.dev/trust-bundle.pem - - # Comfortably inside the 30m headroom (notAfter - beginRefreshAt) that - # cmd/podcertcontroller/internal/servicednssigner/servicednssigner.go - # leaves; hashing two small files costs nothing. - INTERVAL=60 - - reloaded="" - while true; do - current="$(sha256sum "${CERT}" "${CA}")" - # Reloading fails until the server is accepting connections, which is - # where every pod starts out, so only record a hash once it has worked. - # Starting empty also means a restart of this container costs one - # redundant reload rather than a missed one. - if [ "${current}" != "${reloaded}" ] \ - && psql -U postgres -d postgres -Atc 'SELECT pg_reload_conf()' >/dev/null 2>&1; then - reloaded="${current}" - echo "$(date -u +%FT%TZ) reloaded TLS configuration" - fi - sleep "${INTERVAL}" & - wait $! - done ---- -apiVersion: v1 -kind: Service -metadata: - name: {{ $name }} - namespace: {{ .Release.Namespace }} -spec: - clusterIP: None - selector: - app: {{ $name }} - ports: - - name: postgres - port: 5432 - targetPort: 5432 ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: {{ $name }} - namespace: {{ .Release.Namespace }} -spec: - serviceName: {{ $name }} - replicas: 1 - selector: - matchLabels: - app: {{ $name }} - template: - metadata: - labels: - app: {{ $name }} - spec: - securityContext: - # Group ownership of the projected certificate below, and of the data - # volume so that a freshly provisioned one is writable. OnRootMismatch - # keeps the kubelet from walking the data directory on every start, - # which would leave PGDATA group-writable and postgres refusing to run. - fsGroup: 70 - fsGroupChangePolicy: OnRootMismatch - # PostgreSQL re-reads its TLS files only on SIGHUP, so this sidecar - # reloads the server whenever the kubelet rotates the projected pod - # certificate. fsGroup is also what makes that projection readable: the - # kubelet writes it root-owned for as long as the pod's containers do not - # all agree on one non-root user, and grants the fsGroup group access, - # landing the key at root:postgres 0640, the only shared mode PostgreSQL - # accepts. Pinning runAsUser on the postgres container would make the key - # postgres-owned and group-readable, which it rejects. - # See https://www.postgresql.org/docs/current/ssl-tcp.html#SSL-SETUP - initContainers: - - name: tls-reloader - restartPolicy: Always - image: {{ include "substrate.thirdPartyImage" (list .Values.images.postgres .) }} - securityContext: - runAsUser: 70 - command: - - /bin/sh - - /etc/postgresql/reload-tls.sh - volumeMounts: - - name: config - mountPath: /etc/postgresql - - name: servicedns - mountPath: /run/servicedns.podcert.ate.dev - readOnly: true - - name: podidentity-ca - mountPath: /run/podidentity.podcert.ate.dev - readOnly: true - - name: socket - mountPath: /var/run/postgresql - resources: - requests: - cpu: 10m - memory: 32Mi - {{- with include "substrate.imagePullSecrets" . }}{{- . | nindent 6 }}{{- end }} - containers: - - name: postgres - image: {{ include "substrate.thirdPartyImage" (list .Values.images.postgres .) }} - lifecycle: - postStart: - exec: - command: - - /bin/sh - - -ec - - | - until psql -U postgres -d postgres -Atc 'SELECT 1' >/dev/null 2>&1; do - sleep 1 - done - if ! psql -U postgres -d postgres -Atc \ - "SELECT 1 FROM pg_database WHERE datname = 'atepg'" | grep -qx 1; then - createdb -U postgres atepg - fi - env: - - name: POSTGRES_DB - value: atepg - - name: POSTGRES_HOST_AUTH_METHOD - value: trust - - name: PGDATA - value: /var/lib/postgresql/data/pgdata - ports: - - name: postgres - containerPort: 5432 - readinessProbe: - exec: - command: ["/bin/sh", "-ec", "psql -U postgres -d atepg -Atc 'SELECT 1' >/dev/null"] - initialDelaySeconds: 2 - periodSeconds: 2 - livenessProbe: - exec: - command: ["pg_isready", "-U", "postgres", "-d", "postgres"] - initialDelaySeconds: 10 - periodSeconds: 10 - args: ["-c", "config_file=/etc/postgresql/postgresql.conf"] - volumeMounts: - - name: config - mountPath: /etc/postgresql - - name: servicedns - mountPath: /run/servicedns.podcert.ate.dev - readOnly: true - - name: podidentity-ca - mountPath: /run/podidentity.podcert.ate.dev - readOnly: true - - name: socket - mountPath: /var/run/postgresql - - name: data - mountPath: /var/lib/postgresql/data - resources: -{{ toYaml .Values.postgres.resources | indent 10 }} - volumes: - - name: config - configMap: - name: {{ $name }}-config - - name: servicedns - projected: - # 0600 plus the group read that fsGroup adds is the 0640 above. - defaultMode: 0600 - sources: - - podCertificate: - signerName: servicedns.podcert.ate.dev/identity - keyType: ECDSAP256 - credentialBundlePath: credential-bundle.pem - # The unix socket directory, shared so the sidecar can ask the running - # server to reload. The image defaults both the server and its clients to - # this path, so nothing else has to know about it. - - name: socket - emptyDir: {} - - name: podidentity-ca - projected: - sources: - - clusterTrustBundle: - signerName: podidentity.podcert.ate.dev/identity - labelSelector: - matchLabels: - podcert.ate.dev/canarying: live - path: trust-bundle.pem - volumeClaimTemplates: - - metadata: - name: data - spec: - accessModes: ["ReadWriteOnce"] - resources: - requests: - storage: {{ .Values.postgres.storageSize }} -{{- end }} diff --git a/charts/substrate/templates/role.yaml b/charts/substrate/templates/role.yaml index 8102c28114..07f1973ed2 100644 --- a/charts/substrate/templates/role.yaml +++ b/charts/substrate/templates/role.yaml @@ -110,7 +110,7 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: {{ include "substrate.fullname" (list "ate-controller" .) }} - namespace: ate-system + namespace: {{ .Release.Namespace }} rules: - apiGroups: - discovery.k8s.io diff --git a/charts/substrate/tests/namespace_test.yaml b/charts/substrate/tests/namespace_test.yaml new file mode 100644 index 0000000000..7c4973f267 --- /dev/null +++ b/charts/substrate/tests/namespace_test.yaml @@ -0,0 +1,27 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +suite: Release namespace +templates: +- role.yaml +release: + namespace: kagent +tests: +- it: places the controller Role in the release namespace + template: role.yaml + documentIndex: 1 + asserts: + - equal: + path: metadata.namespace + value: kagent diff --git a/charts/substrate/tests/postgres_test.yaml b/charts/substrate/tests/postgres_test.yaml new file mode 100644 index 0000000000..40c8d55bce --- /dev/null +++ b/charts/substrate/tests/postgres_test.yaml @@ -0,0 +1,107 @@ +# Copyright 2026 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +suite: PostgreSQL configuration +templates: +- ate-api-server-envvars.yaml +- ate-api-server.yaml +tests: +- it: uses the managed schema by default + template: ate-api-server-envvars.yaml + asserts: + - equal: + path: data.ATE_API_POSTGRES_SCHEMA + value: substrate + +- it: mounts separate owner and read-write connections + template: ate-api-server.yaml + documentIndex: 3 + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: --postgres-read-write-connection-string=@file:/etc/ateapi/postgres/read-write/connection-string + - contains: + path: spec.template.spec.containers[0].args + content: --postgres-owner-connection-string=@file:/etc/ateapi/postgres/owner/connection-string + - contains: + path: spec.template.spec.containers[0].args + content: --postgres-read-write-role=substrate_readwrite + - contains: + path: spec.template.spec.containers[0].args + content: --postgres-owner-role=substrate_owner + - notContains: + path: spec.template.spec.containers[0].args + content: + --postgres-bootstrap + - notExists: + path: spec.template.spec.volumes[?(@.name == "postgres-admin")] + - equal: + path: spec.template.spec.volumes[?(@.name == "postgres-read-write-connection")].projected.sources[0].secret.name + value: substrate-postgres-readwrite + - equal: + path: spec.template.spec.volumes[?(@.name == "postgres-owner-connection")].projected.sources[0].secret.name + value: substrate-postgres-owner + +- it: supports prepared database identities + template: ate-api-server.yaml + documentIndex: 3 + set: + postgres: + readWriteConnectionStringSecretRef: + name: tenant-readwrite + key: connectionString + ownerConnectionStringSecretRef: + name: tenant-owner + key: connectionString + readWriteRole: tenant_readwrite + ownerRole: tenant_owner + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: --postgres-read-write-role=tenant_readwrite + - contains: + path: spec.template.spec.containers[0].args + content: --postgres-owner-role=tenant_owner + - equal: + path: spec.template.spec.volumes[?(@.name == "postgres-read-write-connection")].projected.sources[0].secret.name + value: tenant-readwrite + - equal: + path: spec.template.spec.volumes[?(@.name == "postgres-owner-connection")].projected.sources[0].secret.name + value: tenant-owner + +- it: requires a read-write Secret + template: ate-api-server-envvars.yaml + set: + postgres.readWriteConnectionStringSecretRef.name: "" + asserts: + - failedTemplate: + errorMessage: postgres.readWriteConnectionStringSecretRef.name is required + +- it: requires an owner Secret + template: ate-api-server-envvars.yaml + set: + postgres.ownerConnectionStringSecretRef.name: "" + asserts: + - failedTemplate: + errorMessage: postgres.ownerConnectionStringSecretRef.name is required + +- it: configures the maximum connection lifetime + template: ate-api-server.yaml + documentIndex: 3 + set: + postgres.pool.maxConnLifetime: 10m + asserts: + - contains: + path: spec.template.spec.containers[0].args + content: --postgres-max-conn-lifetime=10m diff --git a/charts/substrate/values.yaml b/charts/substrate/values.yaml index 6c3ea024d6..73df812ce0 100644 --- a/charts/substrate/values.yaml +++ b/charts/substrate/values.yaml @@ -24,17 +24,22 @@ createNamespace: false postgres: - enabled: true - storageSize: 1Gi - connectionString: "" - schema: public - resources: - requests: - cpu: "1" - memory: 1Gi - limits: - cpu: "2" - memory: 2Gi + # Read the read/write connection string from a pre-created Secret. + readWriteConnectionStringSecretRef: + name: substrate-postgres-readwrite + key: readWriteConnectionString + # Read the owner connection string from a pre-created Secret. + ownerConnectionStringSecretRef: + name: substrate-postgres-owner + key: ownerConnectionString + # Roles assumed on each connection. Use distinct roles for installs sharing a database. + readWriteRole: substrate_readwrite + ownerRole: substrate_owner + pool: + # Bounds how long established connections can keep an old credential. + # Leave empty to use the upstream pgx default. + maxConnLifetime: "" + schema: substrate rustfs: enabled: true @@ -122,7 +127,6 @@ image: tag: "" images: - postgres: postgres:18-alpine@sha256:9a8afca54e7861fd90fab5fdf4c42477a6b1cb7d293595148e674e0a3181de15 rustfs: rustfs/rustfs:1.0.0-beta.3@sha256:378642b05b7dcb4849fb77ebe6aca4ced1c3f66e7e504247df95a5c9018d3358 awsCli: amazon/aws-cli:2.17.0@sha256:643507c10ada7964ca6157b3d799f030b90577643da9955d319a77399ed80d73 agentgateway: ghcr.io/kagent-dev/substrate/agentgateway:50999825cb55@sha256:f1907a50b2e74a071da53fcd2008d585b6a63d31b4e1ba3ee46cf22b342cf04b diff --git a/manifests/ate-install/ate-api-server-envvars.yaml b/manifests/ate-install/ate-api-server-envvars.yaml index b49cff6e1e..647574752d 100644 --- a/manifests/ate-install/ate-api-server-envvars.yaml +++ b/manifests/ate-install/ate-api-server-envvars.yaml @@ -21,5 +21,4 @@ metadata: name: ate-api-server-envvars namespace: ate-system data: - ATE_API_POSTGRES_CONNECTION_STRING: "postgresql://postgres@postgres.ate-system.svc:5432/atepg?sslmode=verify-full&sslrootcert=/run/servicedns.podcert.ate.dev/trust-bundle.pem&sslcert=/run/podidentity.podcert.ate.dev/credential-bundle.pem&sslkey=/run/podidentity.podcert.ate.dev/credential-bundle.pem" - ATE_API_POSTGRES_SCHEMA: "public" + ATE_API_POSTGRES_SCHEMA: "substrate"