Add CRD validation (#599)
* add CRD manifests with validation * update documentation * patroni slots is not an array but a nested hash map * make deps call tools * cover validation in docs and export it in crds.go * add toggle to disable creation of CRD validation and document it * use templated service account also for CRD-configured helm deployment
This commit is contained in:
parent
052940862a
commit
a3b34f146f
2
Makefile
2
Makefile
|
|
@ -88,7 +88,7 @@ vet:
|
|||
@go vet $(PKG)
|
||||
@staticcheck $(PKG)
|
||||
|
||||
deps:
|
||||
deps: tools
|
||||
GO111MODULE=on go mod vendor
|
||||
|
||||
test:
|
||||
|
|
|
|||
|
|
@ -39,3 +39,262 @@ spec:
|
|||
subresources:
|
||||
status: {}
|
||||
version: v1
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- apiVersion
|
||||
- configuration
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
enum:
|
||||
- OperatorConfiguration
|
||||
apiVersion:
|
||||
type: string
|
||||
enum:
|
||||
- acid.zalan.do/v1
|
||||
configuration:
|
||||
type: object
|
||||
properties:
|
||||
docker_image:
|
||||
type: string
|
||||
enable_crd_validation:
|
||||
type: boolean
|
||||
enable_shm_volume:
|
||||
type: boolean
|
||||
etcd_host:
|
||||
type: string
|
||||
max_instances:
|
||||
type: integer
|
||||
minimum: -1 # -1 = disabled
|
||||
min_instances:
|
||||
type: integer
|
||||
minimum: -1 # -1 = disabled
|
||||
resync_period:
|
||||
type: string
|
||||
repair_period:
|
||||
type: string
|
||||
set_memory_request_to_limit:
|
||||
type: boolean
|
||||
sidecar_docker_images:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
workers:
|
||||
type: integer
|
||||
minimum: 1
|
||||
users:
|
||||
type: object
|
||||
properties:
|
||||
replication_username:
|
||||
type: string
|
||||
super_username:
|
||||
type: string
|
||||
kubernetes:
|
||||
type: object
|
||||
properties:
|
||||
cluster_domain:
|
||||
type: string
|
||||
cluster_labels:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
cluster_name_label:
|
||||
type: string
|
||||
custom_pod_annotations:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
enable_pod_antiaffinity:
|
||||
type: boolean
|
||||
enable_pod_disruption_budget:
|
||||
type: boolean
|
||||
infrastructure_roles_secret_name:
|
||||
type: string
|
||||
inherited_labels:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
node_readiness_label:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
oauth_token_secret_name:
|
||||
type: string
|
||||
pdb_name_format:
|
||||
type: string
|
||||
pod_antiaffinity_topology_key:
|
||||
type: string
|
||||
pod_environment_configmap:
|
||||
type: string
|
||||
pod_management_policy:
|
||||
type: string
|
||||
enum:
|
||||
- "ordered_ready"
|
||||
- "parallel"
|
||||
pod_role_label:
|
||||
type: string
|
||||
pod_service_account_name:
|
||||
type: string
|
||||
pod_terminate_grace_period:
|
||||
type: string
|
||||
secret_name_template:
|
||||
type: string
|
||||
spilo_fsgroup:
|
||||
type: integer
|
||||
spilo_privileged:
|
||||
type: boolean
|
||||
toleration:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
watched_namespace:
|
||||
type: string
|
||||
postgres_pod_resources:
|
||||
type: object
|
||||
properties:
|
||||
default_cpu_limit:
|
||||
type: string
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
default_cpu_request:
|
||||
type: string
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
default_memory_limit:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
default_memory_request:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
timeouts:
|
||||
type: object
|
||||
properties:
|
||||
pod_label_wait_timeout:
|
||||
type: string
|
||||
pod_deletion_wait_timeout:
|
||||
type: string
|
||||
ready_wait_interval:
|
||||
type: string
|
||||
ready_wait_timeout:
|
||||
type: string
|
||||
resource_check_interval:
|
||||
type: string
|
||||
resource_check_timeout:
|
||||
type: string
|
||||
load_balancer:
|
||||
type: object
|
||||
properties:
|
||||
db_hosted_zone:
|
||||
type: string
|
||||
enable_master_load_balancer:
|
||||
type: boolean
|
||||
enable_replica_load_balancer:
|
||||
type: boolean
|
||||
custom_service_annotations:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
master_dns_name_format:
|
||||
type: string
|
||||
replica_dns_name_format:
|
||||
type: string
|
||||
aws_or_gcp:
|
||||
type: object
|
||||
properties:
|
||||
additional_secret_mount:
|
||||
type: string
|
||||
additional_secret_mount_path:
|
||||
type: string
|
||||
aws_region:
|
||||
type: string
|
||||
kube_iam_role:
|
||||
type: string
|
||||
log_s3_bucket:
|
||||
type: string
|
||||
wal_s3_bucket:
|
||||
type: string
|
||||
logical_backup:
|
||||
type: object
|
||||
properties:
|
||||
logical_backup_schedule:
|
||||
type: string
|
||||
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
|
||||
logical_backup_docker_image:
|
||||
type: string
|
||||
logical_backup_s3_bucket:
|
||||
type: string
|
||||
logical_backup_s3_endpoint:
|
||||
type: string
|
||||
logical_backup_s3_sse:
|
||||
type: string
|
||||
logical_backup_s3_access_key_id:
|
||||
type: string
|
||||
logical_backup_s3_secret_access_key:
|
||||
type: string
|
||||
debug:
|
||||
type: object
|
||||
properties:
|
||||
debug_logging:
|
||||
type: boolean
|
||||
enable_database_access:
|
||||
type: boolean
|
||||
teams_api:
|
||||
type: object
|
||||
properties:
|
||||
enable_admin_role_for_users:
|
||||
type: boolean
|
||||
enable_team_superuser:
|
||||
type: boolean
|
||||
enable_teams_api:
|
||||
type: boolean
|
||||
pam_configuration:
|
||||
type: string
|
||||
pam_role_name:
|
||||
type: string
|
||||
postgres_superuser_teams:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
protected_role_names:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
team_admin_role:
|
||||
type: string
|
||||
team_api_role_configuration:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
teams_api_url:
|
||||
type: string
|
||||
logging_rest_api:
|
||||
type: object
|
||||
properties:
|
||||
api_port:
|
||||
type: integer
|
||||
cluster_history_entries:
|
||||
type: integer
|
||||
ring_log_lines:
|
||||
type: integer
|
||||
scalyr:
|
||||
type: object
|
||||
properties:
|
||||
scalyr_api_key:
|
||||
type: string
|
||||
scalyr_cpu_limit:
|
||||
type: string
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
scalyr_cpu_request:
|
||||
type: string
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
scalyr_image:
|
||||
type: string
|
||||
scalyr_memory_limit:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
scalyr_memory_request:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
scalyr_server_url:
|
||||
type: string
|
||||
|
|
|
|||
|
|
@ -51,3 +51,313 @@ spec:
|
|||
subresources:
|
||||
status: {}
|
||||
version: v1
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- apiVersion
|
||||
- spec
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
enum:
|
||||
- postgresql
|
||||
apiVersion:
|
||||
type: string
|
||||
enum:
|
||||
- acid.zalan.do/v1
|
||||
spec:
|
||||
type: object
|
||||
required:
|
||||
- numberOfInstances
|
||||
- teamId
|
||||
- postgresql
|
||||
properties:
|
||||
allowedSourceRanges:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
pattern: '^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\/(\d|[1-2]\d|3[0-2])$'
|
||||
clone:
|
||||
type: object
|
||||
required:
|
||||
- cluster
|
||||
properties:
|
||||
cluster:
|
||||
type: string
|
||||
s3_endpoint:
|
||||
type: string
|
||||
s3_access_key_id:
|
||||
type: string
|
||||
s3_secret_access_key:
|
||||
type: string
|
||||
s3_force_path_style:
|
||||
type: string
|
||||
s3_wal_path:
|
||||
type: string
|
||||
timestamp:
|
||||
type: string
|
||||
pattern: '^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$'
|
||||
# The regexp matches the date-time format (RFC 3339 Section 5.6) that specifies a timezone as an offset relative to UTC
|
||||
# Example: 1996-12-19T16:39:57-08:00
|
||||
# Note: this field requires a timezone
|
||||
uid:
|
||||
format: uuid
|
||||
type: string
|
||||
databases:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
# Note: usernames specified here as database owners must be declared in the users key of the spec key.
|
||||
dockerImage:
|
||||
type: string
|
||||
enableLogicalBackup:
|
||||
type: boolean
|
||||
enableMasterLoadBalancer:
|
||||
type: boolean
|
||||
enableReplicaLoadBalancer:
|
||||
type: boolean
|
||||
enableShmVolume:
|
||||
type: boolean
|
||||
init_containers: # deprecated
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
initContainers:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
logicalBackupSchedule:
|
||||
type: string
|
||||
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
|
||||
maintenanceWindows:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
pattern: '^\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))\ *$'
|
||||
numberOfInstances:
|
||||
type: integer
|
||||
minimum: 0
|
||||
patroni:
|
||||
type: object
|
||||
properties:
|
||||
initdb:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
pg_hba:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
slots:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
ttl:
|
||||
type: integer
|
||||
loop_wait:
|
||||
type: integer
|
||||
retry_timeout:
|
||||
type: integer
|
||||
maximum_lag_on_failover:
|
||||
type: integer
|
||||
podAnnotations:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
pod_priority_class_name: # deprecated
|
||||
type: string
|
||||
podPriorityClassName:
|
||||
type: string
|
||||
postgresql:
|
||||
type: object
|
||||
required:
|
||||
- version
|
||||
properties:
|
||||
version:
|
||||
type: string
|
||||
enum:
|
||||
- "9.3"
|
||||
- "9.4"
|
||||
- "9.5"
|
||||
- "9.6"
|
||||
- "10"
|
||||
- "11"
|
||||
- "12"
|
||||
parameters:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
replicaLoadBalancer: # deprecated
|
||||
type: boolean
|
||||
resources:
|
||||
type: object
|
||||
required:
|
||||
- requests
|
||||
- limits
|
||||
properties:
|
||||
limits:
|
||||
type: object
|
||||
required:
|
||||
- cpu
|
||||
- memory
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
# Decimal natural followed by m, or decimal natural followed by
|
||||
# dot followed by up to three decimal digits.
|
||||
#
|
||||
# This is because the Kubernetes CPU resource has millis as the
|
||||
# maximum precision. The actual values are checked in code
|
||||
# because the regular expression would be huge and horrible and
|
||||
# not very helpful in validation error messages; this one checks
|
||||
# only the format of the given number.
|
||||
#
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu
|
||||
pattern: '^(\d+m|\d+\.\d{1,3})$'
|
||||
# Note: the value specified here must not be zero or be lower
|
||||
# than the corresponding request.
|
||||
memory:
|
||||
type: string
|
||||
# You can express memory as a plain integer or as a fixed-point
|
||||
# integer using one of these suffixes: E, P, T, G, M, k. You can
|
||||
# also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki
|
||||
#
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
# Note: the value specified here must not be zero or be lower
|
||||
# than the corresponding request.
|
||||
requests:
|
||||
type: object
|
||||
required:
|
||||
- cpu
|
||||
- memory
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
# Decimal natural followed by m, or decimal natural followed by
|
||||
# dot followed by up to three decimal digits.
|
||||
#
|
||||
# This is because the Kubernetes CPU resource has millis as the
|
||||
# maximum precision. The actual values are checked in code
|
||||
# because the regular expression would be huge and horrible and
|
||||
# not very helpful in validation error messages; this one checks
|
||||
# only the format of the given number.
|
||||
#
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu
|
||||
pattern: '^(\d+m|\d+\.\d{1,3})$'
|
||||
# Note: the value specified here must not be zero or be higher
|
||||
# than the corresponding limit.
|
||||
memory:
|
||||
type: string
|
||||
# You can express memory as a plain integer or as a fixed-point
|
||||
# integer using one of these suffixes: E, P, T, G, M, k. You can
|
||||
# also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki
|
||||
#
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
# Note: the value specified here must not be zero or be higher
|
||||
# than the corresponding limit.
|
||||
sidecars:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
spiloFSGroup:
|
||||
type: integer
|
||||
standby:
|
||||
type: object
|
||||
required:
|
||||
- s3_wal_path
|
||||
properties:
|
||||
s3_wal_path:
|
||||
type: string
|
||||
teamId:
|
||||
type: string
|
||||
tolerations:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
- effect
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
enum:
|
||||
- Equal
|
||||
- Exists
|
||||
value:
|
||||
type: string
|
||||
effect:
|
||||
type: string
|
||||
enum:
|
||||
- NoExecute
|
||||
- NoSchedule
|
||||
- PreferNoSchedule
|
||||
tolerationSeconds:
|
||||
type: integer
|
||||
useLoadBalancer: # deprecated
|
||||
type: boolean
|
||||
users:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: array
|
||||
nullable: true
|
||||
description: "Role flags specified here must not contradict each other"
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- bypassrls
|
||||
- BYPASSRLS
|
||||
- nobypassrls
|
||||
- NOBYPASSRLS
|
||||
- createdb
|
||||
- CREATEDB
|
||||
- nocreatedb
|
||||
- NOCREATEDB
|
||||
- createrole
|
||||
- CREATEROLE
|
||||
- nocreaterole
|
||||
- NOCREATEROLE
|
||||
- inherit
|
||||
- INHERIT
|
||||
- noinherit
|
||||
- NOINHERIT
|
||||
- login
|
||||
- LOGIN
|
||||
- nologin
|
||||
- NOLOGIN
|
||||
- replication
|
||||
- REPLICATION
|
||||
- noreplication
|
||||
- NOREPLICATION
|
||||
- superuser
|
||||
- SUPERUSER
|
||||
- nosuperuser
|
||||
- NOSUPERUSER
|
||||
volume:
|
||||
type: object
|
||||
required:
|
||||
- size
|
||||
properties:
|
||||
size:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
# Note: the value specified here must not be zero.
|
||||
storageClass:
|
||||
type: string
|
||||
subPath:
|
||||
type: string
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ configuration:
|
|||
{{ toYaml .Values.configUsers | indent 4 }}
|
||||
kubernetes:
|
||||
oauth_token_secret_name: {{ template "postgres-operator.fullname" . }}
|
||||
pod_service_account_name: operator
|
||||
pod_service_account_name: {{ include "postgres-operator.serviceAccountName" . }}
|
||||
{{ toYaml .Values.configKubernetes | indent 4 }}
|
||||
postgres_pod_resources:
|
||||
{{ toYaml .Values.configPostgresPodResources | indent 4 }}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ configTarget: "OperatorConfigurationCRD"
|
|||
|
||||
# general top-level configuration parameters
|
||||
configGeneral:
|
||||
# choose if deployment creates/updates CRDs with OpenAPIV3Validation
|
||||
enable_crd_validation: true
|
||||
# start any new database pod without limitations on shm memory
|
||||
enable_shm_volume: true
|
||||
# etcd connection string for Patroni. Empty uses K8s-native DCS.
|
||||
|
|
@ -57,7 +59,10 @@ configKubernetes:
|
|||
# label assigned to Kubernetes objects created by the operator
|
||||
cluster_name_label: cluster-name
|
||||
# additional annotations to add to every database pod
|
||||
custom_pod_annotations:
|
||||
# custom_pod_annotations:
|
||||
# keya: valuea
|
||||
# keyb: valueb
|
||||
|
||||
# toggles pod anti affinity on the Postgres pods
|
||||
enable_pod_antiaffinity: false
|
||||
# toggles PDB to set to MinAvailabe 0 or 1
|
||||
|
|
@ -74,7 +79,8 @@ configKubernetes:
|
|||
# master_pod_move_timeout: 20m
|
||||
|
||||
# set of labels that a running and active node should possess to be considered ready
|
||||
# node_readiness_label: ""
|
||||
# node_readiness_label:
|
||||
# status: ready
|
||||
|
||||
# name of the secret containing the OAuth2 token to pass to the teams API
|
||||
# oauth_token_secret_name: postgresql-operator
|
||||
|
|
@ -214,7 +220,8 @@ configTeamsApi:
|
|||
# operator will add all team member roles to this group and add a pg_hba line
|
||||
pam_role_name: zalandos
|
||||
# List of teams which members need the superuser role in each Postgres cluster
|
||||
# postgres_superuser_teams: "postgres_superusers"
|
||||
# postgres_superuser_teams:
|
||||
# - postgres_superusers
|
||||
|
||||
# List of roles that cannot be overwritten by an application, team or infrastructure role
|
||||
protected_role_names:
|
||||
|
|
@ -228,7 +235,7 @@ configTeamsApi:
|
|||
# teams_api_url: http://fake-teams-api.default.svc.cluster.local
|
||||
|
||||
# Scalyr is a log management tool that Zalando uses as a sidecar
|
||||
scalyr:
|
||||
configScalyr:
|
||||
# API key for the Scalyr sidecar
|
||||
# scalyr_api_key: ""
|
||||
|
||||
|
|
@ -257,9 +264,7 @@ serviceAccount:
|
|||
create: true
|
||||
# The name of the ServiceAccount to use.
|
||||
# If not set and create is true, a name is generated using the fullname template
|
||||
# When relying solely on the OperatorConfiguration CRD, this value has to be "operator"
|
||||
# Otherwise, the operator tries to use the "default" service account which is forbidden
|
||||
name: operator
|
||||
name:
|
||||
|
||||
priorityClassName: ""
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ configTarget: "ConfigMap"
|
|||
|
||||
# general configuration parameters
|
||||
configGeneral:
|
||||
# choose if deployment creates/updates CRDs with OpenAPIV3Validation
|
||||
enable_crd_validation: "true"
|
||||
# start any new database pod without limitations on shm memory
|
||||
enable_shm_volume: "true"
|
||||
# etcd connection string for Patroni. Empty uses K8s-native DCS.
|
||||
|
|
@ -55,7 +57,8 @@ configKubernetes:
|
|||
# label assigned to Kubernetes objects created by the operator
|
||||
cluster_name_label: version
|
||||
# annotations attached to each database pod
|
||||
# custom_pod_annotations: keya:valuea
|
||||
# custom_pod_annotations: keya:valuea,keyb:valueb
|
||||
|
||||
# toggles pod anti affinity on the Postgres pods
|
||||
enable_pod_antiaffinity: "false"
|
||||
# toggles PDB to set to MinAvailabe 0 or 1
|
||||
|
|
@ -136,9 +139,9 @@ configLoadBalancer:
|
|||
# toggles service type load balancer pointing to the replica pod of the cluster
|
||||
enable_replica_load_balancer: "false"
|
||||
# defines the DNS name string template for the master load balancer cluster
|
||||
master_dns_name_format: '{cluster}.{team}.staging.{hostedzone}'
|
||||
master_dns_name_format: '{cluster}.{team}.{hostedzone}'
|
||||
# defines the DNS name string template for the replica load balancer cluster
|
||||
replica_dns_name_format: '{cluster}-repl.{team}.staging.{hostedzone}'
|
||||
replica_dns_name_format: '{cluster}-repl.{team}.{hostedzone}'
|
||||
|
||||
# options to aid debugging of the operator itself
|
||||
configDebug:
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ pipeline:
|
|||
IMAGE=registry-write.opensource.zalan.do/acid/postgres-operator-test
|
||||
fi
|
||||
export IMAGE
|
||||
make tools deps docker
|
||||
make deps docker
|
||||
- desc: 'Run unit tests'
|
||||
cmd: |
|
||||
export PATH=$PATH:$HOME/go/bin
|
||||
|
|
|
|||
|
|
@ -3,6 +3,30 @@
|
|||
Learn how to configure and manage the Postgres Operator in your Kubernetes (K8s)
|
||||
environment.
|
||||
|
||||
## CRD Validation
|
||||
|
||||
[CustomResourceDefinitions](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/#customresourcedefinitions)
|
||||
will be registered with schema validation by default when the operator is
|
||||
deployed. The `OperatorConfiguration` CRD will only get created if the
|
||||
`POSTGRES_OPERATOR_CONFIGURATION_OBJECT` [environment variable](../manifests/postgres-operator.yaml#L36)
|
||||
in the deployment yaml is set and not empty.
|
||||
|
||||
When submitting manifests of [`postgresql`](../manifests/postgresql.crd.yaml) or
|
||||
[`OperatorConfiguration`](../manifests/operatorconfiguration.crd.yaml) custom
|
||||
resources with kubectl, validation can be bypassed with `--validate=false`. The
|
||||
operator can also be configured to not register CRDs with validation on `ADD` or
|
||||
`UPDATE` events. Running instances are not affected when enabling the validation
|
||||
afterwards unless the manifests is not changed then. Note, that the provided CRD
|
||||
manifests contain the validation for users to understand what schema is
|
||||
enforced.
|
||||
|
||||
Once the validation is enabled it can only be disabled manually by editing or
|
||||
patching the CRD manifest:
|
||||
|
||||
```bash
|
||||
zk8 patch crd postgresqls.acid.zalan.do -p '{"spec":{"validation": null}}'
|
||||
```
|
||||
|
||||
## Namespaces
|
||||
|
||||
### Select the namespace to deploy to
|
||||
|
|
@ -32,7 +56,7 @@ By default, the operator watches the namespace it is deployed to. You can
|
|||
change this by setting the `WATCHED_NAMESPACE` var in the `env` section of the
|
||||
[operator deployment](../manifests/postgres-operator.yaml) manifest or by
|
||||
altering the `watched_namespace` field in the operator
|
||||
[ConfigMap](../manifests/configmap.yaml#L79).
|
||||
[configuration](../manifests/postgresql-operator-default-configuration.yaml#L49).
|
||||
In the case both are set, the env var takes the precedence. To make the
|
||||
operator listen to all namespaces, explicitly set the field/env var to "`*`".
|
||||
|
||||
|
|
@ -115,7 +139,7 @@ that are aggregated into the K8s [default roles](https://kubernetes.io/docs/refe
|
|||
|
||||
To ensure Postgres pods are running on nodes without any other application pods,
|
||||
you can use [taints and tolerations](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/)
|
||||
and configure the required toleration in the operator ConfigMap.
|
||||
and configure the required toleration in the operator configuration.
|
||||
|
||||
As an example you can set following node taint:
|
||||
|
||||
|
|
@ -136,6 +160,21 @@ data:
|
|||
...
|
||||
```
|
||||
|
||||
For an OperatorConfiguration resource the toleration should be defined like
|
||||
this:
|
||||
|
||||
```yaml
|
||||
apiVersion: "acid.zalan.do/v1"
|
||||
kind: OperatorConfiguration
|
||||
metadata:
|
||||
name: postgresql-configuration
|
||||
configuration:
|
||||
kubernetes:
|
||||
toleration:
|
||||
postgres: "key:postgres,operator:Exists,effect:NoSchedule"
|
||||
...
|
||||
```
|
||||
|
||||
Note that the K8s version 1.13 brings [taint-based eviction](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/#taint-based-evictions)
|
||||
to the beta stage and enables it by default. Postgres pods by default receive
|
||||
tolerations for `unreachable` and `noExecute` taints with the timeout of `5m`.
|
||||
|
|
@ -148,7 +187,7 @@ completely, specify the toleration by leaving out the `tolerationSeconds` value
|
|||
|
||||
To ensure Postgres pods are running on different topologies, you can use
|
||||
[pod anti affinity](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/)
|
||||
and configure the required topology in the operator ConfigMap.
|
||||
and configure the required topology in the operator configuration.
|
||||
|
||||
Enable pod anti affinity by adding following line to the operator ConfigMap:
|
||||
|
||||
|
|
@ -161,21 +200,22 @@ data:
|
|||
enable_pod_antiaffinity: "true"
|
||||
```
|
||||
|
||||
By default the topology key for the pod anti affinity is set to
|
||||
`kubernetes.io/hostname`, you can set another topology key e.g.
|
||||
`failure-domain.beta.kubernetes.io/zone` by adding following line to the
|
||||
operator ConfigMap, see [built-in node labels](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) for available topology keys:
|
||||
Likewise, when using an OperatorConfiguration resource add:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
apiVersion: "acid.zalan.do/v1"
|
||||
kind: OperatorConfiguration
|
||||
metadata:
|
||||
name: postgres-operator
|
||||
data:
|
||||
enable_pod_antiaffinity: "true"
|
||||
pod_antiaffinity_topology_key: "failure-domain.beta.kubernetes.io/zone"
|
||||
name: postgresql-configuration
|
||||
configuration:
|
||||
kubernetes:
|
||||
enable_pod_antiaffinity: true
|
||||
```
|
||||
|
||||
By default the topology key for the pod anti affinity is set to
|
||||
`kubernetes.io/hostname`, you can set another topology key e.g.
|
||||
`failure-domain.beta.kubernetes.io/zone`. See [built-in node labels](https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#interlude-built-in-node-labels) for available topology keys.
|
||||
|
||||
## Pod Disruption Budget
|
||||
|
||||
By default the operator uses a PodDisruptionBudget (PDB) to protect the cluster
|
||||
|
|
@ -280,6 +320,20 @@ data:
|
|||
...
|
||||
```
|
||||
|
||||
**OperatorConfiguration**
|
||||
|
||||
```yaml
|
||||
apiVersion: "acid.zalan.do/v1"
|
||||
kind: OperatorConfiguration
|
||||
metadata:
|
||||
name: postgresql-operator-configuration
|
||||
configuration:
|
||||
kubernetes:
|
||||
# referencing config map with custom settings
|
||||
pod_environment_configmap: postgres-pod-config
|
||||
...
|
||||
```
|
||||
|
||||
**referenced ConfigMap `postgres-pod-config`**
|
||||
|
||||
```yaml
|
||||
|
|
@ -312,7 +366,7 @@ services: one for the master pod and one for replica pods. To expose these
|
|||
services to an outer network, one can attach load balancers to them by setting
|
||||
`enableMasterLoadBalancer` and/or `enableReplicaLoadBalancer` to `true` in the
|
||||
cluster manifest. In the case any of these variables are omitted from the
|
||||
manifest, the operator configmap's settings `enable_master_load_balancer` and
|
||||
manifest, the operator configuration settings `enable_master_load_balancer` and
|
||||
`enable_replica_load_balancer` apply. Note that the operator settings affect
|
||||
all Postgresql services running in all namespaces watched by the operator.
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ by setting the `GO111MODULE` environment variable to `on`. The make targets do
|
|||
this for you, so simply run
|
||||
|
||||
```bash
|
||||
make tools deps
|
||||
make deps
|
||||
```
|
||||
|
||||
This would take a while to complete. You have to redo `make deps` every time
|
||||
|
|
@ -284,6 +284,7 @@ manifest files:
|
|||
|
||||
Postgres manifest parameters are defined in the [api package](../pkg/apis/acid.zalan.do/v1/postgresql_type.go).
|
||||
The operator behavior has to be implemented at least in [k8sres.go](../pkg/cluster/k8sres.go).
|
||||
Validation of CRD parameters is controlled in [crd.go](../pkg/apis/acid.zalan.do/v1/crds.go).
|
||||
Please, reflect your changes in tests, for example in:
|
||||
* [config_test.go](../pkg/util/config/config_test.go)
|
||||
* [k8sres_test.go](../pkg/cluster/k8sres_test.go)
|
||||
|
|
@ -294,6 +295,7 @@ Please, reflect your changes in tests, for example in:
|
|||
For the CRD-based configuration, please update the following files:
|
||||
* the default [OperatorConfiguration](../manifests/postgresql-operator-default-configuration.yaml)
|
||||
* the Helm chart's [values-crd file](../charts/postgres-operator/values.yaml)
|
||||
* the CRD's [validation](../manifests/operatorconfiguration.crd.yaml)
|
||||
|
||||
Reflect the changes in the ConfigMap configuration as well (note that numeric
|
||||
and boolean parameters have to use double quotes here):
|
||||
|
|
|
|||
|
|
@ -55,8 +55,8 @@ kubectl create -f manifests/postgres-operator.yaml # deployment
|
|||
```
|
||||
|
||||
There is a [Kustomization](https://github.com/kubernetes-sigs/kustomize)
|
||||
manifest that [combines the mentioned resources](../manifests/kustomization.yaml) -
|
||||
it can be used with kubectl 1.14 or newer as easy as:
|
||||
manifest that [combines the mentioned resources](../manifests/kustomization.yaml)
|
||||
(except for the CRD) - it can be used with kubectl 1.14 or newer as easy as:
|
||||
|
||||
```bash
|
||||
kubectl apply -k github.com/zalando/postgres-operator/manifests
|
||||
|
|
@ -86,8 +86,9 @@ To use CRD-based configuration you need to specify the [values-crd yaml file](..
|
|||
helm install postgres-operator ./charts/postgres-operator -f ./charts/postgres-operator/values-crd.yaml
|
||||
```
|
||||
|
||||
The chart works with both Helm 2 and Helm 3. Documentation for installing
|
||||
applications with helm2 can be found in the [helm2 docs](https://v2.helm.sh/docs/).
|
||||
The chart works with both Helm 2 and Helm 3. The `crd-install` hook from v2 will
|
||||
be skipped with warning when using v3. Documentation for installing applications
|
||||
with Helm 2 can be found in the [v2 docs](https://v2.helm.sh/docs/).
|
||||
|
||||
### Operator Lifecycle Manager (OLM)
|
||||
|
||||
|
|
@ -119,15 +120,15 @@ kubectl get pod -l app.kubernetes.io/name=postgres-operator
|
|||
kubectl create -f manifests/minimal-postgres-manifest.yaml
|
||||
```
|
||||
|
||||
After the cluster manifest is submitted the operator will create Service and
|
||||
Endpoint resources and a StatefulSet which spins up new Pod(s) given the number
|
||||
of instances specified in the manifest. All resources are named like the
|
||||
cluster. The database pods can be identified by their number suffix, starting
|
||||
from `-0`. They run the [Spilo](https://github.com/zalando/spilo) container
|
||||
image by Zalando. As for the services and endpoints, there will be one for the
|
||||
master pod and another one for all the replicas (`-repl` suffix). Check if all
|
||||
components are coming up. Use the label `application=spilo` to filter and list
|
||||
the label `spilo-role` to see who is currently the master.
|
||||
After the cluster manifest is submitted and passed the validation the operator
|
||||
will create Service and Endpoint resources and a StatefulSet which spins up new
|
||||
Pod(s) given the number of instances specified in the manifest. All resources
|
||||
are named like the cluster. The database pods can be identified by their number
|
||||
suffix, starting from `-0`. They run the [Spilo](https://github.com/zalando/spilo)
|
||||
container image by Zalando. As for the services and endpoints, there will be one
|
||||
for the master pod and another one for all the replicas (`-repl` suffix). Check
|
||||
if all components are coming up. Use the label `application=spilo` to filter and
|
||||
list the label `spilo-role` to see who is currently the master.
|
||||
|
||||
```bash
|
||||
# check the deployed cluster
|
||||
|
|
|
|||
|
|
@ -29,21 +29,20 @@ configuration.
|
|||
|
||||
To test the CRD-based configuration locally, use the following
|
||||
```bash
|
||||
kubectl create -f manifests/operatorconfiguration.crd.yaml # registers the CRD
|
||||
kubectl create -f manifests/postgresql-operator-default-configuration.yaml
|
||||
|
||||
kubectl create -f manifests/operator-service-account-rbac.yaml
|
||||
kubectl create -f manifests/postgres-operator.yaml # set the env var as mentioned above
|
||||
kubectl create -f manifests/postgresql-operator-default-configuration.yaml
|
||||
|
||||
kubectl get operatorconfigurations postgresql-operator-default-configuration -o yaml
|
||||
```
|
||||
Note that the operator first attempts to register the CRD of the
|
||||
`OperatorConfiguration` and then waits for an instance to be created. In
|
||||
between these two event the operator pod may be failing since it cannot fetch
|
||||
the not-yet-existing `OperatorConfiguration` instance.
|
||||
|
||||
The CRD-based configuration is more powerful than the one based on ConfigMaps
|
||||
and should be used unless there is a compatibility requirement to use an already
|
||||
existing configuration. Even in that case, it should be rather straightforward
|
||||
to convert the configmap based configuration into the CRD-based one and restart
|
||||
the operator. The ConfigMaps-based configuration will be deprecated and
|
||||
to convert the ConfigMap-based configuration into the CRD-based one and restart
|
||||
the operator. The ConfigMap-based configuration will be deprecated and
|
||||
subsequently removed in future releases.
|
||||
|
||||
Note that for the CRD-based configuration groups of configuration options below
|
||||
|
|
@ -71,6 +70,11 @@ Variable names are underscore-separated words.
|
|||
|
||||
Those are top-level keys, containing both leaf keys and groups.
|
||||
|
||||
* **enable_crd_validation**
|
||||
toggles if the operator will create or update CRDs with
|
||||
[OpenAPI v3 schema validation](https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/#validation)
|
||||
The default is `true`.
|
||||
|
||||
* **etcd_host**
|
||||
Etcd connection string for Patroni defined as `host:port`. Not required when
|
||||
Patroni native Kubernetes support is used. The default is empty (use
|
||||
|
|
|
|||
|
|
@ -53,9 +53,9 @@ spec:
|
|||
- hostssl all all 0.0.0.0/0 md5
|
||||
- host all all 0.0.0.0/0 md5
|
||||
# slots:
|
||||
# - permanent_physical_1:
|
||||
# permanent_physical_1:
|
||||
# type: physical
|
||||
# - permanent_logical_1:
|
||||
# permanent_logical_1:
|
||||
# type: logical
|
||||
# database: foo
|
||||
# plugin: pgoutput
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ data:
|
|||
cluster_labels: application:spilo
|
||||
cluster_name_label: version
|
||||
# custom_service_annotations: "keyx:valuez,keya:valuea"
|
||||
# custom_pod_annotations: "keya:valuea"
|
||||
# custom_pod_annotations: "keya:valuea,keyb:valueb"
|
||||
db_hosted_zone: db.example.com
|
||||
debug_logging: "true"
|
||||
# default_cpu_limit: "3"
|
||||
|
|
@ -21,6 +21,7 @@ data:
|
|||
# default_memory_request: 100Mi
|
||||
docker_image: registry.opensource.zalan.do/acid/spilo-11:1.6-p1
|
||||
# enable_admin_role_for_users: "true"
|
||||
# enable_crd_validation: "true"
|
||||
# enable_database_access: "true"
|
||||
enable_master_load_balancer: "false"
|
||||
# enable_pod_antiaffinity: "false"
|
||||
|
|
@ -41,7 +42,7 @@ data:
|
|||
# logical_backup_s3_secret_access_key: ""
|
||||
# logical_backup_s3_sse: "AES256"
|
||||
# logical_backup_schedule: "30 00 * * *"
|
||||
master_dns_name_format: "{cluster}.{team}.staging.{hostedzone}"
|
||||
master_dns_name_format: "{cluster}.{team}.{hostedzone}"
|
||||
# master_pod_move_timeout: 10m
|
||||
# max_instances: "-1"
|
||||
# min_instances: "-1"
|
||||
|
|
@ -64,11 +65,11 @@ data:
|
|||
ready_wait_interval: 3s
|
||||
ready_wait_timeout: 30s
|
||||
repair_period: 5m
|
||||
replica_dns_name_format: "{cluster}-repl.{team}.staging.{hostedzone}"
|
||||
replica_dns_name_format: "{cluster}-repl.{team}.{hostedzone}"
|
||||
replication_username: standby
|
||||
resource_check_interval: 3s
|
||||
resource_check_timeout: 10m
|
||||
resync_period: 5m
|
||||
resync_period: 30m
|
||||
ring_log_lines: "100"
|
||||
secret_name_template: "{username}.{cluster}.credentials"
|
||||
# sidecar_docker_images: ""
|
||||
|
|
|
|||
|
|
@ -0,0 +1,276 @@
|
|||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: operatorconfigurations.acid.zalan.do
|
||||
spec:
|
||||
group: acid.zalan.do
|
||||
names:
|
||||
kind: OperatorConfiguration
|
||||
listKind: OperatorConfigurationList
|
||||
plural: operatorconfigurations
|
||||
singular: operatorconfiguration
|
||||
shortNames:
|
||||
- opconfig
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
version: v1
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- apiVersion
|
||||
- configuration
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
enum:
|
||||
- OperatorConfiguration
|
||||
apiVersion:
|
||||
type: string
|
||||
enum:
|
||||
- acid.zalan.do/v1
|
||||
configuration:
|
||||
type: object
|
||||
properties:
|
||||
docker_image:
|
||||
type: string
|
||||
enable_crd_validation:
|
||||
type: boolean
|
||||
enable_shm_volume:
|
||||
type: boolean
|
||||
etcd_host:
|
||||
type: string
|
||||
max_instances:
|
||||
type: integer
|
||||
minimum: -1 # -1 = disabled
|
||||
min_instances:
|
||||
type: integer
|
||||
minimum: -1 # -1 = disabled
|
||||
resync_period:
|
||||
type: string
|
||||
repair_period:
|
||||
type: string
|
||||
set_memory_request_to_limit:
|
||||
type: boolean
|
||||
sidecar_docker_images:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
workers:
|
||||
type: integer
|
||||
minimum: 1
|
||||
users:
|
||||
type: object
|
||||
properties:
|
||||
replication_username:
|
||||
type: string
|
||||
super_username:
|
||||
type: string
|
||||
kubernetes:
|
||||
type: object
|
||||
properties:
|
||||
cluster_domain:
|
||||
type: string
|
||||
cluster_labels:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
cluster_name_label:
|
||||
type: string
|
||||
custom_pod_annotations:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
enable_pod_antiaffinity:
|
||||
type: boolean
|
||||
enable_pod_disruption_budget:
|
||||
type: boolean
|
||||
infrastructure_roles_secret_name:
|
||||
type: string
|
||||
inherited_labels:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
node_readiness_label:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
oauth_token_secret_name:
|
||||
type: string
|
||||
pdb_name_format:
|
||||
type: string
|
||||
pod_antiaffinity_topology_key:
|
||||
type: string
|
||||
pod_environment_configmap:
|
||||
type: string
|
||||
pod_management_policy:
|
||||
type: string
|
||||
enum:
|
||||
- "ordered_ready"
|
||||
- "parallel"
|
||||
pod_role_label:
|
||||
type: string
|
||||
pod_service_account_name:
|
||||
type: string
|
||||
pod_terminate_grace_period:
|
||||
type: string
|
||||
secret_name_template:
|
||||
type: string
|
||||
spilo_fsgroup:
|
||||
type: integer
|
||||
spilo_privileged:
|
||||
type: boolean
|
||||
toleration:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
watched_namespace:
|
||||
type: string
|
||||
postgres_pod_resources:
|
||||
type: object
|
||||
properties:
|
||||
default_cpu_limit:
|
||||
type: string
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
default_cpu_request:
|
||||
type: string
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
default_memory_limit:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
default_memory_request:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
timeouts:
|
||||
type: object
|
||||
properties:
|
||||
pod_label_wait_timeout:
|
||||
type: string
|
||||
pod_deletion_wait_timeout:
|
||||
type: string
|
||||
ready_wait_interval:
|
||||
type: string
|
||||
ready_wait_timeout:
|
||||
type: string
|
||||
resource_check_interval:
|
||||
type: string
|
||||
resource_check_timeout:
|
||||
type: string
|
||||
load_balancer:
|
||||
type: object
|
||||
properties:
|
||||
db_hosted_zone:
|
||||
type: string
|
||||
enable_master_load_balancer:
|
||||
type: boolean
|
||||
enable_replica_load_balancer:
|
||||
type: boolean
|
||||
custom_service_annotations:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
master_dns_name_format:
|
||||
type: string
|
||||
replica_dns_name_format:
|
||||
type: string
|
||||
aws_or_gcp:
|
||||
type: object
|
||||
properties:
|
||||
additional_secret_mount:
|
||||
type: string
|
||||
additional_secret_mount_path:
|
||||
type: string
|
||||
aws_region:
|
||||
type: string
|
||||
kube_iam_role:
|
||||
type: string
|
||||
log_s3_bucket:
|
||||
type: string
|
||||
wal_s3_bucket:
|
||||
type: string
|
||||
logical_backup:
|
||||
type: object
|
||||
properties:
|
||||
logical_backup_schedule:
|
||||
type: string
|
||||
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
|
||||
logical_backup_docker_image:
|
||||
type: string
|
||||
logical_backup_s3_bucket:
|
||||
type: string
|
||||
logical_backup_s3_endpoint:
|
||||
type: string
|
||||
logical_backup_s3_sse:
|
||||
type: string
|
||||
logical_backup_s3_access_key_id:
|
||||
type: string
|
||||
logical_backup_s3_secret_access_key:
|
||||
type: string
|
||||
debug:
|
||||
type: object
|
||||
properties:
|
||||
debug_logging:
|
||||
type: boolean
|
||||
enable_database_access:
|
||||
type: boolean
|
||||
teams_api:
|
||||
type: object
|
||||
properties:
|
||||
enable_admin_role_for_users:
|
||||
type: boolean
|
||||
enable_team_superuser:
|
||||
type: boolean
|
||||
enable_teams_api:
|
||||
type: boolean
|
||||
pam_configuration:
|
||||
type: string
|
||||
pam_role_name:
|
||||
type: string
|
||||
postgres_superuser_teams:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
protected_role_names:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
team_admin_role:
|
||||
type: string
|
||||
team_api_role_configuration:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
teams_api_url:
|
||||
type: string
|
||||
logging_rest_api:
|
||||
type: object
|
||||
properties:
|
||||
api_port:
|
||||
type: integer
|
||||
cluster_history_entries:
|
||||
type: integer
|
||||
ring_log_lines:
|
||||
type: integer
|
||||
scalyr:
|
||||
type: object
|
||||
properties:
|
||||
scalyr_api_key:
|
||||
type: string
|
||||
scalyr_cpu_limit:
|
||||
type: string
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
scalyr_cpu_request:
|
||||
type: string
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
scalyr_image:
|
||||
type: string
|
||||
scalyr_memory_limit:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
scalyr_memory_request:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
scalyr_server_url:
|
||||
type: string
|
||||
|
|
@ -3,6 +3,7 @@ kind: OperatorConfiguration
|
|||
metadata:
|
||||
name: postgresql-operator-default-configuration
|
||||
configuration:
|
||||
# enable_crd_validation: true
|
||||
etcd_host: ""
|
||||
docker_image: registry.opensource.zalan.do/acid/spilo-11:1.6-p1
|
||||
# enable_shm_volume: true
|
||||
|
|
@ -27,24 +28,25 @@ configuration:
|
|||
# keyb: valueb
|
||||
enable_pod_antiaffinity: false
|
||||
enable_pod_disruption_budget: true
|
||||
# infrastructure_roles_secret_name: ""
|
||||
# infrastructure_roles_secret_name: postgresql-infrastructure-roles
|
||||
# inherited_labels:
|
||||
# - application
|
||||
# - environment
|
||||
# node_readiness_label: ""
|
||||
# node_readiness_label:
|
||||
# status: ready
|
||||
oauth_token_secret_name: postgresql-operator
|
||||
pdb_name_format: "postgres-{cluster}-pdb"
|
||||
pod_antiaffinity_topology_key: "kubernetes.io/hostname"
|
||||
# pod_environment_configmap: ""
|
||||
pod_management_policy: "ordered_ready"
|
||||
pod_role_label: spilo-role
|
||||
pod_service_account_name: operator
|
||||
pod_service_account_name: zalando-postgres-operator
|
||||
pod_terminate_grace_period: 5m
|
||||
secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}"
|
||||
# spilo_fsgroup: 103
|
||||
spilo_privileged: false
|
||||
# toleration: {}
|
||||
# watched_namespace:""
|
||||
# watched_namespace: ""
|
||||
postgres_pod_resources:
|
||||
default_cpu_limit: "3"
|
||||
default_cpu_request: 100m
|
||||
|
|
@ -74,7 +76,6 @@ configuration:
|
|||
# log_s3_bucket: ""
|
||||
# wal_s3_bucket: ""
|
||||
logical_backup:
|
||||
log_s3_bucket: ""
|
||||
logical_backup_docker_image: "registry.opensource.zalan.do/acid/logical-backup"
|
||||
logical_backup_s3_access_key_id: ""
|
||||
logical_backup_s3_bucket: "my-bucket-url"
|
||||
|
|
@ -91,7 +92,8 @@ configuration:
|
|||
enable_teams_api: false
|
||||
# pam_configuration: ""
|
||||
pam_role_name: zalandos
|
||||
# postgres_superuser_teams: "postgres_superusers"
|
||||
# postgres_superuser_teams:
|
||||
# - postgres_superusers
|
||||
protected_role_names:
|
||||
- admin
|
||||
team_admin_role: admin
|
||||
|
|
|
|||
|
|
@ -0,0 +1,327 @@
|
|||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: postgresqls.acid.zalan.do
|
||||
spec:
|
||||
group: acid.zalan.do
|
||||
names:
|
||||
kind: postgresql
|
||||
listKind: postgresqlList
|
||||
plural: postgresqls
|
||||
singular: postgresql
|
||||
shortNames:
|
||||
- pg
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
version: v1
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- apiVersion
|
||||
- spec
|
||||
properties:
|
||||
kind:
|
||||
type: string
|
||||
enum:
|
||||
- postgresql
|
||||
apiVersion:
|
||||
type: string
|
||||
enum:
|
||||
- acid.zalan.do/v1
|
||||
spec:
|
||||
type: object
|
||||
required:
|
||||
- numberOfInstances
|
||||
- teamId
|
||||
- postgresql
|
||||
properties:
|
||||
allowedSourceRanges:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: string
|
||||
pattern: '^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\/(\d|[1-2]\d|3[0-2])$'
|
||||
clone:
|
||||
type: object
|
||||
required:
|
||||
- cluster
|
||||
properties:
|
||||
cluster:
|
||||
type: string
|
||||
s3_endpoint:
|
||||
type: string
|
||||
s3_access_key_id:
|
||||
type: string
|
||||
s3_secret_access_key:
|
||||
type: string
|
||||
s3_force_path_style:
|
||||
type: string
|
||||
s3_wal_path:
|
||||
type: string
|
||||
timestamp:
|
||||
type: string
|
||||
pattern: '^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\.[0-9]+)?(([Zz])|([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$'
|
||||
# The regexp matches the date-time format (RFC 3339 Section 5.6) that specifies a timezone as an offset relative to UTC
|
||||
# Example: 1996-12-19T16:39:57-08:00
|
||||
# Note: this field requires a timezone
|
||||
uid:
|
||||
format: uuid
|
||||
type: string
|
||||
databases:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
# Note: usernames specified here as database owners must be declared in the users key of the spec key.
|
||||
dockerImage:
|
||||
type: string
|
||||
enableLogicalBackup:
|
||||
type: boolean
|
||||
enableMasterLoadBalancer:
|
||||
type: boolean
|
||||
enableReplicaLoadBalancer:
|
||||
type: boolean
|
||||
enableShmVolume:
|
||||
type: boolean
|
||||
init_containers: # deprecated
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
initContainers:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
logicalBackupSchedule:
|
||||
type: string
|
||||
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
|
||||
maintenanceWindows:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
pattern: '^\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\d):([0-5]?\d)|(2[0-3]|[01]?\d):([0-5]?\d))\ *$'
|
||||
numberOfInstances:
|
||||
type: integer
|
||||
minimum: 0
|
||||
patroni:
|
||||
type: object
|
||||
properties:
|
||||
initdb:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
pg_hba:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
slots:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
ttl:
|
||||
type: integer
|
||||
loop_wait:
|
||||
type: integer
|
||||
retry_timeout:
|
||||
type: integer
|
||||
maximum_lag_on_failover:
|
||||
type: integer
|
||||
podAnnotations:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
pod_priority_class_name: # deprecated
|
||||
type: string
|
||||
podPriorityClassName:
|
||||
type: string
|
||||
postgresql:
|
||||
type: object
|
||||
required:
|
||||
- version
|
||||
properties:
|
||||
version:
|
||||
type: string
|
||||
enum:
|
||||
- "9.3"
|
||||
- "9.4"
|
||||
- "9.5"
|
||||
- "9.6"
|
||||
- "10"
|
||||
- "11"
|
||||
- "12"
|
||||
parameters:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
replicaLoadBalancer: # deprecated
|
||||
type: boolean
|
||||
resources:
|
||||
type: object
|
||||
required:
|
||||
- requests
|
||||
- limits
|
||||
properties:
|
||||
limits:
|
||||
type: object
|
||||
required:
|
||||
- cpu
|
||||
- memory
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
# Decimal natural followed by m, or decimal natural followed by
|
||||
# dot followed by up to three decimal digits.
|
||||
#
|
||||
# This is because the Kubernetes CPU resource has millis as the
|
||||
# maximum precision. The actual values are checked in code
|
||||
# because the regular expression would be huge and horrible and
|
||||
# not very helpful in validation error messages; this one checks
|
||||
# only the format of the given number.
|
||||
#
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu
|
||||
pattern: '^(\d+m|\d+\.\d{1,3})$'
|
||||
# Note: the value specified here must not be zero or be lower
|
||||
# than the corresponding request.
|
||||
memory:
|
||||
type: string
|
||||
# You can express memory as a plain integer or as a fixed-point
|
||||
# integer using one of these suffixes: E, P, T, G, M, k. You can
|
||||
# also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki
|
||||
#
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
# Note: the value specified here must not be zero or be lower
|
||||
# than the corresponding request.
|
||||
requests:
|
||||
type: object
|
||||
required:
|
||||
- cpu
|
||||
- memory
|
||||
properties:
|
||||
cpu:
|
||||
type: string
|
||||
# Decimal natural followed by m, or decimal natural followed by
|
||||
# dot followed by up to three decimal digits.
|
||||
#
|
||||
# This is because the Kubernetes CPU resource has millis as the
|
||||
# maximum precision. The actual values are checked in code
|
||||
# because the regular expression would be huge and horrible and
|
||||
# not very helpful in validation error messages; this one checks
|
||||
# only the format of the given number.
|
||||
#
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-cpu
|
||||
pattern: '^(\d+m|\d+\.\d{1,3})$'
|
||||
# Note: the value specified here must not be zero or be higher
|
||||
# than the corresponding limit.
|
||||
memory:
|
||||
type: string
|
||||
# You can express memory as a plain integer or as a fixed-point
|
||||
# integer using one of these suffixes: E, P, T, G, M, k. You can
|
||||
# also use the power-of-two equivalents: Ei, Pi, Ti, Gi, Mi, Ki
|
||||
#
|
||||
# https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#meaning-of-memory
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
# Note: the value specified here must not be zero or be higher
|
||||
# than the corresponding limit.
|
||||
sidecars:
|
||||
type: array
|
||||
nullable: true
|
||||
items:
|
||||
type: object
|
||||
additionalProperties: true
|
||||
spiloFSGroup:
|
||||
type: integer
|
||||
standby:
|
||||
type: object
|
||||
required:
|
||||
- s3_wal_path
|
||||
properties:
|
||||
s3_wal_path:
|
||||
type: string
|
||||
teamId:
|
||||
type: string
|
||||
tolerations:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
- effect
|
||||
properties:
|
||||
key:
|
||||
type: string
|
||||
operator:
|
||||
type: string
|
||||
enum:
|
||||
- Equal
|
||||
- Exists
|
||||
value:
|
||||
type: string
|
||||
effect:
|
||||
type: string
|
||||
enum:
|
||||
- NoExecute
|
||||
- NoSchedule
|
||||
- PreferNoSchedule
|
||||
tolerationSeconds:
|
||||
type: integer
|
||||
useLoadBalancer: # deprecated
|
||||
type: boolean
|
||||
users:
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: array
|
||||
nullable: true
|
||||
description: "Role flags specified here must not contradict each other"
|
||||
items:
|
||||
type: string
|
||||
enum:
|
||||
- bypassrls
|
||||
- BYPASSRLS
|
||||
- nobypassrls
|
||||
- NOBYPASSRLS
|
||||
- createdb
|
||||
- CREATEDB
|
||||
- nocreatedb
|
||||
- NOCREATEDB
|
||||
- createrole
|
||||
- CREATEROLE
|
||||
- nocreaterole
|
||||
- NOCREATEROLE
|
||||
- inherit
|
||||
- INHERIT
|
||||
- noinherit
|
||||
- NOINHERIT
|
||||
- login
|
||||
- LOGIN
|
||||
- nologin
|
||||
- NOLOGIN
|
||||
- replication
|
||||
- REPLICATION
|
||||
- noreplication
|
||||
- NOREPLICATION
|
||||
- superuser
|
||||
- SUPERUSER
|
||||
- nosuperuser
|
||||
- NOSUPERUSER
|
||||
volume:
|
||||
type: object
|
||||
required:
|
||||
- size
|
||||
properties:
|
||||
size:
|
||||
type: string
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
# Note: the value specified here must not be zero.
|
||||
storageClass:
|
||||
type: string
|
||||
subPath:
|
||||
type: string
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
package v1
|
||||
|
||||
import (
|
||||
"github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do"
|
||||
acidzalando "github.com/zalando/postgres-operator/pkg/apis/acid.zalan.do"
|
||||
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
|
@ -103,7 +103,902 @@ var OperatorConfigCRDResourceColumns = []apiextv1beta1.CustomResourceColumnDefin
|
|||
},
|
||||
}
|
||||
|
||||
func buildCRD(name, kind, plural, short string, columns []apiextv1beta1.CustomResourceColumnDefinition) *apiextv1beta1.CustomResourceDefinition {
|
||||
var min0 = 0.0
|
||||
var min1 = 1.0
|
||||
var minDisable = -1.0
|
||||
|
||||
// PostgresCRDResourceValidation to check applied manifest parameters
|
||||
var PostgresCRDResourceValidation = apiextv1beta1.CustomResourceValidation{
|
||||
OpenAPIV3Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
Required: []string{"kind", "apiVersion", "spec"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"kind": {
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"postgresql"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"acid.zalan.do/v1"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
"spec": {
|
||||
Type: "object",
|
||||
Required: []string{"numberOfInstances", "teamId", "postgresql"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"allowedSourceRanges": {
|
||||
Type: "array",
|
||||
Nullable: true,
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
Pattern: "^(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\.(\\d|[1-9]\\d|1\\d\\d|2[0-4]\\d|25[0-5])\\/(\\d|[1-2]\\d|3[0-2])$",
|
||||
},
|
||||
},
|
||||
},
|
||||
"clone": {
|
||||
Type: "object",
|
||||
Required: []string{"cluster"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"cluster": {
|
||||
Type: "string",
|
||||
},
|
||||
"s3_endpoint": {
|
||||
Type: "string",
|
||||
},
|
||||
"s3_access_key_id": {
|
||||
Type: "string",
|
||||
},
|
||||
"s3_secret_access_key": {
|
||||
Type: "string",
|
||||
},
|
||||
"s3_force_path_style": {
|
||||
Type: "string",
|
||||
},
|
||||
"s3_wal_path": {
|
||||
Type: "string",
|
||||
},
|
||||
"timestamp": {
|
||||
Type: "string",
|
||||
Description: "Date-time format that specifies a timezone as an offset relative to UTC e.g. 1996-12-19T16:39:57-08:00",
|
||||
Pattern: "^([0-9]+)-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(\\.[0-9]+)?(([Zz])|([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$",
|
||||
},
|
||||
"uid": {
|
||||
Type: "string",
|
||||
Format: "uuid",
|
||||
},
|
||||
},
|
||||
},
|
||||
"databases": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
Description: "User names specified here as database owners must be declared in the users key of the spec key",
|
||||
},
|
||||
},
|
||||
},
|
||||
"dockerImage": {
|
||||
Type: "string",
|
||||
},
|
||||
"enableLogicalBackup": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enableMasterLoadBalancer": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enableReplicaLoadBalancer": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enableShmVolume": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"init_containers": {
|
||||
Type: "array",
|
||||
Description: "Deprecated",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Allows: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"initContainers": {
|
||||
Type: "array",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Allows: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"logicalBackupSchedule": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+|\\*)(/\\d+)?(\\s+(\\d+|\\*)(/\\d+)?){4}$",
|
||||
},
|
||||
"maintenanceWindows": {
|
||||
Type: "array",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
Pattern: "^\\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\\d):([0-5]?\\d)|(2[0-3]|[01]?\\d):([0-5]?\\d))-((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\\d):([0-5]?\\d)|(2[0-3]|[01]?\\d):([0-5]?\\d))\\ *$",
|
||||
},
|
||||
},
|
||||
},
|
||||
"numberOfInstances": {
|
||||
Type: "integer",
|
||||
Minimum: &min0,
|
||||
},
|
||||
"patroni": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"initdb": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"pg_hba": {
|
||||
Type: "array",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"slots": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"ttl": {
|
||||
Type: "integer",
|
||||
},
|
||||
"loop_wait": {
|
||||
Type: "integer",
|
||||
},
|
||||
"retry_timeout": {
|
||||
Type: "integer",
|
||||
},
|
||||
"maximum_lag_on_failover": {
|
||||
Type: "integer",
|
||||
},
|
||||
},
|
||||
},
|
||||
"podAnnotations": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"pod_priority_class_name": {
|
||||
Type: "string",
|
||||
Description: "Deprecated",
|
||||
},
|
||||
"podPriorityClassName": {
|
||||
Type: "string",
|
||||
},
|
||||
"postgresql": {
|
||||
Type: "object",
|
||||
Required: []string{"version"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"version": {
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"9.3"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"9.4"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"9.5"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"9.6"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"10"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"11"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"12"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
"parameters": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"replicaLoadBalancer": {
|
||||
Type: "boolean",
|
||||
Description: "Deprecated",
|
||||
},
|
||||
"resources": {
|
||||
Type: "object",
|
||||
Required: []string{"requests", "limits"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"limits": {
|
||||
Type: "object",
|
||||
Required: []string{"cpu", "memory"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"cpu": {
|
||||
Type: "string",
|
||||
Description: "Decimal natural followed by m, or decimal natural followed by dot followed by up to three decimal digits (precision used by Kubernetes). Must be greater than 0",
|
||||
Pattern: "^(\\d+m|\\d+\\.\\d{1,3})$",
|
||||
},
|
||||
"memory": {
|
||||
Type: "string",
|
||||
Description: "Plain integer or fixed-point integer using one of these suffixes: E, P, T, G, M, k (with or without a tailing i). Must be greater than 0",
|
||||
Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
|
||||
},
|
||||
},
|
||||
},
|
||||
"requests": {
|
||||
Type: "object",
|
||||
Required: []string{"cpu", "memory"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"cpu": {
|
||||
Type: "string",
|
||||
Description: "Decimal natural followed by m, or decimal natural followed by dot followed by up to three decimal digits (precision used by Kubernetes). Must be greater than 0",
|
||||
Pattern: "^(\\d+m|\\d+\\.\\d{1,3})$",
|
||||
},
|
||||
"memory": {
|
||||
Type: "string",
|
||||
Description: "Plain integer or fixed-point integer using one of these suffixes: E, P, T, G, M, k (with or without a tailing i). Must be greater than 0",
|
||||
Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"sidecars": {
|
||||
Type: "array",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Allows: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"spiloFSGroup": {
|
||||
Type: "integer",
|
||||
},
|
||||
"standby": {
|
||||
Type: "object",
|
||||
Required: []string{"s3_wal_path"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"s3_wal_path": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"teamId": {
|
||||
Type: "string",
|
||||
},
|
||||
"tolerations": {
|
||||
Type: "array",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
Required: []string{"key", "operator", "effect"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"key": {
|
||||
Type: "string",
|
||||
},
|
||||
"operator": {
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"Equal"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"Exists"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
"value": {
|
||||
Type: "string",
|
||||
},
|
||||
"effect": {
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"NoExecute"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"NoSchedule"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"PreferNoSchedule"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
"tolerationSeconds": {
|
||||
Type: "integer",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"useLoadBalancer": {
|
||||
Type: "boolean",
|
||||
Description: "Deprecated",
|
||||
},
|
||||
"users": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "array",
|
||||
Description: "Role flags specified here must not contradict each other",
|
||||
Nullable: true,
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"bypassrls"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"BYPASSRLS"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"nobypassrls"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"NOBYPASSRLS"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"createdb"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"CREATEDB"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"nocreatedb"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"NOCREATEDB"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"createrole"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"CREATEROLE"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"nocreaterole"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"NOCREATEROLE"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"inherit"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"INHERIT"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"noinherit"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"NOINHERIT"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"login"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"LOGIN"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"nologin"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"NOLOGIN"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"replication"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"REPLICATION"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"noreplication"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"NOREPLICATION"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"superuser"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"SUPERUSER"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"nosuperuser"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"NOSUPERUSER"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"volume": {
|
||||
Type: "object",
|
||||
Required: []string{"size"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"size": {
|
||||
Type: "string",
|
||||
Description: "Value must not be zero",
|
||||
Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
|
||||
},
|
||||
"storageClass": {
|
||||
Type: "string",
|
||||
},
|
||||
"subPath": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// OperatorConfigCRDResourceValidation to check applied manifest parameters
|
||||
var OperatorConfigCRDResourceValidation = apiextv1beta1.CustomResourceValidation{
|
||||
OpenAPIV3Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "object",
|
||||
Required: []string{"kind", "apiVersion", "configuration"},
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"kind": {
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"OperatorConfiguration"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
"apiVersion": {
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"acid.zalan.do/v1"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
"configuration": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"docker_image": {
|
||||
Type: "string",
|
||||
},
|
||||
"enable_crd_validation": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enable_shm_volume": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"etcd_host": {
|
||||
Type: "string",
|
||||
},
|
||||
"max_instances": {
|
||||
Type: "integer",
|
||||
Description: "-1 = disabled",
|
||||
Minimum: &minDisable,
|
||||
},
|
||||
"min_instances": {
|
||||
Type: "integer",
|
||||
Description: "-1 = disabled",
|
||||
Minimum: &minDisable,
|
||||
},
|
||||
"resync_period": {
|
||||
Type: "string",
|
||||
},
|
||||
"repair_period": {
|
||||
Type: "string",
|
||||
},
|
||||
"set_memory_request_to_limit": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"sidecar_docker_images": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"workers": {
|
||||
Type: "integer",
|
||||
Minimum: &min1,
|
||||
},
|
||||
"users": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"replication_username": {
|
||||
Type: "string",
|
||||
},
|
||||
"super_username": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"kubernetes": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"cluster_domain": {
|
||||
Type: "string",
|
||||
},
|
||||
"cluster_labels": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"cluster_name_label": {
|
||||
Type: "string",
|
||||
},
|
||||
"custom_pod_annotations": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"enable_pod_antiaffinity": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enable_pod_disruption_budget": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"infrastructure_roles_secret_name": {
|
||||
Type: "string",
|
||||
},
|
||||
"inherited_labels": {
|
||||
Type: "array",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"node_readiness_label": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"oauth_token_secret_name": {
|
||||
Type: "string",
|
||||
},
|
||||
"pdb_name_format": {
|
||||
Type: "string",
|
||||
},
|
||||
"pod_antiaffinity_topology_key": {
|
||||
Type: "string",
|
||||
},
|
||||
"pod_environment_configmap": {
|
||||
Type: "string",
|
||||
},
|
||||
"pod_management_policy": {
|
||||
Type: "string",
|
||||
Enum: []apiextv1beta1.JSON{
|
||||
{
|
||||
Raw: []byte(`"ordered_ready"`),
|
||||
},
|
||||
{
|
||||
Raw: []byte(`"parallel"`),
|
||||
},
|
||||
},
|
||||
},
|
||||
"pod_role_label": {
|
||||
Type: "string",
|
||||
},
|
||||
"pod_service_account_name": {
|
||||
Type: "string",
|
||||
},
|
||||
"pod_terminate_grace_period": {
|
||||
Type: "string",
|
||||
},
|
||||
"secret_name_template": {
|
||||
Type: "string",
|
||||
},
|
||||
"spilo_fsgroup": {
|
||||
Type: "integer",
|
||||
},
|
||||
"spilo_privileged": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"toleration": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"watched_namespace": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"postgres_pod_resources": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"default_cpu_limit": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$",
|
||||
},
|
||||
"default_cpu_request": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$",
|
||||
},
|
||||
"default_memory_limit": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
|
||||
},
|
||||
"default_memory_request": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
|
||||
},
|
||||
},
|
||||
},
|
||||
"timeouts": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"pod_label_wait_timeout": {
|
||||
Type: "string",
|
||||
},
|
||||
"pod_deletion_wait_timeout": {
|
||||
Type: "string",
|
||||
},
|
||||
"ready_wait_interval": {
|
||||
Type: "string",
|
||||
},
|
||||
"ready_wait_timeout": {
|
||||
Type: "string",
|
||||
},
|
||||
"resource_check_interval": {
|
||||
Type: "string",
|
||||
},
|
||||
"resource_check_timeout": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"load_balancer": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"db_hosted_zone": {
|
||||
Type: "string",
|
||||
},
|
||||
"enable_master_load_balancer": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enable_replica_load_balancer": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"custom_service_annotations": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"master_dns_name_format": {
|
||||
Type: "string",
|
||||
},
|
||||
"replica_dns_name_format": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"aws_or_gcp": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"additional_secret_mount": {
|
||||
Type: "string",
|
||||
},
|
||||
"additional_secret_mount_path": {
|
||||
Type: "string",
|
||||
},
|
||||
"aws_region": {
|
||||
Type: "string",
|
||||
},
|
||||
"kube_iam_role": {
|
||||
Type: "string",
|
||||
},
|
||||
"log_s3_bucket": {
|
||||
Type: "string",
|
||||
},
|
||||
"wal_s3_bucket": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"logical_backup": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"logical_backup_schedule": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+|\\*)(/\\d+)?(\\s+(\\d+|\\*)(/\\d+)?){4}$",
|
||||
},
|
||||
"logical_backup_docker_image": {
|
||||
Type: "string",
|
||||
},
|
||||
"logical_backup_s3_bucket": {
|
||||
Type: "string",
|
||||
},
|
||||
"logical_backup_s3_endpoint": {
|
||||
Type: "string",
|
||||
},
|
||||
"logical_backup_s3_sse": {
|
||||
Type: "string",
|
||||
},
|
||||
"logical_backup_s3_access_key_id": {
|
||||
Type: "string",
|
||||
},
|
||||
"logical_backup_s3_secret_access_key": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"debug": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"debug_logging": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enable_database_access": {
|
||||
Type: "boolean",
|
||||
},
|
||||
},
|
||||
},
|
||||
"teams_api": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"enable_admin_role_for_users": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enable_team_superuser": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"enable_teams_api": {
|
||||
Type: "boolean",
|
||||
},
|
||||
"pam_configuration": {
|
||||
Type: "string",
|
||||
},
|
||||
"pam_role_name": {
|
||||
Type: "string",
|
||||
},
|
||||
"postgres_superuser_teams": {
|
||||
Type: "array",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"protected_role_names": {
|
||||
Type: "array",
|
||||
Items: &apiextv1beta1.JSONSchemaPropsOrArray{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"team_admin_role": {
|
||||
Type: "string",
|
||||
},
|
||||
"team_api_role_configuration": {
|
||||
Type: "object",
|
||||
AdditionalProperties: &apiextv1beta1.JSONSchemaPropsOrBool{
|
||||
Schema: &apiextv1beta1.JSONSchemaProps{
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"teams_api_url": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
"logging_rest_api": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"api_port": {
|
||||
Type: "integer",
|
||||
},
|
||||
"cluster_history_entries": {
|
||||
Type: "integer",
|
||||
},
|
||||
"ring_log_lines": {
|
||||
Type: "integer",
|
||||
},
|
||||
},
|
||||
},
|
||||
"scalyr": {
|
||||
Type: "object",
|
||||
Properties: map[string]apiextv1beta1.JSONSchemaProps{
|
||||
"scalyr_api_key": {
|
||||
Type: "string",
|
||||
},
|
||||
"scalyr_cpu_limit": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$",
|
||||
},
|
||||
"scalyr_cpu_request": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+m|\\d+(\\.\\d{1,3})?)$",
|
||||
},
|
||||
"scalyr_image": {
|
||||
Type: "string",
|
||||
},
|
||||
"scalyr_memory_limit": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
|
||||
},
|
||||
"scalyr_memory_request": {
|
||||
Type: "string",
|
||||
Pattern: "^(\\d+(e\\d+)?|\\d+(\\.\\d+)?(e\\d+)?[EPTGMK]i?)$",
|
||||
},
|
||||
"scalyr_server_url": {
|
||||
Type: "string",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func buildCRD(name, kind, plural, short string, columns []apiextv1beta1.CustomResourceColumnDefinition, validation apiextv1beta1.CustomResourceValidation) *apiextv1beta1.CustomResourceDefinition {
|
||||
return &apiextv1beta1.CustomResourceDefinition{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
|
|
@ -121,24 +1016,39 @@ func buildCRD(name, kind, plural, short string, columns []apiextv1beta1.CustomRe
|
|||
Status: &apiextv1beta1.CustomResourceSubresourceStatus{},
|
||||
},
|
||||
AdditionalPrinterColumns: columns,
|
||||
Validation: &validation,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// PostgresCRD returns CustomResourceDefinition built from PostgresCRDResource
|
||||
func PostgresCRD() *apiextv1beta1.CustomResourceDefinition {
|
||||
func PostgresCRD(enableValidation *bool) *apiextv1beta1.CustomResourceDefinition {
|
||||
postgresCRDvalidation := apiextv1beta1.CustomResourceValidation{}
|
||||
|
||||
if enableValidation != nil && *enableValidation {
|
||||
postgresCRDvalidation = PostgresCRDResourceValidation
|
||||
}
|
||||
|
||||
return buildCRD(PostgresCRDResouceName,
|
||||
PostgresCRDResourceKind,
|
||||
PostgresCRDResourcePlural,
|
||||
PostgresCRDResourceShort,
|
||||
PostgresCRDResourceColumns)
|
||||
PostgresCRDResourceColumns,
|
||||
postgresCRDvalidation)
|
||||
}
|
||||
|
||||
// ConfigurationCRD returns CustomResourceDefinition built from OperatorConfigCRDResource
|
||||
func ConfigurationCRD() *apiextv1beta1.CustomResourceDefinition {
|
||||
func ConfigurationCRD(enableValidation *bool) *apiextv1beta1.CustomResourceDefinition {
|
||||
opconfigCRDvalidation := apiextv1beta1.CustomResourceValidation{}
|
||||
|
||||
if enableValidation != nil && *enableValidation {
|
||||
opconfigCRDvalidation = OperatorConfigCRDResourceValidation
|
||||
}
|
||||
|
||||
return buildCRD(OperatorConfigCRDResourceName,
|
||||
OperatorConfigCRDResouceKind,
|
||||
OperatorConfigCRDResourcePlural,
|
||||
OperatorConfigCRDResourceShort,
|
||||
OperatorConfigCRDResourceColumns)
|
||||
OperatorConfigCRDResourceColumns,
|
||||
opconfigCRDvalidation)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -150,6 +150,7 @@ type ScalyrConfiguration struct {
|
|||
|
||||
// OperatorConfigurationData defines the operation config
|
||||
type OperatorConfigurationData struct {
|
||||
EnableCRDValidation *bool `json:"enable_crd_validation,omitempty"`
|
||||
EtcdHost string `json:"etcd_host,omitempty"`
|
||||
DockerImage string `json:"docker_image,omitempty"`
|
||||
Workers uint32 `json:"workers,omitempty"`
|
||||
|
|
|
|||
|
|
@ -216,6 +216,11 @@ func (in *OperatorConfiguration) DeepCopyObject() runtime.Object {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OperatorConfigurationData) DeepCopyInto(out *OperatorConfigurationData) {
|
||||
*out = *in
|
||||
if in.EnableCRDValidation != nil {
|
||||
in, out := &in.EnableCRDValidation, &out.EnableCRDValidation
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.ShmVolume != nil {
|
||||
in, out := &in.ShmVolume, &out.ShmVolume
|
||||
*out = new(bool)
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/sirupsen/logrus"
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
rbacv1beta1 "k8s.io/api/rbac/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
|
@ -240,7 +240,7 @@ func (c *Controller) initController() {
|
|||
c.initClients()
|
||||
|
||||
if configObjectName := os.Getenv("POSTGRES_OPERATOR_CONFIGURATION_OBJECT"); configObjectName != "" {
|
||||
if err := c.createConfigurationCRD(); err != nil {
|
||||
if err := c.createConfigurationCRD(c.opConfig.EnableCRDValidation); err != nil {
|
||||
c.logger.Fatalf("could not register Operator Configuration CustomResourceDefinition: %v", err)
|
||||
}
|
||||
if cfg, err := c.readOperatorConfigurationFromCRD(spec.GetOperatorNamespace(), configObjectName); err != nil {
|
||||
|
|
@ -256,7 +256,7 @@ func (c *Controller) initController() {
|
|||
|
||||
c.modifyConfigFromEnvironment()
|
||||
|
||||
if err := c.createPostgresCRD(); err != nil {
|
||||
if err := c.createPostgresCRD(c.opConfig.EnableCRDValidation); err != nil {
|
||||
c.logger.Fatalf("could not register Postgres CustomResourceDefinition: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
|||
result := &config.Config{}
|
||||
|
||||
// general config
|
||||
result.EnableCRDValidation = fromCRD.EnableCRDValidation
|
||||
result.EtcdHost = fromCRD.EtcdHost
|
||||
result.DockerImage = fromCRD.DockerImage
|
||||
result.Workers = fromCRD.Workers
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import (
|
|||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
|
|
@ -91,12 +91,12 @@ func (c *Controller) createOperatorCRD(crd *apiextv1beta1.CustomResourceDefiniti
|
|||
})
|
||||
}
|
||||
|
||||
func (c *Controller) createPostgresCRD() error {
|
||||
return c.createOperatorCRD(acidv1.PostgresCRD())
|
||||
func (c *Controller) createPostgresCRD(enableValidation *bool) error {
|
||||
return c.createOperatorCRD(acidv1.PostgresCRD(enableValidation))
|
||||
}
|
||||
|
||||
func (c *Controller) createConfigurationCRD() error {
|
||||
return c.createOperatorCRD(acidv1.ConfigurationCRD())
|
||||
func (c *Controller) createConfigurationCRD(enableValidation *bool) error {
|
||||
return c.createOperatorCRD(acidv1.ConfigurationCRD(enableValidation))
|
||||
}
|
||||
|
||||
func readDecodedRole(s string) (*spec.PgUser, error) {
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ type CRD struct {
|
|||
ReadyWaitTimeout time.Duration `name:"ready_wait_timeout" default:"30s"`
|
||||
ResyncPeriod time.Duration `name:"resync_period" default:"30m"`
|
||||
RepairPeriod time.Duration `name:"repair_period" default:"5m"`
|
||||
EnableCRDValidation *bool `name:"enable_crd_validation" default:"true"`
|
||||
}
|
||||
|
||||
// Resources describes kubernetes resource specific configuration parameters
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ function build_operator_binary(){
|
|||
|
||||
# redirecting stderr greatly reduces non-informative output during normal builds
|
||||
echo "Build operator binary (stderr redirected to /dev/null)..."
|
||||
make clean tools deps local test > /dev/null 2>&1
|
||||
make clean deps local test > /dev/null 2>&1
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue