diff --git a/api/apps/v1/postgresservice_types.go b/api/apps/v1/postgresservice_types.go index 6d18e2e3..af9a0282 100644 --- a/api/apps/v1/postgresservice_types.go +++ b/api/apps/v1/postgresservice_types.go @@ -23,27 +23,26 @@ import ( // PatroniServicesSpec defines the desired state of PatroniServices // +k8s:openapi-gen=true type PatroniServicesSpec struct { - Patroni *Patroni `json:"patroni,omitempty"` - BackupDaemon *types.BackupDaemon `json:"backupDaemon,omitempty"` - MetricCollector *types.MetricCollector `json:"metricCollector,omitempty"` - AuthSecret string `json:"authSecret,omitempty"` - IntegrationTests *IntegrationTests `json:"integrationTests,omitempty"` - VaultRegistration *types.VaultRegistration `json:"vaultRegistration,omitempty"` - Policies *Policies `json:"policies,omitempty"` - ServiceAccountName string `json:"serviceAccountName,omitempty"` - CloudSql *types.CloudSql `json:"cloudSql,omitempty"` - SiteManager *SiteManager `json:"siteManager,omitempty"` - PowaUI PowaUI `json:"powaUI,omitempty"` - ReplicationController ReplicationController `json:"replicationController,omitempty"` - Pooler Pooler `json:"connectionPooler,omitempty"` - Tracing *Tracing `json:"tracing,omitempty"` - ExternalDataBase *ExternalDataBase `json:"externalDataBase,omitempty"` - PostgresExporter *PostgresExporter `json:"postgresExporter,omitempty"` - QueryExporter QueryExporter `json:"queryExporter,omitempty"` - Tls *Tls `json:"tls,omitempty"` - PgBackRest *PgBackRest `json:"pgBackRest,omitempty"` - InstallationTimestamp string `json:"installationTimestamp,omitempty"` - PrivateRegistry PrivateRegistry `json:"privateRegistry,omitempty"` + Patroni *Patroni `json:"patroni,omitempty"` + BackupDaemon *types.BackupDaemon `json:"backupDaemon,omitempty"` + MetricCollector *types.MetricCollector `json:"metricCollector,omitempty"` + AuthSecret string `json:"authSecret,omitempty"` + IntegrationTests *IntegrationTests `json:"integrationTests,omitempty"` + Policies *Policies `json:"policies,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty"` + CloudSql *types.CloudSql `json:"cloudSql,omitempty"` + SiteManager *SiteManager `json:"siteManager,omitempty"` + PowaUI PowaUI `json:"powaUI,omitempty"` + ReplicationController ReplicationController `json:"replicationController,omitempty"` + Pooler Pooler `json:"connectionPooler,omitempty"` + Tracing *Tracing `json:"tracing,omitempty"` + ExternalDataBase *ExternalDataBase `json:"externalDataBase,omitempty"` + PostgresExporter *PostgresExporter `json:"postgresExporter,omitempty"` + QueryExporter QueryExporter `json:"queryExporter,omitempty"` + Tls *Tls `json:"tls,omitempty"` + PgBackRest *PgBackRest `json:"pgBackRest,omitempty"` + InstallationTimestamp string `json:"installationTimestamp,omitempty"` + PrivateRegistry PrivateRegistry `json:"privateRegistry,omitempty"` } type PrivateRegistry struct { diff --git a/api/apps/v1/zz_generated.deepcopy.go b/api/apps/v1/zz_generated.deepcopy.go index 2d4d30d4..e107cebd 100644 --- a/api/apps/v1/zz_generated.deepcopy.go +++ b/api/apps/v1/zz_generated.deepcopy.go @@ -204,11 +204,6 @@ func (in *PatroniServicesSpec) DeepCopyInto(out *PatroniServicesSpec) { *out = new(IntegrationTests) (*in).DeepCopyInto(*out) } - if in.VaultRegistration != nil { - in, out := &in.VaultRegistration, &out.VaultRegistration - *out = new(apiv1.VaultRegistration) - **out = **in - } if in.Policies != nil { in, out := &in.Policies, &out.Policies *out = new(Policies) diff --git a/api/patroni/v1/patronicore_types.go b/api/patroni/v1/patronicore_types.go index 77d82a66..b5937ba9 100644 --- a/api/patroni/v1/patronicore_types.go +++ b/api/patroni/v1/patronicore_types.go @@ -23,19 +23,18 @@ import ( // PatroniCoreSpec defines the desired state of PatroniCore // +k8s:openapi-gen=true type PatroniCoreSpec struct { - Patroni *Patroni `json:"patroni,omitempty"` - AuthSecret string `json:"authSecret,omitempty"` - IntegrationTests *IntegrationTests `json:"integrationTests,omitempty"` - ConsulRegistration *ConsulRegistration `json:"consulRegistration,omitempty"` - VaultRegistration *types.VaultRegistration `json:"vaultRegistration,omitempty"` - Policies *Policies `json:"policies,omitempty"` - ServiceAccountName string `json:"serviceAccountName,omitempty"` - CloudSql *types.CloudSql `json:"cloudSql,omitempty"` - Tls *Tls `json:"tls,omitempty"` - PgBackRest *PgBackRest `json:"pgBackRest,omitempty"` - Ldap *LdapConfig `json:"ldap,omitempty"` - InstallationTimestamp string `json:"installationTimestamp,omitempty"` - PrivateRegistry PrivateRegistry `json:"privateRegistry,omitempty"` + Patroni *Patroni `json:"patroni,omitempty"` + AuthSecret string `json:"authSecret,omitempty"` + IntegrationTests *IntegrationTests `json:"integrationTests,omitempty"` + ConsulRegistration *ConsulRegistration `json:"consulRegistration,omitempty"` + Policies *Policies `json:"policies,omitempty"` + ServiceAccountName string `json:"serviceAccountName,omitempty"` + CloudSql *types.CloudSql `json:"cloudSql,omitempty"` + Tls *Tls `json:"tls,omitempty"` + PgBackRest *PgBackRest `json:"pgBackRest,omitempty"` + Ldap *LdapConfig `json:"ldap,omitempty"` + InstallationTimestamp string `json:"installationTimestamp,omitempty"` + PrivateRegistry PrivateRegistry `json:"privateRegistry,omitempty"` } type PrivateRegistry struct { @@ -99,7 +98,6 @@ type Patroni struct { PodLabels map[string]string `json:"podLabels,omitempty"` PgHba []string `json:"pgHba,omitempty"` Powa Powa `json:"powa,omitempty"` - VaultRegistration *types.VaultRegistration `json:"vaultRegistration,omitempty"` SecurityContext *v1.PodSecurityContext `json:"securityContext,omitempty"` Unlimited bool `json:"unlimited,omitempty"` PgWalStorageAutoManage bool `json:"pgWalStorageAutoManage,omitempty"` diff --git a/api/patroni/v1/zz_generated.deepcopy.go b/api/patroni/v1/zz_generated.deepcopy.go index 4bf630d5..d8358eda 100644 --- a/api/patroni/v1/zz_generated.deepcopy.go +++ b/api/patroni/v1/zz_generated.deepcopy.go @@ -202,11 +202,6 @@ func (in *Patroni) DeepCopyInto(out *Patroni) { copy(*out, *in) } out.Powa = in.Powa - if in.VaultRegistration != nil { - in, out := &in.VaultRegistration, &out.VaultRegistration - *out = new(apiv1.VaultRegistration) - **out = **in - } if in.SecurityContext != nil { in, out := &in.SecurityContext, &out.SecurityContext *out = new(corev1.PodSecurityContext) @@ -377,11 +372,6 @@ func (in *PatroniCoreSpec) DeepCopyInto(out *PatroniCoreSpec) { *out = new(ConsulRegistration) (*in).DeepCopyInto(*out) } - if in.VaultRegistration != nil { - in, out := &in.VaultRegistration, &out.VaultRegistration - *out = new(apiv1.VaultRegistration) - **out = **in - } if in.Policies != nil { in, out := &in.Policies, &out.Policies *out = new(Policies) diff --git a/charts/patroni-core/crds/qubership.org_patronicores.yaml b/charts/patroni-core/crds/qubership.org_patronicores.yaml index a4f05ad8..eac6c9e7 100644 --- a/charts/patroni-core/crds/qubership.org_patronicores.yaml +++ b/charts/patroni-core/crds/qubership.org_patronicores.yaml @@ -2458,37 +2458,6 @@ spec: type: object unlimited: type: boolean - vaultRegistration: - properties: - dbEngine: - description: Vault DbEngine configuration - properties: - enabled: - type: boolean - maxConnectionLifetime: - type: string - maxIdleConnections: - type: integer - maxOpenConnections: - type: integer - name: - type: string - type: object - dockerImage: - type: string - enabled: - type: boolean - method: - type: string - path: - type: string - role: - type: string - token: - type: string - url: - type: string - type: object type: object pgBackRest: properties: @@ -2672,37 +2641,6 @@ spec: enabled: type: boolean type: object - vaultRegistration: - properties: - dbEngine: - description: Vault DbEngine configuration - properties: - enabled: - type: boolean - maxConnectionLifetime: - type: string - maxIdleConnections: - type: integer - maxOpenConnections: - type: integer - name: - type: string - type: object - dockerImage: - type: string - enabled: - type: boolean - method: - type: string - path: - type: string - role: - type: string - token: - type: string - url: - type: string - type: object type: object status: properties: diff --git a/charts/patroni-core/templates/_helpers.tpl b/charts/patroni-core/templates/_helpers.tpl index ea21ba54..a636846b 100644 --- a/charts/patroni-core/templates/_helpers.tpl +++ b/charts/patroni-core/templates/_helpers.tpl @@ -92,38 +92,10 @@ capabilities: {{- end }} {{- end -}} -{{- define "patroni-core-operator.vaultEnvs" }} -{{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - - name: VAULT_ADDR - value: {{ default "http://vault-service.vault:8200" .Values.vaultRegistration.url }} - - name: VAULT_TOKEN - valueFrom: - secretKeyRef: - name: vault-secret - key: token - - name: PAAS_PLATFORM - value: {{ default "kubernetes" .Values.vaultRegistration.paasPlatform }} - - name: PAAS_VERSION - value: {{ default "1.14" .Values.vaultRegistration.paasVersion | quote }} - - name: OPENSHIFT_SERVER - {{- if and .Values.CLOUD_PROTOCOL .Values.CLOUD_API_HOST .Values.CLOUD_API_PORT }} - value: {{ printf "%s://%s:%v" .Values.CLOUD_PROTOCOL .Values.CLOUD_API_HOST .Values.CLOUD_API_PORT }} - {{- else }} - value: "https://kubernetes.default:443" - {{- end }} -{{- else }} - - name: PAAS_PLATFORM - value: "kubernetes" - - name: PAAS_VERSION - value: "1.14" - - name: OPENSHIFT_SERVER - value: "https://kubernetes.default:443" -{{- end }} -{{- end }} {{- define "find_image" -}} {{- $image := .default -}} - + {{ printf "%s" $image }} {{- end -}} @@ -189,4 +161,4 @@ Init container section for postgres-operator {{- end }} {{- define "patroni-tests.monitoredImages" -}} -{{- end -}} \ No newline at end of file +{{- end -}} diff --git a/charts/patroni-core/templates/cr.yaml b/charts/patroni-core/templates/cr.yaml index d27c9845..c9b8fedc 100644 --- a/charts/patroni-core/templates/cr.yaml +++ b/charts/patroni-core/templates/cr.yaml @@ -11,8 +11,8 @@ spec: enabled: true names: {{- range $i, $v := .Values.privateRegistry.secrets }} - - {{ $v.name }} - {{- end }} + - {{ $v.name }} + {{- end }} {{- end }} installationTimestamp: {{ now | unixEpoch | quote }} {{ if .Values.serviceAccount.create }} @@ -175,22 +175,6 @@ spec: {{ if .Values.consulRegistration }} consulRegistration: {{ toYaml .Values.consulRegistration | indent 4 }} -{{ end }} -{{ if .Values.vaultRegistration }} - vaultRegistration: - dockerImage: {{ template "find_image" (dict "deployName" "vault_env" "SERVICE_NAME" "vault_env" "vals" .Values "default" .Values.vaultRegistration.dockerImage) }} - enabled: {{ .Values.vaultRegistration.enabled }} - path: {{ .Values.vaultRegistration.path | default .Release.Namespace }} - {{- if .Values.vaultRegistration.url }} - url: {{ .Values.vaultRegistration.url }} - {{- end }} - dbEngine: - enabled: {{ .Values.vaultRegistration.dbEngine.enabled }} - name: {{ .Values.vaultRegistration.dbEngine.name | default (printf "%s_%s_postgresql" .Values.CLOUD_PUBLIC_HOST .Release.Namespace) }} - maxOpenConnections: {{ .Values.vaultRegistration.dbEngine.maxOpenConnections | default 5 }} - maxIdleConnections: {{ .Values.vaultRegistration.dbEngine.maxIdleConnections | default 5 }} - maxConnectionLifetime: {{ .Values.vaultRegistration.dbEngine.maxConnectionLifetime | default "5s" }} - {{ end }} {{ if .Values.pgBackRest }} pgBackRest: @@ -286,4 +270,4 @@ majorUpgrade: initDbParams: {{ .Values.patroni.majorUpgrade.initDbParams }} {{- end }} dockerUpgradeImage: {{ template "find_image" (dict "deployName" "pg_upgrade" "SERVICE_NAME" "pg_upgrade" "vals" .Values "default" .Values.patroni.majorUpgrade.dockerUpgradeImage) }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/charts/patroni-core/templates/secrets/vault-secret.yaml b/charts/patroni-core/templates/secrets/vault-secret.yaml deleted file mode 100644 index d8890d5d..00000000 --- a/charts/patroni-core/templates/secrets/vault-secret.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} -apiVersion: v1 -kind: Secret -metadata: - labels: - app: postgres-operator - name: vault-secret - {{ include "kubernetes.labels" . | nindent 4 }} - name: vault-secret -data: - {{- if .Values.VAULT_TOKEN }} - token: {{ .Values.VAULT_TOKEN | b64enc }} - {{- else }} - token: {{ default "#" .Values.vaultRegistration.token | b64enc }} - {{- end }} -type: Opaque -{{- end }} diff --git a/charts/patroni-core/values.yaml b/charts/patroni-core/values.yaml index fec9239a..96d1c7e4 100644 --- a/charts/patroni-core/values.yaml +++ b/charts/patroni-core/values.yaml @@ -17,8 +17,8 @@ privateRegistry: create: false # registry: ghcr.io/netcracker # username: - # password: - # email: + # password: + # email: global: cloudIntegrationEnabled: true @@ -35,7 +35,7 @@ operatorInit: memory: 128Mi requests: cpu: 50m - memory: 128Mi + memory: 128Mi ## This section describes values for postgres-operator deployment operator: @@ -55,17 +55,6 @@ operator: # Field for priority of the pod # priorityClassName: "high-priority" -vaultRegistration: - dockerImage: banzaicloud/vault-env:1.5.0 - enabled: false - # path: /postgres - # url: http://localhost:8200 - # token: s.0il9o9kHeVmzgEhkBP6KqZBq - # paasPlatform: "kubernetes" - # paasVersion: "1.14" - dbEngine: - enabled: false -# name: "postgresql" policies: tolerations: diff --git a/charts/patroni-services/crds/qubership.org_patroniservices.yaml b/charts/patroni-services/crds/qubership.org_patroniservices.yaml index 62ff121c..fd6692ee 100644 --- a/charts/patroni-services/crds/qubership.org_patroniservices.yaml +++ b/charts/patroni-services/crds/qubership.org_patroniservices.yaml @@ -8645,37 +8645,6 @@ spec: host: type: string type: object - vaultRegistration: - properties: - dbEngine: - description: Vault DbEngine configuration - properties: - enabled: - type: boolean - maxConnectionLifetime: - type: string - maxIdleConnections: - type: integer - maxOpenConnections: - type: integer - name: - type: string - type: object - dockerImage: - type: string - enabled: - type: boolean - method: - type: string - path: - type: string - role: - type: string - token: - type: string - url: - type: string - type: object type: object status: description: PatroniServicesStatus defines the observed state of PatroniServices diff --git a/charts/patroni-services/templates/_helpers.tpl b/charts/patroni-services/templates/_helpers.tpl index 7e53fbb0..fcc83b7e 100644 --- a/charts/patroni-services/templates/_helpers.tpl +++ b/charts/patroni-services/templates/_helpers.tpl @@ -105,103 +105,6 @@ Create the name of the service account to use {{- end -}} {{- end -}} -{{/* -Vault operator envs -*/}} -{{- define "postgres-operator.vaultEnvs" }} -{{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - - name: VAULT_ADDR - value: {{ default "http://vault-service.vault:8200" .Values.vaultRegistration.url }} - - name: VAULT_TOKEN - valueFrom: - secretKeyRef: - name: vault-secret-services - key: token - - name: PAAS_PLATFORM - value: {{ default "kubernetes" .Values.vaultRegistration.paasPlatform }} - - name: PAAS_VERSION - value: {{ default "1.14" .Values.vaultRegistration.paasVersion | quote }} - - name: OPENSHIFT_SERVER - {{- if and .Values.CLOUD_PROTOCOL .Values.CLOUD_API_HOST .Values.CLOUD_API_PORT }} - value: {{ printf "%s://%s:%v" .Values.CLOUD_PROTOCOL .Values.CLOUD_API_HOST .Values.CLOUD_API_PORT }} - {{- else }} - value: "https://kubernetes.default:443" - {{- end }} -{{- else }} - - name: PAAS_PLATFORM - value: "kubernetes" - - name: PAAS_VERSION - value: "1.14" - - name: OPENSHIFT_SERVER - value: "https://kubernetes.default:443" -{{- end }} -{{- end }} - -{{/* -Vault env variables for DBaaS -*/}} -{{- define "postgres-dbaas.vaultEnvs" }} -{{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - {{- if and .Values.vaultRegistration.enabled ( not .Values.vaultRegistration.dbEngine.enabled) }} - - name: POSTGRES_ADMIN_PASSWORD - value: {{ printf "vault:%s/postgres-credentials#password" ( .Values.vaultRegistration.path | default .Release.Namespace ) }} - - name: POSTGRES_ADMIN_USERNAME - value: {{ printf "vault:%s/postgres-credentials#username" ( .Values.vaultRegistration.path | default .Release.Namespace ) }} - {{- else }} - - name: POSTGRES_ADMIN_PASSWORD - value: {{ printf "vault:database/static-creds/%s_%s_patroni-sa_postgres#password" .Values.CLOUD_PUBLIC_HOST .Release.Namespace }} - - name: POSTGRES_ADMIN_USERNAME - value: {{ printf "vault:database/static-creds/%s_%s_patroni-sa_postgres#username" .Values.CLOUD_PUBLIC_HOST .Release.Namespace }} - {{- end }} - - name: VAULT_SKIP_VERIFY - value: "True" - - name: VAULT_ADDR - value: {{ .Values.vaultRegistration.url }} - - name: VAULT_PATH - value: {{ printf "%s_%s" .Values.CLOUD_PUBLIC_HOST .Release.Namespace }} - - name: VAULT_ROLE - value: {{ .Values.serviceAccount.name }} - - name: VAULT_IGNORE_MISSING_SECRETS - value: "True" - - name: VAULT_ENV_PASSTHROUGH - value: "VAULT_ADDR,VAULT_ROLE,VAULT_SKIP_VERIFY,VAULT_PATH,VAULT_ENABLED" -{{- else }} - - name: POSTGRES_ADMIN_PASSWORD - valueFrom: - secretKeyRef: - name: postgres-credentials - key: password - - name: POSTGRES_ADMIN_USER - valueFrom: - secretKeyRef: - name: postgres-credentials - key: username -{{- end }} -{{- end }} - -{{/* -Vault env variables for DBaaS -*/}} -{{- define "postgres-dbaas.vaultEnvsReg" }} -{{- if .Values.vaultRegistration.enabled }} - - name: DBAAS_AGGREGATOR_REGISTRATION_USERNAME - value: {{ printf "vault:%s/dbaas-aggregator-registration-credentials#username" ( .Values.vaultRegistration.path | default .Release.Namespace ) }} - - name: DBAAS_AGGREGATOR_REGISTRATION_PASSWORD - value: {{ printf "vault:%s/dbaas-aggregator-registration-credentials#password" ( .Values.vaultRegistration.path | default .Release.Namespace ) }} -{{- else }} - - 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 }} -{{- end }} - {{- define "find_image" -}} {{- $image := .default -}} diff --git a/charts/patroni-services/templates/cr.yaml b/charts/patroni-services/templates/cr.yaml index 1c1a5f3e..47dad35e 100644 --- a/charts/patroni-services/templates/cr.yaml +++ b/charts/patroni-services/templates/cr.yaml @@ -138,22 +138,6 @@ spec: {{ if .Values.consulRegistration }} consulRegistration: {{ toYaml .Values.consulRegistration | indent 4 }} -{{ end }} -{{ if .Values.vaultRegistration }} - vaultRegistration: - dockerImage: {{ template "find_image" (dict "deployName" "vault_env" "SERVICE_NAME" "vault_env" "vals" .Values "default" .Values.vaultRegistration.dockerImage) }} - enabled: {{ .Values.vaultRegistration.enabled }} - path: {{ .Values.vaultRegistration.path | default .Release.Namespace }} - {{- if .Values.vaultRegistration.url }} - url: {{ .Values.vaultRegistration.url }} - {{- end }} - dbEngine: - enabled: {{ .Values.vaultRegistration.dbEngine.enabled }} - name: {{ .Values.vaultRegistration.dbEngine.name | default (printf "%s_%s_postgresql" .Values.CLOUD_PUBLIC_HOST .Release.Namespace) }} - maxOpenConnections: {{ .Values.vaultRegistration.dbEngine.maxOpenConnections | default 5 }} - maxIdleConnections: {{ .Values.vaultRegistration.dbEngine.maxIdleConnections | default 5 }} - maxConnectionLifetime: {{ .Values.vaultRegistration.dbEngine.maxConnectionLifetime | default "5s" }} - {{ end }} {{ if .Values.externalDataBase }} externalDataBase: diff --git a/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml b/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml index acb4f69c..ea123e36 100644 --- a/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml +++ b/charts/patroni-services/templates/dbaas/dbaas-adapter-deployment.yaml @@ -52,11 +52,6 @@ spec: configMap: name: dbaas-postgres-adapter.extensions-config defaultMode: 420 - {{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - - name: vault-env - emptyDir: - medium: Memory - {{- end }} {{- if not .Values.externalDataBase }} {{- if and .Values.tls .Values.tls.enabled }} - name: tls-cert @@ -66,55 +61,19 @@ spec: {{- end }} {{- end }} initContainers: - {{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - - name: copy-vault-env - image: {{ template "find_image" (dict "deployName" "vault_env" "SERVICE_NAME" "vault_env" "vals" .Values "default" .Values.vaultRegistration.dockerImage) }} - command: - - sh - - '-c' - - cp /usr/local/bin/vault-env /vault/ - resources: - limits: - cpu: 50m - memory: 50Mi - requests: - cpu: 50m - memory: 50Mi - securityContext: - {{- include "restricted.globalContainerSecurityContext" . | nindent 12 }} - volumeMounts: - - name: vault-env - mountPath: /vault - terminationMessagePath: /dev/termination-log - terminationMessagePolicy: File - imagePullPolicy: IfNotPresent - {{- end }} - name: init-dbaas-postgres-adapter image: {{ template "find_image" (dict "deployName" "postgresql_dbaas_adapter" "SERVICE_NAME" "postgresql_dbaas_adapter" "vals" .Values "default" .Values.dbaas.dockerImage) }} imagePullPolicy: Always - {{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - command: - - /vault/vault-env - {{- end }} args: - {{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - - sh - - /usr/local/bin/entrypoint - {{- end }} - init securityContext: {{- include "restricted.globalContainerSecurityContext" . | nindent 12 }} volumeMounts: - name: dbaas-default-extensions-mount mountPath: /app/extensions - {{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - - name: vault-env - mountPath: /vault - {{- end }} resources: {{ .Values.dbaas.resources | toYaml | indent 12 }} env: - {{- template "postgres-dbaas.vaultEnvs" . }} - name: POSTGRES_DATABASE value: {{ default "postgres" .Values.dbaas.dbName }} - name: POSTGRES_HOST @@ -144,15 +103,6 @@ spec: containers: - name: dbaas-postgres-adapter image: {{ template "find_image" (dict "deployName" "postgresql_dbaas_adapter" "SERVICE_NAME" "postgresql_dbaas_adapter" "vals" .Values "default" .Values.dbaas.dockerImage) }} - {{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - command: - - /vault/vault-env - {{- end }} - args: - {{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - - sh - - /usr/local/bin/entrypoint - {{- end }} ports: - name: web containerPort: 8080 @@ -160,10 +110,8 @@ spec: securityContext: {{- include "restricted.globalContainerSecurityContext" . | nindent 12 }} env: -{{- template "postgres-dbaas.vaultEnvs" . }} - name: POSTGRES_DATABASE value: {{ default "postgres" .Values.dbaas.dbName }} -{{- template "postgres-dbaas.vaultEnvsReg" . }} - name: DBAAS_ADAPTER_ADDRESS value: {{ default (printf "http://dbaas-postgres-adapter.%s:8080" .Release.Namespace) .Values.dbaas.adapter.address }} - name: DBAAS_AGGREGATOR_REGISTRATION_ADDRESS @@ -204,15 +152,7 @@ spec: - name: EXTENSIONS value: {{ join "," .Values.dbaas.extensions }} {{- end }} - {{- if or .Values.dbaas.vaultIntegration.enabled }} - - name: VAULT_ENABLED - value: {{ default "false" .Values.dbaas.vaultIntegration.enabled | quote }} - - name: VAULT_ROTATION_PERIOD - value: {{ default "86400" .Values.dbaas.vaultIntegration.rotationPeriod | quote }} - - name: VAULT_DB_ENGINE_NAME - value: {{ .Values.vaultRegistration.dbEngine.name | default (printf "%s_%s_postgresql" .Values.CLOUD_PUBLIC_HOST .Release.Namespace) }} - {{- end }} - {{ if .Values.externalDataBase }} + {{ if .Values.externalDataBase }} - name: EXTERNAL_POSTGRESQL value: {{ default "" .Values.externalDataBase.type }} {{- end }} @@ -229,10 +169,6 @@ spec: mountPath: /app/config - name: dbaas-default-extensions-mount mountPath: /app/extensions - {{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} - - name: vault-env - mountPath: /vault - {{- end }} {{- if not .Values.externalDataBase }} {{- if and .Values.tls .Values.tls.enabled }} - name: tls-cert @@ -273,8 +209,8 @@ spec: {{- if .Values.privateRegistry.enabled }} imagePullSecrets: {{- range $i, $v := .Values.privateRegistry.secrets }} - - name: {{ $v.name }} - {{- end }} + - name: {{ $v.name }} + {{- end }} {{- end }} tolerations: {{- range $tKey, $t := .Values.policies.tolerations }} diff --git a/charts/patroni-services/templates/deployment.yaml b/charts/patroni-services/templates/deployment.yaml index 9feb52dc..a77ac9a5 100644 --- a/charts/patroni-services/templates/deployment.yaml +++ b/charts/patroni-services/templates/deployment.yaml @@ -97,7 +97,6 @@ spec: valueFrom: fieldRef: fieldPath: status.hostIP - {{- if not ( and .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled) }} - name: PG_ADMIN_PASSWORD valueFrom: secretKeyRef: @@ -113,7 +112,6 @@ spec: secretKeyRef: name: replicator-credentials key: password - {{- end }} - name: GLOBAL_SECURITY_CONTEXT value: {{ .Values.GLOBAL_SECURITY_CONTEXT | quote | default ("true" | quote) }} - name: CLOUD_PUBLIC_HOST diff --git a/charts/patroni-services/templates/secrets/vault-secret.yaml b/charts/patroni-services/templates/secrets/vault-secret.yaml deleted file mode 100644 index 7d624fbf..00000000 --- a/charts/patroni-services/templates/secrets/vault-secret.yaml +++ /dev/null @@ -1,17 +0,0 @@ -{{- if or .Values.vaultRegistration.enabled .Values.vaultRegistration.dbEngine.enabled }} -apiVersion: v1 -kind: Secret -metadata: - labels: - app: postgres-operator - name: postgres-operator - {{ include "kubernetes.labels" . | nindent 4 }} - name: vault-secret-services -data: - {{- if .Values.VAULT_TOKEN }} - token: {{ .Values.VAULT_TOKEN | b64enc }} - {{- else }} - token: {{ default "#" .Values.vaultRegistration.token | b64enc }} - {{- end }} -type: Opaque -{{- end }} diff --git a/charts/patroni-services/values.yaml b/charts/patroni-services/values.yaml index d20416d8..d1f068c1 100644 --- a/charts/patroni-services/values.yaml +++ b/charts/patroni-services/values.yaml @@ -66,17 +66,6 @@ operator: # checkTimeout: "1s" # deregisterAfter: "100s" -vaultRegistration: - dockerImage: banzaicloud/vault-env:1.5.0 - enabled: false - # path: /postgres - # url: http://localhost:8200 - # token: vaultToken - # paasPlatform: "kubernetes" - # paasVersion: "1.14" - dbEngine: - enabled: false -# name: "postgresql" policies: tolerations: @@ -304,11 +293,6 @@ dbaas: adapter: username: "dbaas-aggregator" password: "dbaas-aggregator" - vaultIntegration: - enabled: false - address: "http://vault-service.vault:8200" - role: "postgres-sa" - rotationPeriod: 86400 # extensions: # - "postgres_fdw" # - "pgcrypto" diff --git a/cmd/pgskipper-operator/main.go b/cmd/pgskipper-operator/main.go index 4f458bd7..ea91aa67 100644 --- a/cmd/pgskipper-operator/main.go +++ b/cmd/pgskipper-operator/main.go @@ -20,7 +20,6 @@ import ( site "github.com/Netcracker/pgskipper-operator/pkg/disasterrecovery" "github.com/Netcracker/pgskipper-operator/pkg/helper" - "github.com/Netcracker/pgskipper-operator/pkg/vault" "github.com/Netcracker/qubership-credential-manager/pkg/hook" "net/http" @@ -118,7 +117,6 @@ func main() { } //Init section - vault.Init() site.InitDRManager() } //+kubebuilder:scaffold:builder diff --git a/controllers/patroni_core_controller.go b/controllers/patroni_core_controller.go index 9b575333..14614bc9 100644 --- a/controllers/patroni_core_controller.go +++ b/controllers/patroni_core_controller.go @@ -32,7 +32,6 @@ import ( "github.com/Netcracker/pgskipper-operator/pkg/scheduler" "github.com/Netcracker/pgskipper-operator/pkg/upgrade" utils "github.com/Netcracker/pgskipper-operator/pkg/util" - "github.com/Netcracker/pgskipper-operator/pkg/vault" "go.uber.org/zap" "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -68,7 +67,6 @@ type PatroniCoreReconciler struct { Scheme *runtime.Scheme helper *helper.PatroniHelper upgrade *upgrade.Upgrade - vaultClient *vault.Client cluster qubershipv1.PatroniCore appsCluster appsv1.PatroniServices namespace string @@ -90,7 +88,6 @@ func NewPatroniCoreReconciler(client client.Client, scheme *runtime.Scheme) *Pat cluster: qubershipv1.PatroniCore{}, appsCluster: appsv1.PatroniServices{}, upgrade: upgrade.Init(client), - vaultClient: vault.NewClient(), namespace: namespace, logger: *logger, resVersions: map[string]string{}, @@ -246,8 +243,6 @@ func (pr *PatroniCoreReconciler) Reconcile(ctx context.Context, request ctrl.Req scheduler.StopAndClear() - // update Cr for Vault client - pr.vaultClient.UpdateCr(cr.Kind) if err := pr.reconcilePatroniCoreCluster(cr); err != nil { switch err.(type) { case *deployerrors.TestsError: @@ -418,7 +413,7 @@ func (pr *PatroniCoreReconciler) reconcilePatroni(cr *qubershipv1.PatroniCore) e return nil } } - pRec := reconciler.NewPatroniReconciler(cr, pr.helper, pr.vaultClient, pr.upgrade, pr.Scheme, utils.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName)) + pRec := reconciler.NewPatroniReconciler(cr, pr.helper, pr.upgrade, pr.Scheme, utils.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName)) if err := pRec.Reconcile(); err != nil { pr.logger.Error("Can not synchronize desired Patroni state to cluster", zap.Error(err)) return err @@ -465,8 +460,6 @@ func (pr *PatroniCoreReconciler) AddExcludeLabelToCm(c client.Client, cmName str func (pr *PatroniCoreReconciler) createTestsPods(cr *qubershipv1.PatroniCore) error { if cr.Spec.IntegrationTests != nil { integrationTestsPod := deployment.NewCoreIntegrationTests(cr, utils.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName)) - // Vault Section - pr.vaultClient.ProcessPodVaultSection(integrationTestsPod, reconciler.Secrets) state, err := utils.GetPodPhase(integrationTestsPod) if err != nil { return err diff --git a/controllers/postgresservice_controller.go b/controllers/postgresservice_controller.go index eb80d9f0..cdefdf60 100644 --- a/controllers/postgresservice_controller.go +++ b/controllers/postgresservice_controller.go @@ -32,7 +32,6 @@ import ( "github.com/Netcracker/pgskipper-operator/pkg/upgrade" utils "github.com/Netcracker/pgskipper-operator/pkg/util" "github.com/Netcracker/pgskipper-operator/pkg/util/constants" - "github.com/Netcracker/pgskipper-operator/pkg/vault" "go.uber.org/zap" "k8s.io/apimachinery/pkg/api/errors" "sigs.k8s.io/controller-runtime/pkg/reconcile" @@ -66,7 +65,6 @@ type PostgresServiceReconciler struct { Scheme *runtime.Scheme helper *helper.Helper upgrade *upgrade.Upgrade - vaultClient *vault.Client cluster qubershipv1.PatroniServices namespace string errorCounter int @@ -103,7 +101,6 @@ func NewPostgresServiceReconciler(client client.Client, scheme *runtime.Scheme) helper: helper.GetHelper(), cluster: qubershipv1.PatroniServices{}, upgrade: upgrade.Init(client), - vaultClient: vault.NewClient(), namespace: namespace, logger: *logger, resVersions: map[string]string{}, @@ -234,17 +231,6 @@ func (r *PostgresServiceReconciler) Reconcile(ctx context.Context, request ctrl. scheduler.StopAndClear() - // update Cr for Vault client - r.vaultClient.UpdateCr(cr.Kind) - - // update Postgres Password - vaultRolesExist := r.vaultClient.IsVaultRolesExist() - if vaultRolesExist { - if err := r.vaultClient.UpdatePgClientPass(); err != nil { - return reconcile.Result{}, err - } - } - if err := r.reconcilePostgresServiceCluster(cr); err != nil { switch err.(type) { case *deployerrors.TestsError: @@ -306,11 +292,6 @@ func (r *PostgresServiceReconciler) Reconcile(ctx context.Context, request ctrl. return reconcile.Result{RequeueAfter: time.Minute}, err } - // Enable rotation controller - if cr.Spec.VaultRegistration.DbEngine.Enabled { - vault.EnableRotationController(r.vaultClient) - } - if err := r.helper.UpdatePGService(); err != nil { r.logger.Error("error during update of pg services", zap.Error(err)) return reconcile.Result{RequeueAfter: time.Minute}, err @@ -470,19 +451,12 @@ func (r *PostgresServiceReconciler) reconcilePostgresServiceCluster(cr *qubershi r.logger.Info("Tests Spec is empty, skipping reconciliation") } - // And delete secrets, that uploaded to vault - if err := r.vaultClient.DeleteSecret(vault.DeletionLabels); err != nil { - r.logger.Error("Cannot delete secret", zap.Error(err)) - return err - } return nil } func (r *PostgresServiceReconciler) createTestsPods(cr *qubershipv1.PatroniServices) error { if cr.Spec.IntegrationTests != nil { integrationTestsPod := deployment.NewIntegrationTestsPod(cr, utils.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName)) - // Vault Section - r.vaultClient.ProcessPodVaultSection(integrationTestsPod, reconciler.Secrets) state, err := utils.GetPodPhase(integrationTestsPod) if err != nil { return err @@ -533,7 +507,7 @@ func (r *PostgresServiceReconciler) createTestsPods(cr *qubershipv1.PatroniServi func (r *PostgresServiceReconciler) reconcileBackupDaemon(cr *qubershipv1.PatroniServices) error { r.logger.Info("Backup Daemon Spec is not empty, proceeding with reconcile") - bRec := reconciler.NewBackupDaemonReconciler(cr, r.helper, r.vaultClient, utils.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName)) + bRec := reconciler.NewBackupDaemonReconciler(cr, r.helper, utils.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName)) if err := bRec.Reconcile(); err != nil { r.logger.Error("Can not synchronize Backup Daemon state to cluster", zap.Error(err)) return err @@ -543,7 +517,7 @@ func (r *PostgresServiceReconciler) reconcileBackupDaemon(cr *qubershipv1.Patron func (r *PostgresServiceReconciler) reconcileMetricCollector(cr *qubershipv1.PatroniServices) error { r.logger.Info("Metric Collector Spec is not empty, proceeding with reconcile") - mcRec := reconciler.NewMetricCollectorReconciler(cr, r.helper, r.vaultClient, r.Scheme, utils.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName)) + mcRec := reconciler.NewMetricCollectorReconciler(cr, r.helper, r.Scheme, utils.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName)) if err := mcRec.Reconcile(); err != nil { r.logger.Error("Can not synchronize Metric Collector state to cluster", zap.Error(err)) return err diff --git a/docs/public/installation.md b/docs/public/installation.md index 97aa5a94..3ab9a7d7 100644 --- a/docs/public/installation.md +++ b/docs/public/installation.md @@ -1,7 +1,6 @@ * [Prerequisites](#prerequisites) * [Common](#common) * [Disaster Recovery](#disaster-recovery) - * [Vault](#vault) * [Kubernetes](#kubernetes) * [Openshift](#openshift) * [AWS](#aws) @@ -479,8 +478,6 @@ This sections describes all possible deploy parameters for PostgreSQL DBaaS Adap | dbaas.adapter.username | string | no | dbaas-aggregator | Specifies the username for DBaaS Postgres Adapter basic authentication. | | dbaas.adapter.password | string | no | dbaas-aggregator | Specifies the password for DBaaS Postgres Adapter basic authentication. | | dbaas.adapter.address | string | no | http://dbaas-adapter.:8080 | Specifies the address of DBaaS Adapter during registration in Aggregator. | -| dbaas.vaultIntegration.enabled | bool | no | false | Indicates whether to enable integration with Vault. | -| dbaas.vaultIntegration.rotationPeriod | string | no | 86400 | Specifies the DB password rotation period in seconds. | | dbaas.extensions | []string | no | n/a | Specifies the list of default extensions for created databases. | | dbaas.updateExtensions | bool | no | false | Specifies if default extensions should be created for existing databases. | | dbaas.apiVersion | string | no | v2 | Specifies the version of DBaaS API. | @@ -545,23 +542,6 @@ Postgres Operator allows register of PostgreSQL connection properties in Consul. | consulRegistration.deregisterAfter | string | yes | n/a | Specifies after which time Service will be de-registered from Consul. | -## vaultRegistration - -Postgres Operator allows store all Postgres Service credentials in Vault. By default, registration disabled. - -| Parameter | Type | Mandatory | Default value | Description | -|--------------------------------------------------|--------|-----------|------------------|-----------------------------------------------------------------------------------------------------------| -| vaultRegistration.enabled | bool | no | false | Indicates that Vault will be used as storage credentials. | -| vaultRegistration.path | string | no | | Specifies Vault path to key-value storage. | -| vaultRegistration.url | string | yes | n/a | Specifies url address to Vault service. | -| vaultRegistration.token | string | yes | n/a | Specifies token to Vault service. | -| vaultRegistration.paasPlatform | string | no | kubernetes | Specifies platform type. | -| vaultRegistration.dbEngine.enabled | bool | yes | false | Indicates that PostgreSQL engine enabled or not. | -| vaultRegistration.dbEngine.name | string | yes | postgresql | Specifies path name to Vault database Engine. | -| vaultRegistration.dbEngine.maxOpenConnections | int | no | 5 | Specifies the maximum number of open connections to the database. | -| vaultRegistration.dbEngine.maxIdleConnections | int | no | 5 | Specifies the maximum number of idle connections to the database. | -| vaultRegistration.dbEngine.maxConnectionLifetime | string | no | 5s | Specifies the maximum amount of time a connection may be reused. If <= 0s connections are reused forever. | - ## externalDataBase It's possible to use Postgres Operator with Managed DBs (Google CloudSQL, Azure Flexible PostgreSQL, Amazon Aurora PostgreSQL). diff --git a/go.mod b/go.mod index 7e0b6a80..8463bea1 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/uuid v1.6.0 github.com/hashicorp/consul/api v1.29.4 - github.com/hashicorp/vault/api v1.15.0 github.com/jackc/pgtype v1.14.3 github.com/jackc/pgx/v4 v4.18.3 github.com/operator-framework/operator-lib v0.15.0 @@ -73,7 +72,6 @@ require ( github.com/hashicorp/go-sockaddr v1.0.6 // indirect github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect - github.com/hashicorp/hcl v1.0.1-vault-5 // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/imdario/mergo v0.3.16 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect diff --git a/go.sum b/go.sum index 4ccbf496..8e5f5876 100644 --- a/go.sum +++ b/go.sum @@ -323,16 +323,12 @@ github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uG github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= -github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= -github.com/hashicorp/vault/api v1.15.0 h1:O24FYQCWwhwKnF7CuSqP30S51rTV7vz1iACXE/pj5DA= -github.com/hashicorp/vault/api v1.15.0/go.mod h1:+5YTO09JGn0u+b6ySD/LLVf8WkJCPLAL2Vkmrn2+CM8= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= diff --git a/pkg/reconciler/backup_daemon.go b/pkg/reconciler/backup_daemon.go index 6f64e178..d76e6508 100644 --- a/pkg/reconciler/backup_daemon.go +++ b/pkg/reconciler/backup_daemon.go @@ -29,7 +29,6 @@ import ( "github.com/Netcracker/pgskipper-operator/pkg/patroni" "github.com/Netcracker/pgskipper-operator/pkg/util" "github.com/Netcracker/pgskipper-operator/pkg/util/constants" - "github.com/Netcracker/pgskipper-operator/pkg/vault" "github.com/Netcracker/qubership-credential-manager/pkg/manager" "go.uber.org/zap" corev1 "k8s.io/api/core/v1" @@ -41,18 +40,16 @@ const ( ) type BackupDaemonReconciler struct { - cr *qubershipv1.PatroniServices - helper *helper.Helper - vaultClient *vault.Client - cluster *patroniv1.PatroniClusterSettings + cr *qubershipv1.PatroniServices + helper *helper.Helper + cluster *patroniv1.PatroniClusterSettings } -func NewBackupDaemonReconciler(cr *qubershipv1.PatroniServices, helper *helper.Helper, vaultClient *vault.Client, cluster *patroniv1.PatroniClusterSettings) *BackupDaemonReconciler { +func NewBackupDaemonReconciler(cr *qubershipv1.PatroniServices, helper *helper.Helper, cluster *patroniv1.PatroniClusterSettings) *BackupDaemonReconciler { return &BackupDaemonReconciler{ - cr: cr, - helper: helper, - vaultClient: vaultClient, - cluster: cluster, + cr: cr, + helper: helper, + cluster: cluster, } } @@ -101,9 +98,6 @@ func (r *BackupDaemonReconciler) Reconcile() error { return err } - // Vault Section - r.vaultClient.ProcessVaultSection(backupDaemonDeployment, vault.BackuperEntrypoint, Secrets) - //Adding securityContexts backupDaemonDeployment.Spec.Template.Spec.Containers[0].SecurityContext = util.GetDefaultSecurityContext() diff --git a/pkg/reconciler/metric_collector.go b/pkg/reconciler/metric_collector.go index 8f33b92a..9d8ea8cd 100644 --- a/pkg/reconciler/metric_collector.go +++ b/pkg/reconciler/metric_collector.go @@ -26,7 +26,6 @@ import ( "github.com/Netcracker/pgskipper-operator/pkg/helper" opUtil "github.com/Netcracker/pgskipper-operator/pkg/util" "github.com/Netcracker/pgskipper-operator/pkg/util/constants" - "github.com/Netcracker/pgskipper-operator/pkg/vault" "github.com/Netcracker/qubership-credential-manager/pkg/manager" "go.uber.org/zap" corev1 "k8s.io/api/core/v1" @@ -36,20 +35,18 @@ import ( var monitoringSecrets = []string{"monitoring-user"} type MetricCollectorReconciler struct { - cr *qubershipv1.PatroniServices - helper *helper.Helper - vaultClient *vault.Client - scheme *runtime.Scheme - cluster *patroniv1.PatroniClusterSettings + cr *qubershipv1.PatroniServices + helper *helper.Helper + scheme *runtime.Scheme + cluster *patroniv1.PatroniClusterSettings } -func NewMetricCollectorReconciler(cr *qubershipv1.PatroniServices, helper *helper.Helper, vaultClient *vault.Client, scheme *runtime.Scheme, cluster *patroniv1.PatroniClusterSettings) *MetricCollectorReconciler { +func NewMetricCollectorReconciler(cr *qubershipv1.PatroniServices, helper *helper.Helper, scheme *runtime.Scheme, cluster *patroniv1.PatroniClusterSettings) *MetricCollectorReconciler { return &MetricCollectorReconciler{ - cr: cr, - helper: helper, - vaultClient: vaultClient, - scheme: scheme, - cluster: cluster, + cr: cr, + helper: helper, + scheme: scheme, + cluster: cluster, } } @@ -70,16 +67,6 @@ func (r *MetricCollectorReconciler) Reconcile() error { } } - pgSecret, err := r.helper.GetSecret(reconciler.MetricCollectorUserCredentials) - if err != nil { - return err - } - - // Process vault role secret - if err := r.vaultClient.ProcessRoleSecret(pgSecret); err != nil { - return err - } - externalDatabase := cr.Spec.ExternalDataBase != nil // apply deployment @@ -92,7 +79,7 @@ func (r *MetricCollectorReconciler) Reconcile() error { } // Add Secret Hash - err = manager.AddCredHashToPodTemplate(credentials.PostgresSecretNames, &monitoringDeployment.Spec.Template) + err := manager.AddCredHashToPodTemplate(credentials.PostgresSecretNames, &monitoringDeployment.Spec.Template) if err != nil { logger.Error(fmt.Sprintf("can't add secret HASH to annotations for %s", monitoringDeployment.Name), zap.Error(err)) return err @@ -106,8 +93,6 @@ func (r *MetricCollectorReconciler) Reconcile() error { logger.Info("Policies is not empty, setting them to Monitoring Agent Deployment") monitoringDeployment.Spec.Template.Spec.Tolerations = cr.Spec.Policies.Tolerations } - // Vault Section - r.vaultClient.ProcessVaultSection(monitoringDeployment, vault.MetricEntrypoint, append(Secrets, monitoringSecrets...)) if externalDatabase && isExtTypeSupported(cr.Spec.ExternalDataBase.Type) { logger.Info("External DB section is not empty, proceeding with env configuration") diff --git a/pkg/reconciler/patroni.go b/pkg/reconciler/patroni.go index 026a4a69..625c4ec9 100644 --- a/pkg/reconciler/patroni.go +++ b/pkg/reconciler/patroni.go @@ -32,7 +32,6 @@ import ( "github.com/Netcracker/pgskipper-operator/pkg/queryexporter" "github.com/Netcracker/pgskipper-operator/pkg/upgrade" opUtil "github.com/Netcracker/pgskipper-operator/pkg/util" - "github.com/Netcracker/pgskipper-operator/pkg/vault" "github.com/Netcracker/qubership-credential-manager/pkg/manager" "go.uber.org/zap" corev1 "k8s.io/api/core/v1" @@ -54,22 +53,20 @@ var commands = []string{ } type PatroniReconciler struct { - cr *v1.PatroniCore - helper *helper.PatroniHelper - vaultClient *vault.Client - upgrade *upgrade.Upgrade - scheme *runtime.Scheme - cluster *v1.PatroniClusterSettings + cr *v1.PatroniCore + helper *helper.PatroniHelper + upgrade *upgrade.Upgrade + scheme *runtime.Scheme + cluster *v1.PatroniClusterSettings } -func NewPatroniReconciler(cr *v1.PatroniCore, helper *helper.PatroniHelper, vaultClient *vault.Client, upgrade *upgrade.Upgrade, scheme *runtime.Scheme, cluster *v1.PatroniClusterSettings) *PatroniReconciler { +func NewPatroniReconciler(cr *v1.PatroniCore, helper *helper.PatroniHelper, upgrade *upgrade.Upgrade, scheme *runtime.Scheme, cluster *v1.PatroniClusterSettings) *PatroniReconciler { return &PatroniReconciler{ - cr: cr, - helper: helper, - vaultClient: vaultClient, - upgrade: upgrade, - scheme: scheme, - cluster: cluster, + cr: cr, + helper: helper, + upgrade: upgrade, + scheme: scheme, + cluster: cluster, } } @@ -130,17 +127,6 @@ func (r *PatroniReconciler) Reconcile() error { return err } - if err := r.vaultClient.ProcessRoleSecret(pgSecret); err != nil { - return err - } - } - - vaultRolesExist := r.vaultClient.IsVaultRolesExist() - - if vaultRolesExist { - if err := r.vaultClient.UpdatePgClientPass(); err != nil { - return err - } } // find possible deployments by pods @@ -308,10 +294,8 @@ func (r *PatroniReconciler) Reconcile() error { } } // Set replicator password from Secret - if !cr.Spec.VaultRegistration.DbEngine.Enabled { - if err := r.helper.SyncReplicatorPassword(r.cluster.PgHost); err != nil { - return err - } + if err := r.helper.SyncReplicatorPassword(r.cluster.PgHost); err != nil { + return err } // add necessary shared_preload_libraries and settings @@ -365,11 +349,6 @@ func (r *PatroniReconciler) Reconcile() error { return err } - // Activating Vault PostgreSQL plugin if it enabled - if err := r.vaultClient.PrepareDbEngine(vaultRolesExist, r.cluster); err != nil { - return err - } - if patroniSpec.Powa.Install { if err := powa.SetUpPOWA(r.cluster.PgHost); err != nil { return err @@ -465,7 +444,6 @@ func (r *PatroniReconciler) processPatroniStatefulset(cr *v1.PatroniCore, deploy return err } - vaultRolesExist := r.vaultClient.IsVaultRolesExist() patroniSpec := cr.Spec.Patroni pvc := storage.NewPvc(fmt.Sprintf("%s-data-%v", opUtil.GetPatroniClusterName(cr.Spec.Patroni.ClusterName), deploymentIdx), patroniSpec.Storage, deploymentIdx) if err := r.helper.ResourceManager.CreatePvcIfNotExists(pvc); err != nil { @@ -510,12 +488,6 @@ func (r *PatroniReconciler) processPatroniStatefulset(cr *v1.PatroniCore, deploy return err } - // Vault Section - // For DbEngine case this section processed later for patroni - if vaultRolesExist || (cr.Spec.VaultRegistration.Enabled && !cr.Spec.VaultRegistration.DbEngine.Enabled) { - r.vaultClient.ProcessVaultSectionStatefulset(patroniDeployment, vault.PatroniEntrypoint, Secrets) - } - if err := r.helper.ResourceManager.CreateOrUpdateStatefulset(patroniDeployment, true); err != nil { logger.Error(fmt.Sprintf("Cannot create or update deployment %s", patroniDeployment.Name), zap.Error(err)) return err @@ -625,11 +597,12 @@ func (r *PatroniReconciler) refreshDependCollationsVersion(pgClient *pgClient.Po // Get all collations with version mismatch for database func (r *PatroniReconciler) getCollationsForRefresh(pgClient *pgClient.PostgresClient, db string) ([]string, error) { + cForRefresh := make([]string, 0) rows, err := pgClient.QueryForDB(db, `SELECT distinct c.collname AS "Collation" FROM pg_depend d JOIN pg_collation c ON (refclassid = 'pg_collation'::regclass AND refobjid = c.oid) - WHERE c.collversion <> pg_collation_actual_version(c.oid) or c.collversion is null;`) + WHERE c.collversion <> pg_collation_actual_version(c.oid) or c.collversion is null;`) if err != nil { logger.Error(fmt.Sprintf("error during fetching collations for database %s", db)) return nil, err @@ -644,6 +617,7 @@ func (r *PatroniReconciler) getCollationsForRefresh(pgClient *pgClient.PostgresC } cForRefresh = append(cForRefresh, collation) } + return cForRefresh, nil } diff --git a/pkg/tests/tests.go b/pkg/tests/tests.go index 96fb897d..f3594d5b 100644 --- a/pkg/tests/tests.go +++ b/pkg/tests/tests.go @@ -21,43 +21,37 @@ import ( "github.com/Netcracker/pgskipper-operator/pkg/deployerrors" "github.com/Netcracker/pgskipper-operator/pkg/deployment" "github.com/Netcracker/pgskipper-operator/pkg/helper" - "github.com/Netcracker/pgskipper-operator/pkg/reconciler" "github.com/Netcracker/pgskipper-operator/pkg/util" opUtil "github.com/Netcracker/pgskipper-operator/pkg/util" - "github.com/Netcracker/pgskipper-operator/pkg/vault" "go.uber.org/zap" ) var logger = util.GetLogger() type Creator struct { - cr *qubershipv1.PatroniServices - helper *helper.Helper - vaultClient *vault.Client - cluster *patroniv1.PatroniClusterSettings + cr *qubershipv1.PatroniServices + helper *helper.Helper + cluster *patroniv1.PatroniClusterSettings } type PatroniCoreCreator struct { - cr *patroniv1.PatroniCore - helper *helper.PatroniHelper - vaultClient *vault.Client - cluster *patroniv1.PatroniClusterSettings + cr *patroniv1.PatroniCore + helper *helper.PatroniHelper + cluster *patroniv1.PatroniClusterSettings } -func NewCreator(cr *qubershipv1.PatroniServices, helper *helper.Helper, vaultClient *vault.Client) *Creator { +func NewCreator(cr *qubershipv1.PatroniServices, helper *helper.Helper) *Creator { return &Creator{ - cr: cr, - helper: helper, - vaultClient: vaultClient, + cr: cr, + helper: helper, } } -func NewCreatorPatroniCore(cr *patroniv1.PatroniCore, helper *helper.PatroniHelper, vaultClient *vault.Client, cluster *patroniv1.PatroniClusterSettings) *PatroniCoreCreator { +func NewCreatorPatroniCore(cr *patroniv1.PatroniCore, helper *helper.PatroniHelper, cluster *patroniv1.PatroniClusterSettings) *PatroniCoreCreator { return &PatroniCoreCreator{ - cr: cr, - helper: helper, - vaultClient: vaultClient, - cluster: cluster, + cr: cr, + helper: helper, + cluster: cluster, } } @@ -65,8 +59,6 @@ func (r *Creator) CreateTestsPods() error { cr := r.cr if cr.Spec.IntegrationTests != nil { integrationTestsPod := deployment.NewIntegrationTestsPod(cr, r.cluster) - // Vault Section - r.vaultClient.ProcessPodVaultSection(integrationTestsPod, reconciler.Secrets) state, err := opUtil.GetPodPhase(integrationTestsPod) if err != nil { return err diff --git a/pkg/vault/env_vault_manager.go b/pkg/vault/env_vault_manager.go deleted file mode 100644 index b726094e..00000000 --- a/pkg/vault/env_vault_manager.go +++ /dev/null @@ -1,368 +0,0 @@ -// Copyright 2024-2025 NetCracker Technology Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package vault - -import ( - "context" - "fmt" - "strings" - - "github.com/Netcracker/pgskipper-operator-core/pkg/util" - utilOp "github.com/Netcracker/pgskipper-operator/pkg/util" - "go.uber.org/zap" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - "k8s.io/apimachinery/pkg/api/resource" - "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" -) - -const ( - VaultPrefix = "vault:" - StaticCredsPath = "database/static-creds/" -) - -var ( - DeletionLabels = map[string]string{"set": "deletion"} - PatroniEntrypoint = []string{"/start.sh"} - BackuperEntrypoint = []string{"/opt/backup/start_backup_daemon.sh"} - MetricEntrypoint = []string{"-c", "/monitor/metrics"} - roleSecrets = []string{"replicator", "postgres", "monitoring-user"} -) - -func (c *Client) ProcessRoleSecret(secret *corev1.Secret) error { - logger.Info(fmt.Sprintf("{%v}", c.registration)) - if c.registration.Enabled && !c.registration.DbEngine.Enabled { - if err := c.MoveSecretToVault(secret); err == nil { - } else { - logger.Error(fmt.Sprintf("Cannot put secret %s to Vault", secret.Name), zap.Error(err)) - return err - } - } else if c.registration.DbEngine.Enabled { - if err := c.LabelSecretToDeletion(secret); err == nil { - } else { - logger.Error(fmt.Sprintf("Cannot label secret %s to deletion", secret.Name), zap.Error(err)) - return err - } - } - return nil -} - -func (c *Client) MoveSecretToVault(secret *corev1.Secret) error { - foundSecret := &corev1.Secret{} - sec := make(map[string]interface{}) - err := c.k8sClient.Get(context.TODO(), types.NamespacedName{ - Name: secret.Name, Namespace: secret.Namespace, - }, foundSecret) - if err != nil && errors.IsNotFound(err) { - logger.Info(fmt.Sprintf("Creating %s secret", secret.ObjectMeta.Name)) - return err - } - var vaultPath = c.registration.Path + "/" + secret.Name - logger.Info(fmt.Sprintf("Putting %s secret to Vault", secret.ObjectMeta.Name)) - postgresSecret := foundSecret.Data - for k, v := range postgresSecret { - sec[k] = string(v) - } - if err = c.vaultWriteSecret(vaultPath, sec); err != nil { - logger.Error("Vault write failed", zap.Error(err)) - return err - } - if err = c.LabelSecretToDeletion(secret); err != nil { - logger.Error("Labeling fault", zap.Error(err)) - return err - } - return nil -} - -func (c *Client) DeleteSecret(labelSelectors map[string]string) error { - logger.Info("Deleting labeled secrets from k8s") - secretList := &corev1.SecretList{} - listOpts := []client.ListOption{ - client.InNamespace(util.GetNameSpace()), - client.MatchingLabels(labelSelectors), - } - if err := c.k8sClient.List(context.Background(), secretList, listOpts...); err == nil { - for secretIdx := 0; secretIdx < len(secretList.Items); secretIdx++ { - vaultedSecret := secretList.Items[secretIdx] - logger.Info(fmt.Sprintf("Delete secret %v", vaultedSecret.ObjectMeta.Name)) - err = c.k8sClient.Delete(context.TODO(), &vaultedSecret) - if err != nil { - logger.Error(fmt.Sprintf("Error delete secret %v", vaultedSecret.ObjectMeta.Name), zap.Error(err)) - return err - } - } - } - return nil -} - -func (c *Client) LabelSecretToDeletion(secret *corev1.Secret) error { - foundSecret := &corev1.Secret{} - err := c.k8sClient.Get(context.TODO(), types.NamespacedName{ - Name: secret.Name, Namespace: secret.Namespace, - }, foundSecret) - if err != nil { - logger.Info(fmt.Sprintf("Cant find %s secret", secret.ObjectMeta.Name)) - return err - } - lables := foundSecret.GetLabels() - lables["set"] = "deletion" - foundSecret.SetLabels(lables) - _ = c.k8sClient.Update(context.Background(), foundSecret) - return nil -} - -func (c *Client) getEnvTemplateForVault(envName string, secretName string, secretKey string, vaultPath string) corev1.EnvVar { - if secretKey == "password" { - envValue := corev1.EnvVar{ - Name: envName, - Value: VaultPrefix + vaultPath + "/" + secretName + "#password", - } - return envValue - } else { - envValue := corev1.EnvVar{ - Name: envName, - Value: VaultPrefix + vaultPath + "/" + secretName + "#username", - } - return envValue - } -} - -func (c *Client) getEnvTemplateForVaultRole(envName string, secretName string, secretKey string) corev1.EnvVar { - if secretKey == "password" { - envValue := corev1.EnvVar{ - Name: envName, - Value: VaultPrefix + StaticCredsPath + GetVaultRoleName(secretName) + "#password", - } - return envValue - } else { - envValue := corev1.EnvVar{ - Name: envName, - Value: VaultPrefix + StaticCredsPath + GetVaultRoleName(secretName) + "#username", - } - return envValue - } -} - -func (c *Client) getVaultRegistrationEnv() []corev1.EnvVar { - envValue := []corev1.EnvVar{ - { - Name: "VAULT_SKIP_VERIFY", - Value: "True", - }, - { - Name: "VAULT_ADDR", - Value: c.registration.Url, - }, - { - Name: "VAULT_PATH", - Value: utilOp.GetServerHostname() + "_" + util.GetNameSpace(), - }, - { - Name: "VAULT_ROLE", - Value: utilOp.GetServiceAccount(), - }, - { - Name: "VAULT_IGNORE_MISSING_SECRETS", - Value: "False", - }, - { - Name: "VAULT_ENV_PASSTHROUGH", - Value: "VAULT_ADDR,VAULT_ROLE,VAULT_SKIP_VERIFY,VAULT_PATH,VAULT_ENABLED", - }, - } - return envValue -} - -func (c *Client) getInitContainerTemplateForVault() []corev1.Container { - initContainer := []corev1.Container{ - { - Name: "copy-vault-env", - Image: c.registration.DockerImage, - SecurityContext: utilOp.GetDefaultSecurityContext(), - VolumeMounts: []corev1.VolumeMount{ - { - MountPath: "/vault", - Name: "vault-env", - }, - }, - Command: []string{ - "sh", - "-c", - "cp /usr/local/bin/vault-env /vault/", - }, - Resources: corev1.ResourceRequirements{ - Requests: map[corev1.ResourceName]resource.Quantity{ - corev1.ResourceCPU: resource.MustParse("50m"), - corev1.ResourceMemory: resource.MustParse("50Mi"), - }, - Limits: map[corev1.ResourceName]resource.Quantity{ - corev1.ResourceCPU: resource.MustParse("50m"), - corev1.ResourceMemory: resource.MustParse("50Mi"), - }, - }, - }, - } - return initContainer -} - -func getVaultVolumeMount() corev1.VolumeMount { - volumeMount := corev1.VolumeMount{ - MountPath: "/vault", - Name: "vault-env", - } - return volumeMount -} - -func getVaultVolume() corev1.Volume { - volume := corev1.Volume{ - Name: "vault-env", - VolumeSource: corev1.VolumeSource{ - EmptyDir: &corev1.EmptyDirVolumeSource{ - Medium: "Memory", - }, - }, - } - return volume -} - -func getVaultCommand() []string { - command := []string{ - "/vault/vault-env", - } - return command -} - -func getVaultArgs(arguments []string) []string { - args := []string{ - "bash", - } - args = append(args, arguments...) - return args -} - -func (c *Client) replaceEnvironments(envs []corev1.EnvVar, secretsForReplace []string) { - // change postgres secrets to vault link - for _, secret := range secretsForReplace { - for k, v := range envs { - if v.ValueFrom != nil && v.ValueFrom.SecretKeyRef != nil { - if contain := strings.Contains(v.ValueFrom.SecretKeyRef.Name, secret); contain { - if c.registration.DbEngine.Enabled && isRoleSecret(secret) { - envs[k] = c.getEnvTemplateForVaultRole(v.Name, secret, v.ValueFrom.SecretKeyRef.Key) - } else { - envs[k] = c.getEnvTemplateForVault(v.Name, v.ValueFrom.SecretKeyRef.Name, v.ValueFrom.SecretKeyRef.Key, c.registration.Path) - } - - } - } - } - } -} - -func (c *Client) ProcessVaultSectionStatefulset(stSet *appsv1.StatefulSet, entrypoint, secrets []string) { - // Vault Section - if c.registration.Enabled || c.registration.DbEngine.Enabled { - // change postgres secrets to vault link - c.replaceEnvironments(stSet.Spec.Template.Spec.Containers[0].Env, secrets) - // add few Vault envs - stSet.Spec.Template.Spec.Containers[0].Env = append(stSet.Spec.Template.Spec.Containers[0].Env, c.getVaultRegistrationEnv()...) - // add volume mount to main container - stSet.Spec.Template.Spec.Containers[0].VolumeMounts = append(stSet.Spec.Template.Spec.Containers[0].VolumeMounts, getVaultVolumeMount()) - // add vault emptydir volume to deployment - stSet.Spec.Template.Spec.Volumes = append(stSet.Spec.Template.Spec.Volumes, getVaultVolume()) - // add vault command for getting credentials - stSet.Spec.Template.Spec.Containers[0].Command = getVaultCommand() - //Adding default security context - stSet.Spec.Template.Spec.Containers[0].SecurityContext = utilOp.GetDefaultSecurityContext() - // add args for start main container after - stSet.Spec.Template.Spec.Containers[0].Args = getVaultArgs(entrypoint) - - for i := 0; i < len(stSet.Spec.Template.Spec.InitContainers); i++ { - c.replaceEnvironments(stSet.Spec.Template.Spec.InitContainers[i].Env, secrets) - stSet.Spec.Template.Spec.InitContainers[i].Env = append(stSet.Spec.Template.Spec.InitContainers[i].Env, c.getVaultRegistrationEnv()...) - stSet.Spec.Template.Spec.InitContainers[i].VolumeMounts = append(stSet.Spec.Template.Spec.InitContainers[i].VolumeMounts, getVaultVolumeMount()) - stSet.Spec.Template.Spec.InitContainers[i].Command = getVaultCommand() - stSet.Spec.Template.Spec.InitContainers[i].Args = append(getVaultArgs(entrypoint), stSet.Spec.Template.Spec.InitContainers[i].Args...) - } - - stSet.Spec.Template.Spec.InitContainers = append(c.getInitContainerTemplateForVault(), stSet.Spec.Template.Spec.InitContainers...) - } -} - -func (c *Client) ProcessVaultSection(deployment *appsv1.Deployment, entrypoint, secrets []string) { - // Vault Section - if c.registration.Enabled || c.registration.DbEngine.Enabled { - // change postgres secrets to vault link - c.replaceEnvironments(deployment.Spec.Template.Spec.Containers[0].Env, secrets) - // add few Vault envs - deployment.Spec.Template.Spec.Containers[0].Env = append(deployment.Spec.Template.Spec.Containers[0].Env, c.getVaultRegistrationEnv()...) - // add volume mount to main container - deployment.Spec.Template.Spec.Containers[0].VolumeMounts = append(deployment.Spec.Template.Spec.Containers[0].VolumeMounts, getVaultVolumeMount()) - // add vault emptydir volume to deployment - deployment.Spec.Template.Spec.Volumes = append(deployment.Spec.Template.Spec.Volumes, getVaultVolume()) - // add vault command for getting credentials - deployment.Spec.Template.Spec.Containers[0].Command = getVaultCommand() - //Adding default security context - deployment.Spec.Template.Spec.Containers[0].SecurityContext = utilOp.GetDefaultSecurityContext() - // add args for start main container after - deployment.Spec.Template.Spec.Containers[0].Args = getVaultArgs(entrypoint) - - for i := 0; i < len(deployment.Spec.Template.Spec.InitContainers); i++ { - c.replaceEnvironments(deployment.Spec.Template.Spec.InitContainers[i].Env, secrets) - deployment.Spec.Template.Spec.InitContainers[i].Env = append(deployment.Spec.Template.Spec.InitContainers[i].Env, c.getVaultRegistrationEnv()...) - deployment.Spec.Template.Spec.InitContainers[i].VolumeMounts = append(deployment.Spec.Template.Spec.InitContainers[i].VolumeMounts, getVaultVolumeMount()) - deployment.Spec.Template.Spec.InitContainers[i].Command = getVaultCommand() - deployment.Spec.Template.Spec.InitContainers[i].Args = append(getVaultArgs(entrypoint), deployment.Spec.Template.Spec.InitContainers[i].Args...) - } - - deployment.Spec.Template.Spec.InitContainers = append(c.getInitContainerTemplateForVault(), deployment.Spec.Template.Spec.InitContainers...) - } -} - -func (c *Client) ProcessPodVaultSection(pod *corev1.Pod, secrets []string) { - if c.registration.Enabled { - // change postgres secrets to vault link - c.replaceEnvironments(pod.Spec.Containers[0].Env, secrets) - // add few Vault envs - pod.Spec.Containers[0].Env = append(pod.Spec.Containers[0].Env, c.getVaultRegistrationEnv()...) - // add init container to deployment - pod.Spec.InitContainers = c.getInitContainerTemplateForVault() - // add volume mount to main container - pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, getVaultVolumeMount()) - // add vault emptydir volume to deployment - pod.Spec.Volumes = append(pod.Spec.Volumes, getVaultVolume()) - // add vault command for getting credentials - pod.Spec.Containers[0].Command = getVaultCommand() - } -} - -func (c *Client) IsEnvContainsVaultRole(envVars []corev1.EnvVar) bool { - for _, env := range envVars { - if strings.Contains(env.Value, VaultPrefix+StaticCredsPath) { - return true - } - } - return false -} - -func isRoleSecret(value string) bool { - for _, v := range roleSecrets { - if strings.Contains(value, v) { - return true - } - } - return false -} diff --git a/pkg/vault/role_rotator.go b/pkg/vault/role_rotator.go deleted file mode 100644 index 09971e8c..00000000 --- a/pkg/vault/role_rotator.go +++ /dev/null @@ -1,265 +0,0 @@ -// Copyright 2024-2025 NetCracker Technology Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package vault - -import ( - "context" - "fmt" - "net/http" - - "github.com/Netcracker/pgskipper-operator-core/pkg/reconciler" - qubershipv1 "github.com/Netcracker/pgskipper-operator/api/apps/v1" - patroniv1 "github.com/Netcracker/pgskipper-operator/api/patroni/v1" - pghelper "github.com/Netcracker/pgskipper-operator/pkg/helper" - "github.com/Netcracker/pgskipper-operator/pkg/util" - "go.uber.org/zap" - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/intstr" - crclient "sigs.k8s.io/controller-runtime/pkg/client" -) - -const operatorName = "postgres-operator" - -var ( - rotController *rotationController - dbaasLabels = map[string]string{"app": "dbaas-postgres-adapter"} -) - -type rotationController struct { - vaultClient *Client - helper *pghelper.Helper - k8sClient crclient.Client - cr *qubershipv1.PatroniServices - coreCr *patroniv1.PatroniCore - isEnabled bool - cluster *patroniv1.PatroniClusterSettings -} - -func EnableRotationController(client *Client) { - rotController.enable(client) -} - -func (rc *rotationController) enable(client *Client) { - rc.isEnabled = true - var err error - rc.cr, err = rc.helper.GetPostgresServiceCR() - if err != nil { - logger.Error("Can't get PatroniServices CR for Vault client") - panic(err) - } - rc.coreCr, err = rc.helper.GetPatroniCoreCR() - if err != nil { - logger.Error("Can't get PatroniCore CR for Vault client") - panic(err) - } - rc.vaultClient = client -} - -func (rc *rotationController) rotate(response http.ResponseWriter, req *http.Request) { - if req.Method != http.MethodPost { - response.WriteHeader(http.StatusMethodNotAllowed) - return - } - - if !rc.isEnabled { - logger.Info("Rotation is disabled") - return - } - - if err := rc.vaultClient.vaultRotatePgRoles(); err != nil { - response.WriteHeader(http.StatusInternalServerError) - return - } - if err := rc.helper.UpdatePatroniReplicas(0, rc.cluster.ClusterName); err != nil { - response.WriteHeader(http.StatusInternalServerError) - } - if err := rc.waitForDeleteByLabels(rc.cluster.PatroniLabels); err != nil { - response.WriteHeader(http.StatusInternalServerError) - return - } - if err := rc.helper.UpdatePatroniReplicas(1, rc.cluster.ClusterName); err != nil { - response.WriteHeader(http.StatusInternalServerError) - } - if err := util.WaitForPatroni(rc.coreCr, rc.cluster.PatroniMasterSelectors, rc.cluster.PatroniReplicasSelector); err != nil { - logger.Error("error during waiting Patroni", zap.Error(err)) - } - if rc.vaultClient.isMetricCollectorInstalled { - if err := rc.restartPodWithLabels(reconciler.MetricCollectorLabels); err != nil { - response.WriteHeader(http.StatusInternalServerError) - return - } - } - if err := rc.restartPodWithLabels(dbaasLabels); err != nil { - response.WriteHeader(http.StatusInternalServerError) - return - } - if rc.vaultClient.isBackupDaemonInstalled { - if err := rc.restartPodWithLabels(reconciler.BackupDaemonLabels); err != nil { - response.WriteHeader(http.StatusInternalServerError) - return - } - } - - if err := rc.vaultClient.UpdatePgClientPass(); err != nil { - response.WriteHeader(http.StatusInternalServerError) - return - } -} - -func (rc *rotationController) restartPodWithLabels(podLabels map[string]string) error { - podList, err := rc.helper.GetNamespacePodListBySelectors(podLabels) - if err != nil { - logger.Error(fmt.Sprintf("Cannot find pods with labels %s", podLabels), zap.Error(err)) - } - - for podIdx := 0; podIdx < len(podList.Items); podIdx++ { - podForRestart := podList.Items[podIdx] - logger.Info(fmt.Sprintf("Restart %v", podForRestart.ObjectMeta.Name)) - if err = rc.k8sClient.Delete(context.Background(), &podForRestart); err != nil { - logger.Error(fmt.Sprintf("Pod %s cannot being restarted", podForRestart.Name), zap.Error(err)) - } - } - return nil -} - -func (rc *rotationController) waitForDeleteByLabels(podLabels map[string]string) error { - podList, err := rc.helper.GetNamespacePodListBySelectors(podLabels) - if err != nil { - logger.Error(fmt.Sprintf("Cannot find pods with labels %s", podLabels), zap.Error(err)) - } - for podIdx := 0; podIdx < len(podList.Items); podIdx++ { - podForRestart := podList.Items[podIdx] - if err = util.WaitDeletePod(&podForRestart); err != nil { - logger.Error(fmt.Sprintf("error during %s pod restart waiting", podForRestart.Name), zap.Error(err)) - } - } - return nil -} - -func Init() { - client, _ := util.GetClient() - helper := pghelper.GetHelper() - cr, _ := helper.GetPostgresServiceCR() - rotController = &rotationController{ - helper: helper, - k8sClient: client, - cluster: util.GetPatroniClusterSettings(cr.Spec.Patroni.ClusterName), - } - if err := exposeRotatorPort(client); err != nil { - logger.Error("can't expose rotate role port.") - // let's assume here, that expose of the port should not break operator - // because rotate not main functional - //panic(err) - } - http.HandleFunc("/rotate-roles", rotController.rotate) -} - -func exposeRotatorPort(client crclient.Client) error { - namespace := util.GetNameSpace() - - oServ := &corev1.Service{} - err := client.Get(context.Background(), types.NamespacedName{ - Name: operatorName, Namespace: namespace, - }, oServ) - if err != nil { - if errors.IsNotFound(err) { - // this is almost copy 'n paste of /operator-framework/operator-sdk@v0.8.0/pkg/metrics/metrics.go#initOperatorService - // but this does not set ownerReference to the service - // hence we do not need finalizers rights - logger.Info("Operator service not found, creating new one.") - oServ = getOperatorService(operatorName, namespace) - if err = client.Create(context.TODO(), oServ); err != nil { - logger.Error(fmt.Sprintf("can't create service: %s", operatorName), zap.Error(err)) - } - } else { - logger.Error("can't get operator service", zap.Error(err)) - } - return err - } - for _, port := range oServ.Spec.Ports { - // checking if rotate already exists - // to avoid: Service "postgres-operator" is invalid: spec.ports[2].name: Duplicate value: "rotate" - if port.Name == "rotate" || port.Port == 8080 { - logger.Info("Rotate port exists, no need to update, exiting.") - return nil - } - } - oServ.Spec.Ports = append(oServ.Spec.Ports, corev1.ServicePort{ - Name: "rotate", - Protocol: corev1.ProtocolTCP, - Port: 8080, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 8080, - }, - }) - - if err = client.Update(context.TODO(), oServ); err != nil { - logger.Error(fmt.Sprintf("can't update service: %s", operatorName), zap.Error(err)) - return err - } - - return nil -} - -func getOperatorService(operatorName string, namespace string) *corev1.Service { - label := map[string]string{"name": operatorName} - return &corev1.Service{ - ObjectMeta: metav1.ObjectMeta{ - Name: operatorName, - Namespace: namespace, - Labels: label, - }, - TypeMeta: metav1.TypeMeta{ - Kind: "Service", - APIVersion: "v1", - }, - Spec: corev1.ServiceSpec{ - Ports: []corev1.ServicePort{ - { - Port: 8383, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 8383, - }, - Name: "metrics", - }, - { - Port: 8080, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 8080, - }, - Name: "rotate", - }, - { - Port: 8443, - Protocol: corev1.ProtocolTCP, - TargetPort: intstr.IntOrString{ - Type: intstr.Int, - IntVal: 8443, - }, - Name: "web-tls", - }, - }, - Selector: label, - }, - } -} diff --git a/pkg/vault/vault_client.go b/pkg/vault/vault_client.go deleted file mode 100644 index 512e453b..00000000 --- a/pkg/vault/vault_client.go +++ /dev/null @@ -1,419 +0,0 @@ -// Copyright 2024-2025 NetCracker Technology Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package vault - -import ( - "fmt" - "sync" - - patroniv1 "github.com/Netcracker/pgskipper-operator/api/patroni/v1" - - types "github.com/Netcracker/pgskipper-operator-core/api/v1" - pgclient "github.com/Netcracker/pgskipper-operator/pkg/client" - "github.com/Netcracker/pgskipper-operator/pkg/helper" - "github.com/Netcracker/pgskipper-operator/pkg/util" - "github.com/hashicorp/vault/api" - "go.uber.org/zap" - crclient "sigs.k8s.io/controller-runtime/pkg/client" -) - -const ( - RotationPeriod = "175200h" -) - -var ( - logger = util.GetLogger() -) - -type Client struct { - helper *helper.PatroniHelper - k8sClient crclient.Client - coreCr *patroniv1.PatroniCore - isMetricCollectorInstalled bool - isBackupDaemonInstalled bool - registration *types.VaultRegistration - mu sync.Mutex -} - -func NewClient() *Client { - newK8sClient, err := util.GetClient() - if err != nil { - panic(err) - } - return &Client{ - helper: helper.GetPatroniHelper(), - k8sClient: newK8sClient, - } -} - -func (c *Client) UpdateCr(kind string) { - //Maybe not the best decision - if kind == "PatroniServices" { - cr, err := c.helper.GetPostgresServiceCR() - if err != nil { - logger.Error("Can't get PatroniServices CR for Vault client") - panic(err) - } - c.registration = cr.Spec.VaultRegistration - c.isMetricCollectorInstalled = cr.Spec.MetricCollector != nil - c.isBackupDaemonInstalled = cr.Spec.BackupDaemon != nil - } else { - coreCr, err := c.helper.GetPatroniCoreCR() - if err != nil { - logger.Error("Can't get PatroniCore CR for Vault client") - panic(err) - } - c.registration = coreCr.Spec.VaultRegistration - c.coreCr = coreCr - } -} - -func (c *Client) CreatePostgresVaultRole(userName string) (string, error) { - roleName := GetVaultRoleName(userName) - logger.Info(fmt.Sprintf("Creation of vault role %s", roleName)) - token, err := util.ReadTokenFromFile() - if err != nil { - logger.Error("can not read the token from file") - return "", err - } - client := c.vaultSetToken(token) - - data := map[string]interface{}{ - "username": userName, - "db_name": c.registration.DbEngine.Name, - "rotation_period": RotationPeriod, - "rotation_statements": []string{"ALTER USER \"{{name}}\" WITH PASSWORD '{{password}}';"}, - } - - path := fmt.Sprintf("database/static-roles/%s", roleName) - - resp, err := client.Logical().Write(path, data) - if err != nil { - logger.Error("can not create Vault role", zap.Error(err)) - return "", err - } - if resp == nil { - err := fmt.Errorf("empty response from Vault") - logger.Error("can not create Vault role", zap.Error(err)) - return "", err - } - logger.Info(fmt.Sprintf("Vault role %s has been created", roleName)) - return roleName, nil -} - -func (c *Client) PrepareDbEngine(vaultExist bool, cluster *patroniv1.PatroniClusterSettings) error { - if c.registration.DbEngine.Enabled { - if !vaultExist { - logger.Info("Activating Postgres Vault engine plugin") - if _, err := c.vaultCreateDbEngine("vault-admin", cluster.PostgresServiceName, cluster.PgHost); err != nil { - logger.Error("can not activate db Engine", zap.Error(err)) - return err - } - // Ensure metric collector role exist - if err := createCollectorPgRole(cluster.PgHost); err != nil { - logger.Info("Cannot create role for metric-collector", zap.Error(err)) - } - // create Vault static roles - c.createDbEngineRoles() - - if err := c.updatePatroniVaultRoles(cluster); err != nil { - return err - } - } - - if err := c.UpdatePgClientPass(); err != nil { - return err - } - } - return nil -} - -func (c *Client) updatePatroniVaultRoles(cluster *patroniv1.PatroniClusterSettings) error { - statefulSets, err := c.helper.GetStatefulsetByNameRegExp(cluster.PatroniDeploymentName) - if err != nil { - return err - } - if c.IsEnvContainsVaultRole(statefulSets[0].Spec.Template.Spec.Containers[0].Env) { - logger.Info("Patroni already have vault role env, skip deployments update") - return nil - } - patrPods, err := c.helper.GetNamespacePodListBySelectors(cluster.PatroniCommonLabels) - if err != nil { - return err - } - if err = c.helper.UpdatePatroniReplicas(0, cluster.ClusterName); err != nil { - return err - } - for _, patroniPod := range patrPods.Items { - if err = util.WaitDeletePod(&patroniPod); err != nil { - logger.Error("waiting for Patroni deployment upgrade failed", zap.Error(err)) - return err - } - } - statefulSets, _ = c.helper.GetStatefulsetByNameRegExp(cluster.PatroniDeploymentName) - for _, d := range statefulSets { - // Scale up Patroni after update - repl := int32(1) - d.Spec.Replicas = &repl - c.ProcessVaultSectionStatefulset(d, PatroniEntrypoint, roleSecrets) - if err = c.helper.CreateOrUpdateStatefulset(d, true); err != nil { - logger.Error(fmt.Sprintf("Cannot create or update deployment %s", d.Name), zap.Error(err)) - return err - } - } - - if err = util.WaitForPatroni(c.coreCr, cluster.PatroniMasterSelectors, cluster.PatroniReplicasSelector); err != nil { - return err - } - return nil -} - -func (c *Client) createDbEngineRoles() { - for _, user := range roleSecrets { - if _, err := c.CreatePostgresVaultRole(user); err != nil { - logger.Error(fmt.Sprintf("can not create %s role", user), zap.Error(err)) - } - } -} - -func GetVaultRoleName(dbRole string) string { - return fmt.Sprintf("%s_%s_%s_%s", util.GetServerHostname(), util.GetNameSpace(), "patroni-sa", dbRole) // No more variety there -} - -func createCollectorPgRole(pgHost string) error { - client := pgclient.GetPostgresClient(pgHost) - // Password hardcode can be ignored, because it's gonna be rotated by vault - if _, err := client.Query("CREATE ROLE \"monitoring-user\" with login password 'p@ssWOrD1'"); err != nil { - return err - } - return nil -} - -func (c *Client) vaultGetToken(jwtToken string) string { - options := map[string]interface{}{ - "jwt": jwtToken, - "role": util.GetServiceAccount(), - } - config := &api.Config{ - Address: c.registration.Url, - } - loginPath := getLoginPath() - client, err := api.NewClient(config) - if err != nil { - fmt.Println(err) - } - clientToken, err := client.Logical().Write(loginPath, options) - if err != nil { - fmt.Println(err) - } - - return string(clientToken.Auth.ClientToken) -} - -func (c *Client) vaultSetToken(jwtToken string) *api.Client { - config := &api.Config{ - Address: c.registration.Url, - } - client, err := api.NewClient(config) - if err != nil { - fmt.Println(err) - return nil - } - clientToken := c.vaultGetToken(jwtToken) - client.SetToken(clientToken) - return client -} - -func (c *Client) vaultRead(path string) (map[string]interface{}, bool) { - token, err := util.ReadTokenFromFile() - if err != nil { - logger.Error("can not read the token from file") - return nil, false - } - client := c.vaultSetToken(token) - secret, err := client.Logical().Read(path) - if err != nil { - return nil, false - } - if secret == nil || secret.Data == nil { - logger.Debug(fmt.Sprintf("No data on path %s", path)) - return nil, false - } - return secret.Data, true -} - -func (c *Client) vaultWriteSecret(path string, secret map[string]interface{}) error { - token, err := util.ReadTokenFromFile() - if err != nil { - logger.Error("can not read the token from file") - return err - } - client := c.vaultSetToken(token) - _, err = client.Logical().Write(path, secret) - if err != nil { - return err - } - return nil -} - -func (c *Client) vaultCreateDbEngine(username string, postgresServiceName string, pgHost string) (bool, error) { - dbEngName := c.registration.DbEngine.Name - path := "/database/config/" + dbEngName - token, err := util.ReadTokenFromFile() - if err != nil { - logger.Error("can not read the token from file") - return false, err - } - if _, ok := c.vaultRead("database/config/" + dbEngName); ok { - logger.Info(fmt.Sprintf("DbEngine %s already exists", dbEngName)) - return false, nil - } - - pgClient := pgclient.GetPostgresClient(pgHost) - rows, err := pgClient.Query(fmt.Sprintf("SELECT 1 FROM pg_user WHERE usename = '%s'", pgclient.EscapeString(username))) - if err != nil { - logger.Error("error during obtaining vault user", zap.Error(err)) - return false, err - } - defer rows.Close() - if rows.Next() { - logger.Info("Vault user already exist") - return false, nil - } - - password := util.GenerateRandomPassword() - _, err = pgClient.Query(fmt.Sprintf("CREATE USER \"%s\" WITH PASSWORD '%s' SUPERUSER", username, password)) - if err != nil { - logger.Error(fmt.Sprintf("create %s user error", username), zap.Error(err)) - return false, err - } - client := c.vaultSetToken(token) - data := map[string]interface{}{ - "plugin_name": "postgresql-database-plugin", - "allowed_roles": "*", - "connection_url": "postgresql://{{username}}:{{password}}@" + postgresServiceName + "." + util.GetNameSpace() + ":5432/postgres?sslmode=disable", - "max_open_connections": c.registration.DbEngine.MaxOpenConnections, - "max_idle_connections": c.registration.DbEngine.MaxIdleConnections, - "max_connection_lifetime": c.registration.DbEngine.MaxConnectionLifetime, - "verify_connection": false, - "username": username, - "password": password, - "root_rotation_statements": []string{"ALTER USER \"{{username}}\" WITH PASSWORD '{{password}}';"}, - } - _, err = client.Logical().Write(path, data) - if err != nil { - return false, err - } - - if err = c.vaultRotateRootCreds(); err != nil { - return false, err - } - - return true, nil -} - -func (c *Client) vaultRotateRootCreds() error { - path := "/database/rotate-root/" + c.registration.DbEngine.Name - token, err := util.ReadTokenFromFile() - if err != nil { - logger.Error("error reading token", zap.Error(err)) - return err - } - - client := c.vaultSetToken(token) - _, err = client.Logical().Write(path, nil) - if err != nil { - logger.Error("error during rotate root vault role", zap.Error(err)) - return err - } - return nil -} - -func (c *Client) vaultRotateStaticCreds(username string) error { - path := "/database/rotate-role/" + GetVaultRoleName(username) - token, err := util.ReadTokenFromFile() - if err != nil { - logger.Error("cannot read token from file", zap.Error(err)) - return err - } - - client := c.vaultSetToken(token) - _, err = client.Logical().Write(path, nil) - if err != nil { - logger.Error("cannot rotate static creds", zap.Error(err)) - return err - } - return nil -} - -func (c *Client) vaultRotatePgRoles() error { - c.mu.Lock() - defer c.mu.Unlock() - for _, role := range roleSecrets { - if !c.isMetricCollectorInstalled && role == "monitoring-user" { - logger.Info("metric collector is not installed, skipping role rotate for monitoring user") - continue - } - if err := c.vaultRotateStaticCreds(role); err != nil { - return err - } - } - return nil -} - -func (c *Client) IsVaultRolesExist() bool { - if !c.registration.Enabled && !c.registration.DbEngine.Enabled { - return false - } - isRolesExist := true - for _, role := range roleSecrets { - if _, success := c.getVaultRoleData(role); !success { - isRolesExist = false - } - } - return isRolesExist -} - -func (c *Client) getVaultRoleData(dbRole string) (map[string]interface{}, bool) { - c.mu.Lock() - defer c.mu.Unlock() - vaultRoleName := GetVaultRoleName(dbRole) - resp, success := c.vaultRead(StaticCredsPath + vaultRoleName) - if !success { - logger.Info(fmt.Sprintf("Can't get data for vault role %s. Does role exist?", vaultRoleName)) - return nil, false - } - return resp, true -} - -func getLoginPath() string { - return "/auth/" + util.GetServerHostname() + "_" + util.GetNameSpace() + "/login" -} - -func (c *Client) UpdatePgClientPass() error { - resp, success := c.getVaultRoleData("postgres") - if !success { - return fmt.Errorf("cannot read vault role creds") - } - - if password, ok := resp["password"]; ok { - logger.Info("Update password for pg in operator") - pgclient.UpdatePostgresClientPassword(password.(string)) - } else { - logger.Error("Password not found in client creds") - return fmt.Errorf("cannot rotate pg client creds") - } - return nil -}