diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index e0b3ccc18..a7cc65739 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -126,7 +126,9 @@ This installs the following components into your cluster: | Prometheus | Metrics collection | `kagent` | | Metrics Server | Kubernetes resource metrics | `kube-system` | -PostgreSQL (with pgvector) is deployed automatically as part of `make helm-install` via the bundled Helm chart. The optional addons above provide observability components. +PostgreSQL is deployed automatically as part of `make helm-install` via the bundled Helm chart. The optional addons above provide observability components. + +> **pgvector:** The default bundled PostgreSQL image (`postgres:18`) does not include the pgvector extension. If you need vector features (e.g. long-term memory), either use an external PostgreSQL instance with pgvector installed, or override the bundled image to `pgvector/pgvector:pg18-trixie` and set `database.postgres.vectorEnabled=true`. The `make helm-install` target does this automatically for local development. Verify the database connection by checking the controller logs: diff --git a/Makefile b/Makefile index cdbaf690d..99d93a029 100644 --- a/Makefile +++ b/Makefile @@ -375,6 +375,10 @@ helm-install-provider: helm-version check-api-key --set kmcp.enabled=$(KMCP_ENABLED) \ --set kmcp.image.tag=$(KMCP_VERSION) \ --set querydoc.openai.apiKey=$(OPENAI_API_KEY) \ + --set database.postgres.bundled.image.repository=pgvector \ + --set database.postgres.bundled.image.name=pgvector \ + --set database.postgres.bundled.image.tag=pg18-trixie \ + --set database.postgres.vectorEnabled=true \ $(KAGENT_HELM_EXTRA_ARGS) .PHONY: helm-install diff --git a/contrib/cncf/technical-review.md b/contrib/cncf/technical-review.md index 763ff2bd8..3465997f2 100644 --- a/contrib/cncf/technical-review.md +++ b/contrib/cncf/technical-review.md @@ -3,9 +3,9 @@ _This document provides a General Technical Review of the kagent project. This is a living document that demonstrates to the Technical Advisory Group (TAG) that the project satisfies the Engineering Principle requirements for moving levels. This document follows the template outlined [in the TOC subproject review](https://github.com/cncf/toc/blob/main/toc_subprojects/project-reviews-subproject/general-technical-questions.md)_ - **Project:** kagent -- **Project Version:** v0.7.5 +- **Project Version:** v0.8.0 - **Website:** [https://kagent.dev](https://kagent.dev) -- **Date Updated:** 2025-12-01 +- **Date Updated:** 2026-03-19 - **Template Version:** v1.0 - **Description:** kagent is a Kubernetes native framework for building AI agents. Kubernetes is the most popular orchestration platform for running workloads, and **kagent** makes it easy to build, deploy and manage AI agents in Kubernetes. The **kagent** framework is designed to be easy to understand and use, and to provide a flexible and powerful way to build and manage AI agents. @@ -326,7 +326,7 @@ Default values can be found in [helm/kagent/values.yaml](https://github.com/kage **Additional Configurations:** For production use, configure: -- PostgreSQL database connection (`database.type=postgres`, `database.postgres.url`) +- External PostgreSQL connection (set `database.postgres.bundled.enabled=false` and set either `database.postgres.url` or `database.postgres.urlFile`) - LLM API keys via Secrets (`providers.openAI.apiKeySecretRef`) - TLS for external LLM connections (`modelConfig.tls`) - Resource limits based on workload (`agents.*.resources`) diff --git a/helm/kagent/templates/NOTES.txt b/helm/kagent/templates/NOTES.txt index d42bd2a6d..29510bc19 100644 --- a/helm/kagent/templates/NOTES.txt +++ b/helm/kagent/templates/NOTES.txt @@ -59,4 +59,27 @@ TROUBLESHOOTING: DOCUMENTATION: Visit https://kagent.dev for comprehensive documentation and examples. +{{ if .Values.database.postgres.bundled.enabled -}} +################################################################################ +{{- if and (eq .Values.database.postgres.url "") (eq .Values.database.postgres.urlFile "") }} +# WARNING: BUNDLED DATABASE IN USE # +################################################################################ + The bundled PostgreSQL instance is enabled. It is intended for development and + evaluation only — not suitable for production use. Data may be lost if the + pod is restarted or rescheduled. + + To use an external database, set: + database.postgres.url= or database.postgres.urlFile= +{{- else }} +# NOTE: BUNDLED DATABASE DEPLOYED BUT NOT IN USE BY CONTROLLER # +################################################################################ + The bundled PostgreSQL pod is running, but the controller is connected to an + external database (database.postgres.url or database.postgres.urlFile is set). + + To connect the controller to the bundled instance instead, unset url/urlFile: + database.postgres.url="" + To stop deploying the bundled pod entirely, set: + database.postgres.bundled.enabled=false +{{- end }} +{{- end }} ################################################################################ diff --git a/helm/kagent/templates/_helpers.tpl b/helm/kagent/templates/_helpers.tpl index 7625a8610..816f6638a 100644 --- a/helm/kagent/templates/_helpers.tpl +++ b/helm/kagent/templates/_helpers.tpl @@ -122,14 +122,18 @@ PostgreSQL service name for the bundled postgres instance {{- end -}} {{/* -PostgreSQL URL - auto-computed from bundled config when url is empty, otherwise uses database.postgres.url +Bundled PostgreSQL image - constructs the full image reference from registry/repository/name/tag */}} -{{- define "kagent.postgresqlUrl" -}} -{{- if not (eq .Values.database.postgres.url "") -}} -{{- .Values.database.postgres.url -}} -{{- else -}} -{{- printf "postgres://%s:%s@%s.%s.svc.cluster.local:5432/%s" .Values.database.postgres.bundled.user .Values.database.postgres.bundled.password (include "kagent.postgresqlServiceName" .) (include "kagent.namespace" .) .Values.database.postgres.bundled.database -}} +{{- define "kagent.postgresql.image" -}} +{{- $pg := .Values.database.postgres.bundled -}} +{{- printf "%s/%s/%s:%s" $pg.image.registry $pg.image.repository $pg.image.name $pg.image.tag -}} {{- end -}} + +{{/* +Password secret name - returns the chart-managed Secret name for POSTGRES_PASSWORD. +*/}} +{{- define "kagent.passwordSecretName" -}} +{{- printf "%s-postgresql" (include "kagent.fullname" .) -}} {{- end -}} {{/* diff --git a/helm/kagent/templates/controller-configmap.yaml b/helm/kagent/templates/controller-configmap.yaml index ffe2abc9e..4b18e636f 100644 --- a/helm/kagent/templates/controller-configmap.yaml +++ b/helm/kagent/templates/controller-configmap.yaml @@ -51,11 +51,6 @@ data: {{- if .Values.proxy.url }} PROXY_URL: {{ .Values.proxy.url | quote }} {{- end }} - {{- if not (eq .Values.database.postgres.urlFile "") }} - POSTGRES_DATABASE_URL_FILE: {{ .Values.database.postgres.urlFile | quote }} - {{- else }} - POSTGRES_DATABASE_URL: {{ include "kagent.postgresqlUrl" . | quote }} - {{- end }} DATABASE_VECTOR_ENABLED: {{ .Values.database.postgres.vectorEnabled | quote }} STREAMING_INITIAL_BUF_SIZE: {{ .Values.controller.streaming.initialBufSize | quote }} STREAMING_MAX_BUF_SIZE: {{ .Values.controller.streaming.maxBufSize | quote }} diff --git a/helm/kagent/templates/controller-deployment.yaml b/helm/kagent/templates/controller-deployment.yaml index b332a9e7a..3d264913a 100644 --- a/helm/kagent/templates/controller-deployment.yaml +++ b/helm/kagent/templates/controller-deployment.yaml @@ -14,6 +14,7 @@ spec: metadata: annotations: checksum/configmap: {{ include (print $.Template.BasePath "/controller-configmap.yaml") . | sha256sum }} + checksum/secret: {{ include (print $.Template.BasePath "/postgresql-secret.yaml") . | sha256sum }} {{- with .Values.controller.podAnnotations }} {{- toYaml . | nindent 8 }} {{- end }} @@ -60,6 +61,23 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName + {{- if .Values.database.postgres.urlFile }} + - name: POSTGRES_DATABASE_URL_FILE + value: {{ .Values.database.postgres.urlFile | quote }} + {{- else if .Values.database.postgres.url }} + - name: POSTGRES_DATABASE_URL + value: {{ .Values.database.postgres.url | quote }} + {{- else if .Values.database.postgres.bundled.enabled }} + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "kagent.passwordSecretName" . }} + key: POSTGRES_PASSWORD + - name: POSTGRES_DATABASE_URL + value: {{ printf "postgres://kagent:$(POSTGRES_PASSWORD)@%s.%s.svc.cluster.local:5432/kagent?sslmode=disable" (include "kagent.postgresqlServiceName" .) (include "kagent.namespace" .) | quote }} + {{- else }} + {{ fail "No database connection configured. Set database.postgres.url, database.postgres.urlFile, or enable database.postgres.bundled." }} + {{- end }} {{- with .Values.controller.env }} {{- toYaml . | nindent 12 }} {{- end }} diff --git a/helm/kagent/templates/postgresql-secret.yaml b/helm/kagent/templates/postgresql-secret.yaml new file mode 100644 index 000000000..3adb5b3c4 --- /dev/null +++ b/helm/kagent/templates/postgresql-secret.yaml @@ -0,0 +1,13 @@ +{{- if .Values.database.postgres.bundled.enabled }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "kagent.passwordSecretName" . }} + namespace: {{ include "kagent.namespace" . }} + labels: + {{- include "kagent.labels" . | nindent 4 }} + app.kubernetes.io/component: database +type: Opaque +data: + POSTGRES_PASSWORD: {{ "kagent" | b64enc | quote }} +{{- end }} diff --git a/helm/kagent/templates/postgresql.yaml b/helm/kagent/templates/postgresql.yaml index 43ba99690..82d4384c6 100644 --- a/helm/kagent/templates/postgresql.yaml +++ b/helm/kagent/templates/postgresql.yaml @@ -1,90 +1,125 @@ -{{- if and (eq .Values.database.postgres.url "") (eq .Values.database.postgres.urlFile "") }} ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: {{ include "kagent.fullname" . }}-postgresql - namespace: {{ include "kagent.namespace" . }} - labels: - {{- include "kagent.labels" . | nindent 4 }} - app.kubernetes.io/component: postgresql -data: - POSTGRES_DB: {{ .Values.database.postgres.bundled.database | quote }} - POSTGRES_USER: {{ .Values.database.postgres.bundled.user | quote }} - POSTGRES_PASSWORD: {{ .Values.database.postgres.bundled.password | quote }} +{{- if .Values.database.postgres.bundled.enabled }} +{{- $pg := .Values.database.postgres.bundled }} +{{- $fullname := include "kagent.postgresqlServiceName" . }} --- apiVersion: v1 kind: PersistentVolumeClaim metadata: - name: {{ include "kagent.fullname" . }}-postgresql + name: {{ $fullname }} namespace: {{ include "kagent.namespace" . }} labels: {{- include "kagent.labels" . | nindent 4 }} - app.kubernetes.io/component: postgresql + app.kubernetes.io/component: database spec: accessModes: - ReadWriteOnce resources: requests: - storage: {{ .Values.database.postgres.bundled.storage | quote }} + storage: {{ $pg.storage | quote }} --- apiVersion: apps/v1 kind: Deployment metadata: - name: {{ include "kagent.fullname" . }}-postgresql + name: {{ $fullname }} namespace: {{ include "kagent.namespace" . }} labels: {{- include "kagent.labels" . | nindent 4 }} - app.kubernetes.io/component: postgresql + app.kubernetes.io/component: database spec: replicas: 1 + strategy: + type: Recreate selector: matchLabels: {{- include "kagent.selectorLabels" . | nindent 6 }} - app.kubernetes.io/component: postgresql + app.kubernetes.io/component: database template: metadata: labels: {{- include "kagent.selectorLabels" . | nindent 8 }} - app.kubernetes.io/component: postgresql + app.kubernetes.io/component: database spec: + securityContext: + fsGroup: 999 + runAsUser: 999 + runAsGroup: 999 + runAsNonRoot: true containers: - name: postgresql - image: {{ .Values.database.postgres.bundled.image | quote }} + image: {{ include "kagent.postgresql.image" . }} + imagePullPolicy: {{ $pg.image.pullPolicy }} + securityContext: + allowPrivilegeEscalation: false ports: - - containerPort: 5432 - envFrom: - - configMapRef: - name: {{ include "kagent.fullname" . }}-postgresql - volumeMounts: - - name: postgresql-storage - mountPath: /var/lib/postgresql + - name: postgresql + containerPort: 5432 + protocol: TCP + env: + - name: POSTGRES_DB + value: "kagent" + - name: POSTGRES_USER + value: "kagent" + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "kagent.passwordSecretName" . }} + key: POSTGRES_PASSWORD + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + livenessProbe: + exec: + command: + - pg_isready + - -U + - kagent + - -d + - kagent + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + successThreshold: 1 + readinessProbe: + exec: + command: + - pg_isready + - -U + - kagent + - -d + - kagent + initialDelaySeconds: 5 + periodSeconds: 5 + timeoutSeconds: 3 + failureThreshold: 3 + successThreshold: 1 + {{- if $pg.resources }} resources: - requests: - memory: "256Mi" - cpu: "250m" - limits: - memory: "512Mi" - cpu: "500m" + {{- toYaml $pg.resources | nindent 12 }} + {{- end }} + volumeMounts: + - name: data + mountPath: /var/lib/postgresql/data volumes: - - name: postgresql-storage + - name: data persistentVolumeClaim: - claimName: {{ include "kagent.fullname" . }}-postgresql + claimName: {{ $fullname }} --- apiVersion: v1 kind: Service metadata: - name: {{ include "kagent.postgresqlServiceName" . }} + name: {{ $fullname }} namespace: {{ include "kagent.namespace" . }} labels: {{- include "kagent.labels" . | nindent 4 }} - app.kubernetes.io/component: postgresql + app.kubernetes.io/component: database spec: + type: ClusterIP + ports: + - name: postgresql + port: 5432 + targetPort: postgresql + protocol: TCP selector: {{- include "kagent.selectorLabels" . | nindent 4 }} - app.kubernetes.io/component: postgresql - ports: - - port: 5432 - targetPort: 5432 - type: ClusterIP + app.kubernetes.io/component: database {{- end }} diff --git a/helm/kagent/tests/controller-deployment_test.yaml b/helm/kagent/tests/controller-deployment_test.yaml index b69140cd5..63df8ca2f 100644 --- a/helm/kagent/tests/controller-deployment_test.yaml +++ b/helm/kagent/tests/controller-deployment_test.yaml @@ -2,6 +2,7 @@ suite: test controller deployment templates: - controller-deployment.yaml - controller-configmap.yaml + - postgresql-secret.yaml tests: - it: should render controller deployment with default values template: controller-deployment.yaml @@ -209,4 +210,150 @@ tests: - isNull: path: spec.template.spec.volumes - isNull: - path: spec.template.spec.containers[0].volumeMounts \ No newline at end of file + path: spec.template.spec.containers[0].volumeMounts + + # ============================================================================= + # Database Configuration Tests + # ============================================================================= + + - it: should set POSTGRES_PASSWORD from secret and POSTGRES_DATABASE_URL with bundled connection string by default + template: controller-deployment.yaml + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: RELEASE-NAME-postgresql + key: POSTGRES_PASSWORD + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_DATABASE_URL + value: "postgres://kagent:$(POSTGRES_PASSWORD)@RELEASE-NAME-postgresql.NAMESPACE.svc.cluster.local:5432/kagent?sslmode=disable" + + - it: should set POSTGRES_DATABASE_URL with external url when url is set + template: controller-deployment.yaml + set: + database: + postgres: + url: "postgres://user:pass@external-host:5432/db" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_DATABASE_URL + value: "postgres://user:pass@external-host:5432/db" + + - it: should set POSTGRES_DATABASE_URL_FILE and omit POSTGRES_PASSWORD when urlFile is set + template: controller-deployment.yaml + set: + database: + postgres: + urlFile: "/var/secrets/db-url" + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_DATABASE_URL_FILE + value: "/var/secrets/db-url" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_PASSWORD + + - it: should set DATABASE_VECTOR_ENABLED to false by default + template: controller-configmap.yaml + asserts: + - equal: + path: data.DATABASE_VECTOR_ENABLED + value: "false" + + - it: should set DATABASE_VECTOR_ENABLED to true when enabled + template: controller-configmap.yaml + set: + database: + postgres: + vectorEnabled: true + asserts: + - equal: + path: data.DATABASE_VECTOR_ENABLED + value: "true" + + - it: should not set POSTGRES_DATABASE_URL in configmap + template: controller-configmap.yaml + asserts: + - notExists: + path: data.POSTGRES_DATABASE_URL + + - it: should not set POSTGRES_PASSWORD when url is set and bundled is enabled + template: controller-deployment.yaml + set: + database: + postgres: + url: "postgres://user:pass@external-host:5432/db" + bundled: + enabled: true + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_PASSWORD + + - it: should not set POSTGRES_PASSWORD when url is set and bundled is disabled + template: controller-deployment.yaml + set: + database: + postgres: + url: "postgres://user:pass@external-host:5432/db" + bundled: + enabled: false + asserts: + - notContains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_PASSWORD + + - it: should set POSTGRES_DATABASE_URL_FILE and omit POSTGRES_PASSWORD when urlFile and bundled are both enabled + template: controller-deployment.yaml + set: + database: + postgres: + urlFile: "/var/secrets/db-url" + bundled: + enabled: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_DATABASE_URL_FILE + value: "/var/secrets/db-url" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_PASSWORD + - notContains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_DATABASE_URL + + - it: should set external POSTGRES_DATABASE_URL and omit POSTGRES_PASSWORD when url and bundled are both enabled + template: controller-deployment.yaml + set: + database: + postgres: + url: "postgres://user:pass@external-host:5432/db" + bundled: + enabled: true + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_DATABASE_URL + value: "postgres://user:pass@external-host:5432/db" + - notContains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_PASSWORD + diff --git a/helm/kagent/tests/postgresql_test.yaml b/helm/kagent/tests/postgresql_test.yaml new file mode 100644 index 000000000..2e7b885bc --- /dev/null +++ b/helm/kagent/tests/postgresql_test.yaml @@ -0,0 +1,277 @@ +suite: test postgresql +templates: + - postgresql.yaml + - postgresql-secret.yaml +tests: + # ============================================================================= + # bundled mode (default — url and urlFile both empty, bundled.enabled true) + # ============================================================================= + + - it: should render PVC, Deployment, and Service when bundled is enabled + template: postgresql.yaml + asserts: + - hasDocuments: + count: 3 + + - it: should not render any resources when bundled is disabled + template: postgresql.yaml + set: + database: + postgres: + bundled: + enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should still render resources when url is set and bundled is enabled + template: postgresql.yaml + set: + database: + postgres: + url: "postgres://user:pass@external-host:5432/db" + asserts: + - hasDocuments: + count: 3 + + - it: should still render resources when urlFile is set and bundled is enabled + template: postgresql.yaml + set: + database: + postgres: + urlFile: "/var/secrets/db-url" + asserts: + - hasDocuments: + count: 3 + + + - it: should render PVC with correct storage size + template: postgresql.yaml + documentIndex: 0 + asserts: + - isKind: + of: PersistentVolumeClaim + - equal: + path: spec.resources.requests.storage + value: "500Mi" + + - it: should render PVC with custom storage size + template: postgresql.yaml + documentIndex: 0 + set: + database: + postgres: + bundled: + storage: 10Gi + asserts: + - equal: + path: spec.resources.requests.storage + value: "10Gi" + + - it: should render Deployment with default pgvector image + template: postgresql.yaml + documentIndex: 1 + asserts: + - isKind: + of: Deployment + - equal: + path: spec.template.spec.containers[0].image + value: docker.io/library/postgres:18 + + - it: should render Deployment with custom image + template: postgresql.yaml + documentIndex: 1 + set: + database: + postgres: + bundled: + image: + registry: my-registry.example.com + repository: myorg + name: postgres + tag: "15" + asserts: + - equal: + path: spec.template.spec.containers[0].image + value: my-registry.example.com/myorg/postgres:15 + + - it: should read POSTGRES_PASSWORD from chart-managed secret + template: postgresql.yaml + documentIndex: 1 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: RELEASE-NAME-postgresql + key: POSTGRES_PASSWORD + + - it: should set POSTGRES_DB and POSTGRES_USER to hardcoded values + template: postgresql.yaml + documentIndex: 1 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_DB + value: "kagent" + - contains: + path: spec.template.spec.containers[0].env + content: + name: POSTGRES_USER + value: "kagent" + + - it: should set PGDATA env var + template: postgresql.yaml + documentIndex: 1 + asserts: + - contains: + path: spec.template.spec.containers[0].env + content: + name: PGDATA + value: /var/lib/postgresql/data/pgdata + + - it: should have liveness and readiness probes + template: postgresql.yaml + documentIndex: 1 + asserts: + - isNotNull: + path: spec.template.spec.containers[0].livenessProbe + - isNotNull: + path: spec.template.spec.containers[0].readinessProbe + + - it: should render Deployment with default resource requests and limits + template: postgresql.yaml + documentIndex: 1 + asserts: + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 250m + - equal: + path: spec.template.spec.containers[0].resources.requests.memory + value: 256Mi + - equal: + path: spec.template.spec.containers[0].resources.limits.cpu + value: 500m + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 512Mi + + - it: should render Deployment with custom resources + template: postgresql.yaml + documentIndex: 1 + set: + database: + postgres: + bundled: + resources: + requests: + cpu: 500m + memory: 512Mi + limits: + cpu: "2" + memory: 2Gi + asserts: + - equal: + path: spec.template.spec.containers[0].resources.requests.cpu + value: 500m + - equal: + path: spec.template.spec.containers[0].resources.limits.memory + value: 2Gi + + - it: should render Deployment with Recreate strategy + template: postgresql.yaml + documentIndex: 1 + asserts: + - equal: + path: spec.strategy.type + value: Recreate + + - it: should render Deployment with security context + template: postgresql.yaml + documentIndex: 1 + asserts: + - equal: + path: spec.template.spec.securityContext.runAsNonRoot + value: true + - equal: + path: spec.template.spec.securityContext.runAsUser + value: 999 + + - it: should render Service with hardcoded ClusterIP type and port 5432 + template: postgresql.yaml + documentIndex: 2 + asserts: + - isKind: + of: Service + - equal: + path: spec.type + value: ClusterIP + - equal: + path: spec.ports[0].port + value: 5432 + + - it: should use correct selector labels on Service + template: postgresql.yaml + documentIndex: 2 + asserts: + - equal: + path: spec.selector["app.kubernetes.io/component"] + value: database + + # ============================================================================= + # postgresql-secret.yaml + # ============================================================================= + + - it: should create secret in bundled mode + template: postgresql-secret.yaml + asserts: + - isKind: + of: Secret + - equal: + path: metadata.name + value: RELEASE-NAME-postgresql + - isNotNull: + path: data.POSTGRES_PASSWORD + + - it: should base64-encode the hardcoded demo password + template: postgresql-secret.yaml + asserts: + - equal: + path: data.POSTGRES_PASSWORD + # echo -n "kagent" | base64 + value: "a2FnZW50" + + - it: should not create secret when bundled is disabled + template: postgresql-secret.yaml + set: + database: + postgres: + bundled: + enabled: false + asserts: + - hasDocuments: + count: 0 + + - it: should still create secret when url is set and bundled is enabled + template: postgresql-secret.yaml + set: + database: + postgres: + url: "postgres://user:pass@host:5432/db" + asserts: + - hasDocuments: + count: 1 + + - it: should still create secret when urlFile is set and bundled is enabled + template: postgresql-secret.yaml + set: + database: + postgres: + urlFile: "/var/secrets/db-url" + asserts: + - hasDocuments: + count: 1 + diff --git a/helm/kagent/tests/security-context_test.yaml b/helm/kagent/tests/security-context_test.yaml index ab2a71813..828227048 100644 --- a/helm/kagent/tests/security-context_test.yaml +++ b/helm/kagent/tests/security-context_test.yaml @@ -3,6 +3,7 @@ templates: - _helpers.tpl - controller-configmap.yaml - controller-deployment.yaml + - postgresql-secret.yaml - ui-deployment.yaml tests: # ============================================================================= diff --git a/helm/kagent/values.yaml b/helm/kagent/values.yaml index 3726c3702..4fa8f4762 100644 --- a/helm/kagent/values.yaml +++ b/helm/kagent/values.yaml @@ -53,23 +53,44 @@ nodeSelector: {} database: postgres: - # PostgreSQL connection string. Leave empty to deploy the bundled postgres instance. - # Set this to use an external PostgreSQL. + # -- External PostgreSQL connection string. + # Is always used if set regardless of the `.bundled.enabled` field. url: "" - # Path to a file containing the database URL. Takes precedence over url when set. - # Leave empty to use the bundled postgres instance. + # -- Path to a file containing the database URL. Takes precedence over url when set. + # Is always used if set regardless of the `.bundled.enabled` field. urlFile: "" - # Enable pgvector extension and memory table migration. - # Requires pgvector to be installed on the PostgreSQL server. - # Set to false when using an external PostgreSQL that does not have pgvector. - vectorEnabled: true - # Bundled PostgreSQL configuration — used when url and urlFile are both empty. + # -- Enable the pgvector migration + # Required to use features that depend on database vector capability. (e.g. long-term memory) + # Set to true when using an external PostgreSQL that has the pgvector extension installed. + vectorEnabled: false + # -- Bundled PostgreSQL instance — for development and evaluation only. + # Not suitable for production. Deployed when enabled is true and url/urlFile are not set. bundled: - image: pgvector/pgvector:pg18-trixie + # -- Set to false to disable the bundled database and provide your own via url or urlFile. + enabled: true + image: + # -- Bundled PostgreSQL image registry + registry: docker.io + # -- Bundled PostgreSQL image repository (org/namespace) + repository: library + # -- Bundled PostgreSQL image name + name: postgres + # -- Bundled PostgreSQL image tag + tag: "18" + # -- Bundled PostgreSQL image pull policy + pullPolicy: IfNotPresent + # -- PersistentVolumeClaim size for demo PostgreSQL data storage: 500Mi - database: postgres - user: postgres - password: kagent + # The database name, user, and password are hardcoded for the bundled instance (all: "kagent"). + # This is intentional for a dev/eval setup. Switch to an external database for production. + # -- Resource requests/limits for the demo PostgreSQL container + resources: + requests: + cpu: 250m + memory: 256Mi + limits: + cpu: 500m + memory: 512Mi # ============================================================================== # CONTROLLER CONFIGURATION