Merge branch 'master' into gh-pages

This commit is contained in:
Felix Kunde 2021-01-12 10:59:30 +01:00
commit 0cc2559b8e
51 changed files with 328 additions and 91 deletions

View File

@ -22,7 +22,7 @@ jobs:
- name: Run unit tests - name: Run unit tests
run: go test -race -covermode atomic -coverprofile=coverage.out ./... run: go test -race -covermode atomic -coverprofile=coverage.out ./...
- name: Convert coverage to lcov - name: Convert coverage to lcov
uses: jandelgado/gcov2lcov-action@v1.0.5 uses: jandelgado/gcov2lcov-action@v1.0.8
- name: Coveralls - name: Coveralls
uses: coverallsapp/github-action@master uses: coverallsapp/github-action@master
with: with:

View File

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2020 Zalando SE Copyright (c) 2021 Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -65,32 +65,45 @@ spec:
properties: properties:
docker_image: docker_image:
type: string type: string
default: "registry.opensource.zalan.do/acid/spilo-13:2.0-p2"
enable_crd_validation: enable_crd_validation:
type: boolean type: boolean
default: true
enable_lazy_spilo_upgrade: enable_lazy_spilo_upgrade:
type: boolean type: boolean
default: false
enable_pgversion_env_var: enable_pgversion_env_var:
type: boolean type: boolean
default: true
enable_shm_volume: enable_shm_volume:
type: boolean type: boolean
default: true
enable_spilo_wal_path_compat: enable_spilo_wal_path_compat:
type: boolean type: boolean
default: false
etcd_host: etcd_host:
type: string type: string
default: ""
kubernetes_use_configmaps: kubernetes_use_configmaps:
type: boolean type: boolean
default: false
max_instances: max_instances:
type: integer type: integer
minimum: -1 # -1 = disabled minimum: -1 # -1 = disabled
default: -1
min_instances: min_instances:
type: integer type: integer
minimum: -1 # -1 = disabled minimum: -1 # -1 = disabled
default: -1
resync_period: resync_period:
type: string type: string
default: "30m"
repair_period: repair_period:
type: string type: string
default: "5m"
set_memory_request_to_limit: set_memory_request_to_limit:
type: boolean type: boolean
default: false
sidecar_docker_images: sidecar_docker_images:
type: object type: object
additionalProperties: additionalProperties:
@ -104,24 +117,31 @@ spec:
workers: workers:
type: integer type: integer
minimum: 1 minimum: 1
default: 8
users: users:
type: object type: object
properties: properties:
replication_username: replication_username:
type: string type: string
default: standby
super_username: super_username:
type: string type: string
default: postgres
kubernetes: kubernetes:
type: object type: object
properties: properties:
cluster_domain: cluster_domain:
type: string type: string
default: "cluster.local"
cluster_labels: cluster_labels:
type: object type: object
additionalProperties: additionalProperties:
type: string type: string
default:
application: spilo
cluster_name_label: cluster_name_label:
type: string type: string
default: "cluster-name"
custom_pod_annotations: custom_pod_annotations:
type: object type: object
additionalProperties: additionalProperties:
@ -136,12 +156,16 @@ spec:
type: string type: string
enable_init_containers: enable_init_containers:
type: boolean type: boolean
default: true
enable_pod_antiaffinity: enable_pod_antiaffinity:
type: boolean type: boolean
default: false
enable_pod_disruption_budget: enable_pod_disruption_budget:
type: boolean type: boolean
default: true
enable_sidecars: enable_sidecars:
type: boolean type: boolean
default: true
infrastructure_roles_secret_name: infrastructure_roles_secret_name:
type: string type: string
infrastructure_roles_secrets: infrastructure_roles_secrets:
@ -180,16 +204,20 @@ spec:
type: string type: string
master_pod_move_timeout: master_pod_move_timeout:
type: string type: string
default: "20m"
node_readiness_label: node_readiness_label:
type: object type: object
additionalProperties: additionalProperties:
type: string type: string
oauth_token_secret_name: oauth_token_secret_name:
type: string type: string
default: "postgresql-operator"
pdb_name_format: pdb_name_format:
type: string type: string
default: "postgres-{cluster}-pdb"
pod_antiaffinity_topology_key: pod_antiaffinity_topology_key:
type: string type: string
default: "kubernetes.io/hostname"
pod_environment_configmap: pod_environment_configmap:
type: string type: string
pod_environment_secret: pod_environment_secret:
@ -199,20 +227,27 @@ spec:
enum: enum:
- "ordered_ready" - "ordered_ready"
- "parallel" - "parallel"
default: "ordered_ready"
pod_priority_class_name: pod_priority_class_name:
type: string type: string
pod_role_label: pod_role_label:
type: string type: string
default: "spilo-role"
pod_service_account_definition: pod_service_account_definition:
type: string type: string
default: ""
pod_service_account_name: pod_service_account_name:
type: string type: string
default: "postgres-pod"
pod_service_account_role_binding_definition: pod_service_account_role_binding_definition:
type: string type: string
default: ""
pod_terminate_grace_period: pod_terminate_grace_period:
type: string type: string
default: "5m"
secret_name_template: secret_name_template:
type: string type: string
default: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}"
spilo_runasuser: spilo_runasuser:
type: integer type: integer
spilo_runasgroup: spilo_runasgroup:
@ -221,12 +256,14 @@ spec:
type: integer type: integer
spilo_privileged: spilo_privileged:
type: boolean type: boolean
default: false
storage_resize_mode: storage_resize_mode:
type: string type: string
enum: enum:
- "ebs" - "ebs"
- "pvc" - "pvc"
- "off" - "off"
default: "pvc"
toleration: toleration:
type: object type: object
additionalProperties: additionalProperties:
@ -239,36 +276,48 @@ spec:
default_cpu_limit: default_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "1"
default_cpu_request: default_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "100m"
default_memory_limit: default_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "500Mi"
default_memory_request: default_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "100Mi"
min_cpu_limit: min_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "250m"
min_memory_limit: min_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "250Mi"
timeouts: timeouts:
type: object type: object
properties: properties:
pod_label_wait_timeout: pod_label_wait_timeout:
type: string type: string
default: "10m"
pod_deletion_wait_timeout: pod_deletion_wait_timeout:
type: string type: string
default: "10m"
ready_wait_interval: ready_wait_interval:
type: string type: string
default: "4s"
ready_wait_timeout: ready_wait_timeout:
type: string type: string
default: "30s"
resource_check_interval: resource_check_interval:
type: string type: string
default: "3s"
resource_check_timeout: resource_check_timeout:
type: string type: string
default: "10m"
load_balancer: load_balancer:
type: object type: object
properties: properties:
@ -278,19 +327,25 @@ spec:
type: string type: string
db_hosted_zone: db_hosted_zone:
type: string type: string
default: "db.example.com"
enable_master_load_balancer: enable_master_load_balancer:
type: boolean type: boolean
default: true
enable_replica_load_balancer: enable_replica_load_balancer:
type: boolean type: boolean
default: false
external_traffic_policy: external_traffic_policy:
type: string type: string
enum: enum:
- "Cluster" - "Cluster"
- "Local" - "Local"
default: "Cluster"
master_dns_name_format: master_dns_name_format:
type: string type: string
default: "{cluster}.{team}.{hostedzone}"
replica_dns_name_format: replica_dns_name_format:
type: string type: string
default: "{cluster}-repl.{team}.{hostedzone}"
aws_or_gcp: aws_or_gcp:
type: object type: object
properties: properties:
@ -298,12 +353,16 @@ spec:
type: string type: string
additional_secret_mount_path: additional_secret_mount_path:
type: string type: string
default: "/meta/credentials"
aws_region: aws_region:
type: string type: string
default: "eu-central-1"
enable_ebs_gp3_migration: enable_ebs_gp3_migration:
type: boolean type: boolean
default: false
enable_ebs_gp3_migration_max_size: enable_ebs_gp3_migration_max_size:
type: integer type: integer
default: 1000
gcp_credentials: gcp_credentials:
type: string type: string
kube_iam_role: kube_iam_role:
@ -319,10 +378,15 @@ spec:
properties: properties:
logical_backup_docker_image: logical_backup_docker_image:
type: string type: string
default: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0"
logical_backup_google_application_credentials: logical_backup_google_application_credentials:
type: string type: string
logical_backup_job_prefix:
type: string
default: "logical-backup-"
logical_backup_provider: logical_backup_provider:
type: string type: string
default: "s3"
logical_backup_s3_access_key_id: logical_backup_s3_access_key_id:
type: string type: string
logical_backup_s3_bucket: logical_backup_s3_bucket:
@ -338,30 +402,40 @@ spec:
logical_backup_schedule: logical_backup_schedule:
type: string type: string
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
default: "30 00 * * *"
debug: debug:
type: object type: object
properties: properties:
debug_logging: debug_logging:
type: boolean type: boolean
default: true
enable_database_access: enable_database_access:
type: boolean type: boolean
default: true
teams_api: teams_api:
type: object type: object
properties: properties:
enable_admin_role_for_users: enable_admin_role_for_users:
type: boolean type: boolean
default: true
enable_postgres_team_crd: enable_postgres_team_crd:
type: boolean type: boolean
default: true
enable_postgres_team_crd_superusers: enable_postgres_team_crd_superusers:
type: boolean type: boolean
default: false
enable_team_superuser: enable_team_superuser:
type: boolean type: boolean
default: false
enable_teams_api: enable_teams_api:
type: boolean type: boolean
default: true
pam_configuration: pam_configuration:
type: string type: string
default: "https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees"
pam_role_name: pam_role_name:
type: string type: string
default: "zalandos"
postgres_superuser_teams: postgres_superuser_teams:
type: array type: array
items: items:
@ -370,23 +444,32 @@ spec:
type: array type: array
items: items:
type: string type: string
default:
- admin
team_admin_role: team_admin_role:
type: string type: string
default: "admin"
team_api_role_configuration: team_api_role_configuration:
type: object type: object
additionalProperties: additionalProperties:
type: string type: string
default:
log_statement: all
teams_api_url: teams_api_url:
type: string type: string
defaults: "https://teams.example.com/api/"
logging_rest_api: logging_rest_api:
type: object type: object
properties: properties:
api_port: api_port:
type: integer type: integer
default: 8080
cluster_history_entries: cluster_history_entries:
type: integer type: integer
default: 1000
ring_log_lines: ring_log_lines:
type: integer type: integer
default: 100
scalyr: # deprecated scalyr: # deprecated
type: object type: object
properties: properties:
@ -395,60 +478,65 @@ spec:
scalyr_cpu_limit: scalyr_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "1"
scalyr_cpu_request: scalyr_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "100m"
scalyr_image: scalyr_image:
type: string type: string
scalyr_memory_limit: scalyr_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "500Mi"
scalyr_memory_request: scalyr_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "50Mi"
scalyr_server_url: scalyr_server_url:
type: string type: string
default: "https://upload.eu.scalyr.com"
connection_pooler: connection_pooler:
type: object type: object
properties: properties:
connection_pooler_schema: connection_pooler_schema:
type: string type: string
#default: "pooler" default: "pooler"
connection_pooler_user: connection_pooler_user:
type: string type: string
#default: "pooler" default: "pooler"
connection_pooler_image: connection_pooler_image:
type: string type: string
#default: "registry.opensource.zalan.do/acid/pgbouncer" default: "registry.opensource.zalan.do/acid/pgbouncer:master-12"
connection_pooler_max_db_connections: connection_pooler_max_db_connections:
type: integer type: integer
#default: 60 default: 60
connection_pooler_mode: connection_pooler_mode:
type: string type: string
enum: enum:
- "session" - "session"
- "transaction" - "transaction"
#default: "transaction" default: "transaction"
connection_pooler_number_of_instances: connection_pooler_number_of_instances:
type: integer type: integer
minimum: 2 minimum: 1
#default: 2 default: 2
connection_pooler_default_cpu_limit: connection_pooler_default_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
#default: "1" default: "1"
connection_pooler_default_cpu_request: connection_pooler_default_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
#default: "500m" default: "500m"
connection_pooler_default_memory_limit: connection_pooler_default_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
#default: "100Mi" default: "100Mi"
connection_pooler_default_memory_request: connection_pooler_default_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
#default: "100Mi" default: "100Mi"
status: status:
type: object type: object
additionalProperties: additionalProperties:

View File

@ -249,6 +249,13 @@ configAwsOrGcp:
configLogicalBackup: configLogicalBackup:
# image for pods of the logical backup job (example runs pg_dumpall) # image for pods of the logical backup job (example runs pg_dumpall)
logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0" logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0"
# path of google cloud service account json file
# logical_backup_google_application_credentials: ""
# prefix for the backup job name
logical_backup_job_prefix: "logical-backup-"
# storage provider - either "s3" or "gcs"
logical_backup_provider: "s3"
# S3 Access Key ID # S3 Access Key ID
logical_backup_s3_access_key_id: "" logical_backup_s3_access_key_id: ""
# S3 bucket to store backup results # S3 bucket to store backup results

View File

@ -239,15 +239,22 @@ configAwsOrGcp:
# configure K8s cron job managed by the operator # configure K8s cron job managed by the operator
configLogicalBackup: configLogicalBackup:
# image for pods of the logical backup job (example runs pg_dumpall) # image for pods of the logical backup job (example runs pg_dumpall)
logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v.1.6.0" logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0"
# path of google cloud service account json file
# logical_backup_google_application_credentials: ""
# prefix for the backup job name
logical_backup_job_prefix: "logical-backup-"
# storage provider - either "s3" or "gcs"
logical_backup_provider: "s3"
# S3 Access Key ID # S3 Access Key ID
logical_backup_s3_access_key_id: "" logical_backup_s3_access_key_id: ""
# S3 bucket to store backup results # S3 bucket to store backup results
logical_backup_s3_bucket: "my-bucket-url" logical_backup_s3_bucket: "my-bucket-url"
# S3 region of bucket
logical_backup_s3_region: ""
# S3 endpoint url when not using AWS # S3 endpoint url when not using AWS
logical_backup_s3_endpoint: "" logical_backup_s3_endpoint: ""
# S3 region of bucket
logical_backup_s3_region: ""
# S3 Secret Access Key # S3 Secret Access Key
logical_backup_s3_secret_access_key: "" logical_backup_s3_secret_access_key: ""
# S3 server side encryption # S3 server side encryption
@ -255,6 +262,7 @@ configLogicalBackup:
# backup schedule in the cron format # backup schedule in the cron format
logical_backup_schedule: "30 00 * * *" logical_backup_schedule: "30 00 * * *"
# automate creation of human users with teams API service # automate creation of human users with teams API service
configTeamsApi: configTeamsApi:
# team_admin_role will have the rights to grant roles coming from PG manifests # team_admin_role will have the rights to grant roles coming from PG manifests

View File

@ -1,5 +1,5 @@
FROM alpine FROM alpine
MAINTAINER Team ACID @ Zalando <team-acid@zalando.de> LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>"
# We need root certificates to deal with teams api over https # We need root certificates to deal with teams api over https
RUN apk --no-cache add ca-certificates go git musl-dev RUN apk --no-cache add ca-certificates go git musl-dev

View File

@ -1,5 +1,5 @@
FROM alpine FROM alpine
MAINTAINER Team ACID @ Zalando <team-acid@zalando.de> LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>"
# We need root certificates to deal with teams api over https # We need root certificates to deal with teams api over https
RUN apk --no-cache add curl RUN apk --no-cache add curl

View File

@ -30,10 +30,10 @@ To trigger the upgrade, increase the version in the cluster manifest. After
Pods are rotated `configure_spilo` will notice the version mismatch and start Pods are rotated `configure_spilo` will notice the version mismatch and start
the old version again. You can then exec into the Postgres container of the the old version again. You can then exec into the Postgres container of the
master instance and call `python3 /scripts/inplace_upgrade.py N` where `N` master instance and call `python3 /scripts/inplace_upgrade.py N` where `N`
is the number of members of your cluster (see `number_of_instances`). The is the number of members of your cluster (see [`numberOfInstances`](https://github.com/zalando/postgres-operator/blob/50cb5898ea715a1db7e634de928b2d16dc8cd969/manifests/minimal-postgres-manifest.yaml#L10)).
upgrade is usually fast, well under one minute for most DBs. Note, that changes The upgrade is usually fast, well under one minute for most DBs. Note, that
become irrevertible once `pg_upgrade` is called. To understand the upgrade changes become irrevertible once `pg_upgrade` is called. To understand the
procedure, refer to the [corresponding PR in Spilo](https://github.com/zalando/spilo/pull/488). upgrade procedure, refer to the [corresponding PR in Spilo](https://github.com/zalando/spilo/pull/488).
## CRD Validation ## CRD Validation

View File

@ -126,7 +126,7 @@ Those are top-level keys, containing both leaf keys and groups.
* **workers** * **workers**
number of working routines the operator spawns to process requests to number of working routines the operator spawns to process requests to
create/update/delete/sync clusters concurrently. The default is `4`. create/update/delete/sync clusters concurrently. The default is `8`.
* **max_instances** * **max_instances**
operator will cap the number of instances in any managed Postgres cluster up operator will cap the number of instances in any managed Postgres cluster up
@ -551,44 +551,47 @@ These parameters configure a K8s cron job managed by the operator to produce
Postgres logical backups. In the CRD-based configuration those parameters are Postgres logical backups. In the CRD-based configuration those parameters are
grouped under the `logical_backup` key. grouped under the `logical_backup` key.
* **logical_backup_schedule**
Backup schedule in the cron format. Please take the
[reference schedule format](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#schedule)
into account. Default: "30 00 \* \* \*"
* **logical_backup_docker_image** * **logical_backup_docker_image**
An image for pods of the logical backup job. The [example image](../../docker/logical-backup/Dockerfile) An image for pods of the logical backup job. The [example image](../../docker/logical-backup/Dockerfile)
runs `pg_dumpall` on a replica if possible and uploads compressed results to 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`. 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 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:v1.6.0"
* **logical_backup_google_application_credentials**
Specifies the path of the google cloud service account json file. Default is empty.
* **logical_backup_job_prefix**
The prefix to be prepended to the name of a k8s CronJob running the backups. Beware the prefix counts towards the name length restrictions imposed by k8s. Empty string is a legitimate value. Operator does not do the actual renaming: It simply creates the job with the new prefix. You will have to delete the old cron job manually. Default: "logical-backup-".
* **logical_backup_provider** * **logical_backup_provider**
Specifies the storage provider to which the backup should be uploaded (`s3` or `gcs`). Specifies the storage provider to which the backup should be uploaded (`s3` or `gcs`).
Default: "s3" Default: "s3"
* **logical_backup_s3_access_key_id**
When set, value will be in AWS_ACCESS_KEY_ID env variable. The Default is empty.
* **logical_backup_s3_bucket** * **logical_backup_s3_bucket**
S3 bucket to store backup results. The bucket has to be present and S3 bucket to store backup results. The bucket has to be present and
accessible by Postgres pods. Default: empty. accessible by Postgres pods. Default: empty.
* **logical_backup_s3_endpoint**
When using non-AWS S3 storage, endpoint can be set as a ENV variable. The default is empty.
* **logical_backup_s3_region** * **logical_backup_s3_region**
Specifies the region of the bucket which is required with some non-AWS S3 storage services. The default is empty. Specifies the region of the bucket which is required with some non-AWS S3 storage services. The default is empty.
* **logical_backup_s3_endpoint** * **logical_backup_s3_secret_access_key**
When using non-AWS S3 storage, endpoint can be set as a ENV variable. The default is empty. When set, value will be in AWS_SECRET_ACCESS_KEY env variable. The Default is empty.
* **logical_backup_s3_sse** * **logical_backup_s3_sse**
Specify server side encryption that S3 storage is using. If empty string Specify server side encryption that S3 storage is using. If empty string
is specified, no argument will be passed to `aws s3` command. Default: "AES256". is specified, no argument will be passed to `aws s3` command. Default: "AES256".
* **logical_backup_s3_access_key_id** * **logical_backup_schedule**
When set, value will be in AWS_ACCESS_KEY_ID env variable. The Default is empty. Backup schedule in the cron format. Please take the
[reference schedule format](https://kubernetes.io/docs/tasks/job/automated-tasks-with-cron-jobs/#schedule)
* **logical_backup_s3_secret_access_key** into account. Default: "30 00 \* \* \*"
When set, value will be in AWS_SECRET_ACCESS_KEY env variable. The Default is empty.
* **logical_backup_google_application_credentials**
Specifies the path of the google cloud service account json file. Default is empty.
## Debugging the operator ## Debugging the operator

View File

@ -63,6 +63,9 @@ data:
# kube_iam_role: "" # kube_iam_role: ""
# log_s3_bucket: "" # log_s3_bucket: ""
logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0" logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0"
# logical_backup_google_application_credentials: ""
logical_backup_job_prefix: "logical-backup-"
logical_backup_provider: "s3"
# logical_backup_s3_access_key_id: "" # logical_backup_s3_access_key_id: ""
logical_backup_s3_bucket: "my-bucket-url" logical_backup_s3_bucket: "my-bucket-url"
# logical_backup_s3_region: "" # logical_backup_s3_region: ""

View File

@ -61,32 +61,45 @@ spec:
properties: properties:
docker_image: docker_image:
type: string type: string
default: "registry.opensource.zalan.do/acid/spilo-13:2.0-p2"
enable_crd_validation: enable_crd_validation:
type: boolean type: boolean
default: true
enable_lazy_spilo_upgrade: enable_lazy_spilo_upgrade:
type: boolean type: boolean
default: false
enable_pgversion_env_var: enable_pgversion_env_var:
type: boolean type: boolean
default: true
enable_shm_volume: enable_shm_volume:
type: boolean type: boolean
default: true
enable_spilo_wal_path_compat: enable_spilo_wal_path_compat:
type: boolean type: boolean
default: false
etcd_host: etcd_host:
type: string type: string
default: ""
kubernetes_use_configmaps: kubernetes_use_configmaps:
type: boolean type: boolean
default: false
max_instances: max_instances:
type: integer type: integer
minimum: -1 # -1 = disabled minimum: -1 # -1 = disabled
default: -1
min_instances: min_instances:
type: integer type: integer
minimum: -1 # -1 = disabled minimum: -1 # -1 = disabled
default: -1
resync_period: resync_period:
type: string type: string
default: "30m"
repair_period: repair_period:
type: string type: string
default: "5m"
set_memory_request_to_limit: set_memory_request_to_limit:
type: boolean type: boolean
default: false
sidecar_docker_images: sidecar_docker_images:
type: object type: object
additionalProperties: additionalProperties:
@ -100,24 +113,31 @@ spec:
workers: workers:
type: integer type: integer
minimum: 1 minimum: 1
default: 8
users: users:
type: object type: object
properties: properties:
replication_username: replication_username:
type: string type: string
default: standby
super_username: super_username:
type: string type: string
default: postgres
kubernetes: kubernetes:
type: object type: object
properties: properties:
cluster_domain: cluster_domain:
type: string type: string
default: "cluster.local"
cluster_labels: cluster_labels:
type: object type: object
additionalProperties: additionalProperties:
type: string type: string
default:
application: spilo
cluster_name_label: cluster_name_label:
type: string type: string
default: "cluster-name"
custom_pod_annotations: custom_pod_annotations:
type: object type: object
additionalProperties: additionalProperties:
@ -132,12 +152,16 @@ spec:
type: string type: string
enable_init_containers: enable_init_containers:
type: boolean type: boolean
default: true
enable_pod_antiaffinity: enable_pod_antiaffinity:
type: boolean type: boolean
default: false
enable_pod_disruption_budget: enable_pod_disruption_budget:
type: boolean type: boolean
default: true
enable_sidecars: enable_sidecars:
type: boolean type: boolean
default: true
infrastructure_roles_secret_name: infrastructure_roles_secret_name:
type: string type: string
infrastructure_roles_secrets: infrastructure_roles_secrets:
@ -176,16 +200,20 @@ spec:
type: string type: string
master_pod_move_timeout: master_pod_move_timeout:
type: string type: string
default: "20m"
node_readiness_label: node_readiness_label:
type: object type: object
additionalProperties: additionalProperties:
type: string type: string
oauth_token_secret_name: oauth_token_secret_name:
type: string type: string
default: "postgresql-operator"
pdb_name_format: pdb_name_format:
type: string type: string
default: "postgres-{cluster}-pdb"
pod_antiaffinity_topology_key: pod_antiaffinity_topology_key:
type: string type: string
default: "kubernetes.io/hostname"
pod_environment_configmap: pod_environment_configmap:
type: string type: string
pod_environment_secret: pod_environment_secret:
@ -195,20 +223,27 @@ spec:
enum: enum:
- "ordered_ready" - "ordered_ready"
- "parallel" - "parallel"
default: "ordered_ready"
pod_priority_class_name: pod_priority_class_name:
type: string type: string
pod_role_label: pod_role_label:
type: string type: string
default: "spilo-role"
pod_service_account_definition: pod_service_account_definition:
type: string type: string
default: ""
pod_service_account_name: pod_service_account_name:
type: string type: string
default: "postgres-pod"
pod_service_account_role_binding_definition: pod_service_account_role_binding_definition:
type: string type: string
default: ""
pod_terminate_grace_period: pod_terminate_grace_period:
type: string type: string
default: "5m"
secret_name_template: secret_name_template:
type: string type: string
default: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}"
spilo_runasuser: spilo_runasuser:
type: integer type: integer
spilo_runasgroup: spilo_runasgroup:
@ -217,12 +252,14 @@ spec:
type: integer type: integer
spilo_privileged: spilo_privileged:
type: boolean type: boolean
default: false
storage_resize_mode: storage_resize_mode:
type: string type: string
enum: enum:
- "ebs" - "ebs"
- "pvc" - "pvc"
- "off" - "off"
default: "pvc"
toleration: toleration:
type: object type: object
additionalProperties: additionalProperties:
@ -235,36 +272,48 @@ spec:
default_cpu_limit: default_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "1"
default_cpu_request: default_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "100m"
default_memory_limit: default_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "500Mi"
default_memory_request: default_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "100Mi"
min_cpu_limit: min_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "250m"
min_memory_limit: min_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "250Mi"
timeouts: timeouts:
type: object type: object
properties: properties:
pod_label_wait_timeout: pod_label_wait_timeout:
type: string type: string
default: "10m"
pod_deletion_wait_timeout: pod_deletion_wait_timeout:
type: string type: string
default: "10m"
ready_wait_interval: ready_wait_interval:
type: string type: string
default: "4s"
ready_wait_timeout: ready_wait_timeout:
type: string type: string
default: "30s"
resource_check_interval: resource_check_interval:
type: string type: string
default: "3s"
resource_check_timeout: resource_check_timeout:
type: string type: string
default: "10m"
load_balancer: load_balancer:
type: object type: object
properties: properties:
@ -274,19 +323,25 @@ spec:
type: string type: string
db_hosted_zone: db_hosted_zone:
type: string type: string
default: "db.example.com"
enable_master_load_balancer: enable_master_load_balancer:
type: boolean type: boolean
default: true
enable_replica_load_balancer: enable_replica_load_balancer:
type: boolean type: boolean
default: false
external_traffic_policy: external_traffic_policy:
type: string type: string
enum: enum:
- "Cluster" - "Cluster"
- "Local" - "Local"
default: "Cluster"
master_dns_name_format: master_dns_name_format:
type: string type: string
default: "{cluster}.{team}.{hostedzone}"
replica_dns_name_format: replica_dns_name_format:
type: string type: string
default: "{cluster}-repl.{team}.{hostedzone}"
aws_or_gcp: aws_or_gcp:
type: object type: object
properties: properties:
@ -294,12 +349,16 @@ spec:
type: string type: string
additional_secret_mount_path: additional_secret_mount_path:
type: string type: string
default: "/meta/credentials"
aws_region: aws_region:
type: string type: string
default: "eu-central-1"
enable_ebs_gp3_migration: enable_ebs_gp3_migration:
type: boolean type: boolean
default: false
enable_ebs_gp3_migration_max_size: enable_ebs_gp3_migration_max_size:
type: integer type: integer
default: 1000
gcp_credentials: gcp_credentials:
type: string type: string
kube_iam_role: kube_iam_role:
@ -315,10 +374,15 @@ spec:
properties: properties:
logical_backup_docker_image: logical_backup_docker_image:
type: string type: string
default: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0"
logical_backup_google_application_credentials: logical_backup_google_application_credentials:
type: string type: string
logical_backup_job_prefix:
type: string
default: "logical-backup-"
logical_backup_provider: logical_backup_provider:
type: string type: string
default: "s3"
logical_backup_s3_access_key_id: logical_backup_s3_access_key_id:
type: string type: string
logical_backup_s3_bucket: logical_backup_s3_bucket:
@ -334,30 +398,40 @@ spec:
logical_backup_schedule: logical_backup_schedule:
type: string type: string
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$' pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
default: "30 00 * * *"
debug: debug:
type: object type: object
properties: properties:
debug_logging: debug_logging:
type: boolean type: boolean
default: true
enable_database_access: enable_database_access:
type: boolean type: boolean
default: true
teams_api: teams_api:
type: object type: object
properties: properties:
enable_admin_role_for_users: enable_admin_role_for_users:
type: boolean type: boolean
default: true
enable_postgres_team_crd: enable_postgres_team_crd:
type: boolean type: boolean
default: true
enable_postgres_team_crd_superusers: enable_postgres_team_crd_superusers:
type: boolean type: boolean
default: false
enable_team_superuser: enable_team_superuser:
type: boolean type: boolean
default: false
enable_teams_api: enable_teams_api:
type: boolean type: boolean
default: true
pam_configuration: pam_configuration:
type: string type: string
default: "https://info.example.com/oauth2/tokeninfo?access_token= uid realm=/employees"
pam_role_name: pam_role_name:
type: string type: string
default: "zalandos"
postgres_superuser_teams: postgres_superuser_teams:
type: array type: array
items: items:
@ -366,23 +440,32 @@ spec:
type: array type: array
items: items:
type: string type: string
default:
- admin
team_admin_role: team_admin_role:
type: string type: string
default: "admin"
team_api_role_configuration: team_api_role_configuration:
type: object type: object
additionalProperties: additionalProperties:
type: string type: string
default:
log_statement: all
teams_api_url: teams_api_url:
type: string type: string
defaults: "https://teams.example.com/api/"
logging_rest_api: logging_rest_api:
type: object type: object
properties: properties:
api_port: api_port:
type: integer type: integer
default: 8080
cluster_history_entries: cluster_history_entries:
type: integer type: integer
default: 1000
ring_log_lines: ring_log_lines:
type: integer type: integer
default: 100
scalyr: # deprecated scalyr: # deprecated
type: object type: object
properties: properties:
@ -391,60 +474,65 @@ spec:
scalyr_cpu_limit: scalyr_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "1"
scalyr_cpu_request: scalyr_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
default: "100m"
scalyr_image: scalyr_image:
type: string type: string
scalyr_memory_limit: scalyr_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "500Mi"
scalyr_memory_request: scalyr_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
default: "50Mi"
scalyr_server_url: scalyr_server_url:
type: string type: string
default: "https://upload.eu.scalyr.com"
connection_pooler: connection_pooler:
type: object type: object
properties: properties:
connection_pooler_schema: connection_pooler_schema:
type: string type: string
#default: "pooler" default: "pooler"
connection_pooler_user: connection_pooler_user:
type: string type: string
#default: "pooler" default: "pooler"
connection_pooler_image: connection_pooler_image:
type: string type: string
#default: "registry.opensource.zalan.do/acid/pgbouncer" default: "registry.opensource.zalan.do/acid/pgbouncer:master-12"
connection_pooler_max_db_connections: connection_pooler_max_db_connections:
type: integer type: integer
#default: 60 default: 60
connection_pooler_mode: connection_pooler_mode:
type: string type: string
enum: enum:
- "session" - "session"
- "transaction" - "transaction"
#default: "transaction" default: "transaction"
connection_pooler_number_of_instances: connection_pooler_number_of_instances:
type: integer type: integer
minimum: 2 minimum: 1
#default: 2 default: 2
connection_pooler_default_cpu_limit: connection_pooler_default_cpu_limit:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
#default: "1" default: "1"
connection_pooler_default_cpu_request: connection_pooler_default_cpu_request:
type: string type: string
pattern: '^(\d+m|\d+(\.\d{1,3})?)$' pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
#default: "500m" default: "500m"
connection_pooler_default_memory_limit: connection_pooler_default_memory_limit:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
#default: "100Mi" default: "100Mi"
connection_pooler_default_memory_request: connection_pooler_default_memory_request:
type: string type: string
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$' pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
#default: "100Mi" default: "100Mi"
status: status:
type: object type: object
additionalProperties: additionalProperties:

View File

@ -115,7 +115,10 @@ configuration:
# wal_gs_bucket: "" # wal_gs_bucket: ""
# wal_s3_bucket: "" # wal_s3_bucket: ""
logical_backup: logical_backup:
logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v.1.6.0" logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup:v1.6.0"
# logical_backup_google_application_credentials: ""
logical_backup_job_prefix: "logical-backup-"
logical_backup_provider: "s3"
# logical_backup_s3_access_key_id: "" # logical_backup_s3_access_key_id: ""
logical_backup_s3_bucket: "my-bucket-url" logical_backup_s3_bucket: "my-bucket-url"
# logical_backup_s3_endpoint: "" # logical_backup_s3_endpoint: ""

View File

@ -106,7 +106,6 @@ var OperatorConfigCRDResourceColumns = []apiextv1.CustomResourceColumnDefinition
var min0 = 0.0 var min0 = 0.0
var min1 = 1.0 var min1 = 1.0
var min2 = 2.0
var minDisable = -1.0 var minDisable = -1.0
// PostgresCRDResourceValidation to check applied manifest parameters // PostgresCRDResourceValidation to check applied manifest parameters
@ -232,7 +231,7 @@ var PostgresCRDResourceValidation = apiextv1.CustomResourceValidation{
}, },
"numberOfInstances": { "numberOfInstances": {
Type: "integer", Type: "integer",
Minimum: &min2, Minimum: &min1,
}, },
"resources": { "resources": {
Type: "object", Type: "object",
@ -1294,6 +1293,9 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
"logical_backup_google_application_credentials": { "logical_backup_google_application_credentials": {
Type: "string", Type: "string",
}, },
"logical_backup_job_prefix": {
Type: "string",
},
"logical_backup_provider": { "logical_backup_provider": {
Type: "string", Type: "string",
}, },
@ -1470,7 +1472,7 @@ var OperatorConfigCRDResourceValidation = apiextv1.CustomResourceValidation{
}, },
"connection_pooler_number_of_instances": { "connection_pooler_number_of_instances": {
Type: "integer", Type: "integer",
Minimum: &min2, Minimum: &min1,
}, },
"connection_pooler_schema": { "connection_pooler_schema": {
Type: "string", Type: "string",

View File

@ -196,6 +196,7 @@ type OperatorLogicalBackupConfiguration struct {
S3SecretAccessKey string `json:"logical_backup_s3_secret_access_key,omitempty"` S3SecretAccessKey string `json:"logical_backup_s3_secret_access_key,omitempty"`
S3SSE string `json:"logical_backup_s3_sse,omitempty"` S3SSE string `json:"logical_backup_s3_sse,omitempty"`
GoogleApplicationCredentials string `json:"logical_backup_google_application_credentials,omitempty"` GoogleApplicationCredentials string `json:"logical_backup_google_application_credentials,omitempty"`
JobPrefix string `json:"logical_backup_job_prefix,omitempty"`
} }
// OperatorConfigurationData defines the operation config // OperatorConfigurationData defines the operation config

View File

@ -1,7 +1,7 @@
// +build !ignore_autogenerated // +build !ignore_autogenerated
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -2079,7 +2079,7 @@ func (c *Cluster) generateLogicalBackupPodEnvVars() []v1.EnvVar {
// getLogicalBackupJobName returns the name; the job itself may not exists // getLogicalBackupJobName returns the name; the job itself may not exists
func (c *Cluster) getLogicalBackupJobName() (jobName string) { func (c *Cluster) getLogicalBackupJobName() (jobName string) {
return "logical-backup-" + c.clusterName().Name return c.OpConfig.LogicalBackupJobPrefix + c.clusterName().Name
} }
// Return an array of ownerReferences to make an arbitraty object dependent on // Return an array of ownerReferences to make an arbitraty object dependent on

View File

@ -4,6 +4,7 @@ import (
"context" "context"
"fmt" "fmt"
"math/rand" "math/rand"
"time"
appsv1 "k8s.io/api/apps/v1" appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
@ -11,6 +12,7 @@ import (
"github.com/zalando/postgres-operator/pkg/spec" "github.com/zalando/postgres-operator/pkg/spec"
"github.com/zalando/postgres-operator/pkg/util" "github.com/zalando/postgres-operator/pkg/util"
"github.com/zalando/postgres-operator/pkg/util/retryutil"
) )
func (c *Cluster) listPods() ([]v1.Pod, error) { func (c *Cluster) listPods() ([]v1.Pod, error) {
@ -309,7 +311,23 @@ func (c *Cluster) isSafeToRecreatePods(pods *v1.PodList) bool {
} }
for _, pod := range pods.Items { for _, pod := range pods.Items {
state, err := c.patroni.GetPatroniMemberState(&pod)
var state string
err := retryutil.Retry(1*time.Second, 5*time.Second,
func() (bool, error) {
var err error
state, err = c.patroni.GetPatroniMemberState(&pod)
if err != nil {
return false, err
}
return true, nil
},
)
if err != nil { if err != nil {
c.logger.Errorf("failed to get Patroni state for pod: %s", err) c.logger.Errorf("failed to get Patroni state for pod: %s", err)
return false return false

View File

@ -141,11 +141,11 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
result.AdditionalSecretMount = fromCRD.AWSGCP.AdditionalSecretMount result.AdditionalSecretMount = fromCRD.AWSGCP.AdditionalSecretMount
result.AdditionalSecretMountPath = util.Coalesce(fromCRD.AWSGCP.AdditionalSecretMountPath, "/meta/credentials") result.AdditionalSecretMountPath = util.Coalesce(fromCRD.AWSGCP.AdditionalSecretMountPath, "/meta/credentials")
result.EnableEBSGp3Migration = fromCRD.AWSGCP.EnableEBSGp3Migration result.EnableEBSGp3Migration = fromCRD.AWSGCP.EnableEBSGp3Migration
result.EnableEBSGp3MigrationMaxSize = fromCRD.AWSGCP.EnableEBSGp3MigrationMaxSize result.EnableEBSGp3MigrationMaxSize = util.CoalesceInt64(fromCRD.AWSGCP.EnableEBSGp3MigrationMaxSize, 1000)
// logical backup config // logical backup config
result.LogicalBackupSchedule = util.Coalesce(fromCRD.LogicalBackup.Schedule, "30 00 * * *") 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:v1.6.0")
result.LogicalBackupProvider = util.Coalesce(fromCRD.LogicalBackup.BackupProvider, "s3") result.LogicalBackupProvider = util.Coalesce(fromCRD.LogicalBackup.BackupProvider, "s3")
result.LogicalBackupS3Bucket = fromCRD.LogicalBackup.S3Bucket result.LogicalBackupS3Bucket = fromCRD.LogicalBackup.S3Bucket
result.LogicalBackupS3Region = fromCRD.LogicalBackup.S3Region result.LogicalBackupS3Region = fromCRD.LogicalBackup.S3Region
@ -154,6 +154,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
result.LogicalBackupS3SecretAccessKey = fromCRD.LogicalBackup.S3SecretAccessKey result.LogicalBackupS3SecretAccessKey = fromCRD.LogicalBackup.S3SecretAccessKey
result.LogicalBackupS3SSE = fromCRD.LogicalBackup.S3SSE result.LogicalBackupS3SSE = fromCRD.LogicalBackup.S3SSE
result.LogicalBackupGoogleApplicationCredentials = fromCRD.LogicalBackup.GoogleApplicationCredentials result.LogicalBackupGoogleApplicationCredentials = fromCRD.LogicalBackup.GoogleApplicationCredentials
result.LogicalBackupJobPrefix = util.Coalesce(fromCRD.LogicalBackup.JobPrefix, "logical-backup-")
// debug config // debug config
result.DebugLogging = fromCRD.OperatorDebug.DebugLogging result.DebugLogging = fromCRD.OperatorDebug.DebugLogging

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2020 Compose, Zalando SE Copyright 2021 Compose, Zalando SE
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View File

@ -112,7 +112,7 @@ type Scalyr struct {
// LogicalBackup defines configuration for logical backup // LogicalBackup defines configuration for logical backup
type LogicalBackup struct { type LogicalBackup struct {
LogicalBackupSchedule string `name:"logical_backup_schedule" default:"30 00 * * *"` 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:v1.6.0"`
LogicalBackupProvider string `name:"logical_backup_provider" default:"s3"` LogicalBackupProvider string `name:"logical_backup_provider" default:"s3"`
LogicalBackupS3Bucket string `name:"logical_backup_s3_bucket" default:""` LogicalBackupS3Bucket string `name:"logical_backup_s3_bucket" default:""`
LogicalBackupS3Region string `name:"logical_backup_s3_region" default:""` LogicalBackupS3Region string `name:"logical_backup_s3_region" default:""`
@ -121,6 +121,7 @@ type LogicalBackup struct {
LogicalBackupS3SecretAccessKey string `name:"logical_backup_s3_secret_access_key" default:""` LogicalBackupS3SecretAccessKey string `name:"logical_backup_s3_secret_access_key" default:""`
LogicalBackupS3SSE string `name:"logical_backup_s3_sse" default:""` LogicalBackupS3SSE string `name:"logical_backup_s3_sse" default:""`
LogicalBackupGoogleApplicationCredentials string `name:"logical_backup_google_application_credentials" default:""` LogicalBackupGoogleApplicationCredentials string `name:"logical_backup_google_application_credentials" default:""`
LogicalBackupJobPrefix string `name:"logical_backup_job_prefix" default:"logical-backup-"`
} }
// Operator options for connection pooler // Operator options for connection pooler

View File

@ -271,6 +271,14 @@ func CoalesceUInt32(val, defaultVal uint32) uint32 {
return val 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 // CoalesceBool works like coalesce but for *bool
func CoalesceBool(val, defaultVal *bool) *bool { func CoalesceBool(val, defaultVal *bool) *bool {
if val == nil { if val == nil {

View File

@ -1,5 +1,5 @@
FROM alpine:3.6 FROM alpine:3.6
MAINTAINER team-acid@zalando.de LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>"
EXPOSE 8081 EXPOSE 8081

View File

@ -21,7 +21,7 @@ AWS_ENDPOINT = getenv('AWS_ENDPOINT')
OPERATOR_CLUSTER_NAME_LABEL = getenv('OPERATOR_CLUSTER_NAME_LABEL', 'cluster-name') OPERATOR_CLUSTER_NAME_LABEL = getenv('OPERATOR_CLUSTER_NAME_LABEL', 'cluster-name')
COMMON_CLUSTER_LABEL = getenv('COMMON_CLUSTER_LABEL', '{"application":"spilo"}') COMMON_CLUSTER_LABEL = getenv('COMMON_CLUSTER_LABEL', '{"application":"spilo"}')
COMMON_POOLER_LABEL = getenv('COMMONG_POOLER_LABEL', '{"application":"db-connection-pooler"}') COMMON_POOLER_LABEL = getenv('COMMON_POOLER_LABEL', '{"application":"db-connection-pooler"}')
logger.info("Common Cluster Label: {}".format(COMMON_CLUSTER_LABEL)) logger.info("Common Cluster Label: {}".format(COMMON_CLUSTER_LABEL))
logger.info("Common Pooler Label: {}".format(COMMON_POOLER_LABEL)) logger.info("Common Pooler Label: {}".format(COMMON_POOLER_LABEL))
@ -107,6 +107,12 @@ def encode_labels(label_selector):
]) ])
def cluster_labels(spilo_cluster):
labels = COMMON_CLUSTER_LABEL
labels[OPERATOR_CLUSTER_NAME_LABEL] = spilo_cluster
return labels
def kubernetes_url( def kubernetes_url(
resource_type, resource_type,
namespace='default', namespace='default',
@ -151,7 +157,7 @@ def read_pods(cluster, namespace, spilo_cluster):
cluster=cluster, cluster=cluster,
resource_type='pods', resource_type='pods',
namespace=namespace, namespace=namespace,
label_selector={OPERATOR_CLUSTER_NAME_LABEL: spilo_cluster}, label_selector=cluster_labels(spilo_cluster),
) )