diff --git a/.github/workflows/lint-test.yaml b/.github/workflows/lint-test.yaml index 9d85686..ba87c36 100644 --- a/.github/workflows/lint-test.yaml +++ b/.github/workflows/lint-test.yaml @@ -35,8 +35,10 @@ jobs: run: ct lint --target-branch main - name: Create kind cluster - uses: helm/kind-action@v1.2.0 if: steps.list-changed.outputs.changed == 'true' + uses: helm/kind-action@v1.2.0 + with: + version: v0.12.0 - name: Run chart-testing (install) run: ct install --target-branch main diff --git a/charts/postgres-operator/Chart.yaml b/charts/postgres-operator/Chart.yaml index e09d2f2..b02e01e 100644 --- a/charts/postgres-operator/Chart.yaml +++ b/charts/postgres-operator/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v2 name: postgres-operator description: Postgres Operator creates and manages PostgreSQL clusters running in Kubernetes -version: 1.7.3 -appVersion: 1.7.1 +version: 1.8.0 +appVersion: 1.8.0 home: https://github.com/zalando/postgres-operator sources: - https://github.com/zalando/postgres-operator diff --git a/charts/postgres-operator/README.md b/charts/postgres-operator/README.md index 49d715e..50ecadc 100644 --- a/charts/postgres-operator/README.md +++ b/charts/postgres-operator/README.md @@ -34,132 +34,145 @@ The command removes all the Kubernetes components associated with the chart and The following table lists the configurable parameters of the Postgres-operator chart and their default values. -| Parameter | Description | Default | -| ------------------------ | ----------------------- | -------------- | -| `image.registry` | | `"registry.opensource.zalan.do"` | -| `image.repository` | | `"acid/postgres-operator"` | -| `image.tag` | | `"v1.7.1"` | -| `image.pullPolicy` | | `"IfNotPresent"` | -| `podAnnotations` | | `{}` | -| `podLabels` | | `{}` | -| `enableJsonLogging` | | `false` | -| `configGeneral.enable_crd_validation` | | `true` | -| `configGeneral.enable_lazy_spilo_upgrade` | | `false` | -| `configGeneral.enable_pgversion_env_var` | | `true` | -| `configGeneral.enable_shm_volume` | | `true` | -| `configGeneral.enable_spilo_wal_path_compat` | | `false` | -| `configGeneral.etcd_host` | | `""` | -| `configGeneral.docker_image` | | `"registry.opensource.zalan.do/acid/spilo-14:2.1-p4"` | -| `configGeneral.min_instances` | | `-1` | -| `configGeneral.max_instances` | | `-1` | -| `configGeneral.repair_period` | | `"5m"` | -| `configGeneral.resync_period` | | `"30m"` | -| `configGeneral.workers` | | `8` | -| `configUsers.replication_username` | | `"standby"` | -| `configUsers.super_username` | | `"postgres"` | -| `configMajorVersionUpgrade.major_version_upgrade_mode` | | `"off"` | -| `configMajorVersionUpgrade.minimal_major_version` | | `"9.6"` | -| `configMajorVersionUpgrade.target_major_version` | | `"14"` | -| `configKubernetes.cluster_domain` | | `"cluster.local"` | -| `configKubernetes.cluster_labels.application` | | `"spilo"` | -| `configKubernetes.cluster_name_label` | | `"cluster-name"` | -| `configKubernetes.enable_cross_namespace_secret` | | `false` | -| `configKubernetes.enable_init_containers` | | `true` | -| `configKubernetes.enable_pod_antiaffinity` | | `false` | -| `configKubernetes.enable_pod_disruption_budget` | | `true` | -| `configKubernetes.enable_sidecars` | | `true` | -| `configKubernetes.pdb_name_format` | | `"postgres-{cluster}-pdb"` | -| `configKubernetes.pod_antiaffinity_topology_key` | | `"kubernetes.io/hostname"` | -| `configKubernetes.pod_management_policy` | | `"ordered_ready"` | -| `configKubernetes.pod_role_label` | | `"spilo-role"` | -| `configKubernetes.pod_terminate_grace_period` | | `"5m"` | -| `configKubernetes.secret_name_template` | | `"{username}.{cluster}.credentials.{tprkind}.{tprgroup}"` | -| `configKubernetes.spilo_privileged` | | `false` | -| `configKubernetes.spilo_allow_privilege_escalation` | | `true` | -| `configKubernetes.storage_resize_mode` | | `"pvc"` | -| `configKubernetes.watched_namespace` | listen to all namespaces | `"*"` | -| `configPostgresPodResources.default_cpu_limit` | | `"1"` | -| `configPostgresPodResources.default_cpu_request` | | `"100m"` | -| `configPostgresPodResources.default_memory_limit` | | `"500Mi"` | -| `configPostgresPodResources.default_memory_request` | | `"100Mi"` | -| `configPostgresPodResources.min_cpu_limit` | | `"250m"` | -| `configPostgresPodResources.min_memory_limit` | | `"250Mi"` | -| `configTimeouts.pod_deletion_wait_timeout` | | `"10m"` | -| `configTimeouts.pod_label_wait_timeout` | | `"10m"` | -| `configTimeouts.ready_wait_interval` | | `"3s"` | -| `configTimeouts.ready_wait_timeout` | | `"30s"` | -| `configTimeouts.resource_check_interval` | | `"3s"` | -| `configTimeouts.resource_check_timeout` | | `"10m"` | -| `configLoadBalancer.db_hosted_zone` | | `"db.example.com"` | -| `configLoadBalancer.enable_master_load_balancer` | | `false` | -| `configLoadBalancer.enable_replica_load_balancer` | | `false` | -| `configLoadBalancer.external_traffic_policy` | | `"Cluster"` | -| `configLoadBalancer.master_dns_name_format` | | `"{cluster}.{team}.{hostedzone}"` | -| `configLoadBalancer.replica_dns_name_format` | | `"{cluster}-repl.{team}.{hostedzone}"` | -| `configDebug.debug_logging` | | `true` | -| `configDebug.enable_database_access` | | `true` | -| `configLoggingRestApi.api_port` | | `8080` | -| `configLoggingRestApi.cluster_history_entries` | | `1000` | -| `configLoggingRestApi.ring_log_lines` | | `100` | -| `configAwsOrGcp.aws_region` | | `"eu-central-1"` | -| `configAwsOrGcp.enable_ebs_gp3_migration` | | `false` | -| `configLogicalBackup.logical_backup_docker_image` | | `"registry.opensource.zalan.do/acid/logical-backup:v1.7.1"` | -| `configLogicalBackup.logical_backup_job_prefix` | | `"logical-backup-"` | -| `configLogicalBackup.logical_backup_provider` | | `"s3"` | -| `configLogicalBackup.logical_backup_s3_access_key_id` | | `""` | -| `configLogicalBackup.logical_backup_s3_bucket` | | `"my-bucket-url"` | -| `configLogicalBackup.logical_backup_s3_region` | | `""` | -| `configLogicalBackup.logical_backup_s3_endpoint` | | `""` | -| `configLogicalBackup.logical_backup_s3_secret_access_key` | | `""` | -| `configLogicalBackup.logical_backup_s3_sse` | | `"AES256"` | -| `configLogicalBackup.logical_backup_schedule` | | `"30 00 * * *"` | -| `configTeamsApi.enable_admin_role_for_users` | | `true` | -| `configTeamsApi.enable_postgres_team_crd` | | `false` | -| `configTeamsApi.enable_postgres_team_crd_superusers` | | `false` | -| `configTeamsApi.enable_team_member_deprecation` | | `false` | -| `configTeamsApi.enable_team_superuser` | | `false` | -| `configTeamsApi.enable_teams_api` | | `false` | -| `configTeamsApi.pam_role_name` | | `"zalandos"` | -| `configTeamsApi.postgres_superuser_teams` | | `["postgres_superusers"]` | -| `configTeamsApi.protected_role_names` | | `["admin"]` | -| `configTeamsApi.role_deletion_suffix` | | `"_deleted"` | -| `configTeamsApi.team_admin_role` | | `"admin"` | -| `configTeamsApi.team_api_role_configuration.log_statement` | | `"all"` | -| `configConnectionPooler.connection_pooler_schema` | | `"pooler"` | -| `configConnectionPooler.connection_pooler_user` | | `"pooler"` | -| `configConnectionPooler.connection_pooler_image` | | `"registry.opensource.zalan.do/acid/pgbouncer:master-19"` | -| `configConnectionPooler.connection_pooler_max_db_connections` | | `60` | -| `configConnectionPooler.connection_pooler_mode` | | `"transaction"` | -| `configConnectionPooler.connection_pooler_number_of_instances` | | `2` | -| `configConnectionPooler.connection_pooler_default_cpu_request` | | `"500m"` | -| `configConnectionPooler.connection_pooler_default_memory_request` | | `"100Mi"` | -| `configConnectionPooler.connection_pooler_default_cpu_limit` | | `"1"` | -| `configConnectionPooler.connection_pooler_default_memory_limit` | | `"100Mi"` | -| `rbac.create` | | `true` | -| `crd.create` | | `true` | -| `serviceAccount.create` | | `true` | -| `serviceAccount.name` | | `null` | -| `podServiceAccount.name` | | `"postgres-pod"` | -| `priorityClassName` | | `""` | -| `podPriorityClassName` | | `""` | -| `resources.limits.cpu` | | `"500m"` | -| `resources.limits.memory` | | `"500Mi"` | -| `resources.requests.cpu` | | `"100m"` | -| `resources.requests.memory` | | `"250Mi"` | -| `securityContext.runAsUser` | | `1000` | -| `securityContext.runAsNonRoot` | | `true` | -| `securityContext.readOnlyRootFilesystem` | | `true` | -| `securityContext.allowPrivilegeEscalation` | | `false` | -| `affinity` | | `{}` | -| `nodeSelector` | | `{}` | -| `tolerations` | | `[]` | -| `controllerID.create` | | `false` | -| `controllerID.name` | | `null` | -| `pod_environment_config` | | `{}` | +| Key | Type | Default | Description | +|-----|------|---------|-------------| +| image.registry | string | `"registry.opensource.zalan.do"` | | +| image.repository | string | `"acid/postgres-operator"` | | +| image.tag | string | `"v1.8.0"` | | +| image.pullPolicy | string | `"IfNotPresent"` | | +| podAnnotations | object | `{}` | | +| podLabels | object | `{}` | | +| enableJsonLogging | bool | `false` | | +| configGeneral.enable_crd_registration | bool | `true` | | +| configGeneral.crd_categories[0] | string | `"all"` | | +| configGeneral.enable_lazy_spilo_upgrade | bool | `false` | | +| configGeneral.enable_pgversion_env_var | bool | `true` | | +| configGeneral.enable_shm_volume | bool | `true` | | +| configGeneral.enable_spilo_wal_path_compat | bool | `false` | | +| configGeneral.etcd_host | string | `""` | | +| configGeneral.docker_image | string | `"registry.opensource.zalan.do/acid/spilo-14:2.1-p5"` | | +| configGeneral.min_instances | int | `-1` | | +| configGeneral.max_instances | int | `-1` | | +| configGeneral.repair_period | string | `"5m"` | | +| configGeneral.resync_period | string | `"30m"` | | +| configGeneral.workers | int | `8` | | +| configUsers.enable_password_rotation | bool | `false` | | +| configUsers.password_rotation_interval | int | `90` | | +| configUsers.password_rotation_user_retention | int | `180` | | +| configUsers.replication_username | string | `"standby"` | | +| configUsers.super_username | string | `"postgres"` | | +| configMajorVersionUpgrade.major_version_upgrade_mode | string | `"off"` | | +| configMajorVersionUpgrade.minimal_major_version | string | `"9.6"` | | +| configMajorVersionUpgrade.target_major_version | string | `"14"` | | +| configKubernetes.cluster_domain | string | `"cluster.local"` | | +| configKubernetes.cluster_labels.application | string | `"spilo"` | | +| configKubernetes.cluster_name_label | string | `"cluster-name"` | | +| configKubernetes.enable_cross_namespace_secret | bool | `false` | | +| configKubernetes.enable_init_containers | bool | `true` | | +| configKubernetes.enable_pod_antiaffinity | bool | `false` | | +| configKubernetes.enable_pod_disruption_budget | bool | `true` | | +| configKubernetes.enable_sidecars | bool | `true` | | +| configKubernetes.pdb_name_format | string | `"postgres-{cluster}-pdb"` | | +| configKubernetes.pod_antiaffinity_topology_key | string | `"kubernetes.io/hostname"` | | +| configKubernetes.pod_management_policy | string | `"ordered_ready"` | | +| configKubernetes.pod_role_label | string | `"spilo-role"` | | +| configKubernetes.pod_terminate_grace_period | string | `"5m"` | | +| configKubernetes.secret_name_template | string | `"{username}.{cluster}.credentials.{tprkind}.{tprgroup}"` | | +| configKubernetes.spilo_privileged | bool | `false` | | +| configKubernetes.spilo_allow_privilege_escalation | bool | `true` | | +| configKubernetes.storage_resize_mode | string | `"pvc"` | | +| configKubernetes.watched_namespace | string | `"*"` | | +| configPostgresPodResources.default_cpu_limit | string | `"1"` | | +| configPostgresPodResources.default_cpu_request | string | `"100m"` | | +| configPostgresPodResources.default_memory_limit | string | `"500Mi"` | | +| configPostgresPodResources.default_memory_request | string | `"100Mi"` | | +| configPostgresPodResources.min_cpu_limit | string | `"250m"` | | +| configPostgresPodResources.min_memory_limit | string | `"250Mi"` | | +| configTimeouts.patroni_api_check_interval | string | `"1s"` | | +| configTimeouts.patroni_api_check_timeout | string | `"5s"` | | +| configTimeouts.pod_deletion_wait_timeout | string | `"10m"` | | +| configTimeouts.pod_label_wait_timeout | string | `"10m"` | | +| configTimeouts.ready_wait_interval | string | `"3s"` | | +| configTimeouts.ready_wait_timeout | string | `"30s"` | | +| configTimeouts.resource_check_interval | string | `"3s"` | | +| configTimeouts.resource_check_timeout | string | `"10m"` | | +| configLoadBalancer.db_hosted_zone | string | `"db.example.com"` | | +| configLoadBalancer.enable_master_load_balancer | bool | `false` | | +| configLoadBalancer.enable_master_pooler_load_balancer | bool | `false` | | +| configLoadBalancer.enable_replica_load_balancer | bool | `false` | | +| configLoadBalancer.enable_replica_pooler_load_balancer | bool | `false` | | +| configLoadBalancer.external_traffic_policy | string | `"Cluster"` | | +| configLoadBalancer.master_dns_name_format | string | `"{cluster}.{team}.{hostedzone}"` | | +| configLoadBalancer.replica_dns_name_format | string | `"{cluster}-repl.{team}.{hostedzone}"` | | +| configDebug.debug_logging | bool | `true` | | +| configDebug.enable_database_access | bool | `true` | | +| configLoggingRestApi.api_port | int | `8080` | | +| configLoggingRestApi.cluster_history_entries | int | `1000` | | +| configLoggingRestApi.ring_log_lines | int | `100` | | +| configAwsOrGcp.aws_region | string | `"eu-central-1"` | | +| configAwsOrGcp.enable_ebs_gp3_migration | bool | `false` | | +| configLogicalBackup.logical_backup_docker_image | string | `"registry.opensource.zalan.do/acid/logical-backup:v1.8.0"` | | +| configLogicalBackup.logical_backup_job_prefix | string | `"logical-backup-"` | | +| configLogicalBackup.logical_backup_provider | string | `"s3"` | | +| configLogicalBackup.logical_backup_s3_access_key_id | string | `""` | | +| configLogicalBackup.logical_backup_s3_bucket | string | `"my-bucket-url"` | | +| configLogicalBackup.logical_backup_s3_region | string | `""` | | +| configLogicalBackup.logical_backup_s3_endpoint | string | `""` | | +| configLogicalBackup.logical_backup_s3_secret_access_key | string | `""` | | +| configLogicalBackup.logical_backup_s3_sse | string | `"AES256"` | | +| configLogicalBackup.logical_backup_s3_retention_time | string | `""` | | +| configLogicalBackup.logical_backup_schedule | string | `"30 00 * * *"` | | +| configTeamsApi.enable_admin_role_for_users | bool | `true` | | +| configTeamsApi.enable_postgres_team_crd | bool | `false` | | +| configTeamsApi.enable_postgres_team_crd_superusers | bool | `false` | | +| configTeamsApi.enable_team_member_deprecation | bool | `false` | | +| configTeamsApi.enable_team_superuser | bool | `false` | | +| configTeamsApi.enable_teams_api | bool | `false` | | +| configTeamsApi.pam_role_name | string | `"zalandos"` | | +| configTeamsApi.postgres_superuser_teams[0] | string | `"postgres_superusers"` | | +| configTeamsApi.protected_role_names[0] | string | `"admin"` | | +| configTeamsApi.protected_role_names[1] | string | `"cron_admin"` | | +| configTeamsApi.role_deletion_suffix | string | `"_deleted"` | | +| configTeamsApi.team_admin_role | string | `"admin"` | | +| configTeamsApi.team_api_role_configuration.log_statement | string | `"all"` | | +| configConnectionPooler.connection_pooler_schema | string | `"pooler"` | | +| configConnectionPooler.connection_pooler_user | string | `"pooler"` | | +| configConnectionPooler.connection_pooler_image | string | `"registry.opensource.zalan.do/acid/pgbouncer:master-22"` | | +| configConnectionPooler.connection_pooler_max_db_connections | int | `60` | | +| configConnectionPooler.connection_pooler_mode | string | `"transaction"` | | +| configConnectionPooler.connection_pooler_number_of_instances | int | `2` | | +| configConnectionPooler.connection_pooler_default_cpu_request | string | `"500m"` | | +| configConnectionPooler.connection_pooler_default_memory_request | string | `"100Mi"` | | +| configConnectionPooler.connection_pooler_default_cpu_limit | string | `"1"` | | +| configConnectionPooler.connection_pooler_default_memory_limit | string | `"100Mi"` | | +| enableStreams | bool | `false` | | +| rbac.create | bool | `true` | | +| rbac.createAggregateClusterRoles | bool | `false` | | +| serviceAccount.create | bool | `true` | | +| serviceAccount.name | string | `nil` | | +| podServiceAccount.name | string | `"postgres-pod"` | | +| priorityClassName | string | `""` | | +| podPriorityClassName | string | `""` | | +| resources.limits.cpu | string | `"500m"` | | +| resources.limits.memory | string | `"500Mi"` | | +| resources.requests.cpu | string | `"100m"` | | +| resources.requests.memory | string | `"250Mi"` | | +| securityContext.runAsUser | int | `1000` | | +| securityContext.runAsNonRoot | bool | `true` | | +| securityContext.readOnlyRootFilesystem | bool | `true` | | +| securityContext.allowPrivilegeEscalation | bool | `false` | | +| securityContext.capabilities.drop[0] | string | `"ALL"` | | +| affinity | object | `{}` | | +| nodeSelector | object | `{}` | | +| tolerations | list | `[]` | | +| controllerID.create | bool | `false` | | +| controllerID.name | string | `nil` | | +| pod_environment_config | object | `{}` | | ## Changes compared to the [official chart](https://github.com/zalando/postgres-operator/tree/master/charts/postgres-operator) - No `ConfigMap` config-target. - `pod_environment_configmap` is created automatically. Contents can be configured via `pod_environment_config`. +- Enhanced security (dropped ALL capabilities for the operator-pod). diff --git a/charts/postgres-operator/crds/operatorconfigurations.yaml b/charts/postgres-operator/crds/operatorconfigurations.yaml index 327ed13..4e708ac 100644 --- a/charts/postgres-operator/crds/operatorconfigurations.yaml +++ b/charts/postgres-operator/crds/operatorconfigurations.yaml @@ -4,8 +4,6 @@ metadata: name: operatorconfigurations.acid.zalan.do labels: app.kubernetes.io/name: postgres-operator - annotations: - "helm.sh/hook": crd-install spec: group: acid.zalan.do names: @@ -63,11 +61,20 @@ spec: configuration: type: object properties: + crd_categories: + type: array + nullable: true + items: + type: string docker_image: type: string - default: "registry.opensource.zalan.do/acid/spilo-14:2.1-p4" + default: "registry.opensource.zalan.do/acid/spilo-14:2.1-p5" + enable_crd_registration: + type: boolean + default: true enable_crd_validation: type: boolean + description: deprecated default: true enable_lazy_spilo_upgrade: type: boolean @@ -89,11 +96,13 @@ spec: default: false max_instances: type: integer - minimum: -1 # -1 = disabled + description: "-1 = disabled" + minimum: -1 default: -1 min_instances: type: integer - minimum: -1 # -1 = disabled + description: "-1 = disabled" + minimum: -1 default: -1 resync_period: type: string @@ -121,6 +130,20 @@ spec: users: type: object properties: + additional_owner_roles: + type: array + nullable: true + items: + type: string + enable_password_rotation: + type: boolean + default: false + password_rotation_interval: + type: integer + default: 90 + password_rotation_user_retention: + type: integer + default: 180 replication_username: type: string default: standby @@ -133,6 +156,10 @@ spec: major_version_upgrade_mode: type: string default: "off" + major_version_upgrade_team_allow_list: + type: array + items: + type: string minimal_major_version: type: string default: "9.6" @@ -170,12 +197,12 @@ spec: type: array items: type: string - enable_init_containers: - type: boolean - default: true enable_cross_namespace_secret: type: boolean default: false + enable_init_containers: + type: boolean + default: true enable_pod_antiaffinity: type: boolean default: false @@ -185,6 +212,10 @@ spec: enable_sidecars: type: boolean default: true + ignored_annotations: + type: array + items: + type: string infrastructure_roles_secret_name: type: string infrastructure_roles_secrets: @@ -228,6 +259,11 @@ spec: type: object additionalProperties: type: string + node_readiness_label_merge: + type: string + enum: + - "AND" + - "OR" oauth_token_secret_name: type: string default: "postgresql-operator" @@ -322,6 +358,12 @@ spec: timeouts: type: object properties: + patroni_api_check_interval: + type: string + default: "1s" + patroni_api_check_timeout: + type: string + default: "5s" pod_label_wait_timeout: type: string default: "10m" @@ -353,9 +395,15 @@ spec: enable_master_load_balancer: type: boolean default: true + enable_master_pooler_load_balancer: + type: boolean + default: false enable_replica_load_balancer: type: boolean default: false + enable_replica_pooler_load_balancer: + type: boolean + default: false external_traffic_policy: type: string enum: @@ -391,18 +439,18 @@ spec: type: string log_s3_bucket: type: string + wal_az_storage_account: + type: string wal_gs_bucket: type: string wal_s3_bucket: type: string - wal_az_storage_account: - type: string logical_backup: type: object properties: logical_backup_docker_image: type: string - default: "registry.opensource.zalan.do/acid/logical-backup:v1.7.1" + default: "registry.opensource.zalan.do/acid/logical-backup:v1.8.0" logical_backup_google_application_credentials: type: string logical_backup_job_prefix: @@ -423,6 +471,8 @@ spec: type: string logical_backup_s3_sse: type: string + logical_backup_s3_retention_time: + type: string logical_backup_schedule: type: string pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' @@ -473,6 +523,7 @@ spec: type: string default: - admin + - cron_admin role_deletion_suffix: type: string default: "_deleted" @@ -537,7 +588,7 @@ spec: default: "pooler" connection_pooler_image: type: string - default: "registry.opensource.zalan.do/acid/pgbouncer:master-19" + default: "registry.opensource.zalan.do/acid/pgbouncer:master-22" connection_pooler_max_db_connections: type: integer default: 60 diff --git a/charts/postgres-operator/crds/postgresqls.yaml b/charts/postgres-operator/crds/postgresqls.yaml index 9ac4cfb..8534650 100644 --- a/charts/postgres-operator/crds/postgresqls.yaml +++ b/charts/postgres-operator/crds/postgresqls.yaml @@ -4,8 +4,6 @@ metadata: name: postgresqls.acid.zalan.do labels: app.kubernetes.io/name: postgres-operator - annotations: - "helm.sh/hook": crd-install spec: group: acid.zalan.do names: @@ -149,18 +147,12 @@ spec: - "transaction" numberOfInstances: type: integer - minimum: 2 + minimum: 1 resources: type: object - required: - - requests - - limits properties: limits: type: object - required: - - cpu - - memory properties: cpu: type: string @@ -170,9 +162,6 @@ spec: pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' requests: type: object - required: - - cpu - - memory properties: cpu: type: string @@ -199,16 +188,27 @@ spec: type: boolean enableMasterLoadBalancer: type: boolean + enableMasterPoolerLoadBalancer: + type: boolean enableReplicaLoadBalancer: type: boolean + enableReplicaPoolerLoadBalancer: + type: boolean enableShmVolume: type: boolean - init_containers: # deprecated + env: type: array nullable: true items: type: object x-kubernetes-preserve-unknown-fields: true + init_containers: + type: array + description: deprecated + nullable: true + items: + type: object + x-kubernetes-preserve-unknown-fields: true initContainers: type: array nullable: true @@ -231,8 +231,8 @@ spec: items: type: object required: - - weight - preference + - weight properties: preference: type: object @@ -344,14 +344,17 @@ spec: type: boolean synchronous_mode_strict: type: boolean + synchronous_node_count: + type: integer ttl: type: integer podAnnotations: type: object additionalProperties: type: string - pod_priority_class_name: # deprecated + pod_priority_class_name: type: string + description: deprecated podPriorityClassName: type: string postgresql: @@ -395,19 +398,14 @@ spec: type: boolean secretNamespace: type: string - replicaLoadBalancer: # deprecated + replicaLoadBalancer: type: boolean + description: deprecated resources: type: object - required: - - requests - - limits properties: limits: type: object - required: - - cpu - - memory properties: cpu: type: string @@ -436,9 +434,6 @@ spec: # than the corresponding limit. requests: type: object - required: - - cpu - - memory properties: cpu: type: string @@ -466,11 +461,55 @@ spec: type: integer standby: type: object - required: - - s3_wal_path properties: s3_wal_path: type: string + gs_wal_path: + type: string + standby_host: + type: string + standby_port: + type: string + oneOf: + - required: + - s3_wal_path + - required: + - gs_wal_path + - required: + - standby_host + streams: + type: array + nullable: true + items: + type: object + required: + - applicationId + - database + - tables + properties: + applicationId: + type: string + batchSize: + type: integer + database: + type: string + filter: + type: object + additionalProperties: + type: string + tables: + type: object + additionalProperties: + type: object + required: + - eventType + properties: + eventType: + type: string + idColumn: + type: string + payloadColumn: + type: string teamId: type: string tls: @@ -492,10 +531,6 @@ spec: type: array items: type: object - required: - - key - - operator - - effect properties: key: type: string @@ -514,14 +549,14 @@ spec: - PreferNoSchedule tolerationSeconds: type: integer - useLoadBalancer: # deprecated + useLoadBalancer: type: boolean + description: deprecated users: type: object additionalProperties: type: array nullable: true - description: "Role flags specified here must not contradict each other" items: type: string enum: @@ -553,6 +588,16 @@ spec: - SUPERUSER - nosuperuser - NOSUPERUSER + usersWithPasswordRotation: + type: array + nullable: true + items: + type: string + usersWithInPlacePasswordRotation: + type: array + nullable: true + items: + type: string volume: type: object required: diff --git a/charts/postgres-operator/crds/postgresteams.yaml b/charts/postgres-operator/crds/postgresteams.yaml index fbf873b..b7a3684 100644 --- a/charts/postgres-operator/crds/postgresteams.yaml +++ b/charts/postgres-operator/crds/postgresteams.yaml @@ -4,8 +4,6 @@ metadata: name: postgresteams.acid.zalan.do labels: app.kubernetes.io/name: postgres-operator - annotations: - "helm.sh/hook": crd-install spec: group: acid.zalan.do names: diff --git a/charts/postgres-operator/templates/clusterrole-postgres-pod.yaml b/charts/postgres-operator/templates/clusterrole-postgres-pod.yaml index 33c4382..fdccf16 100644 --- a/charts/postgres-operator/templates/clusterrole-postgres-pod.yaml +++ b/charts/postgres-operator/templates/clusterrole-postgres-pod.yaml @@ -9,7 +9,7 @@ metadata: app.kubernetes.io/managed-by: {{ .Release.Service }} app.kubernetes.io/instance: {{ .Release.Name }} rules: -# Patroni needs to watch and manage endpoints +# Patroni needs to watch and manage config maps or endpoints {{- if toString .Values.configGeneral.kubernetes_use_configmaps | eq "true" }} - apiGroups: - "" @@ -24,12 +24,6 @@ rules: - patch - update - watch -- apiGroups: - - "" - resources: - - endpoints - verbs: - - get {{- else }} - apiGroups: - "" diff --git a/charts/postgres-operator/templates/clusterrole.yaml b/charts/postgres-operator/templates/clusterrole.yaml index 885bad3..199086a 100644 --- a/charts/postgres-operator/templates/clusterrole.yaml +++ b/charts/postgres-operator/templates/clusterrole.yaml @@ -34,16 +34,34 @@ rules: - get - list - watch +# all verbs allowed for event streams +{{- if .Values.enableStreams }} +- apiGroups: + - zalando.org + resources: + - fabriceventstreams + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch +{{- end }} # to create or get/update CRDs when starting up - apiGroups: - apiextensions.k8s.io resources: - customresourcedefinitions verbs: - - create - get +{{- if toString .Values.configGeneral.enable_crd_registration | eq "true" }} + - create - patch - update +{{- end }} # to send events to the CRs - apiGroups: - "" @@ -71,12 +89,6 @@ rules: - patch - update - watch -- apiGroups: - - "" - resources: - - endpoints - verbs: - - get {{- else }} # to read configuration from ConfigMaps - apiGroups: diff --git a/charts/postgres-operator/templates/crds.yaml b/charts/postgres-operator/templates/crds.yaml deleted file mode 100644 index 7338300..0000000 --- a/charts/postgres-operator/templates/crds.yaml +++ /dev/null @@ -1,6 +0,0 @@ -{{ if .Values.crd.create }} -{{- range $path, $bytes := .Files.Glob "crds/*.yaml" }} -{{ $.Files.Get $path }} ---- -{{- end }} -{{- end }} diff --git a/charts/postgres-operator/templates/user-facing-clusterroles.yaml b/charts/postgres-operator/templates/user-facing-clusterroles.yaml new file mode 100644 index 0000000..d7db347 --- /dev/null +++ b/charts/postgres-operator/templates/user-facing-clusterroles.yaml @@ -0,0 +1,71 @@ +{{ if .Values.rbac.createAggregateClusterRoles }} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + rbac.authorization.k8s.io/aggregate-to-admin: "true" + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator.fullname" . }}:users:admin +rules: +- apiGroups: + - acid.zalan.do + resources: + - postgresqls + - postgresqls/status + verbs: + - create + - delete + - deletecollection + - get + - list + - patch + - update + - watch + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + rbac.authorization.k8s.io/aggregate-to-edit: "true" + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator.fullname" . }}:users:edit +rules: +- apiGroups: + - acid.zalan.do + resources: + - postgresqls + verbs: + - create + - update + - patch + - delete + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + rbac.authorization.k8s.io/aggregate-to-view: "true" + app.kubernetes.io/name: {{ template "postgres-operator.name" . }} + helm.sh/chart: {{ template "postgres-operator.chart" . }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + name: {{ template "postgres-operator.fullname" . }}:users:view +rules: +- apiGroups: + - acid.zalan.do + resources: + - postgresqls + - postgresqls/status + verbs: + - get + - list + - watch +{{ end }} diff --git a/charts/postgres-operator/values.yaml b/charts/postgres-operator/values.yaml index 512e80d..7156cf9 100644 --- a/charts/postgres-operator/values.yaml +++ b/charts/postgres-operator/values.yaml @@ -1,7 +1,7 @@ image: registry: registry.opensource.zalan.do repository: acid/postgres-operator - tag: v1.7.1 + tag: v1.8.0 pullPolicy: "IfNotPresent" # Optionally specify an array of imagePullSecrets. @@ -18,8 +18,11 @@ enableJsonLogging: false # general configuration parameters configGeneral: - # choose if deployment creates/updates CRDs with OpenAPIV3Validation - enable_crd_validation: true + # the deployment should create/update the CRDs + enable_crd_registration: true + # specify categories under which crds should be listed + crd_categories: + - "all" # update only the statefulsets without immediately doing the rolling update enable_lazy_spilo_upgrade: false # set the PGVERSION env var instead of providing the version via postgresql.bin_dir in SPILO_CONFIGURATION @@ -33,7 +36,7 @@ configGeneral: # Select if setup uses endpoints (default), or configmaps to manage leader (DCS=k8s) # kubernetes_use_configmaps: false # Spilo docker image - docker_image: registry.opensource.zalan.do/acid/spilo-14:2.1-p4 + docker_image: registry.opensource.zalan.do/acid/spilo-14:2.1-p5 # min number of instances in Postgres cluster. -1 = no limit min_instances: -1 # max number of instances in Postgres cluster. -1 = no limit @@ -54,6 +57,16 @@ configGeneral: # parameters describing Postgres users configUsers: + # roles to be granted to database owners + # additional_owner_roles: + # - cron_admin + + # enable password rotation for app users that are not database owners + enable_password_rotation: false + # rotation interval for updating credentials in K8s secrets of app users + password_rotation_interval: 90 + # retention interval to keep rotation users + password_rotation_user_retention: 180 # postgres username used for replication between instances replication_username: standby # postgres superuser name to be created by initdb @@ -62,6 +75,10 @@ configUsers: configMajorVersionUpgrade: # "off": no upgrade, "manual": manifest triggers action, "full": minimal version violation triggers too major_version_upgrade_mode: "off" + # upgrades will only be carried out for clusters of listed teams when mode is "off" + # major_version_upgrade_team_allow_list: + # - acid + # minimal Postgres major version that will not automatically be upgraded minimal_major_version: "9.6" # target Postgres major version when upgrading clusters automatically @@ -105,6 +122,11 @@ configKubernetes: enable_pod_disruption_budget: true # enables sidecar containers to run alongside Spilo in the same pod enable_sidecars: true + + # annotations to be ignored when comparing statefulsets, services etc. + # ignored_annotations: + # - k8s.v1.cni.cncf.io/network-status + # namespaced name of the secret containing infrastructure roles names and passwords # infrastructure_roles_secret_name: postgresql-infrastructure-roles @@ -124,6 +146,9 @@ configKubernetes: # node_readiness_label: # status: ready + # defines how nodeAffinity from manifest should be merged with node_readiness_label + # node_readiness_label_merge: "OR" + # namespaced name of the secret containing the OAuth2 token to pass to the teams API # oauth_token_secret_name: postgresql-operator @@ -190,6 +215,10 @@ configPostgresPodResources: # timeouts related to some operator actions configTimeouts: + # interval between consecutive attempts of operator calling the Patroni API + patroni_api_check_interval: 1s + # timeout when waiting for successful response from Patroni API + patroni_api_check_timeout: 5s # timeout when waiting for the Postgres pods to be deleted pod_deletion_wait_timeout: 10m # timeout when waiting for pod role and cluster labels @@ -214,8 +243,12 @@ configLoadBalancer: # toggles service type load balancer pointing to the master pod of the cluster enable_master_load_balancer: false + # toggles service type load balancer pointing to the master pooler pod of the cluster + enable_master_pooler_load_balancer: false # toggles service type load balancer pointing to the replica pod of the cluster enable_replica_load_balancer: false + # toggles service type load balancer pointing to the replica pooler pod of the cluster + enable_replica_pooler_load_balancer: false # define external traffic policy for the load balancer external_traffic_policy: "Cluster" # defines the DNS name string template for the master load balancer cluster @@ -276,7 +309,7 @@ configAwsOrGcp: # configure K8s cron job managed by the operator configLogicalBackup: # image for pods of the logical backup job (example runs pg_dumpall) - logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v1.7.1" + logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v1.8.0" # path of google cloud service account json file # logical_backup_google_application_credentials: "" @@ -296,6 +329,8 @@ configLogicalBackup: logical_backup_s3_secret_access_key: "" # S3 server side encryption logical_backup_s3_sse: "AES256" + # S3 retention time for stored backups for example "2 week" or "7 days" + logical_backup_s3_retention_time: "" # backup schedule in the cron format logical_backup_schedule: "30 00 * * *" @@ -324,6 +359,7 @@ configTeamsApi: # List of roles that cannot be overwritten by an application, team or infrastructure role protected_role_names: - admin + - cron_admin # Suffix to add if members are removed from TeamsAPI or PostgresTeam CRD role_deletion_suffix: "_deleted" # role name to grant to team members created from the Teams API @@ -341,7 +377,7 @@ configConnectionPooler: # db user for pooler to use connection_pooler_user: "pooler" # docker image - connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-19" + connection_pooler_image: "registry.opensource.zalan.do/acid/pgbouncer:master-22" # max db connections the pooler should hold connection_pooler_max_db_connections: 60 # default pooling mode @@ -354,14 +390,14 @@ configConnectionPooler: connection_pooler_default_cpu_limit: "1" connection_pooler_default_memory_limit: 100Mi +# Zalando's internal CDC stream feature +enableStreams: false + rbac: # Specifies whether RBAC resources should be created create: true - -crd: - # Specifies whether custom resource definitions should be created - # When using helm3, this is ignored; instead use "--skip-crds" to skip. - create: true + # Specifies whether ClusterRoles that are aggregated into the K8s default roles should be created. (https://kubernetes.io/docs/reference/access-authn-authz/rbac/#default-roles-and-role-bindings) + createAggregateClusterRoles: false serviceAccount: # Specifies whether a ServiceAccount should be created