From 203fb0bc96af9cf1b8f58a243d2958b62c6c2222 Mon Sep 17 00:00:00 2001 From: svetychkina Date: Fri, 22 May 2026 12:46:00 +0500 Subject: [PATCH 01/14] fix: dbaas and monitoring secrets --- .../patroni-services/templates/_helpers.tpl | 3 +- .../dbaas/dbaas-adapter-deployment.yaml | 32 ++++++++---- operator/pkg/deployment/monitoring.go | 50 ++++++++++++------- .../collector/pkg/initiate/initiate.go | 4 +- .../collector/pkg/util/util.go | 9 ++++ 5 files changed, 67 insertions(+), 31 deletions(-) diff --git a/operator/charts/patroni-services/templates/_helpers.tpl b/operator/charts/patroni-services/templates/_helpers.tpl index 0f56456b..2e169aeb 100644 --- a/operator/charts/patroni-services/templates/_helpers.tpl +++ b/operator/charts/patroni-services/templates/_helpers.tpl @@ -136,6 +136,7 @@ POSTGRES ADMIN env variables for DBaaS {{/* Aggregator Registration env variables for DBaaS */}} +{{/* {{- define "postgres-dbaas.aggregatorEnvsReg" }} - name: DBAAS_AGGREGATOR_REGISTRATION_USERNAME valueFrom: @@ -148,7 +149,7 @@ Aggregator Registration env variables for DBaaS name: dbaas-aggregator-registration-credentials key: password {{- end }} - +*/}} {{- define "find_image" -}} {{- $image := .default -}} diff --git a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index 8243cb68..c982e52e 100644 --- a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -58,6 +58,12 @@ spec: secret: secretName: {{ include "postgres.certServicesSecret" . }} defaultMode: 416 + - name: dbaas-adapter-credentials + secret: + secretName: dbaas-adapter-credentials + - name: dbaas-adapter-registration-credentials + secret: + secretName: dbaas-adapter-registration-credentials {{- end }} {{- end }} initContainers: @@ -125,16 +131,16 @@ spec: value: {{ include "dbaas.pgHostRO" . }} - name: POSTGRES_PORT value: {{ default "5432" .Values.dbaas.pgPort | quote }} - - name: DBAAS_ADAPTER_API_USER - valueFrom: - secretKeyRef: - name: dbaas-adapter-credentials - key: username - - name: DBAAS_ADAPTER_API_PASSWORD - valueFrom: - secretKeyRef: - name: dbaas-adapter-credentials - key: password + # - name: DBAAS_ADAPTER_API_USER + # valueFrom: + # secretKeyRef: + # name: dbaas-adapter-credentials + # key: username + # - name: DBAAS_ADAPTER_API_PASSWORD + # valueFrom: + # secretKeyRef: + # name: dbaas-adapter-credentials + # key: password - name: DBAAS_AGGREGATOR_PHYSICAL_DATABASE_IDENTIFIER value: {{ .Values.dbaas.aggregator.physicalDatabaseIdentifier | default (printf "%s:%s" .Release.Namespace "postgres")}} - name: CLOUD_NAMESPACE @@ -177,6 +183,12 @@ spec: - name: tls-cert mountPath: /certs/ {{- end }} + - name: dbaas-adapter-credentials + mountPath: /secrets/credentials + readOnly: true + - name: dbaas-adapter-registration-credentials + mountPath: /secrets/credentials + readOnly: true {{- end }} livenessProbe: httpGet: diff --git a/operator/pkg/deployment/monitoring.go b/operator/pkg/deployment/monitoring.go index 714c0ec8..5aba9016 100644 --- a/operator/pkg/deployment/monitoring.go +++ b/operator/pkg/deployment/monitoring.go @@ -75,6 +75,14 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl }, }, }, + { + Name: "monitoring-user-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: MetricCollectorUserCredentials}, + }, + }, + }, }, InitContainers: []corev1.Container{}, Containers: []corev1.Container{ @@ -84,24 +92,24 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl Command: []string{}, Args: []string{}, Env: append([]corev1.EnvVar{ - { - Name: "MONITORING_USER", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: MetricCollectorUserCredentials}, - Key: "username", - }, - }, - }, - { - Name: "MONITORING_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: MetricCollectorUserCredentials}, - Key: "password", - }, - }, - }, + // { + // Name: "MONITORING_USER", + // ValueFrom: &corev1.EnvVarSource{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{Name: MetricCollectorUserCredentials}, + // Key: "username", + // }, + // }, + // }, + // { + // Name: "MONITORING_PASSWORD", + // ValueFrom: &corev1.EnvVarSource{ + // SecretKeyRef: &corev1.SecretKeySelector{ + // LocalObjectReference: corev1.LocalObjectReference{Name: MetricCollectorUserCredentials}, + // Key: "password", + // }, + // }, + // }, { Name: "PG_ROOT_USER", ValueFrom: &corev1.EnvVarSource{ @@ -197,6 +205,11 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl SubPath: "telegraf_temp.conf", Name: "telegraf-config-volume", }, + { + MountPath: "/etc/monitoring-user-credentials", + Name: "monitoring-user-credentials", + ReadOnly: true, + }, }, Resources: *metricCollector.Resources, LivenessProbe: &corev1.Probe{ @@ -232,6 +245,7 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl }, }, } + if metricCollector.PriorityClassName != "" { deployment.Spec.Template.Spec.PriorityClassName = metricCollector.PriorityClassName } diff --git a/services/monitoring-agent/collector/pkg/initiate/initiate.go b/services/monitoring-agent/collector/pkg/initiate/initiate.go index 7cbf5640..5e58eae2 100644 --- a/services/monitoring-agent/collector/pkg/initiate/initiate.go +++ b/services/monitoring-agent/collector/pkg/initiate/initiate.go @@ -36,8 +36,8 @@ func InitMetricCollector() { logger.Info("Will run preparation scripts") clusterName := util.GetEnv("PGCLUSTER", "patroni") - monitoringRole := util.GetEnv("MONITORING_USER", "monitoring-user") - monitoringPassword := util.GetEnv("MONITORING_PASSWORD", "monitoring_password") + monitoringRole := util.GetSecret("username") + monitoringPassword := util.GetSecret("password") pgHost := util.GetEnv("POSTGRES_HOST", "pg-patroni") pgPort := util.GetEnvInt("POSTGRES_PORT", 5432) diff --git a/services/monitoring-agent/collector/pkg/util/util.go b/services/monitoring-agent/collector/pkg/util/util.go index ae572b68..545179de 100644 --- a/services/monitoring-agent/collector/pkg/util/util.go +++ b/services/monitoring-agent/collector/pkg/util/util.go @@ -59,6 +59,7 @@ var ( ) const certificatesFolder = "/certs" +const MetricCollectorCredentialsFolder = "/etc/monitoring-user-credentials" func GetLogger() *zap.Logger { cfg := zap.NewProductionConfig() @@ -92,6 +93,14 @@ func GetProtocol() (string, string) { } +func GetSecret(filename string) string { + secretByte, err := os.ReadFile("/etc/monitoring-user-credentials/" + filename) + if err != nil { + log.Fatal("failed to read monitoring secret: ", err) + } + return strings.TrimSpace(string(secretByte[:])) +} + func GetToken() string { tokenByte, err := os.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/token") if err != nil { From 32ec656ee9d882c432cb8d161960e3f40c66cef0 Mon Sep 17 00:00:00 2001 From: svetychkina Date: Tue, 2 Jun 2026 12:03:16 +0500 Subject: [PATCH 02/14] fix: monitoring secrets --- .../templates/secrets/monitoring-secret.yaml | 2 +- operator/pkg/deployment/monitoring.go | 60 +++++++++---------- .../collector/pkg/postgres/client.go | 4 +- .../collector/pkg/util/util.go | 2 +- 4 files changed, 32 insertions(+), 36 deletions(-) diff --git a/operator/charts/patroni-services/templates/secrets/monitoring-secret.yaml b/operator/charts/patroni-services/templates/secrets/monitoring-secret.yaml index 1a337097..48e56823 100644 --- a/operator/charts/patroni-services/templates/secrets/monitoring-secret.yaml +++ b/operator/charts/patroni-services/templates/secrets/monitoring-secret.yaml @@ -9,6 +9,6 @@ metadata: name: monitoring-credentials data: username: {{ "monitoring-user" | b64enc }} - password: {{ .Values.metricCollector.userPassword | b64enc }} + password: {{ default "p@ssWOrD1" .Values.metricCollector.userPassword | b64enc }} type: Opaque {{- end }} diff --git a/operator/pkg/deployment/monitoring.go b/operator/pkg/deployment/monitoring.go index 5aba9016..2cb65a97 100644 --- a/operator/pkg/deployment/monitoring.go +++ b/operator/pkg/deployment/monitoring.go @@ -25,6 +25,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/utils/ptr" ) var ( @@ -79,7 +80,17 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl Name: "monitoring-user-credentials", VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - SecretName: MetricCollectorUserCredentials}, + SecretName: MetricCollectorUserCredentials, + DefaultMode: ptr.To[int32](0400), + }, + }, + }, + { + Name: "influx-db-admin-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: influxDbAdminCredentials, + DefaultMode: ptr.To[int32](0400), }, }, }, @@ -92,24 +103,14 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl Command: []string{}, Args: []string{}, Env: append([]corev1.EnvVar{ - // { - // Name: "MONITORING_USER", - // ValueFrom: &corev1.EnvVarSource{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{Name: MetricCollectorUserCredentials}, - // Key: "username", - // }, - // }, - // }, - // { - // Name: "MONITORING_PASSWORD", - // ValueFrom: &corev1.EnvVarSource{ - // SecretKeyRef: &corev1.SecretKeySelector{ - // LocalObjectReference: corev1.LocalObjectReference{Name: MetricCollectorUserCredentials}, - // Key: "password", - // }, - // }, - // }, + { + Name: "MONITORING_USER_FILE", + Value: "/etc/secrets/" + MetricCollectorUserCredentials + "/username", + }, + { + Name: "MONITORING_PASSWORD_FILE", + Value: "/etc/secrets/" + MetricCollectorUserCredentials + "/password", + }, { Name: "PG_ROOT_USER", ValueFrom: &corev1.EnvVarSource{ @@ -130,21 +131,11 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl }, { Name: "INFLUXDB_USER", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: influxDbAdminCredentials}, - Key: "username", - }, - }, + Value: "/etc/secrets/" + influxDbAdminCredentials + "/username", }, { Name: "INFLUXDB_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: influxDbAdminCredentials}, - Key: "password", - }, - }, + Value: "/etc/secrets/" + influxDbAdminCredentials + "/password", }, { Name: "NAMESPACE", @@ -206,10 +197,15 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl Name: "telegraf-config-volume", }, { - MountPath: "/etc/monitoring-user-credentials", + MountPath: "/etc/secrets/monitoring-user-credentials", Name: "monitoring-user-credentials", ReadOnly: true, }, + { + MountPath: "/etc/secrets/influx-db-admin-credentials", + Name: "influx-db-admin-credentials", + ReadOnly: true, + }, }, Resources: *metricCollector.Resources, LivenessProbe: &corev1.Probe{ diff --git a/services/monitoring-agent/collector/pkg/postgres/client.go b/services/monitoring-agent/collector/pkg/postgres/client.go index 71a1a5ba..ef36ea0e 100644 --- a/services/monitoring-agent/collector/pkg/postgres/client.go +++ b/services/monitoring-agent/collector/pkg/postgres/client.go @@ -31,8 +31,8 @@ var logger = util.GetLogger() var ( PgHost = util.GetEnv("POSTGRES_HOST", "pg-patroni") PgPort = util.GetEnvInt("POSTGRES_PORT", 5432) - PgUser = util.GetEnv("MONITORING_USER", "monitoring-user") - PgPass = util.GetEnv("MONITORING_PASSWORD", "monitoring_password") + PgUser = util.GetSecret("username") + PgPass = util.GetSecret("password") PgDatabase = util.GetEnv("POSTGRES_DATABASE", "postgres") PgSsl = util.GetEnv("PGSSLMODE", "prefer") ) diff --git a/services/monitoring-agent/collector/pkg/util/util.go b/services/monitoring-agent/collector/pkg/util/util.go index 545179de..d73b4ea3 100644 --- a/services/monitoring-agent/collector/pkg/util/util.go +++ b/services/monitoring-agent/collector/pkg/util/util.go @@ -94,7 +94,7 @@ func GetProtocol() (string, string) { } func GetSecret(filename string) string { - secretByte, err := os.ReadFile("/etc/monitoring-user-credentials/" + filename) + secretByte, err := os.ReadFile("/etc/secrets/monitoring-user-credentials/" + filename) if err != nil { log.Fatal("failed to read monitoring secret: ", err) } From 2458b8aee109598a12ee7b32053b44840d82db7b Mon Sep 17 00:00:00 2001 From: svetychkina Date: Thu, 4 Jun 2026 16:34:29 +0500 Subject: [PATCH 03/14] fix: replicator, pg secrets for monitoring --- .../dbaas/dbaas-adapter-deployment.yaml | 10 ------- .../logical-repliction-controller.yaml | 2 +- .../templates/secrets/monitoring-secret.yaml | 2 +- operator/pkg/deployment/monitoring.go | 29 +++++++++++-------- services/dbaas-adapter/adapter/util/util.go | 9 ++++++ 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index c982e52e..5a3d33b5 100644 --- a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -131,16 +131,6 @@ spec: value: {{ include "dbaas.pgHostRO" . }} - name: POSTGRES_PORT value: {{ default "5432" .Values.dbaas.pgPort | quote }} - # - name: DBAAS_ADAPTER_API_USER - # valueFrom: - # secretKeyRef: - # name: dbaas-adapter-credentials - # key: username - # - name: DBAAS_ADAPTER_API_PASSWORD - # valueFrom: - # secretKeyRef: - # name: dbaas-adapter-credentials - # key: password - name: DBAAS_AGGREGATOR_PHYSICAL_DATABASE_IDENTIFIER value: {{ .Values.dbaas.aggregator.physicalDatabaseIdentifier | default (printf "%s:%s" .Release.Namespace "postgres")}} - name: CLOUD_NAMESPACE diff --git a/operator/charts/patroni-services/templates/secrets/logical-repliction-controller.yaml b/operator/charts/patroni-services/templates/secrets/logical-repliction-controller.yaml index 10f8c261..b41738a3 100644 --- a/operator/charts/patroni-services/templates/secrets/logical-repliction-controller.yaml +++ b/operator/charts/patroni-services/templates/secrets/logical-repliction-controller.yaml @@ -9,6 +9,6 @@ metadata: name: logical-replication-controller-creds data: username: {{ default "replicator" .Values.replicationController.apiUser | b64enc }} - password: {{ default "paSsW0rdForReplicat!oN" .Values.replicationController.apiPassword | b64enc }} + password: {{ .Values.replicationController.apiPassword | b64enc }} type: Opaque {{ end }} diff --git a/operator/charts/patroni-services/templates/secrets/monitoring-secret.yaml b/operator/charts/patroni-services/templates/secrets/monitoring-secret.yaml index 48e56823..1a337097 100644 --- a/operator/charts/patroni-services/templates/secrets/monitoring-secret.yaml +++ b/operator/charts/patroni-services/templates/secrets/monitoring-secret.yaml @@ -9,6 +9,6 @@ metadata: name: monitoring-credentials data: username: {{ "monitoring-user" | b64enc }} - password: {{ default "p@ssWOrD1" .Values.metricCollector.userPassword | b64enc }} + password: {{ .Values.metricCollector.userPassword | b64enc }} type: Opaque {{- end }} diff --git a/operator/pkg/deployment/monitoring.go b/operator/pkg/deployment/monitoring.go index 2cb65a97..5fe8f3b2 100644 --- a/operator/pkg/deployment/monitoring.go +++ b/operator/pkg/deployment/monitoring.go @@ -38,6 +38,7 @@ const ( MetricCollectorUserCredentials = "monitoring-credentials" influxDbAdminCredentials = "influx-db-admin-credentials" telegrafConfig = "telegraf-configmap" + PostgresUserCredentials = "postgres-credentials" ) func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcluster string, serviceAccountName string) *appsv1.Deployment { @@ -94,6 +95,15 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl }, }, }, + { + Name: "postgres-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "postgres-credentials", + DefaultMode: ptr.To[int32](0400), + }, + }, + }, }, InitContainers: []corev1.Container{}, Containers: []corev1.Container{ @@ -113,21 +123,11 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl }, { Name: "PG_ROOT_USER", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: GetRootSecretName(pgcluster)}, - Key: "username", - }, - }, + Value: "/etc/secrets/" + PostgresUserCredentials + "/pg-username", }, { Name: "PG_ROOT_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: GetRootSecretName(pgcluster)}, - Key: "password", - }, - }, + Value: "/etc/secrets/" + PostgresUserCredentials + "/pg-password", }, { Name: "INFLUXDB_USER", @@ -206,6 +206,11 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl Name: "influx-db-admin-credentials", ReadOnly: true, }, + { + MountPath: "/etc/secrets/postgres-credentials", + Name: "postgres-credentials", + ReadOnly: true, + }, }, Resources: *metricCollector.Resources, LivenessProbe: &corev1.Probe{ diff --git a/services/dbaas-adapter/adapter/util/util.go b/services/dbaas-adapter/adapter/util/util.go index e1d48f83..593e1139 100644 --- a/services/dbaas-adapter/adapter/util/util.go +++ b/services/dbaas-adapter/adapter/util/util.go @@ -24,6 +24,7 @@ import ( "k8s.io/client-go/rest" "os" "strconv" + "strings" ) const ( @@ -135,6 +136,14 @@ func GetEnvBool(key string, fallback bool) bool { return fallback } +func GetSecret(filename string) string { + secretByte, err := os.ReadFile("/etc/secrets/dbaas-adapter-credentials/" + filename) + if err != nil { + log.Fatal("failed to read dbaas-adapter secret: ", zap.Error(err)) + } + return strings.TrimSpace(string(secretByte[:])) +} + func GetK8sClient() (*kubernetes.Clientset, error) { config, err := rest.InClusterConfig() if err != nil { From 995ef966acea8c8d20ceb2ba4c1b6832f4302987 Mon Sep 17 00:00:00 2001 From: svetychkina Date: Wed, 10 Jun 2026 12:38:24 +0500 Subject: [PATCH 04/14] fix: unification + exporter, replication --- .../patroni-services/templates/_helpers.tpl | 33 ------------------- .../dbaas/dbaas-adapter-deployment.yaml | 24 ++++++++------ operator/pkg/client/client.go | 24 ++++++++++++-- operator/pkg/deployment/monitoring.go | 30 ++--------------- operator/pkg/queryexporter/query_exporter.go | 29 +++++++++++++--- .../replication_controller.go | 18 +++------- operator/pkg/util/util.go | 19 +++++++++++ services/dbaas-adapter/adapter/main.go | 26 +++++++++------ services/dbaas-adapter/adapter/util/util.go | 16 ++++++--- .../collector/pkg/initiate/initiate.go | 14 +++++--- .../collector/pkg/postgres/client.go | 11 +++++-- .../collector/pkg/util/util.go | 24 ++++++++++---- .../pgbackrest-sidecar/pkg/utils/utils.go | 18 ++++++++++ .../pgskipper-replication-controller/main.go | 8 +++-- .../replication-controller/pkg/utils/utils.go | 17 ++++++++++ 15 files changed, 192 insertions(+), 119 deletions(-) diff --git a/operator/charts/patroni-services/templates/_helpers.tpl b/operator/charts/patroni-services/templates/_helpers.tpl index 2e169aeb..ef432f39 100644 --- a/operator/charts/patroni-services/templates/_helpers.tpl +++ b/operator/charts/patroni-services/templates/_helpers.tpl @@ -117,39 +117,6 @@ K8s Platform envs value: "https://kubernetes.default:443" {{- end }} -{{/* -POSTGRES ADMIN env variables for DBaaS -*/}} -{{- define "postgres-dbaas.pgAdminEnvs" }} - - name: POSTGRES_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: postgres-credentials - key: password - - name: POSTGRES_ADMIN_USER - valueFrom: - secretKeyRef: - name: postgres-credentials - key: username -{{- end }} - -{{/* -Aggregator Registration env variables for DBaaS -*/}} -{{/* -{{- define "postgres-dbaas.aggregatorEnvsReg" }} - - name: DBAAS_AGGREGATOR_REGISTRATION_USERNAME - valueFrom: - secretKeyRef: - name: dbaas-aggregator-registration-credentials - key: username - - name: DBAAS_AGGREGATOR_REGISTRATION_PASSWORD - valueFrom: - secretKeyRef: - name: dbaas-aggregator-registration-credentials - key: password -{{- end }} -*/}} {{- define "find_image" -}} {{- $image := .default -}} diff --git a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index 5a3d33b5..da279f79 100644 --- a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -52,18 +52,21 @@ spec: configMap: name: dbaas-postgres-adapter.extensions-config defaultMode: 420 - {{- if not .Values.externalDataBase }} - {{- if and .Values.tls .Values.tls.enabled }} - - name: tls-cert - secret: - secretName: {{ include "postgres.certServicesSecret" . }} - defaultMode: 416 - name: dbaas-adapter-credentials secret: secretName: dbaas-adapter-credentials - name: dbaas-adapter-registration-credentials secret: secretName: dbaas-adapter-registration-credentials + - name: postgres-credentials + secret: + secretName: postgres-credentials + {{- if not .Values.externalDataBase }} + {{- if and .Values.tls .Values.tls.enabled }} + - name: tls-cert + secret: + secretName: {{ include "postgres.certServicesSecret" . }} + defaultMode: 416 {{- end }} {{- end }} initContainers: @@ -117,10 +120,8 @@ spec: securityContext: {{- include "restricted.globalContainerSecurityContext" . | nindent 12 }} env: -{{- template "postgres-dbaas.pgAdminEnvs" . }} - name: POSTGRES_DATABASE value: {{ default "postgres" .Values.dbaas.dbName }} -{{- template "postgres-dbaas.aggregatorEnvsReg" . }} - name: DBAAS_ADAPTER_ADDRESS value: {{ default (printf "http://dbaas-postgres-adapter.%s:8080" .Release.Namespace) .Values.dbaas.adapter.address }} - name: DBAAS_AGGREGATOR_REGISTRATION_ADDRESS @@ -174,10 +175,13 @@ spec: mountPath: /certs/ {{- end }} - name: dbaas-adapter-credentials - mountPath: /secrets/credentials + mountPath: /var/run/secrets/postgresql/dbaas-adapter-credentials readOnly: true - name: dbaas-adapter-registration-credentials - mountPath: /secrets/credentials + mountPath: /var/run/secrets/postgresql/dbaas-adapter-registration-credentials + readOnly: true + - name: postgres-credentials + mountPath: /var/run/secrets/postgresql/postgres-credentials readOnly: true {{- end }} livenessProbe: diff --git a/operator/pkg/client/client.go b/operator/pkg/client/client.go index 9ab04a78..a4757492 100644 --- a/operator/pkg/client/client.go +++ b/operator/pkg/client/client.go @@ -33,11 +33,17 @@ import ( "github.com/Netcracker/pgskipper-operator/pkg/util" ) +const ( + secretsBasePath = "/var/run/secrets/postgresql/" + + pgUserCredsPath = secretsBasePath + "postgres-credentials/" +) + var ( instance *PostgresClient logger = util.GetLogger() - pgUser = flag.String("pg_user", getEnv("PG_ADMIN_USER", "postgres"), "Username of admin user in PostgreSQL, env: PG_ADMIN_USER") - pgPass = flag.String("pg_pass", getEnv("PG_ADMIN_PASSWORD", ""), "Password of admin user in PostgreSQL, env: PG_ADMIN_PASSWORD") + pgUser = flag.String("pg_user", ReadSecretFile(pgUserCredsPath+"username", "postgres"), "Username of admin user in PostgreSQL") + pgPass = flag.String("pg_pass", ReadSecretFile(pgUserCredsPath+"password", ""), "Password of admin user in PostgreSQL") dbName = "postgres" ssl = "off" ) @@ -244,3 +250,17 @@ func getEnv(key, fallback string) string { func EscapeString(str string) string { return strings.ReplaceAll(str, "'", "''") } + +func ReadSecretFile(path, defaultVal string) string { + data, err := os.ReadFile(path) + if err != nil { + logger.Error(fmt.Sprintf("Failed to read secret file %s: %v", path, err)) + return defaultVal + } + value := strings.TrimSpace(string(data)) + if value == "" { + logger.Info(fmt.Sprintf("Secret file %s is empty, using default value", path)) + return defaultVal + } + return value +} \ No newline at end of file diff --git a/operator/pkg/deployment/monitoring.go b/operator/pkg/deployment/monitoring.go index 5fe8f3b2..683848ae 100644 --- a/operator/pkg/deployment/monitoring.go +++ b/operator/pkg/deployment/monitoring.go @@ -113,30 +113,6 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl Command: []string{}, Args: []string{}, Env: append([]corev1.EnvVar{ - { - Name: "MONITORING_USER_FILE", - Value: "/etc/secrets/" + MetricCollectorUserCredentials + "/username", - }, - { - Name: "MONITORING_PASSWORD_FILE", - Value: "/etc/secrets/" + MetricCollectorUserCredentials + "/password", - }, - { - Name: "PG_ROOT_USER", - Value: "/etc/secrets/" + PostgresUserCredentials + "/pg-username", - }, - { - Name: "PG_ROOT_PASSWORD", - Value: "/etc/secrets/" + PostgresUserCredentials + "/pg-password", - }, - { - Name: "INFLUXDB_USER", - Value: "/etc/secrets/" + influxDbAdminCredentials + "/username", - }, - { - Name: "INFLUXDB_PASSWORD", - Value: "/etc/secrets/" + influxDbAdminCredentials + "/password", - }, { Name: "NAMESPACE", ValueFrom: &corev1.EnvVarSource{ @@ -197,17 +173,17 @@ func NewMonitoringDeployment(metricCollector *netcrackerv1.MetricCollector, pgcl Name: "telegraf-config-volume", }, { - MountPath: "/etc/secrets/monitoring-user-credentials", + MountPath: "/var/run/secrets/postgresql/monitoring-user-credentials", Name: "monitoring-user-credentials", ReadOnly: true, }, { - MountPath: "/etc/secrets/influx-db-admin-credentials", + MountPath: "/var/run/secrets/postgresql/influx-db-admin-credentials", Name: "influx-db-admin-credentials", ReadOnly: true, }, { - MountPath: "/etc/secrets/postgres-credentials", + MountPath: "/var/run/secrets/postgresql/postgres-credentials", Name: "postgres-credentials", ReadOnly: true, }, diff --git a/operator/pkg/queryexporter/query_exporter.go b/operator/pkg/queryexporter/query_exporter.go index 1896fda5..f7c277e2 100644 --- a/operator/pkg/queryexporter/query_exporter.go +++ b/operator/pkg/queryexporter/query_exporter.go @@ -31,7 +31,13 @@ import ( "k8s.io/apimachinery/pkg/util/intstr" ) -const CMName = "query-exporter-config" +const ( + CMName = "query-exporter-config" + + secretsBasePath = "/var/run/secrets/postgresql/" + + pgUserCredsPath = secretsBasePath + "postgres-credentials/" +) var ( logger = util.GetLogger() @@ -106,6 +112,14 @@ func getVolumes() []corev1.Volume { }, }, }, + { + Name: "postgresql-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "postgresql-credentials", + }, + }, + }, } } @@ -115,6 +129,10 @@ func getVolumeMounts() []corev1.VolumeMount { MountPath: "/config", Name: "config-volume", }, + { + MountPath: "/var/run/secrets/postgresql/", + Name: "postgresql-credentials", + }, } } @@ -152,13 +170,14 @@ func getEnvVariables(spec v1.QueryExporter) []corev1.EnvVar { Name: "QUERY_EXPORTER_DISABLE_SELF_MONITOR", Value: strconv.FormatBool(spec.SelfMonitorDisabled), }, +// todo: read credentials from secret { - Name: "POSTGRES_USER", - ValueFrom: getSecretFieldEnv("username"), + Name: "POSTGRES_USER", + Value: util.ReadSecretFile(pgUserCredsPath+"username", "postgres"), }, { - Name: "POSTGRES_PASSWORD", - ValueFrom: getSecretFieldEnv("password"), + Name: "POSTGRES_PASSWORD", + Value: util.ReadSecretFile(pgUserCredsPath+"password", ""), }, { Name: "EXCLUDED_QUERIES", diff --git a/operator/pkg/replicationcontroller/replication_controller.go b/operator/pkg/replicationcontroller/replication_controller.go index 7854f49c..9e85a8de 100644 --- a/operator/pkg/replicationcontroller/replication_controller.go +++ b/operator/pkg/replicationcontroller/replication_controller.go @@ -75,22 +75,12 @@ func NewRCDeployment(cr v1.PatroniServices, sa, clusterName string, pgPort int) Value: strconv.Itoa(pgPort), }, { - Name: "POSTGRES_ADMIN_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "postgres-credentials"}, - Key: "username", - }, - }, + Name: "POSTGRES_ADMIN_USER", + Value: util.ReadSecretFile(util.PgUserCredsPath+"username", "postgres"), }, { - Name: "POSTGRES_ADMIN_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "postgres-credentials"}, - Key: "password", - }, - }, + Name: "POSTGRES_ADMIN_PASSWORD", + Value: util.ReadSecretFile(util.PgUserCredsPath+"password", ""), }, { Name: "API_USER", diff --git a/operator/pkg/util/util.go b/operator/pkg/util/util.go index 607ff444..195dc7bd 100644 --- a/operator/pkg/util/util.go +++ b/operator/pkg/util/util.go @@ -55,6 +55,9 @@ import ( const ( TokenFilePath = "/var/run/secrets/kubernetes.io/serviceaccount/token" ClusterName = "patroni" + + secretBasePath = "/var/run/secrets/postgresql/" + PgUserCredsPath = secretBasePath + "postgres-credentials/" ) var ( @@ -431,3 +434,19 @@ func HashJson(o interface{}) string { hash.Write(cr) return fmt.Sprintf("%x", hash.Sum(nil)) } + +func ReadSecretFile(path string, defaultVal string) string { + data, err := os.ReadFile(path) + if err != nil { + uLog.Error(fmt.Sprintf("Failed to read secret file %s: %v", path, err)) + return defaultVal + } + + value := strings.TrimSpace(string(data)) + + if value == "" { + uLog.Info(fmt.Sprintf("Secret file %s is empty, using default value", path)) + return defaultVal + } + return value +} \ No newline at end of file diff --git a/services/dbaas-adapter/adapter/main.go b/services/dbaas-adapter/adapter/main.go index ac13a39e..c477782a 100644 --- a/services/dbaas-adapter/adapter/main.go +++ b/services/dbaas-adapter/adapter/main.go @@ -40,6 +40,12 @@ import ( const ( appName = "postgresql" appPath = "/" + appName + + secretsBasePath = "/var/run/secrets/postgresql/" + + pgUserCredsPath = secretsBasePath + "postgres-credentials/" + adapterCredsPath = secretsBasePath + "dbaas-adapter-credentials/" + registrationCredsPath = secretsBasePath + "dbaas-aggregator-registration-credentials/" ) var ( @@ -49,8 +55,8 @@ var ( pgHost = flag.String("pg_host", util.GetEnv("POSTGRES_HOST", "127.0.0.1"), "Host of PostgreSQL cluster, env: POSTGRES_HOST") pgPort = flag.Int("pg_port", util.GetEnvInt("POSTGRES_PORT", 5432), "Port of PostgreSQL cluster, env: POSTGRES_PORT") - pgUser = flag.String("pg_user", util.GetEnv("POSTGRES_ADMIN_USER", "postgres"), "Username of dbaas user in PostgreSQL, env: POSTGRES_ADMIN_USER") - pgPass = flag.String("pg_pass", util.GetEnv("POSTGRES_ADMIN_PASSWORD", ""), "Password of dbaas user in PostgreSQL, env: POSTGRES_ADMIN_PASSWORD") + pgUser = flag.String("pg_user", util.ReadSecretFile(pgUserCredsPath+"username", "postgres"), "Username of dbaas user in PostgreSQL") + pgPass = flag.String("pg_pass", util.ReadSecretFile(pgUserCredsPath+"password", ""), "Password of dbaas user in PostgreSQL") pgDatabase = flag.String("pg_database", util.GetEnv("POSTGRES_DATABASE", "postgres"), "PostgreSQL database, env: POSTGRES_DATABASE") pgSsl = flag.String("pg_ssl", util.GetEnv("PG_SSL", "off"), "Enable ssl connection to postgreSQL, env: PG_SSL") @@ -71,13 +77,13 @@ var ( servePort = flag.Int("serve_port", 8080, "Port to serve requests incoming to adapter") serveUser = flag.String( "serve_user", - util.GetEnv("DBAAS_ADAPTER_API_USER", "dbaas-aggregator"), - "Username to authorize incoming requests, env: DBAAS_ADAPTER_API_USER", + util.ReadSecretFile(adapterCredsPath+"username", "dbaas-aggregator"), + "Username to authorize incoming requests", ) servePass = flag.String( "serve_pass", - util.GetEnv("DBAAS_ADAPTER_API_PASSWORD", "dbaas-aggregator"), - "Password to authorize incoming requests, env: DBAAS_ADAPTER_API_PASSWORD", + util.ReadSecretFile(adapterCredsPath+"password", "dbaas-aggregator"), + "Password to authorize incoming requests", ) phydbid = flag.String( @@ -100,14 +106,14 @@ var ( dbaasAggregatorRegistrationUsername = flag.String( "registration_username", - util.GetEnv("DBAAS_AGGREGATOR_REGISTRATION_USERNAME", "cluster-dba"), - "Username of basic auth to reach aggregator for registration, env DBAAS_AGGREGATOR_REGISTRATION_USERNAME ", + util.ReadSecretFile(registrationCredsPath+"username", "cluster-dba"), + "Username of basic auth to reach aggregator for registration", ) dbaasAggregatorRegistrationPassword = flag.String( "registration_password", - util.GetEnv("DBAAS_AGGREGATOR_REGISTRATION_PASSWORD", ""), - "Username of basic auth to reach aggregator for registration, env DBAAS_AGGREGATOR_REGISTRATION_PASSWORD ", + util.ReadSecretFile(registrationCredsPath+"password", ""), + "Password of basic auth to reach aggregator for registration", ) labelsFileName = flag.String( diff --git a/services/dbaas-adapter/adapter/util/util.go b/services/dbaas-adapter/adapter/util/util.go index 593e1139..7a0acbdd 100644 --- a/services/dbaas-adapter/adapter/util/util.go +++ b/services/dbaas-adapter/adapter/util/util.go @@ -136,12 +136,20 @@ func GetEnvBool(key string, fallback bool) bool { return fallback } -func GetSecret(filename string) string { - secretByte, err := os.ReadFile("/etc/secrets/dbaas-adapter-credentials/" + filename) +func ReadSecretFile(path string, defaultVal string) string { + data, err := os.ReadFile(path) if err != nil { - log.Fatal("failed to read dbaas-adapter secret: ", zap.Error(err)) + log.Error(fmt.Sprintf("Failed to read secret file %s: %v", path, err)) + return defaultVal } - return strings.TrimSpace(string(secretByte[:])) + + value := strings.TrimSpace(string(data)) + + if value == "" { + log.Info(fmt.Sprintf("Secret file %s is empty, using default value", path)) + return defaultVal + } + return value } func GetK8sClient() (*kubernetes.Clientset, error) { diff --git a/services/monitoring-agent/collector/pkg/initiate/initiate.go b/services/monitoring-agent/collector/pkg/initiate/initiate.go index 5e58eae2..580dcee7 100644 --- a/services/monitoring-agent/collector/pkg/initiate/initiate.go +++ b/services/monitoring-agent/collector/pkg/initiate/initiate.go @@ -26,6 +26,12 @@ import ( "k8s.io/apimachinery/pkg/types" ) +const ( + secretsBasePath = "/var/run/secrets/postgresql/" + monitoringUserCredsPath = secretsBasePath + "monitoring-user-credentials/" + pgUserCredsPath = secretsBasePath + "postgres-credentials/" +) + var ( logger = util.GetLogger() ctx = context.Background() @@ -36,8 +42,8 @@ func InitMetricCollector() { logger.Info("Will run preparation scripts") clusterName := util.GetEnv("PGCLUSTER", "patroni") - monitoringRole := util.GetSecret("username") - monitoringPassword := util.GetSecret("password") + monitoringRole := util.ReadSecretFile(monitoringUserCredsPath+"username", "") + monitoringPassword := util.ReadSecretFile(monitoringUserCredsPath+"password", "") pgHost := util.GetEnv("POSTGRES_HOST", "pg-patroni") pgPort := util.GetEnvInt("POSTGRES_PORT", 5432) @@ -80,8 +86,8 @@ func InitMetricCollector() { func getPGCredentials(clusterName string) (user, password string) { namespace := util.GetEnv("NAMESPACE", "postgres-service") - user = util.GetEnv("PG_ROOT_USER", "") - password = util.GetEnv("PG_ROOT_PASSWORD", "") + user = util.ReadSecretFile(pgUserCredsPath+"username", "") + password = util.ReadSecretFile(pgUserCredsPath+"password", "") if user != "" || password != "" { return user, password diff --git a/services/monitoring-agent/collector/pkg/postgres/client.go b/services/monitoring-agent/collector/pkg/postgres/client.go index ef36ea0e..58a55feb 100644 --- a/services/monitoring-agent/collector/pkg/postgres/client.go +++ b/services/monitoring-agent/collector/pkg/postgres/client.go @@ -26,13 +26,20 @@ import ( "go.uber.org/zap" ) +const ( + secretsBasePath = "/var/run/secrets/postgresql/" + + pgUserCredsPath = secretsBasePath + "postgres-credentials/" + +) + var logger = util.GetLogger() var ( PgHost = util.GetEnv("POSTGRES_HOST", "pg-patroni") PgPort = util.GetEnvInt("POSTGRES_PORT", 5432) - PgUser = util.GetSecret("username") - PgPass = util.GetSecret("password") + PgUser = util.ReadSecretFile(pgUserCredsPath+"username", "") + PgPass = util.ReadSecretFile(pgUserCredsPath+"password", "") PgDatabase = util.GetEnv("POSTGRES_DATABASE", "postgres") PgSsl = util.GetEnv("PGSSLMODE", "prefer") ) diff --git a/services/monitoring-agent/collector/pkg/util/util.go b/services/monitoring-agent/collector/pkg/util/util.go index d73b4ea3..cd402ec2 100644 --- a/services/monitoring-agent/collector/pkg/util/util.go +++ b/services/monitoring-agent/collector/pkg/util/util.go @@ -58,8 +58,12 @@ var ( debugEnabled = GetEnv("DEBUG_ENABLED", "false") ) -const certificatesFolder = "/certs" -const MetricCollectorCredentialsFolder = "/etc/monitoring-user-credentials" +const ( + secretsBasePath = "/var/run/secrets/postgresql/" + + certificatesFolder = "/certs" + metricCollectorCredentialsFolder = secretsBasePath + "monitoring-user-credentials/" +) func GetLogger() *zap.Logger { cfg := zap.NewProductionConfig() @@ -93,12 +97,20 @@ func GetProtocol() (string, string) { } -func GetSecret(filename string) string { - secretByte, err := os.ReadFile("/etc/secrets/monitoring-user-credentials/" + filename) +func ReadSecretFile(path string, defaultVal string) string { + data, err := os.ReadFile(path) if err != nil { - log.Fatal("failed to read monitoring secret: ", err) + Log.Error(fmt.Sprintf("Failed to read secret file %s: %v", path, err)) + return defaultVal + } + + value := strings.TrimSpace(string(data[:])) + + if value == "" { + Log.Info(fmt.Sprintf("Secret file %s is empty, using default value", path)) + return defaultVal } - return strings.TrimSpace(string(secretByte[:])) + return value } func GetToken() string { diff --git a/services/pgbackrest-sidecar/pkg/utils/utils.go b/services/pgbackrest-sidecar/pkg/utils/utils.go index 0a4a8cba..b3fadc26 100644 --- a/services/pgbackrest-sidecar/pkg/utils/utils.go +++ b/services/pgbackrest-sidecar/pkg/utils/utils.go @@ -20,6 +20,8 @@ import ( "fmt" "os" "os/exec" + "strings" + "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -88,3 +90,19 @@ func GetLogger() *zap.Logger { defer func() { _ = logger.Sync() }() return logger } + +func ReadSecretFile(path, defaultVal string) string { + data, err := os.ReadFile(path) + if err != nil { + logger.Error(fmt.Sprintf("Failed to read secret file %s: %v", path, err)) + return defaultVal + } + + value := strings.TrimSpace(string(data[:])) + + if value == "" { + logger.Info(fmt.Sprintf("Secret file %s is empty, using default value", path)) + return defaultVal + } + return value +} \ No newline at end of file diff --git a/services/replication-controller/cmd/pgskipper-replication-controller/main.go b/services/replication-controller/cmd/pgskipper-replication-controller/main.go index 0a10ad58..be818821 100644 --- a/services/replication-controller/cmd/pgskipper-replication-controller/main.go +++ b/services/replication-controller/cmd/pgskipper-replication-controller/main.go @@ -37,13 +37,17 @@ const ( usersPath = "/users" httpsPort = 8443 + + secretsBasePath = "/var/run/secrets/postgresql/" + + pgUserCredsPath = secretsBasePath + "postgres-credentials/" ) var ( pgHost = flag.String("pg_host", utils.GetEnv("POSTGRES_HOST", "127.0.0.1"), "Host of PostgreSQL cluster, env: POSTGRES_HOST") pgPort = flag.Int("pg_port", utils.GetEnvInt("POSTGRES_PORT", 5432), "Port of PostgreSQL cluster, env: POSTGRES_PORT") - pgUser = flag.String("pg_user", utils.GetEnv("POSTGRES_ADMIN_USER", "postgres"), "Username of controller user in PostgreSQL, env: POSTGRES_ADMIN_USER") - pgPass = flag.String("pg_pass", utils.GetEnv("POSTGRES_ADMIN_PASSWORD", ""), "Password of controller user in PostgreSQL, env: POSTGRES_ADMIN_PASSWORD") + pgUser = flag.String("pg_user", utils.ReadSecretFile(pgUserCredsPath+"username", "postgres"), "Username of controller user in PostgreSQL, env: POSTGRES_ADMIN_USER") + pgPass = flag.String("pg_pass", utils.ReadSecretFile(pgUserCredsPath+"password", ""), "Password of controller user in PostgreSQL, env: POSTGRES_ADMIN_PASSWORD") pgSsl = flag.String("pg_ssl", utils.GetEnv("PG_SSL", "off"), "Enable ssl connection to postgreSQL, env: PG_SSL") servePort = flag.Int("serve_port", 8080, "Port to serve requests incoming to controller") diff --git a/services/replication-controller/pkg/utils/utils.go b/services/replication-controller/pkg/utils/utils.go index c87cb70f..7f22a52d 100644 --- a/services/replication-controller/pkg/utils/utils.go +++ b/services/replication-controller/pkg/utils/utils.go @@ -20,6 +20,7 @@ import ( "fmt" "os" "strconv" + "strings" "github.com/gofiber/fiber/v2" "github.com/google/uuid" @@ -87,6 +88,22 @@ func GetEnvBool(key string, fallback bool) bool { return fallback } +func ReadSecretFile(path, defaultVal string) string { + data, err := os.ReadFile(path) + if err != nil { + log.Error(fmt.Sprintf("Failed to read secret file %s: %v", path, err)) + return defaultVal + } + + value := strings.TrimSpace(string(data)) + + if value == "" { + log.Info(fmt.Sprintf("Secret file %s is empty, using default value", path)) + return defaultVal + } + return value +} + func ContextLogger(ctx context.Context) *zap.Logger { logger := GetLogger() return logger.With(zap.ByteString("request_id", []byte(fmt.Sprintf("%s", ctx.Value(RequestId("request_id")))))) From 0faa7c4df84541983fb42f2aa04597c8df6d33af Mon Sep 17 00:00:00 2001 From: svetychkina Date: Tue, 16 Jun 2026 18:18:02 +0500 Subject: [PATCH 05/14] fix: [CPCAP-9492] replace Secret-to-ENV with file-based --- .../patroni-core/templates/deployment.yaml | 31 ++++++++--------- .../dbaas/dbaas-adapter-deployment.yaml | 2 ++ .../templates/deployment.yaml | 31 ++++++++--------- operator/pkg/deployment/backup.go | 32 ++++++++---------- operator/pkg/helper/patroni_core_helper.go | 9 +++-- operator/pkg/queryexporter/query_exporter.go | 15 ++------- .../replication_controller.go | 33 +++++++++++++++++++ .../backup-daemon/docker/granular/configs.py | 17 ++++++++-- .../docker/postgres/aws-s3-backup.sh | 24 ++++++++++++++ .../docker/postgres/postgres_backup.sh | 3 ++ .../backup-daemon/docker/postgres/utils.py | 24 +++++++++++--- .../maintenance/recovery/recovery.py | 24 +++++++++++--- .../maintenance/recovery/utils_pg.py | 16 ++++++++- services/patroni/scripts/archive_wal.sh | 3 +- services/query-exporter/build/bin/entrypoint | 13 +++++++- .../pgskipper-replication-controller/main.go | 13 ++++---- services/upgrade/docker/start.sh | 2 +- tests/robot/Lib/lib.robot | 15 +++++++-- tests/robot/Lib/pgsLibrary.py | 22 +++++++++++-- .../check_backup_api_auth.robot | 2 +- ...check_granular_backups_list_auth_api.robot | 2 +- ...ular_restore_added_data_after_backup.robot | 2 +- ...eck_granular_restore_backup_auth_api.robot | 4 +-- ...r_restore_backup_with_new_names_auth.robot | 2 +- ...nular_restore_backup_with_roles_auth.robot | 2 +- ...eck_granular_restore_status_auth_api.robot | 4 +-- ...eck_granular_restore_with_owner_auth.robot | 2 +- ..._granular_restore_with_specified_dbs.robot | 2 +- .../check_scale_down_backup_daemon.robot | 2 +- .../check_terminate_backup_api/keywords.robot | 4 +-- 30 files changed, 254 insertions(+), 103 deletions(-) diff --git a/operator/charts/patroni-core/templates/deployment.yaml b/operator/charts/patroni-core/templates/deployment.yaml index ea1107b0..eac59fd4 100644 --- a/operator/charts/patroni-core/templates/deployment.yaml +++ b/operator/charts/patroni-core/templates/deployment.yaml @@ -65,6 +65,13 @@ spec: readOnly: true {{ end }} {{ end }} + volumeMounts: + - mountPath: /var/run/secrets/postgresql/postgres-credentials + name: postgres-credentials + readOnly: true + - mountPath: /var/run/secrets/postgresql/replicator-credentials + name: replicator-credentials + readOnly: true env: - name: WATCH_NAMESPACE valueFrom: @@ -94,21 +101,6 @@ spec: valueFrom: fieldRef: fieldPath: status.hostIP - - name: PG_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: postgres-credentials - key: password - - name: PG_ADMIN_USER - valueFrom: - secretKeyRef: - name: postgres-credentials - key: username - - name: PG_REPLICATOR_PASSWORD - valueFrom: - secretKeyRef: - name: replicator-credentials - key: password - name: GLOBAL_SECURITY_CONTEXT value: {{ .Values.GLOBAL_SECURITY_CONTEXT | quote | default ("true" | quote) }} - name: CLOUD_PUBLIC_HOST @@ -158,6 +150,15 @@ spec: secretName: {{ default "cloudsql-instance-credentials" .Values.externalDataBase.authSecretName }} {{ end }} {{ end }} + volumes: + - name: postgres-credentials + secret: + defaultMode: 420 + secretName: postgres-credentials + - name: replicator-credentials + secret: + defaultMode: 420 + secretName: replicator-credentials tolerations: {{- range $tKey, $t := .Values.policies.tolerations }} - key: {{ $t.key }} diff --git a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index da279f79..58191c67 100644 --- a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -55,9 +55,11 @@ spec: - name: dbaas-adapter-credentials secret: secretName: dbaas-adapter-credentials + defaultMode: 420 - name: dbaas-adapter-registration-credentials secret: secretName: dbaas-adapter-registration-credentials + defaultMode: 420 - name: postgres-credentials secret: secretName: postgres-credentials diff --git a/operator/charts/patroni-services/templates/deployment.yaml b/operator/charts/patroni-services/templates/deployment.yaml index 3bd24b0f..96654911 100644 --- a/operator/charts/patroni-services/templates/deployment.yaml +++ b/operator/charts/patroni-services/templates/deployment.yaml @@ -72,6 +72,12 @@ spec: - name: tls-cert mountPath: /certs/ {{- end }} + - name: postgres-credentials + mountPath: /var/run/secrets/postgres-credentials + readOnly: true + - name: replicator-credentials + mountPath: /var/run/secrets/replicator-credentials + readOnly: true {{- end }} env: - name: WATCH_NAMESPACE @@ -106,21 +112,6 @@ spec: valueFrom: fieldRef: fieldPath: status.hostIP - - name: PG_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: postgres-credentials - key: password - - name: PG_ADMIN_USER - valueFrom: - secretKeyRef: - name: postgres-credentials - key: username - - name: PG_REPLICATOR_PASSWORD - valueFrom: - secretKeyRef: - name: replicator-credentials - key: password - name: GLOBAL_SECURITY_CONTEXT value: {{ .Values.GLOBAL_SECURITY_CONTEXT | quote | default ("true" | quote) }} - name: CLOUD_PUBLIC_HOST @@ -178,6 +169,16 @@ spec: secretName: {{ .Values.tls.certificateSecretName }} defaultMode: 416 {{- end }} + {{- if .Values.replicationController }} + - name: replicator-credentials + secret: + secretName: replicator-credentials + defaultMode: 420 + {{- end }} + - name: postgres-credentials + secret: + secretName: postgres-credentials + defaultMode: 420 {{- end }} tolerations: {{- range $tKey, $t := .Values.policies.tolerations }} diff --git a/operator/pkg/deployment/backup.go b/operator/pkg/deployment/backup.go index 72271f47..b2348c46 100644 --- a/operator/pkg/deployment/backup.go +++ b/operator/pkg/deployment/backup.go @@ -25,6 +25,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/utils/ptr" ) var ( @@ -72,6 +73,15 @@ func NewBackupDaemonDeployment(backupDaemon *netcrackerv1.BackupDaemon, pgCluste }, }, }, + { + Name: "postgres-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: GetRootSecretName(pgClusterName), + DefaultMode: ptr.To[int32](0400), + }, + }, + }, }, ServiceAccountName: serviceAccountName, Affinity: &backupDaemon.Affinity, @@ -83,24 +93,6 @@ func NewBackupDaemonDeployment(backupDaemon *netcrackerv1.BackupDaemon, pgCluste Command: []string{}, Args: []string{}, Env: []corev1.EnvVar{ - { - Name: "POSTGRES_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: GetRootSecretName(pgClusterName)}, - Key: "password", - }, - }, - }, - { - Name: "POSTGRES_USER", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: GetRootSecretName(pgClusterName)}, - Key: "username", - }, - }, - }, { Name: "PGPASSWORD", ValueFrom: &corev1.EnvVarSource{ @@ -230,6 +222,10 @@ func NewBackupDaemonDeployment(backupDaemon *netcrackerv1.BackupDaemon, pgCluste MountPath: "/backup-storage", Name: "backup-data", }, + { + MountPath: "/var/run/secrets/postgresql/", + Name: "postgres-credentials", + }, }, LivenessProbe: &corev1.Probe{ ProbeHandler: corev1.ProbeHandler{ diff --git a/operator/pkg/helper/patroni_core_helper.go b/operator/pkg/helper/patroni_core_helper.go index 6e45ec64..92a9db08 100644 --- a/operator/pkg/helper/patroni_core_helper.go +++ b/operator/pkg/helper/patroni_core_helper.go @@ -42,7 +42,12 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -var pHelper *PatroniHelper = nil +var ( + pHelper *PatroniHelper = nil + + secretFilePath = "/var/run/secrets/postgresql/" + replicatorPasswordPath = secretFilePath + "replicator-credentials/" +) type PatroniHelper struct { ResourceManager @@ -444,7 +449,7 @@ func (ph *PatroniHelper) RevokeGrantOnPublicSchema(pgHost string) error { } func (ph *PatroniHelper) SyncReplicatorPassword(pgHost string) error { - password := util.GetEnv("PG_REPLICATOR_PASSWORD", "replicator") + password := util.ReadSecretFile(replicatorPasswordPath+"password", "") pgC := pgClient.GetPostgresClient(pgHost) if pgC == nil { return errors.New("Can't create Postgres Client") diff --git a/operator/pkg/queryexporter/query_exporter.go b/operator/pkg/queryexporter/query_exporter.go index f7c277e2..aa344192 100644 --- a/operator/pkg/queryexporter/query_exporter.go +++ b/operator/pkg/queryexporter/query_exporter.go @@ -113,10 +113,10 @@ func getVolumes() []corev1.Volume { }, }, { - Name: "postgresql-credentials", + Name: "postgres-credentials", VolumeSource: corev1.VolumeSource{ Secret: &corev1.SecretVolumeSource{ - SecretName: "postgresql-credentials", + SecretName: "postgres-credentials", }, }, }, @@ -131,7 +131,7 @@ func getVolumeMounts() []corev1.VolumeMount { }, { MountPath: "/var/run/secrets/postgresql/", - Name: "postgresql-credentials", + Name: "postgres-credentials", }, } } @@ -170,15 +170,6 @@ func getEnvVariables(spec v1.QueryExporter) []corev1.EnvVar { Name: "QUERY_EXPORTER_DISABLE_SELF_MONITOR", Value: strconv.FormatBool(spec.SelfMonitorDisabled), }, -// todo: read credentials from secret - { - Name: "POSTGRES_USER", - Value: util.ReadSecretFile(pgUserCredsPath+"username", "postgres"), - }, - { - Name: "POSTGRES_PASSWORD", - Value: util.ReadSecretFile(pgUserCredsPath+"password", ""), - }, { Name: "EXCLUDED_QUERIES", Value: strings.Join(spec.ExcludeQueries, ","), diff --git a/operator/pkg/replicationcontroller/replication_controller.go b/operator/pkg/replicationcontroller/replication_controller.go index 9e85a8de..c28ea92d 100644 --- a/operator/pkg/replicationcontroller/replication_controller.go +++ b/operator/pkg/replicationcontroller/replication_controller.go @@ -24,6 +24,7 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/utils/ptr" ) const ( @@ -57,6 +58,26 @@ func NewRCDeployment(cr v1.PatroniServices, sa, clusterName string, pgPort int) Spec: corev1.PodSpec{ ServiceAccountName: sa, Affinity: &spec.Affinity, + Volumes: []corev1.Volume{ + { + Name: "postgres-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "postgres-credentials", + DefaultMode: ptr.To[int32](0400), + }, + }, + }, + { + Name: "replicator-api-creds", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "logical-replication-controller-creds", + DefaultMode: ptr.To[int32](0400), + }, + }, + }, + }, InitContainers: []corev1.Container{}, Containers: []corev1.Container{ { @@ -105,6 +126,18 @@ func NewRCDeployment(cr v1.PatroniServices, sa, clusterName string, pgPort int) Value: spec.SslMode, }, }, + VolumeMounts: []corev1.VolumeMount{ + { + MountPath: "/var/run/secrets/postgresql/replicator-api-creds", + Name: "replicator-api-creds", + ReadOnly: true, + }, + { + MountPath: "/var/run/secrets/postgresql/postgres-credentials", + Name: "postgres-credentials", + ReadOnly: true, + }, + }, Ports: []corev1.ContainerPort{ {ContainerPort: 8080, Name: "web", Protocol: corev1.ProtocolTCP}, }, diff --git a/services/backup-daemon/docker/granular/configs.py b/services/backup-daemon/docker/granular/configs.py index c0736f4d..ea7abc1e 100644 --- a/services/backup-daemon/docker/granular/configs.py +++ b/services/backup-daemon/docker/granular/configs.py @@ -17,6 +17,8 @@ import logging from utils import get_postgres_version_by_path +_SECRET_BASE_PATH = "/var/run/secrets/postgresql/" +_PG_USER_CREDS_PATH = _SECRET_BASE_PATH + "postgres-credentials/" _PROTECTED_DATABASES = ['template0', 'template1', 'postgres', 'rdsadmin', # aws rds @@ -63,6 +65,17 @@ def backups_storage(version=None): storage_path = '/backup-storage/pg18/granular' return storage_path +def read_secret_file(path: str, default_val: str): + try: + with open(path, 'r') as f: + value = f.read().strip() + except OSError as e: + logging.error(f"Failed to read secret file {path}: {e}") + return default_val + if not value: + logging.info(f"Secret file {path} is empty, using default value") + return default_val + return value def default_namespace(): return 'default' @@ -77,7 +90,7 @@ def default_backup_expiration_period(): def postgresql_user(): - return os.getenv('POSTGRES_USER') or 'postgres' + return read_secret_file(_PG_USER_CREDS_PATH + "username", 'postgres') def postgresql_host(): @@ -89,7 +102,7 @@ def postgresql_port(): def postgres_password(): - return os.getenv('POSTGRES_PASSWORD') + return read_secret_file(_PG_USER_CREDS_PATH + "password", '') def postgresql_no_role_password_flag(): diff --git a/services/backup-daemon/docker/postgres/aws-s3-backup.sh b/services/backup-daemon/docker/postgres/aws-s3-backup.sh index 67eeab79..18398318 100755 --- a/services/backup-daemon/docker/postgres/aws-s3-backup.sh +++ b/services/backup-daemon/docker/postgres/aws-s3-backup.sh @@ -27,6 +27,30 @@ readonly BUCKET="$1" # Go to AWS S3 terminology readonly BACKUP_ID="$2" BACKUP_NAME="pg_${PG_CLUSTER_NAME}_backup_${BACKUP_ID}.tar.gz" +SECRET_BASE_PATH="/var/run/secrets/postgresql/" +PG_USER_CREDS_PATH="${SECRET_BASE_PATH}postgres-credentials/" + +function read_secret_file() { + local path="$1" + local default_val="$2" + if [ ! -f "$path" ]; then + echo "Failed to read secret file ${path}" >&2 + echo "$default_val" + return + fi + local value + value=$(tr -d '[:space:]' < "$path") + if [ -z "$value" ]; then + echo "Secret file ${path} is empty, using default value" >&2 + echo "$default_val" + return + fi + echo "$value" +} + +POSTGRES_USER=$(read_secret_file "${PG_USER_CREDS_PATH}username" "postgres") +POSTGRES_PASSWORD=$(read_secret_file "${PG_USER_CREDS_PATH}password" "") + function log() { log_module "$1" "aws-s3-backup" "$2" diff --git a/services/backup-daemon/docker/postgres/postgres_backup.sh b/services/backup-daemon/docker/postgres/postgres_backup.sh index 9d692112..1bc40a1d 100755 --- a/services/backup-daemon/docker/postgres/postgres_backup.sh +++ b/services/backup-daemon/docker/postgres/postgres_backup.sh @@ -26,6 +26,9 @@ readonly ENCRYPTION_KEY="$2" BACKUP_DESTINATION_DIRECTORY="$1" BACKUP_NAME="pg_${PG_CLUSTER_NAME}_backup_$(basename ${BACKUP_DESTINATION_DIRECTORY}).tar.gz" +POSTGRES_USER=$(cat /var/run/secrets/postgres-credentials/username) +POSTGRES_PASSWORD=$(cat /var/run/secrets/postgres-credentials/password) + source utils.sh function test_swift() { diff --git a/services/backup-daemon/docker/postgres/utils.py b/services/backup-daemon/docker/postgres/utils.py index 6674cf01..0e14682e 100644 --- a/services/backup-daemon/docker/postgres/utils.py +++ b/services/backup-daemon/docker/postgres/utils.py @@ -18,6 +18,7 @@ log = logging.getLogger("utils") +POSTGRES_CREDS_PATH = '/var/run/secrets/postgresql/postgres-credentials' def execute_query(conn_properties, query): conn = None @@ -35,8 +36,8 @@ def get_version_of_pgsql_server(): conn_properties = { 'host': os.getenv('POSTGRES_HOST'), 'port': os.getenv('POSTGRES_PORT'), - 'user': os.getenv('POSTGRES_USER') or 'postgres', - 'password': os.getenv('POSTGRES_PASSWORD'), + 'user': read_secret_file(f'{POSTGRES_CREDS_PATH}/username', 'postgres'), + 'password': read_secret_file(f'{POSTGRES_CREDS_PATH}/password', ''), 'database': 'postgres', 'connect_timeout': int(os.getenv("CONNECT_TIMEOUT", "5")), } @@ -81,11 +82,24 @@ def get_encryption(): encrypt_backups = os.getenv("KEY_SOURCE", 'false').lower() return encrypt_backups != 'false' +def read_secret_file(path: str, default_val: str) -> str: + try: + with open(path, 'r') as f: + value = f.read().strip() + except OSError as e: + logging.error(f"Failed to read secret file {path}: {e}") + return default_val -def validate_user(username, password): + if not value: + logging.info(f"Secret file {path} is empty, using default value") + return default_val + + return value + +def validate_user(username: str, password: str) -> bool: if not os.getenv("AUTH", "false").lower() == "false": - return username == os.getenv("POSTGRES_USER") and \ - password == os.getenv("POSTGRES_PASSWORD") + return username == read_secret_file(f'{POSTGRES_CREDS_PATH}/username', "postgres") and \ + password == read_secret_file(f'{POSTGRES_CREDS_PATH}/password', "") else: return True diff --git a/services/backup-daemon/maintenance/recovery/recovery.py b/services/backup-daemon/maintenance/recovery/recovery.py index ff9e67c8..62cd0f2c 100644 --- a/services/backup-daemon/maintenance/recovery/recovery.py +++ b/services/backup-daemon/maintenance/recovery/recovery.py @@ -64,6 +64,20 @@ Value can be '' if wal_archive is disabled and 'curl -v -S -f --connect-timeout 3 postgres-backup-daemon:8082/archive/get?filename=%f -o %p' if enabled. """ +_SECRET_FILE_PATH = "/var/run/secrets/postgresql/" +_PG_CREDS_PATH = _SECRET_FILE_PATH + "postgres-credentials/" + +def read_secret_file(path: str, default_val: str) -> str: + try: + with open(path, 'r') as f: + value = f.read().strip() + except OSError as e: + logging.error(f"Failed to read secret file {path}: {e}") + return default_val + if not value: + logging.info(f"Secret file {path} is empty, using default value") + return default_val + return value class PoolLogger(object): @@ -383,10 +397,10 @@ def statefulset_from_pod(pod_name: str) -> str: def download_archive(oc_client, recovery_pod_id, restore_version): if restore_version: - oc_client.oc_exec(recovery_pod_id, "sh -c 'cd {} ; curl -u postgres:\"$PG_ROOT_PASSWORD\" postgres-backup-daemon:8081/get?id={} | tar -xzf - '" - .format(pg_data_dir, restore_version)) + oc_client.oc_exec(recovery_pod_id, "sh -c 'cd {} ; curl -u postgres:\"$(cat /var/run/secrets/postgresql/postgres-credentials/password)\" postgres-backup-daemon:8081/get?id={} | tar -xzf - '" + .format(pg_data_dir, restore_version)) #do not touch yet else: - oc_client.oc_exec(recovery_pod_id, "sh -c 'cd {} ; curl -u postgres:\"$PG_ROOT_PASSWORD\" postgres-backup-daemon:8081/get | tar -xzf - '" + oc_client.oc_exec(recovery_pod_id, "sh -c 'cd {} ; curl -u postgres:\"$(cat /var/run/secrets/postgresql/postgres-credentials/password)\" postgres-backup-daemon:8081/get | tar -xzf - '" .format(pg_data_dir)) @@ -629,11 +643,11 @@ def perform_recovery(oc_openshift_url, oc_username, oc_password, oc_project, log.info("Try to validate backup {} against list of backups from {}".format(restore_version, backup_daemon_pod_id)) - backup_list = requests.get("http://localhost:8081/list", auth=('postgres', os.getenv('POSTGRES_PASSWORD'))) + backup_list = requests.get("http://localhost:8081/list", auth=('postgres', read_secret_file(_PG_CREDS_PATH + 'password', ""))) validate_restore_version(backup_list.json(), restore_version) elif recovery_target_time: log.info("Try to find backup id from specified recovery_target_time={}".format(recovery_target_time)) - backup_list = requests.get("http://localhost:8081/list", auth=('postgres', os.getenv('POSTGRES_PASSWORD'))) + backup_list = requests.get("http://localhost:8081/list", auth=('postgres', read_secret_file(_PG_CREDS_PATH + 'password', ""))) cluster_tz_name = oc_client.oc_exec(backup_daemon_pod_id, 'date "+%Z"').strip() log.debug("Cluster time zone: {}" + cluster_tz_name) diff --git a/services/backup-daemon/maintenance/recovery/utils_pg.py b/services/backup-daemon/maintenance/recovery/utils_pg.py index 39cf8e1a..ed1b136b 100644 --- a/services/backup-daemon/maintenance/recovery/utils_pg.py +++ b/services/backup-daemon/maintenance/recovery/utils_pg.py @@ -19,6 +19,20 @@ log = logging.getLogger() +_SECRET_FILE_PATH = "/var/run/secrets/postgresql/" +_PG_CREDS_PATH = _SECRET_FILE_PATH + "postgres-credentials/" + +def read_secret_file(path: str, default_val: str) -> str: + try: + with open(path, 'r') as f: + value = f.read().strip() + except OSError as e: + logging.error(f"Failed to read secret file {path}: {e}") + return default_val + if not value: + logging.info(f"Secret file {path} is empty, using default value") + return default_val + return value class PostgresqlClient: @@ -32,7 +46,7 @@ def execute_select_query(self, query): import os try: connection = psycopg2.connect(user="postgres", - password=os.getenv('POSTGRES_PASSWORD'), + password=read_secret_file(_PG_CREDS_PATH + 'password', ""), # host=os.getenv('POSTGRES_HOST'), port="5432", database="postgres") diff --git a/services/patroni/scripts/archive_wal.sh b/services/patroni/scripts/archive_wal.sh index 4aa75e5b..2f3bea98 100644 --- a/services/patroni/scripts/archive_wal.sh +++ b/services/patroni/scripts/archive_wal.sh @@ -19,7 +19,8 @@ f="${2}" set +x -export `cat /proc/1/environ | tr '\0' '\n' | grep PG_ROOT_PASSWORD` +#export `cat /proc/1/environ | tr '\0' '\n' | grep PG_ROOT_PASSWORD` +PG_ROOT_PASSWORD=`cat /var/run/secrets/postgresql/postgres-credentials/password | tr '\0' '\n' | grep PG_ROOT_PASSWORD | cut -d "=" -f2` sha256sum -b "$p" | cut -d " " -f1 | xargs -I {} echo sha256={} | \ python3 -c "import sys; print(chr(38) + sys.stdin.read().strip())" | \ diff --git a/services/query-exporter/build/bin/entrypoint b/services/query-exporter/build/bin/entrypoint index 837b791a..02d7df97 100755 --- a/services/query-exporter/build/bin/entrypoint +++ b/services/query-exporter/build/bin/entrypoint @@ -1,3 +1,14 @@ #!/bin/sh -e -exec ${EXPORTER_FILE} $@ +read_secret() { + local path="$1" + + if [ -f "$path" ]; then + cat "$path" + fi +} + +POSTGRES_USER="$(read_secret /var/run/secrets/postgres/postgres-credentials/username)" +POSTGRES_PASSWORD="$(read_secret /var/run/secrets/postgres/postgres-credentials/password)" + +POSTGRES_USER="${POSTGRES_USER}" POSTGRES_PASSWORD="${POSTGRES_PASSWORD}" exec ${EXPORTER_FILE} $@ \ No newline at end of file diff --git a/services/replication-controller/cmd/pgskipper-replication-controller/main.go b/services/replication-controller/cmd/pgskipper-replication-controller/main.go index be818821..696623f7 100644 --- a/services/replication-controller/cmd/pgskipper-replication-controller/main.go +++ b/services/replication-controller/cmd/pgskipper-replication-controller/main.go @@ -41,25 +41,26 @@ const ( secretsBasePath = "/var/run/secrets/postgresql/" pgUserCredsPath = secretsBasePath + "postgres-credentials/" + apiUserCredsPath = secretsBasePath + "logical-repl-credentials/" ) var ( pgHost = flag.String("pg_host", utils.GetEnv("POSTGRES_HOST", "127.0.0.1"), "Host of PostgreSQL cluster, env: POSTGRES_HOST") pgPort = flag.Int("pg_port", utils.GetEnvInt("POSTGRES_PORT", 5432), "Port of PostgreSQL cluster, env: POSTGRES_PORT") - pgUser = flag.String("pg_user", utils.ReadSecretFile(pgUserCredsPath+"username", "postgres"), "Username of controller user in PostgreSQL, env: POSTGRES_ADMIN_USER") - pgPass = flag.String("pg_pass", utils.ReadSecretFile(pgUserCredsPath+"password", ""), "Password of controller user in PostgreSQL, env: POSTGRES_ADMIN_PASSWORD") + pgUser = flag.String("pg_user", utils.ReadSecretFile(pgUserCredsPath+"username", "postgres"), "Username of controller user in PostgreSQL") + pgPass = flag.String("pg_pass", utils.ReadSecretFile(pgUserCredsPath+"password", ""), "Password of controller user in PostgreSQL") pgSsl = flag.String("pg_ssl", utils.GetEnv("PG_SSL", "off"), "Enable ssl connection to postgreSQL, env: PG_SSL") servePort = flag.Int("serve_port", 8080, "Port to serve requests incoming to controller") serveUser = flag.String( "server_user", - utils.GetEnv("API_USER", "logical-repl-user"), - "Username to authorize incoming requests, env: API_USER", + utils.ReadSecretFile(apiUserCredsPath+"username", "logical-repl-user"), + "Username to authorize incoming requests", ) servePass = flag.String( "server_pass", - utils.GetEnv("API_PASSWORD", "logical-repl-password"), - "Password to authorize incoming requests, env: API_PASSWORD", + utils.ReadSecretFile(apiUserCredsPath+"password", "logical-repl-password"), + "Password to authorize incoming requests", ) log = utils.GetLogger() diff --git a/services/upgrade/docker/start.sh b/services/upgrade/docker/start.sh index 2b3b651e..f51868f1 100755 --- a/services/upgrade/docker/start.sh +++ b/services/upgrade/docker/start.sh @@ -107,7 +107,7 @@ function handle_master_upgrade() { --old-bindir "/usr/lib/postgresql/${PG_VERSION}/bin" \ --new-bindir "/usr/lib/postgresql/${PG_VERSION_TARGET}/bin" \ --check \ - > /var/lib/pgsql/data/check_result + > /var/lib/pgsql/data/check_result 2>&1 CHECK_CODE=$? diff --git a/tests/robot/Lib/lib.robot b/tests/robot/Lib/lib.robot index 5eb07ec4..604cf049 100644 --- a/tests/robot/Lib/lib.robot +++ b/tests/robot/Lib/lib.robot @@ -11,6 +11,8 @@ Library ../Lib/pgsLibrary.py namespace=${NAMESPACE} ssl_mode=${PGSSL ${NAMESPACE} %{POD_NAMESPACE} ${PGSSLMODE} %{PGSSLMODE} ${INTERNAL_TLS_ENABLED} %{INTERNAL_TLS_ENABLED} +${PG_ROOT_PASSWORD_PATH} /var/run/secrets/postgresql/postgres-credentials/password +${PG_ROOT_USERNAME_PATH} /var/run/secrets/postgresql/postgres-credentials/username *** Keywords *** Checks Before Tests @@ -335,7 +337,7 @@ Check /backups Endpoint For Granular Backups ... response code should be `200` and response should contain `storage` key ... and `status` key with `UP` value ... - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} ${PGSSLMODE}= Get Environment Variable PGSSLMODE ${scheme}= Set Variable If '${PGSSLMODE}' == 'require' https http @@ -372,7 +374,7 @@ Check Enabled Auth ${resp}= GET On Session postgres_backup_daemon /delete/test?namespace=test Should Be Equal ${resp.status_code} ${401} #set auth credentials - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} Create Granular Backup ${name_space} ${auth} ${databases} #wait backup complete @@ -445,3 +447,12 @@ Check Backup Api With Broken Metric File Wait Replica Pods In Up State ${replicas_status}= Wait Replica Pods Scale up Should Be Equal ${replicas_status} ${True} + +Get Secret Or Env + [Arguments] ${env_name} ${file_path} + ${value}= Get Environment Variable ${env_name} default=${EMPTY} + IF not $value + ${value}= Get File ${file_path} + ${value}= Strip String ${value} + END + RETURN ${value} diff --git a/tests/robot/Lib/pgsLibrary.py b/tests/robot/Lib/pgsLibrary.py index 7f82f7d1..5efbb5ea 100644 --- a/tests/robot/Lib/pgsLibrary.py +++ b/tests/robot/Lib/pgsLibrary.py @@ -32,6 +32,8 @@ log = logging.getLogger() log.setLevel(logging.DEBUG) +POSTGRES_CREDS_PATH = "/var/run/secrets/postgresql/postgres-credentials" + class pgsLibrary(object): def __init__(self, namespace, ssl_mode, internal_tls): self._namespace = namespace @@ -247,7 +249,7 @@ def get_replica_count(self, dc_name): @keyword('Execute Query') def execute_query(self, host, query, dbname='postgres'): - password = os.getenv("PG_ROOT_PASSWORD") + password = self.read_secret_file(POSTGRES_CREDS_PATH + "/password", "") connection_properties = { 'host': host, 'password': password, @@ -415,8 +417,8 @@ def get_pg_version(self): def connection_for_pg(self): conn = psycopg2.connect(dbname='postgres', - user=os.getenv('POSTGRES_USER', "postgres"), - password=os.getenv('PG_ROOT_PASSWORD'), + user=self.read_secret_file(POSTGRES_CREDS_PATH + "/username", "postgres"), + password=self.read_secret_file(POSTGRES_CREDS_PATH + "/password", ""), host="pg-" + os.getenv("PG_CLUSTER_NAME", "patroni")) return conn @@ -821,3 +823,17 @@ def get_dd_images_from_config_map(self, config_map_name): def get_image_from_resource(self, type, name, container_name): return self.pl_lib.get_resource_image(type, name, self._namespace, container_name) + + def read_secret_file(self, path: str, default_val: str) -> str: + try: + with open(path, "r") as f: + value = f.read().strip() + except OSError as e: + logging.error(f"Failed to read secret file {path}: {e}") + return default_val + + if not value: + logging.info(f"Secret file {path} is empty, using default value") + return default_val + + return value \ No newline at end of file diff --git a/tests/robot/check_full_backup_api/check_backup_api_auth.robot b/tests/robot/check_full_backup_api/check_backup_api_auth.robot index 76259a2b..7cb325f9 100644 --- a/tests/robot/check_full_backup_api/check_backup_api_auth.robot +++ b/tests/robot/check_full_backup_api/check_backup_api_auth.robot @@ -30,7 +30,7 @@ Check Enabled Auth Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:8081 ${resp}= GET On Session postgres_backup_daemon /backups/list expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:8081 auth=${auth} ${resp}= GET On Session postgres_backup_daemon /backups/list diff --git a/tests/robot/check_granular_api/check_granular_backups_list_auth_api.robot b/tests/robot/check_granular_api/check_granular_backups_list_auth_api.robot index ed0fc8d8..c23a44ad 100644 --- a/tests/robot/check_granular_api/check_granular_backups_list_auth_api.robot +++ b/tests/robot/check_granular_api/check_granular_backups_list_auth_api.robot @@ -12,7 +12,7 @@ Create Backup And Wait Create Backup And Wait Till Complete ${name_space} Check Backup List - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} # wait while daemon will start backup ${backups_in_namespace}= Create Dictionary diff --git a/tests/robot/check_granular_api/check_granular_restore_added_data_after_backup.robot b/tests/robot/check_granular_api/check_granular_restore_added_data_after_backup.robot index b325e73e..dfe845d5 100644 --- a/tests/robot/check_granular_api/check_granular_restore_added_data_after_backup.robot +++ b/tests/robot/check_granular_api/check_granular_restore_added_data_after_backup.robot @@ -97,7 +97,7 @@ Check Enabled Auth With Restore Added Data After Backup Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 ${resp}= POST On Session postgres_backup_daemon /restore/request expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} ${PG_CLUSTER_NAME}= Get Environment Variable PG_CLUSTER_NAME default=patroni ${POSTGRES_USER}= Get Environment Variable POSTGRES_USER default=postgres diff --git a/tests/robot/check_granular_api/check_granular_restore_backup_auth_api.robot b/tests/robot/check_granular_api/check_granular_restore_backup_auth_api.robot index 474398ee..98d5684b 100644 --- a/tests/robot/check_granular_api/check_granular_restore_backup_auth_api.robot +++ b/tests/robot/check_granular_api/check_granular_restore_backup_auth_api.robot @@ -89,7 +89,7 @@ Check Enabled Auth Regular Backup Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 ${resp}= POST On Session postgres_backup_daemon /restore/request expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} ${PG_CLUSTER_NAME}= Get Environment Variable PG_CLUSTER_NAME default=patroni ${POSTGRES_USER}= Get Environment Variable POSTGRES_USER default=postgres @@ -154,7 +154,7 @@ Check Enabled Auth Failed Backup Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 ${resp}= POST On Session postgres_backup_daemon /restore/request expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORDF + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 auth=${auth} ${name_space}= Get Current Date result_format=%Y%m%d%H%M diff --git a/tests/robot/check_granular_api/check_granular_restore_backup_with_new_names_auth.robot b/tests/robot/check_granular_api/check_granular_restore_backup_with_new_names_auth.robot index 995a7a19..9eaab126 100644 --- a/tests/robot/check_granular_api/check_granular_restore_backup_with_new_names_auth.robot +++ b/tests/robot/check_granular_api/check_granular_restore_backup_with_new_names_auth.robot @@ -87,7 +87,7 @@ Check Enabled Auth With Db Name Change Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 ${resp}= POST On Session postgres_backup_daemon /restore/request expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} ${PG_CLUSTER_NAME}= Get Environment Variable PG_CLUSTER_NAME default=patroni ${POSTGRES_USER}= Get Environment Variable POSTGRES_USER default=postgres diff --git a/tests/robot/check_granular_api/check_granular_restore_backup_with_roles_auth.robot b/tests/robot/check_granular_api/check_granular_restore_backup_with_roles_auth.robot index 8c8f2a7c..41164f67 100644 --- a/tests/robot/check_granular_api/check_granular_restore_backup_with_roles_auth.robot +++ b/tests/robot/check_granular_api/check_granular_restore_backup_with_roles_auth.robot @@ -79,7 +79,7 @@ Check Enabled Auth With Roles Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 ${resp}= POST On Session postgres_backup_daemon /restore/request expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} ${PG_CLUSTER_NAME}= Get Environment Variable PG_CLUSTER_NAME default=patroni ${POSTGRES_USER}= Get Environment Variable POSTGRES_USER default=postgres diff --git a/tests/robot/check_granular_api/check_granular_restore_status_auth_api.robot b/tests/robot/check_granular_api/check_granular_restore_status_auth_api.robot index b43ec26c..f3dcc48c 100644 --- a/tests/robot/check_granular_api/check_granular_restore_status_auth_api.robot +++ b/tests/robot/check_granular_api/check_granular_restore_status_auth_api.robot @@ -94,7 +94,7 @@ Check Enabled Auth restore endpoint ${resp}= Get On Session postgres_backup_daemon url=/restore/status/test expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} ${PG_CLUSTER_NAME}= Get Environment Variable PG_CLUSTER_NAME default=patroni ${POSTGRES_USER}= Get Environment Variable POSTGRES_USER default=postgres @@ -162,7 +162,7 @@ Check Enabled Auth not existing ${resp}= Get On Session postgres_backup_daemon url=/restore/status/test expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 auth=${auth} diff --git a/tests/robot/check_granular_api/check_granular_restore_with_owner_auth.robot b/tests/robot/check_granular_api/check_granular_restore_with_owner_auth.robot index 74df7f7f..58679dee 100644 --- a/tests/robot/check_granular_api/check_granular_restore_with_owner_auth.robot +++ b/tests/robot/check_granular_api/check_granular_restore_with_owner_auth.robot @@ -90,7 +90,7 @@ Check Enabled Auth With Owner Of DB Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 ${resp}= POST On Session postgres_backup_daemon /restore/request expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 auth=${auth} ${name_space}= Get Current Date result_format=%Y%m%d%H%M diff --git a/tests/robot/check_granular_api/check_granular_restore_with_specified_dbs.robot b/tests/robot/check_granular_api/check_granular_restore_with_specified_dbs.robot index c1ff418e..5b948723 100644 --- a/tests/robot/check_granular_api/check_granular_restore_with_specified_dbs.robot +++ b/tests/robot/check_granular_api/check_granular_restore_with_specified_dbs.robot @@ -99,7 +99,7 @@ Check Enabled Auth With Specified DBs Create Session postgres_backup_daemon ${scheme}://postgres-backup-daemon:9000 ${resp}= POST On Session postgres_backup_daemon /restore/request expected_status=401 Should Be Equal ${resp.status_code} ${401} - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} ${PG_CLUSTER_NAME}= Get Environment Variable PG_CLUSTER_NAME default=patroni ${POSTGRES_USER}= Get Environment Variable POSTGRES_USER default=postgres diff --git a/tests/robot/check_scale_down_backup_daemon/check_scale_down_backup_daemon.robot b/tests/robot/check_scale_down_backup_daemon/check_scale_down_backup_daemon.robot index 9edcd05a..762ddf1b 100644 --- a/tests/robot/check_scale_down_backup_daemon/check_scale_down_backup_daemon.robot +++ b/tests/robot/check_scale_down_backup_daemon/check_scale_down_backup_daemon.robot @@ -17,7 +17,7 @@ Setup Set Suite Variable ${db_name} test_ha_backup_${postfix} Make Backup And Return ID - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List postgres ${PG_ROOT_PASSWORD} ${databases}= Create List ${db_name} &{data}= Create Dictionary databases=${databases} diff --git a/tests/robot/check_terminate_backup_api/keywords.robot b/tests/robot/check_terminate_backup_api/keywords.robot index e3a7fd4f..0f0d11b4 100644 --- a/tests/robot/check_terminate_backup_api/keywords.robot +++ b/tests/robot/check_terminate_backup_api/keywords.robot @@ -34,7 +34,7 @@ Check Authorization Should Be Equal ${resp.status_code} ${401} Prepare Auth - ${POSTGRES_USER}= Get Environment Variable POSTGRES_USER default=postgres - ${PG_ROOT_PASSWORD}= Get Environment Variable PG_ROOT_PASSWORD + ${POSTGRES_USER}= Get Secret Or Env POSTGRES_USER ${PG_ROOT_USERNAME_PATH} + ${PG_ROOT_PASSWORD}= Get Secret Or Env PG_ROOT_PASSWORD ${PG_ROOT_PASSWORD_PATH} ${auth}= Create List ${POSTGRES_USER} ${PG_ROOT_PASSWORD} [Return] ${auth} From 96fef77b1048e29f8a533b9a2458fcbe09175a9a Mon Sep 17 00:00:00 2001 From: svetychkina Date: Tue, 16 Jun 2026 18:27:34 +0500 Subject: [PATCH 06/14] Update pgsLibrary.py --- tests/robot/Lib/pgsLibrary.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/robot/Lib/pgsLibrary.py b/tests/robot/Lib/pgsLibrary.py index 9f76043a..a75878e6 100644 --- a/tests/robot/Lib/pgsLibrary.py +++ b/tests/robot/Lib/pgsLibrary.py @@ -467,9 +467,12 @@ def delete_test_db(self, *base_names): conn.set_isolation_level(0) with conn.cursor() as cursor: for base_name in base_names: - cursor.execute("SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE pid <> pg_backend_pid() AND datname = '{}';".format(base_name)) - cursor.execute('DROP DATABASE IF EXISTS {}'.format(base_name)) -d.metadata.labels \ + cursor.execute('DROP DATABASE IF EXISTS "{}" WITH (FORCE)'.format(base_name)) + + @keyword('Get Pod Daemon') + def get_pod_daemon(self): + for pod in self.pl_lib.get_pods(self._namespace): + if "app" in pod.metadata.labels \ and pod.metadata.labels['app'] == 'postgres-backup-daemon' \ and pod.status.phase == 'Running': return pod From 2c1d27f5bf870cff9cda8b4016f4f6cbf508bc3b Mon Sep 17 00:00:00 2001 From: svetychkina Date: Tue, 16 Jun 2026 18:57:42 +0500 Subject: [PATCH 07/14] fix: [CPCAP-9492] tests --- operator/pkg/deployment/tests.go | 36 +++++++++++++++----------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/operator/pkg/deployment/tests.go b/operator/pkg/deployment/tests.go index cedafa87..053c609b 100644 --- a/operator/pkg/deployment/tests.go +++ b/operator/pkg/deployment/tests.go @@ -65,6 +65,16 @@ func NewIntegrationTestsPod(cr *v1.PatroniServices, cluster *patroniv1.PatroniCl Spec: corev1.PodSpec{ ServiceAccountName: cr.Spec.ServiceAccountName, Affinity: &testsSpec.Affinity, + Volumes: []corev1.Volume{ + { + Name: "postgres-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "postgres-credentials", + }, + }, + }, + }, InitContainers: []corev1.Container{}, Containers: []corev1.Container{ { @@ -73,24 +83,6 @@ func NewIntegrationTestsPod(cr *v1.PatroniServices, cluster *patroniv1.PatroniCl ImagePullPolicy: cr.Spec.ImagePullPolicy, SecurityContext: util.GetDefaultSecurityContext(), Env: []corev1.EnvVar{ - { - Name: "POSTGRES_USER", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "postgres-credentials"}, - Key: "username", - }, - }, - }, - { - Name: "PG_ROOT_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "postgres-credentials"}, - Key: "password", - }, - }, - }, { Name: "PG_CLUSTER_NAME", Value: cluster.ClusterName, @@ -128,7 +120,13 @@ func NewIntegrationTestsPod(cr *v1.PatroniServices, cluster *patroniv1.PatroniCl Value: testsSpec.MonitoredImages, }, }, - VolumeMounts: []corev1.VolumeMount{}, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "postgres-credentials", + MountPath: "/var/run/secrets/postgres/postgres-credentials", + ReadOnly: true, + }, + }, }, }, RestartPolicy: corev1.RestartPolicyNever, From 69d4eb0674e08efe807ad63d84d455461e32b12f Mon Sep 17 00:00:00 2001 From: svetychkina Date: Tue, 16 Jun 2026 19:46:03 +0500 Subject: [PATCH 08/14] fix: [CPCAP-9492] path to secrets --- operator/pkg/deployment/tests.go | 2 +- services/backup-daemon/docker/postgres/postgres_backup.sh | 4 ++-- services/query-exporter/build/bin/entrypoint | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/operator/pkg/deployment/tests.go b/operator/pkg/deployment/tests.go index 053c609b..9a89550f 100644 --- a/operator/pkg/deployment/tests.go +++ b/operator/pkg/deployment/tests.go @@ -123,7 +123,7 @@ func NewIntegrationTestsPod(cr *v1.PatroniServices, cluster *patroniv1.PatroniCl VolumeMounts: []corev1.VolumeMount{ { Name: "postgres-credentials", - MountPath: "/var/run/secrets/postgres/postgres-credentials", + MountPath: "/var/run/secrets/postgresql/postgres-credentials", ReadOnly: true, }, }, diff --git a/services/backup-daemon/docker/postgres/postgres_backup.sh b/services/backup-daemon/docker/postgres/postgres_backup.sh index 1bc40a1d..cfe0d7d2 100755 --- a/services/backup-daemon/docker/postgres/postgres_backup.sh +++ b/services/backup-daemon/docker/postgres/postgres_backup.sh @@ -26,8 +26,8 @@ readonly ENCRYPTION_KEY="$2" BACKUP_DESTINATION_DIRECTORY="$1" BACKUP_NAME="pg_${PG_CLUSTER_NAME}_backup_$(basename ${BACKUP_DESTINATION_DIRECTORY}).tar.gz" -POSTGRES_USER=$(cat /var/run/secrets/postgres-credentials/username) -POSTGRES_PASSWORD=$(cat /var/run/secrets/postgres-credentials/password) +POSTGRES_USER=$(cat /var/run/secrets/postgresql/postgres-credentials/username) +POSTGRES_PASSWORD=$(cat /var/run/secrets/postgresql/postgres-credentials/password) source utils.sh diff --git a/services/query-exporter/build/bin/entrypoint b/services/query-exporter/build/bin/entrypoint index 02d7df97..4de5cd62 100755 --- a/services/query-exporter/build/bin/entrypoint +++ b/services/query-exporter/build/bin/entrypoint @@ -8,7 +8,7 @@ read_secret() { fi } -POSTGRES_USER="$(read_secret /var/run/secrets/postgres/postgres-credentials/username)" -POSTGRES_PASSWORD="$(read_secret /var/run/secrets/postgres/postgres-credentials/password)" +POSTGRES_USER="$(read_secret /var/run/secrets/postgresql/postgres-credentials/username)" +POSTGRES_PASSWORD="$(read_secret /var/run/secrets/postgresql/postgres-credentials/password)" POSTGRES_USER="${POSTGRES_USER}" POSTGRES_PASSWORD="${POSTGRES_PASSWORD}" exec ${EXPORTER_FILE} $@ \ No newline at end of file From 97578573295bd572c91b98868192eb0c82dc80a9 Mon Sep 17 00:00:00 2001 From: svetychkina Date: Wed, 17 Jun 2026 14:52:58 +0500 Subject: [PATCH 09/14] fix: [CPCAP-9492] tests secrets hardening --- operator/pkg/deployment/tests.go | 36 +++++++++++++++----------------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/operator/pkg/deployment/tests.go b/operator/pkg/deployment/tests.go index 9a89550f..9e437526 100644 --- a/operator/pkg/deployment/tests.go +++ b/operator/pkg/deployment/tests.go @@ -190,6 +190,16 @@ func NewCoreIntegrationTests(cr *patroniv1.PatroniCore, cluster *patroniv1.Patro Spec: corev1.PodSpec{ ServiceAccountName: cr.Spec.ServiceAccountName, Affinity: &testsSpec.Affinity, + Volumes: []corev1.Volume{ + { + Name: "postgres-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: "postgres-credentials", + }, + }, + }, + }, InitContainers: []corev1.Container{}, Containers: []corev1.Container{ { @@ -198,24 +208,6 @@ func NewCoreIntegrationTests(cr *patroniv1.PatroniCore, cluster *patroniv1.Patro ImagePullPolicy: cr.Spec.ImagePullPolicy, SecurityContext: util.GetDefaultSecurityContext(), Env: []corev1.EnvVar{ - { - Name: "POSTGRES_USER", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "postgres-credentials"}, - Key: "username", - }, - }, - }, - { - Name: "PG_ROOT_PASSWORD", - ValueFrom: &corev1.EnvVarSource{ - SecretKeyRef: &corev1.SecretKeySelector{ - LocalObjectReference: corev1.LocalObjectReference{Name: "postgres-credentials"}, - Key: "password", - }, - }, - }, { Name: "PG_CLUSTER_NAME", Value: cluster.ClusterName, @@ -257,7 +249,13 @@ func NewCoreIntegrationTests(cr *patroniv1.PatroniCore, cluster *patroniv1.Patro Value: testsSpec.MonitoredImages, }, }, - VolumeMounts: []corev1.VolumeMount{}, + VolumeMounts: []corev1.VolumeMount{ + { + Name: "postgres-credentials", + MountPath: "/var/run/secrets/postgresql/postgres-credentials", + ReadOnly: true, + }, + }, }, }, RestartPolicy: corev1.RestartPolicyNever, From 3de62e6bd522c213160498fb7b27405f4e825c7e Mon Sep 17 00:00:00 2001 From: svetychkina Date: Wed, 17 Jun 2026 16:34:25 +0500 Subject: [PATCH 10/14] fix: [CPCAP-9492] delete template --- .../templates/dbaas/dbaas-adapter-deployment.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index e5daf4cd..4fd8c115 100644 --- a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -90,7 +90,6 @@ spec: resources: {{ .Values.dbaas.resources | toYaml | indent 12 }} env: - {{- template "postgres-dbaas.pgAdminEnvs" . }} - name: POSTGRES_DATABASE value: {{ default "postgres" .Values.dbaas.dbName }} - name: POSTGRES_HOST From 1c23c8d91e7ac1c5c375ef97cbbd9dd633e4cd98 Mon Sep 17 00:00:00 2001 From: svetychkina Date: Thu, 18 Jun 2026 15:37:43 +0500 Subject: [PATCH 11/14] fix: [CPCAP-9492] secrets naming --- .../templates/dbaas/dbaas-adapter-deployment.yaml | 4 ++-- operator/charts/patroni-services/templates/deployment.yaml | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index 4fd8c115..709747d1 100644 --- a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -185,8 +185,8 @@ spec: - name: dbaas-adapter-credentials mountPath: /var/run/secrets/postgresql/dbaas-adapter-credentials readOnly: true - - name: dbaas-adapter-registration-credentials - mountPath: /var/run/secrets/postgresql/dbaas-adapter-registration-credentials + - name: dbaas-aggregator-registration-credentials + mountPath: /var/run/secrets/postgresql/dbaas-aggregator-registration-credentials readOnly: true - name: postgres-credentials mountPath: /var/run/secrets/postgresql/postgres-credentials diff --git a/operator/charts/patroni-services/templates/deployment.yaml b/operator/charts/patroni-services/templates/deployment.yaml index 9e51d2cb..853c4efe 100644 --- a/operator/charts/patroni-services/templates/deployment.yaml +++ b/operator/charts/patroni-services/templates/deployment.yaml @@ -72,6 +72,7 @@ spec: {{- if and .Values.tls .Values.tls.enabled }} - name: tls-cert mountPath: /certs/ + {{- end }} {{- end }} - name: postgres-credentials mountPath: /var/run/secrets/postgres-credentials @@ -79,7 +80,6 @@ spec: - name: replicator-credentials mountPath: /var/run/secrets/replicator-credentials readOnly: true - {{- end }} env: - name: WATCH_NAMESPACE valueFrom: @@ -178,12 +178,12 @@ spec: secret: secretName: replicator-credentials defaultMode: 420 + {{- end }} {{- end }} - name: postgres-credentials secret: secretName: postgres-credentials defaultMode: 420 - {{- end }} tolerations: {{- range $tKey, $t := .Values.policies.tolerations }} - key: {{ $t.key }} From 2c74b37e97646a8db32c6200e1a6af15f53ea89b Mon Sep 17 00:00:00 2001 From: svetychkina Date: Thu, 18 Jun 2026 15:46:44 +0500 Subject: [PATCH 12/14] fix: [CPCAP-9492] secrets naming --- .../templates/dbaas/dbaas-adapter-deployment.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index 709747d1..dd8cc940 100644 --- a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -59,9 +59,9 @@ spec: secret: secretName: dbaas-adapter-credentials defaultMode: 420 - - name: dbaas-adapter-registration-credentials + - name: dbaas-aggregator-registration-credentials secret: - secretName: dbaas-adapter-registration-credentials + secretName: dbaas-aggregator-registration-credentials defaultMode: 420 - name: postgres-credentials secret: From a5dc81132a5965c270cabef21f6194e9dbd77145 Mon Sep 17 00:00:00 2001 From: svetychkina Date: Thu, 18 Jun 2026 16:54:15 +0500 Subject: [PATCH 13/14] fix: [CPCAP-9492] add secrets volume directly to deployment --- operator/pkg/deployment/backup.go | 32 ++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/operator/pkg/deployment/backup.go b/operator/pkg/deployment/backup.go index b2348c46..1009c93b 100644 --- a/operator/pkg/deployment/backup.go +++ b/operator/pkg/deployment/backup.go @@ -73,15 +73,15 @@ func NewBackupDaemonDeployment(backupDaemon *netcrackerv1.BackupDaemon, pgCluste }, }, }, - { - Name: "postgres-credentials", - VolumeSource: corev1.VolumeSource{ - Secret: &corev1.SecretVolumeSource{ - SecretName: GetRootSecretName(pgClusterName), - DefaultMode: ptr.To[int32](0400), - }, - }, - }, +// { +// Name: "postgres-credentials", +// VolumeSource: corev1.VolumeSource{ +// Secret: &corev1.SecretVolumeSource{ +// SecretName: GetRootSecretName(pgClusterName), +// DefaultMode: ptr.To[int32](0400), +// }, +// }, +// }, }, ServiceAccountName: serviceAccountName, Affinity: &backupDaemon.Affinity, @@ -292,6 +292,20 @@ func NewBackupDaemonDeployment(backupDaemon *netcrackerv1.BackupDaemon, pgCluste }, } } +// Add postgres-credentials volume regardless of storage type + deployment.Spec.Template.Spec.Volumes = append( + deployment.Spec.Template.Spec.Volumes, + corev1.Volume{ + Name: "postgres-credentials", + VolumeSource: corev1.VolumeSource{ + Secret: &corev1.SecretVolumeSource{ + SecretName: GetRootSecretName(pgClusterName), + DefaultMode: ptr.To[int32](0400), + }, + }, + }, + ) + if backupDaemon.ExternalPv != nil { deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes, getExternalBackupVolume()) From d01c7519ac7f352d5daac645ca80e02ce261204c Mon Sep 17 00:00:00 2001 From: svetychkina Date: Fri, 19 Jun 2026 17:09:33 +0500 Subject: [PATCH 14/14] fix: [CPCAP-9492] add volumemounts to init container --- .../templates/dbaas/dbaas-adapter-deployment.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index dd8cc940..399edecd 100644 --- a/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/operator/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -87,6 +87,15 @@ spec: mountPath: /tmp - name: dbaas-default-extensions-mount mountPath: /app/extensions + - name: dbaas-adapter-credentials + mountPath: /var/run/secrets/postgresql/dbaas-adapter-credentials + readOnly: true + - name: dbaas-aggregator-registration-credentials + mountPath: /var/run/secrets/postgresql/dbaas-aggregator-registration-credentials + readOnly: true + - name: postgres-credentials + mountPath: /var/run/secrets/postgresql/postgres-credentials + readOnly: true resources: {{ .Values.dbaas.resources | toYaml | indent 12 }} env: