{{- if .Values.postgres.enabled }} --- apiVersion: v1 kind: ConfigMap metadata: name: {{ include "tod.fullname" . }}-postgres-init labels: {{- include "tod.componentLabels" (dict "context" . "component" "postgres") | nindent 4 }} data: init.sql: | -- Enable TimescaleDB (required for hypertables) CREATE EXTENSION IF NOT EXISTS timescaledb; -- app_user role (RLS enforced, DML only) DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '{{ .Values.postgres.auth.appUsername }}') THEN CREATE ROLE {{ .Values.postgres.auth.appUsername }} WITH LOGIN PASSWORD '{{ .Values.secrets.dbAppPassword }}'; END IF; END $$; GRANT CONNECT ON DATABASE {{ .Values.postgres.auth.database }} TO {{ .Values.postgres.auth.appUsername }}; GRANT USAGE ON SCHEMA public TO {{ .Values.postgres.auth.appUsername }}; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO {{ .Values.postgres.auth.appUsername }}; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO {{ .Values.postgres.auth.appUsername }}; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO {{ .Values.postgres.auth.appUsername }}; ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT USAGE, SELECT ON SEQUENCES TO {{ .Values.postgres.auth.appUsername }}; -- poller_user role (bypasses RLS for cross-tenant device polling) DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = 'poller_user') THEN CREATE ROLE poller_user WITH LOGIN PASSWORD '{{ .Values.secrets.dbPollerPassword }}' NOSUPERUSER NOCREATEDB NOCREATEROLE BYPASSRLS; END IF; END $$; GRANT CONNECT ON DATABASE {{ .Values.postgres.auth.database }} TO poller_user; GRANT USAGE ON SCHEMA public TO poller_user; --- apiVersion: apps/v1 kind: StatefulSet metadata: name: {{ include "tod.fullname" . }}-postgres labels: {{- include "tod.componentLabels" (dict "context" . "component" "postgres") | nindent 4 }} spec: serviceName: {{ include "tod.fullname" . }}-postgres replicas: 1 selector: matchLabels: {{- include "tod.componentSelectorLabels" (dict "context" . "component" "postgres") | nindent 6 }} template: metadata: labels: {{- include "tod.componentSelectorLabels" (dict "context" . "component" "postgres") | nindent 8 }} spec: containers: - name: postgres image: "{{ .Values.postgres.image.repository }}:{{ .Values.postgres.image.tag }}" imagePullPolicy: {{ .Values.postgres.image.pullPolicy }} ports: - name: postgres containerPort: 5432 protocol: TCP env: - name: POSTGRES_DB value: {{ .Values.postgres.auth.database | quote }} - name: POSTGRES_USER value: {{ .Values.postgres.auth.username | quote }} - name: POSTGRES_PASSWORD valueFrom: secretKeyRef: name: {{ include "tod.fullname" . }}-secrets key: DB_PASSWORD - name: APP_USER value: {{ .Values.postgres.auth.appUsername | quote }} - name: APP_USER_PASSWORD valueFrom: secretKeyRef: name: {{ include "tod.fullname" . }}-secrets key: DB_APP_PASSWORD volumeMounts: - name: postgres-data mountPath: /var/lib/postgresql/data - name: init-scripts mountPath: /docker-entrypoint-initdb.d readOnly: true resources: {{- toYaml .Values.postgres.resources | nindent 12 }} livenessProbe: exec: command: - pg_isready - -U - postgres - -d - tod initialDelaySeconds: 30 periodSeconds: 10 failureThreshold: 5 readinessProbe: exec: command: - pg_isready initialDelaySeconds: 10 periodSeconds: 5 failureThreshold: 3 volumes: - name: init-scripts configMap: name: {{ include "tod.fullname" . }}-postgres-init volumeClaimTemplates: - metadata: name: postgres-data spec: accessModes: - ReadWriteOnce {{- if .Values.postgres.storageClass }} storageClassName: {{ .Values.postgres.storageClass | quote }} {{- end }} resources: requests: storage: {{ .Values.postgres.storage }} --- apiVersion: v1 kind: Service metadata: name: {{ include "tod.fullname" . }}-postgres labels: {{- include "tod.componentLabels" (dict "context" . "component" "postgres") | nindent 4 }} spec: clusterIP: None ports: - name: postgres port: {{ .Values.postgres.service.port }} targetPort: postgres protocol: TCP selector: {{- include "tod.componentSelectorLabels" (dict "context" . "component" "postgres") | nindent 4 }} {{- end }}