From 3168da624c07c63697dcb25dff346d43f494fa13 Mon Sep 17 00:00:00 2001 From: Felix Kunde Date: Mon, 4 Jan 2021 18:19:36 +0100 Subject: [PATCH] add default values to operatorconfiguration crd --- .../crds/operatorconfigurations.yaml | 107 ++++++++++++++++-- .../postgres-operator-1.6.0.tgz | Bin 18549 -> 19010 bytes docs/reference/operator_parameters.md | 2 +- manifests/operatorconfiguration.crd.yaml | 107 ++++++++++++++++-- pkg/controller/operator_config.go | 4 +- pkg/util/config/config.go | 4 +- pkg/util/util.go | 8 ++ 7 files changed, 205 insertions(+), 27 deletions(-) diff --git a/charts/postgres-operator/crds/operatorconfigurations.yaml b/charts/postgres-operator/crds/operatorconfigurations.yaml index 2ac9ca7fc..3c9a2ece2 100644 --- a/charts/postgres-operator/crds/operatorconfigurations.yaml +++ b/charts/postgres-operator/crds/operatorconfigurations.yaml @@ -65,32 +65,45 @@ spec: properties: docker_image: type: string + default: "registry.opensource.zalan.do/acid/spilo-13:2.0-p2" enable_crd_validation: type: boolean + default: true enable_lazy_spilo_upgrade: type: boolean + default: false enable_pgversion_env_var: type: boolean + default: true enable_shm_volume: type: boolean + default: true enable_spilo_wal_path_compat: type: boolean + default: false etcd_host: type: string + default: "" kubernetes_use_configmaps: type: boolean + default: false max_instances: type: integer minimum: -1 # -1 = disabled + default: -1 min_instances: type: integer minimum: -1 # -1 = disabled + default: -1 resync_period: type: string + default: "30m" repair_period: type: string + default: "5m" set_memory_request_to_limit: type: boolean + default: false sidecar_docker_images: type: object additionalProperties: @@ -104,24 +117,31 @@ spec: workers: type: integer minimum: 1 + default: 8 users: type: object properties: replication_username: type: string + default: standby super_username: type: string + default: postgres kubernetes: type: object properties: cluster_domain: type: string + default: "cluster.local" cluster_labels: type: object additionalProperties: type: string + default: + application: spilo cluster_name_label: type: string + default: "cluster-name" custom_pod_annotations: type: object additionalProperties: @@ -136,12 +156,16 @@ spec: type: string enable_init_containers: type: boolean + default: true enable_pod_antiaffinity: type: boolean + default: false enable_pod_disruption_budget: type: boolean + default: true enable_sidecars: type: boolean + default: true infrastructure_roles_secret_name: type: string infrastructure_roles_secrets: @@ -180,16 +204,20 @@ spec: type: string master_pod_move_timeout: type: string + default: "20m" node_readiness_label: type: object additionalProperties: type: string oauth_token_secret_name: type: string + default: "postgresql-operator" pdb_name_format: type: string + default: "postgres-{cluster}-pdb" pod_antiaffinity_topology_key: type: string + default: "kubernetes.io/hostname" pod_environment_configmap: type: string pod_environment_secret: @@ -199,20 +227,27 @@ spec: enum: - "ordered_ready" - "parallel" + default: "ordered_ready" pod_priority_class_name: type: string pod_role_label: type: string + default: "spilo-role" pod_service_account_definition: type: string + default: "" pod_service_account_name: type: string + default: "postgres-pod" pod_service_account_role_binding_definition: type: string + default: "" pod_terminate_grace_period: type: string + default: "5m" secret_name_template: type: string + default: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}" spilo_runasuser: type: integer spilo_runasgroup: @@ -221,12 +256,14 @@ spec: type: integer spilo_privileged: type: boolean + default: false storage_resize_mode: type: string enum: - "ebs" - "pvc" - "off" + default: "pvc" toleration: type: object additionalProperties: @@ -239,36 +276,48 @@ spec: default_cpu_limit: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "1" default_cpu_request: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "100m" default_memory_limit: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "500Mi" default_memory_request: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "100Mi" min_cpu_limit: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "250m" min_memory_limit: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "250Mi" timeouts: type: object properties: pod_label_wait_timeout: type: string + default: "10m" pod_deletion_wait_timeout: type: string + default: "10m" ready_wait_interval: type: string + default: "4s" ready_wait_timeout: type: string + default: "30s" resource_check_interval: type: string + default: "3s" resource_check_timeout: type: string + default: "10m" load_balancer: type: object properties: @@ -278,19 +327,25 @@ spec: type: string db_hosted_zone: type: string + default: "db.example.com" enable_master_load_balancer: type: boolean + default: false enable_replica_load_balancer: type: boolean + default: false external_traffic_policy: type: string enum: - "Cluster" - "Local" + default: "Cluster" master_dns_name_format: type: string + default: "{cluster}.{team}.{hostedzone}" replica_dns_name_format: type: string + default: "{cluster}-repl.{team}.{hostedzone}" aws_or_gcp: type: object properties: @@ -298,12 +353,16 @@ spec: type: string additional_secret_mount_path: type: string + default: "/meta/credentials" aws_region: type: string + default: "eu-central-1" enable_ebs_gp3_migration: type: boolean + default: false enable_ebs_gp3_migration_max_size: type: integer + default: 1000 gcp_credentials: type: string kube_iam_role: @@ -319,10 +378,12 @@ spec: properties: logical_backup_docker_image: type: string + default: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0" logical_backup_google_application_credentials: type: string logical_backup_provider: type: string + default: "s3" logical_backup_s3_access_key_id: type: string logical_backup_s3_bucket: @@ -338,30 +399,40 @@ spec: logical_backup_schedule: type: string pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' + default: "30 00 * * *" debug: type: object properties: debug_logging: type: boolean + default: true enable_database_access: type: boolean + default: true teams_api: type: object properties: enable_admin_role_for_users: type: boolean + default: true enable_postgres_team_crd: type: boolean + default: true enable_postgres_team_crd_superusers: type: boolean + default: false enable_team_superuser: type: boolean + default: false enable_teams_api: type: boolean + default: true pam_configuration: type: string + default: "https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees" pam_role_name: type: string + default: "zalandos" postgres_superuser_teams: type: array items: @@ -370,23 +441,32 @@ spec: type: array items: type: string + default: + - admin team_admin_role: type: string + default: "admin" team_api_role_configuration: type: object additionalProperties: type: string + default: + log_statement: all teams_api_url: type: string + defaults: "https://teams.example.com/api/" logging_rest_api: type: object properties: api_port: type: integer + default: 8080 cluster_history_entries: type: integer + default: 1000 ring_log_lines: type: integer + default: 100 scalyr: # deprecated type: object properties: @@ -395,60 +475,65 @@ spec: scalyr_cpu_limit: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "1" scalyr_cpu_request: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "100m" scalyr_image: type: string scalyr_memory_limit: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "500Mi" scalyr_memory_request: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "50Mi" scalyr_server_url: type: string + default: "https://upload.eu.scalyr.com" connection_pooler: type: object properties: connection_pooler_schema: type: string - #default: "pooler" + default: "pooler" connection_pooler_user: type: string - #default: "pooler" + default: "pooler" connection_pooler_image: type: string - #default: "registry.opensource.zalan.do/acid/pgbouncer" + default: "registry.opensource.zalan.do/acid/pgbouncer:master-12" connection_pooler_max_db_connections: type: integer - #default: 60 + default: 60 connection_pooler_mode: type: string enum: - "session" - "transaction" - #default: "transaction" + default: "transaction" connection_pooler_number_of_instances: type: integer - minimum: 2 - #default: 2 + minimum: 1 + default: 2 connection_pooler_default_cpu_limit: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' - #default: "1" + default: "1" connection_pooler_default_cpu_request: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' - #default: "500m" + default: "500m" connection_pooler_default_memory_limit: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' - #default: "100Mi" + default: "100Mi" connection_pooler_default_memory_request: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' - #default: "100Mi" + default: "100Mi" status: type: object additionalProperties: diff --git a/charts/postgres-operator/postgres-operator-1.6.0.tgz b/charts/postgres-operator/postgres-operator-1.6.0.tgz index b57f99027d13b696e638eb10a52b7ab03e24ca4c..34fd9b4f5c7b852ecdfaad30ad1f97faea77d4ec 100644 GIT binary patch delta 18698 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 Z$LH~Re7?-{{{;X5|Nq=tvuyyL0RXJYifaG> delta 18303 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

bj`^}RTDYvobzsB} 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 diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 01e5c4039..87f065044 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -561,7 +561,7 @@ grouped under the `logical_backup` key. runs `pg_dumpall` on a replica if possible and uploads compressed results to an S3 bucket under the key `/spilo/pg_cluster_name/cluster_k8s_uuid/logical_backups`. The default image is the same image built with the Zalando-internal CI - pipeline. Default: "registry.opensource.zalan.do/acid/logical-backup" + pipeline. Default: "registry.opensource.zalan.do/acid/logical-backup:v.1.6.0" * **logical_backup_provider** Specifies the storage provider to which the backup should be uploaded (`s3` or `gcs`). diff --git a/manifests/operatorconfiguration.crd.yaml b/manifests/operatorconfiguration.crd.yaml index 50405a8cc..3cc43a616 100644 --- a/manifests/operatorconfiguration.crd.yaml +++ b/manifests/operatorconfiguration.crd.yaml @@ -61,32 +61,45 @@ spec: properties: docker_image: type: string + default: "registry.opensource.zalan.do/acid/spilo-13:2.0-p2" enable_crd_validation: type: boolean + default: true enable_lazy_spilo_upgrade: type: boolean + default: false enable_pgversion_env_var: type: boolean + default: true enable_shm_volume: type: boolean + default: true enable_spilo_wal_path_compat: type: boolean + default: false etcd_host: type: string + default: "" kubernetes_use_configmaps: type: boolean + default: false max_instances: type: integer minimum: -1 # -1 = disabled + default: -1 min_instances: type: integer minimum: -1 # -1 = disabled + default: -1 resync_period: type: string + default: "30m" repair_period: type: string + default: "5m" set_memory_request_to_limit: type: boolean + default: false sidecar_docker_images: type: object additionalProperties: @@ -100,24 +113,31 @@ spec: workers: type: integer minimum: 1 + default: 8 users: type: object properties: replication_username: type: string + default: standby super_username: type: string + default: postgres kubernetes: type: object properties: cluster_domain: type: string + default: "cluster.local" cluster_labels: type: object additionalProperties: type: string + default: + application: spilo cluster_name_label: type: string + default: "cluster-name" custom_pod_annotations: type: object additionalProperties: @@ -132,12 +152,16 @@ spec: type: string enable_init_containers: type: boolean + default: true enable_pod_antiaffinity: type: boolean + default: false enable_pod_disruption_budget: type: boolean + default: true enable_sidecars: type: boolean + default: true infrastructure_roles_secret_name: type: string infrastructure_roles_secrets: @@ -176,16 +200,20 @@ spec: type: string master_pod_move_timeout: type: string + default: "20m" node_readiness_label: type: object additionalProperties: type: string oauth_token_secret_name: type: string + default: "postgresql-operator" pdb_name_format: type: string + default: "postgres-{cluster}-pdb" pod_antiaffinity_topology_key: type: string + default: "kubernetes.io/hostname" pod_environment_configmap: type: string pod_environment_secret: @@ -195,20 +223,27 @@ spec: enum: - "ordered_ready" - "parallel" + default: "ordered_ready" pod_priority_class_name: type: string pod_role_label: type: string + default: "spilo-role" pod_service_account_definition: type: string + default: "" pod_service_account_name: type: string + default: "postgres-pod" pod_service_account_role_binding_definition: type: string + default: "" pod_terminate_grace_period: type: string + default: "5m" secret_name_template: type: string + default: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}" spilo_runasuser: type: integer spilo_runasgroup: @@ -217,12 +252,14 @@ spec: type: integer spilo_privileged: type: boolean + default: false storage_resize_mode: type: string enum: - "ebs" - "pvc" - "off" + default: "pvc" toleration: type: object additionalProperties: @@ -235,36 +272,48 @@ spec: default_cpu_limit: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "1" default_cpu_request: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "100m" default_memory_limit: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "500Mi" default_memory_request: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "100Mi" min_cpu_limit: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "250m" min_memory_limit: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "250Mi" timeouts: type: object properties: pod_label_wait_timeout: type: string + default: "10m" pod_deletion_wait_timeout: type: string + default: "10m" ready_wait_interval: type: string + default: "4s" ready_wait_timeout: type: string + default: "30s" resource_check_interval: type: string + default: "3s" resource_check_timeout: type: string + default: "10m" load_balancer: type: object properties: @@ -274,19 +323,25 @@ spec: type: string db_hosted_zone: type: string + default: "db.example.com" enable_master_load_balancer: type: boolean + default: false enable_replica_load_balancer: type: boolean + default: false external_traffic_policy: type: string enum: - "Cluster" - "Local" + default: "Cluster" master_dns_name_format: type: string + default: "{cluster}.{team}.{hostedzone}" replica_dns_name_format: type: string + default: "{cluster}-repl.{team}.{hostedzone}" aws_or_gcp: type: object properties: @@ -294,12 +349,16 @@ spec: type: string additional_secret_mount_path: type: string + default: "/meta/credentials" aws_region: type: string + default: "eu-central-1" enable_ebs_gp3_migration: type: boolean + default: false enable_ebs_gp3_migration_max_size: type: integer + default: 1000 gcp_credentials: type: string kube_iam_role: @@ -315,10 +374,12 @@ spec: properties: logical_backup_docker_image: type: string + default: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0" logical_backup_google_application_credentials: type: string logical_backup_provider: type: string + default: "s3" logical_backup_s3_access_key_id: type: string logical_backup_s3_bucket: @@ -334,30 +395,40 @@ spec: logical_backup_schedule: type: string pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' + default: "30 00 * * *" debug: type: object properties: debug_logging: type: boolean + default: true enable_database_access: type: boolean + default: true teams_api: type: object properties: enable_admin_role_for_users: type: boolean + default: true enable_postgres_team_crd: type: boolean + default: true enable_postgres_team_crd_superusers: type: boolean + default: false enable_team_superuser: type: boolean + default: false enable_teams_api: type: boolean + default: true pam_configuration: type: string + default: "https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees" pam_role_name: type: string + default: "zalandos" postgres_superuser_teams: type: array items: @@ -366,23 +437,32 @@ spec: type: array items: type: string + default: + - admin team_admin_role: type: string + default: "admin" team_api_role_configuration: type: object additionalProperties: type: string + default: + log_statement: all teams_api_url: type: string + defaults: "https://teams.example.com/api/" logging_rest_api: type: object properties: api_port: type: integer + default: 8080 cluster_history_entries: type: integer + default: 1000 ring_log_lines: type: integer + default: 100 scalyr: # deprecated type: object properties: @@ -391,60 +471,65 @@ spec: scalyr_cpu_limit: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "1" scalyr_cpu_request: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' + default: "100m" scalyr_image: type: string scalyr_memory_limit: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "500Mi" scalyr_memory_request: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' + default: "50Mi" scalyr_server_url: type: string + default: "https://upload.eu.scalyr.com" connection_pooler: type: object properties: connection_pooler_schema: type: string - #default: "pooler" + default: "pooler" connection_pooler_user: type: string - #default: "pooler" + default: "pooler" connection_pooler_image: type: string - #default: "registry.opensource.zalan.do/acid/pgbouncer" + default: "registry.opensource.zalan.do/acid/pgbouncer:master-12" connection_pooler_max_db_connections: type: integer - #default: 60 + default: 60 connection_pooler_mode: type: string enum: - "session" - "transaction" - #default: "transaction" + default: "transaction" connection_pooler_number_of_instances: type: integer - minimum: 2 - #default: 2 + minimum: 1 + default: 2 connection_pooler_default_cpu_limit: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' - #default: "1" + default: "1" connection_pooler_default_cpu_request: type: string pattern: '^(\d+m|\d+(\.\d{1,3})?)$' - #default: "500m" + default: "500m" connection_pooler_default_memory_limit: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' - #default: "100Mi" + default: "100Mi" connection_pooler_default_memory_request: type: string pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' - #default: "100Mi" + default: "100Mi" status: type: object additionalProperties: diff --git a/pkg/controller/operator_config.go b/pkg/controller/operator_config.go index a55dab2d8..024d6c260 100644 --- a/pkg/controller/operator_config.go +++ b/pkg/controller/operator_config.go @@ -141,11 +141,11 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur result.AdditionalSecretMount = fromCRD.AWSGCP.AdditionalSecretMount result.AdditionalSecretMountPath = util.Coalesce(fromCRD.AWSGCP.AdditionalSecretMountPath, "/meta/credentials") result.EnableEBSGp3Migration = fromCRD.AWSGCP.EnableEBSGp3Migration - result.EnableEBSGp3MigrationMaxSize = fromCRD.AWSGCP.EnableEBSGp3MigrationMaxSize + result.EnableEBSGp3MigrationMaxSize = util.CoalesceInt64(fromCRD.AWSGCP.EnableEBSGp3MigrationMaxSize, 1000) // logical backup config result.LogicalBackupSchedule = util.Coalesce(fromCRD.LogicalBackup.Schedule, "30 00 * * *") - result.LogicalBackupDockerImage = util.Coalesce(fromCRD.LogicalBackup.DockerImage, "registry.opensource.zalan.do/acid/logical-backup") + result.LogicalBackupDockerImage = util.Coalesce(fromCRD.LogicalBackup.DockerImage, "registry.opensource.zalan.do/acid/logical-backup:v.1.6.0") result.LogicalBackupProvider = util.Coalesce(fromCRD.LogicalBackup.BackupProvider, "s3") result.LogicalBackupS3Bucket = fromCRD.LogicalBackup.S3Bucket result.LogicalBackupS3Region = fromCRD.LogicalBackup.S3Region diff --git a/pkg/util/config/config.go b/pkg/util/config/config.go index 62cfdec57..72667df03 100644 --- a/pkg/util/config/config.go +++ b/pkg/util/config/config.go @@ -112,7 +112,7 @@ type Scalyr struct { // LogicalBackup defines configuration for logical backup type LogicalBackup struct { LogicalBackupSchedule string `name:"logical_backup_schedule" default:"30 00 * * *"` - LogicalBackupDockerImage string `name:"logical_backup_docker_image" default:"registry.opensource.zalan.do/acid/logical-backup"` + LogicalBackupDockerImage string `name:"logical_backup_docker_image" default:"registry.opensource.zalan.do/acid/logical-backup:v.1.6.0"` LogicalBackupProvider string `name:"logical_backup_provider" default:"s3"` LogicalBackupS3Bucket string `name:"logical_backup_s3_bucket" default:""` LogicalBackupS3Region string `name:"logical_backup_s3_region" default:""` @@ -176,7 +176,7 @@ type Config struct { EnableAdminRoleForUsers bool `name:"enable_admin_role_for_users" default:"true"` EnablePostgresTeamCRD bool `name:"enable_postgres_team_crd" default:"false"` EnablePostgresTeamCRDSuperusers bool `name:"enable_postgres_team_crd_superusers" default:"false"` - EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"true"` + EnableMasterLoadBalancer bool `name:"enable_master_load_balancer" default:"false"` EnableReplicaLoadBalancer bool `name:"enable_replica_load_balancer" default:"false"` CustomServiceAnnotations map[string]string `name:"custom_service_annotations"` CustomPodAnnotations map[string]string `name:"custom_pod_annotations"` diff --git a/pkg/util/util.go b/pkg/util/util.go index 20e2915ba..bebb9f8da 100644 --- a/pkg/util/util.go +++ b/pkg/util/util.go @@ -271,6 +271,14 @@ func CoalesceUInt32(val, defaultVal uint32) uint32 { return val } +// CoalesceInt64 works like coalesce but for int64 +func CoalesceInt64(val, defaultVal int64) int64 { + if val == 0 { + return defaultVal + } + return val +} + // CoalesceBool works like coalesce but for *bool func CoalesceBool(val, defaultVal *bool) *bool { if val == nil {