Generate postgresql CRD from go structs
Signed-off-by: Mikkel Oscar Lyderik Larsen <mikkel.larsen@zalando.de>
This commit is contained in:
parent
06ac340fe0
commit
4e0692205b
11
Makefile
11
Makefile
|
|
@ -21,7 +21,7 @@ GITSTATUS = $(shell git status --porcelain || echo "no changes")
|
|||
SOURCES = cmd/main.go
|
||||
VERSION ?= $(shell git describe --tags --always --dirty)
|
||||
CRD_SOURCES = $(shell find pkg/apis/zalando.org pkg/apis/acid.zalan.do -name '*.go' -not -name '*.deepcopy.go')
|
||||
GENERATED_CRDS = manifests/postgresteam.crd.yaml
|
||||
GENERATED_CRDS = manifests/postgresteam.crd.yaml manifests/postgresql.crd.yaml
|
||||
GENERATED = pkg/apis/zalando.org/v1/zz_generated.deepcopy.go pkg/apis/acid.zalan.do/v1/zz_generated.deepcopy.go
|
||||
DIRS := cmd pkg
|
||||
PKG := `go list ./... | grep -v /vendor/`
|
||||
|
|
@ -54,6 +54,7 @@ default: local
|
|||
|
||||
clean:
|
||||
rm -rf build
|
||||
rm $(GENERATED)
|
||||
|
||||
verify:
|
||||
hack/verify-codegen.sh
|
||||
|
|
@ -63,9 +64,13 @@ $(GENERATED): go.mod $(CRD_SOURCES)
|
|||
|
||||
$(GENERATED_CRDS): $(GENERATED)
|
||||
go tool controller-gen crd:crdVersions=v1,allowDangerousTypes=true paths=./pkg/apis/acid.zalan.do/... output:crd:dir=manifests
|
||||
# only generate postgresteam.crd.yaml for now
|
||||
# only generate postgresteam.crd.yaml and postgresql.crd.yaml for now
|
||||
@rm manifests/acid.zalan.do_operatorconfigurations.yaml
|
||||
@rm manifests/acid.zalan.do_postgresqls.yaml
|
||||
@mv manifests/acid.zalan.do_postgresqls.yaml manifests/postgresql.crd.yaml
|
||||
@# hack to use lowercase kind and listKind
|
||||
@sed -i -e 's/kind: Postgresql/kind: postgresql/' manifests/postgresql.crd.yaml
|
||||
@sed -i -e 's/listKind: PostgresqlList/listKind: postgresqlList/' manifests/postgresql.crd.yaml
|
||||
@hack/adjust_postgresql_crd.sh
|
||||
@mv manifests/acid.zalan.do_postgresteams.yaml manifests/postgresteam.crd.yaml
|
||||
|
||||
local: ${SOURCES} $(GENERATED_CRDS)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Hack to adjust the generated postgresql CRD YAML file and add missing field
|
||||
# settings which can not be expressed via kubebuilder markers.
|
||||
#
|
||||
# Injections:
|
||||
#
|
||||
# * oneOf: for the standby field to enforce that only one of s3_wal_path, gs_wal_path or standby_host is set.
|
||||
# * This can later be done with // +kubebuilder:validation:ExactlyOneOf marker, but this requires latest Kubernetes version. (Currently the operator depends on v1.32.9)
|
||||
# * type: string and pattern for the maintenanceWindows items.
|
||||
|
||||
file="${1:-"manifests/postgresql.crd.yaml"}"
|
||||
|
||||
sed -i '/^[[:space:]]*standby:$/{
|
||||
# Capture the indentation
|
||||
s/^\([[:space:]]*\)standby:$/\1standby:\n\1 oneOf:\n\1 - required:\n\1 - s3_wal_path\n\1 - required:\n\1 - gs_wal_path\n\1 - required:\n\1 - standby_host/
|
||||
}' "$file"
|
||||
|
||||
sed -i '/^[[:space:]]*maintenanceWindows:$/{
|
||||
# Capture the indentation
|
||||
s/^\([[:space:]]*\)maintenanceWindows:$/\1maintenanceWindows:\n\1 items:\n\1 pattern: '\''^\\ *((Mon|Tue|Wed|Thu|Fri|Sat|Sun):(2[0-3]|[01]?\\d):([0-5]?\\d)|(2[0-3]|[01]?\\d):([0-5]?\\d))-((2[0-3]|[01]?\\d):([0-5]?\\d)|(2[0-3]|[01]?\\d):([0-5]?\\d))\\ *$'\''\n\1 type: string/
|
||||
}' "$file"
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: postgresqls.acid.zalan.do
|
||||
spec:
|
||||
group: acid.zalan.do
|
||||
|
|
@ -40,7 +43,8 @@ spec:
|
|||
jsonPath: .spec.resources.requests.memory
|
||||
name: Memory-Request
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
- description: Age of the PostgreSQL cluster
|
||||
jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
- description: Current sync status of postgresql resource
|
||||
|
|
@ -50,19 +54,33 @@ spec:
|
|||
name: v1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Postgresql defines PostgreSQL Custom Resource Definition Object.
|
||||
properties:
|
||||
apiVersion:
|
||||
enum:
|
||||
- acid.zalan.do/v1
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
enum:
|
||||
- postgresql
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: PostgresSpec defines the specification for the PostgreSQL
|
||||
TPR.
|
||||
properties:
|
||||
additionalVolumes:
|
||||
items:
|
||||
description: AdditionalVolume specs additional optional volumes
|
||||
for statefulset
|
||||
properties:
|
||||
isSubPathExpr:
|
||||
type: boolean
|
||||
|
|
@ -87,12 +105,16 @@ spec:
|
|||
type: object
|
||||
type: array
|
||||
allowedSourceRanges:
|
||||
description: load balancers' source ranges are the same for master
|
||||
and replica services
|
||||
items:
|
||||
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])$
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
clone:
|
||||
description: CloneDescription describes which cluster the new should
|
||||
clone and up to which point in time
|
||||
properties:
|
||||
cluster:
|
||||
type: string
|
||||
|
|
@ -107,11 +129,11 @@ spec:
|
|||
s3_wal_path:
|
||||
type: string
|
||||
timestamp:
|
||||
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]+)?(([+-]([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
|
||||
|
||||
description: |-
|
||||
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
|
||||
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]+)?(([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$
|
||||
type: string
|
||||
uid:
|
||||
format: uuid
|
||||
|
|
@ -120,37 +142,112 @@ spec:
|
|||
- cluster
|
||||
type: object
|
||||
connectionPooler:
|
||||
description: |-
|
||||
ConnectionPooler Options for connection pooler
|
||||
|
||||
pgbouncer-large (with higher resources) or odyssey-small (with smaller
|
||||
resources)
|
||||
Type string `json:"type,omitempty"`
|
||||
|
||||
makes sense to expose. E.g. pool size (min/max boundaries), max client
|
||||
connections etc.
|
||||
properties:
|
||||
dockerImage:
|
||||
type: string
|
||||
maxDBConnections:
|
||||
format: int32
|
||||
type: integer
|
||||
mode:
|
||||
enum:
|
||||
- "session"
|
||||
- "transaction"
|
||||
- session
|
||||
- transaction
|
||||
type: string
|
||||
numberOfInstances:
|
||||
format: int32
|
||||
minimum: 1
|
||||
type: integer
|
||||
resources:
|
||||
description: Resources describes requests and limits for the cluster
|
||||
resouces.
|
||||
properties:
|
||||
limits:
|
||||
description: ResourceDescription describes CPU and memory
|
||||
resources defined for a cluster.
|
||||
properties:
|
||||
cpu:
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
description: |-
|
||||
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
|
||||
|
||||
Note: the value specified here must not be zero or be lower
|
||||
than the corresponding request.
|
||||
pattern: ^(\d+m|\d+(\.\d{1,3})?)$
|
||||
type: string
|
||||
hugepages-1Gi:
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
hugepages-2Mi:
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
memory:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
description: |-
|
||||
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
|
||||
|
||||
Note: the value specified here must not be zero or be higher
|
||||
than the corresponding limit.
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
type: object
|
||||
requests:
|
||||
description: ResourceDescription describes CPU and memory
|
||||
resources defined for a cluster.
|
||||
properties:
|
||||
cpu:
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
description: |-
|
||||
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
|
||||
|
||||
Note: the value specified here must not be zero or be lower
|
||||
than the corresponding request.
|
||||
pattern: ^(\d+m|\d+(\.\d{1,3})?)$
|
||||
type: string
|
||||
hugepages-1Gi:
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
hugepages-2Mi:
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
memory:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
description: |-
|
||||
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
|
||||
|
||||
Note: the value specified here must not be zero or be higher
|
||||
than the corresponding limit.
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
|
|
@ -162,7 +259,9 @@ spec:
|
|||
databases:
|
||||
additionalProperties:
|
||||
type: string
|
||||
# Note: usernames specified here as database owners must be declared in the users key of the spec key.
|
||||
description: |-
|
||||
Note: usernames specified here as database owners must be declared
|
||||
in the users key of the spec key.
|
||||
type: object
|
||||
dockerImage:
|
||||
type: string
|
||||
|
|
@ -171,6 +270,9 @@ spec:
|
|||
enableLogicalBackup:
|
||||
type: boolean
|
||||
enableMasterLoadBalancer:
|
||||
description: |-
|
||||
vars that enable load balancers are pointers because it is important to know if any of them is omitted from the Postgres manifest
|
||||
in that case the var evaluates to nil and the value is taken from the operator config
|
||||
type: boolean
|
||||
enableMasterPoolerLoadBalancer:
|
||||
type: boolean
|
||||
|
|
@ -183,28 +285,19 @@ spec:
|
|||
enableShmVolume:
|
||||
type: boolean
|
||||
env:
|
||||
items:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
nullable: true
|
||||
type: array
|
||||
initContainers:
|
||||
items:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
nullable: true
|
||||
type: array
|
||||
init_containers:
|
||||
description: deprecated
|
||||
items:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
description: deprecated json tags
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
initContainers:
|
||||
nullable: true
|
||||
type: array
|
||||
logicalBackupRetention:
|
||||
type: string
|
||||
logicalBackupSchedule:
|
||||
pattern: '^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$'
|
||||
pattern: ^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$
|
||||
type: string
|
||||
maintenanceWindows:
|
||||
items:
|
||||
|
|
@ -214,101 +307,214 @@ spec:
|
|||
masterServiceAnnotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: MasterServiceAnnotations takes precedence over ServiceAnnotations
|
||||
for master role if not empty
|
||||
type: object
|
||||
nodeAffinity:
|
||||
description: Node affinity is a group of node affinity scheduling
|
||||
rules.
|
||||
properties:
|
||||
preferredDuringSchedulingIgnoredDuringExecution:
|
||||
description: |-
|
||||
The scheduler will prefer to schedule pods to nodes that satisfy
|
||||
the affinity expressions specified by this field, but it may choose
|
||||
a node that violates one or more of the expressions. The node that is
|
||||
most preferred is the one with the greatest sum of weights, i.e.
|
||||
for each node that meets all of the scheduling requirements (resource
|
||||
request, requiredDuringScheduling affinity expressions, etc.),
|
||||
compute a sum by iterating through the elements of this field and adding
|
||||
"weight" to the sum if the node matches the corresponding matchExpressions; the
|
||||
node(s) with the highest sum are the most preferred.
|
||||
items:
|
||||
description: |-
|
||||
An empty preferred scheduling term matches all objects with implicit weight 0
|
||||
(i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).
|
||||
properties:
|
||||
preference:
|
||||
description: A node selector term, associated with the corresponding
|
||||
weight.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: A list of node selector requirements by
|
||||
node's labels.
|
||||
items:
|
||||
description: |-
|
||||
A node selector requirement is a selector that contains values, a key, and an operator
|
||||
that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: The label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
Represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
An array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. If the operator is Gt or Lt, the values
|
||||
array must have a single element, which will be interpreted as an integer.
|
||||
This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchFields:
|
||||
description: A list of node selector requirements by
|
||||
node's fields.
|
||||
items:
|
||||
description: |-
|
||||
A node selector requirement is a selector that contains values, a key, and an operator
|
||||
that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: The label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
Represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
An array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. If the operator is Gt or Lt, the values
|
||||
array must have a single element, which will be interpreted as an integer.
|
||||
This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
weight:
|
||||
description: Weight associated with matching the corresponding
|
||||
nodeSelectorTerm, in the range 1-100.
|
||||
format: int32
|
||||
type: integer
|
||||
required:
|
||||
- preference
|
||||
- weight
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
description: |-
|
||||
If the affinity requirements specified by this field are not met at
|
||||
scheduling time, the pod will not be scheduled onto the node.
|
||||
If the affinity requirements specified by this field cease to be met
|
||||
at some point during pod execution (e.g. due to an update), the system
|
||||
may or may not try to eventually evict the pod from its node.
|
||||
properties:
|
||||
nodeSelectorTerms:
|
||||
description: Required. A list of node selector terms. The
|
||||
terms are ORed.
|
||||
items:
|
||||
description: |-
|
||||
A null or empty node selector term matches no objects. The requirements of
|
||||
them are ANDed.
|
||||
The TopologySelectorTerm type implements a subset of the NodeSelectorTerm.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: A list of node selector requirements by
|
||||
node's labels.
|
||||
items:
|
||||
description: |-
|
||||
A node selector requirement is a selector that contains values, a key, and an operator
|
||||
that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: The label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
Represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
An array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. If the operator is Gt or Lt, the values
|
||||
array must have a single element, which will be interpreted as an integer.
|
||||
This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchFields:
|
||||
description: A list of node selector requirements by
|
||||
node's fields.
|
||||
items:
|
||||
description: |-
|
||||
A node selector requirement is a selector that contains values, a key, and an operator
|
||||
that relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: The label key that the selector applies
|
||||
to.
|
||||
type: string
|
||||
operator:
|
||||
description: |-
|
||||
Represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
An array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. If the operator is Gt or Lt, the values
|
||||
array must have a single element, which will be interpreted as an integer.
|
||||
This array is replaced during a strategic merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- nodeSelectorTerms
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
type: object
|
||||
numberOfInstances:
|
||||
format: int32
|
||||
minimum: 0
|
||||
type: integer
|
||||
patroni:
|
||||
description: Patroni contains Patroni-specific configuration
|
||||
properties:
|
||||
failsafe_mode:
|
||||
type: boolean
|
||||
|
|
@ -317,14 +523,17 @@ spec:
|
|||
type: string
|
||||
type: object
|
||||
loop_wait:
|
||||
format: int32
|
||||
type: integer
|
||||
maximum_lag_on_failover:
|
||||
format: int64
|
||||
type: integer
|
||||
pg_hba:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
retry_timeout:
|
||||
format: int32
|
||||
type: integer
|
||||
slots:
|
||||
additionalProperties:
|
||||
|
|
@ -337,20 +546,24 @@ spec:
|
|||
synchronous_mode_strict:
|
||||
type: boolean
|
||||
synchronous_node_count:
|
||||
format: int32
|
||||
type: integer
|
||||
ttl:
|
||||
format: int32
|
||||
type: integer
|
||||
type: object
|
||||
pod_priority_class_name:
|
||||
description: deprecated
|
||||
type: string
|
||||
podAnnotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
type: object
|
||||
podPriorityClassName:
|
||||
type: string
|
||||
pod_priority_class_name:
|
||||
description: deprecated
|
||||
type: string
|
||||
postgresql:
|
||||
description: PostgresqlParam describes PostgreSQL version and pairs
|
||||
of configuration parameter name - values.
|
||||
properties:
|
||||
parameters:
|
||||
additionalProperties:
|
||||
|
|
@ -358,17 +571,18 @@ spec:
|
|||
type: object
|
||||
version:
|
||||
enum:
|
||||
- "13"
|
||||
- "14"
|
||||
- "15"
|
||||
- "16"
|
||||
- "17"
|
||||
- 13
|
||||
- 14
|
||||
- 15
|
||||
- 16
|
||||
- 17
|
||||
type: string
|
||||
required:
|
||||
- version
|
||||
type: object
|
||||
preparedDatabases:
|
||||
additionalProperties:
|
||||
description: PreparedDatabase describes elements to be bootstrapped
|
||||
properties:
|
||||
defaultUsers:
|
||||
type: boolean
|
||||
|
|
@ -378,6 +592,8 @@ spec:
|
|||
type: object
|
||||
schemas:
|
||||
additionalProperties:
|
||||
description: PreparedSchema describes elements to be bootstrapped
|
||||
per schema
|
||||
properties:
|
||||
defaultRoles:
|
||||
type: boolean
|
||||
|
|
@ -395,58 +611,91 @@ spec:
|
|||
replicaServiceAnnotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: ReplicaServiceAnnotations takes precedence over ServiceAnnotations
|
||||
for replica role if not empty
|
||||
type: object
|
||||
resources:
|
||||
description: Resources describes requests and limits for the cluster
|
||||
resouces.
|
||||
properties:
|
||||
limits:
|
||||
description: ResourceDescription describes CPU and memory resources
|
||||
defined for a cluster.
|
||||
properties:
|
||||
cpu:
|
||||
# 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.
|
||||
description: |-
|
||||
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
|
||||
|
||||
Note: the value specified here must not be zero or be lower
|
||||
than the corresponding request.
|
||||
pattern: ^(\d+m|\d+(\.\d{1,3})?)$
|
||||
type: string
|
||||
hugepages-1Gi:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
hugepages-2Mi:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
memory:
|
||||
# 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.
|
||||
description: |-
|
||||
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
|
||||
|
||||
Note: the value specified here must not be zero or be higher
|
||||
than the corresponding limit.
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
type: object
|
||||
requests:
|
||||
description: ResourceDescription describes CPU and memory resources
|
||||
defined for a cluster.
|
||||
properties:
|
||||
cpu:
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
description: |-
|
||||
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
|
||||
|
||||
Note: the value specified here must not be zero or be lower
|
||||
than the corresponding request.
|
||||
pattern: ^(\d+m|\d+(\.\d{1,3})?)$
|
||||
type: string
|
||||
hugepages-1Gi:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
hugepages-2Mi:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
memory:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
description: |-
|
||||
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
|
||||
|
||||
Note: the value specified here must not be zero or be higher
|
||||
than the corresponding limit.
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
type: object
|
||||
type: object
|
||||
|
|
@ -457,16 +706,16 @@ spec:
|
|||
type: string
|
||||
type: object
|
||||
sidecars:
|
||||
items:
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
nullable: true
|
||||
type: array
|
||||
spiloFSGroup:
|
||||
format: int64
|
||||
type: integer
|
||||
spiloRunAsGroup:
|
||||
format: int64
|
||||
type: integer
|
||||
spiloRunAsUser:
|
||||
format: int64
|
||||
type: integer
|
||||
standby:
|
||||
oneOf:
|
||||
|
|
@ -476,6 +725,8 @@ spec:
|
|||
- gs_wal_path
|
||||
- required:
|
||||
- standby_host
|
||||
description: StandbyDescription contains remote primary config or
|
||||
s3/gs wal path
|
||||
properties:
|
||||
gs_wal_path:
|
||||
type: string
|
||||
|
|
@ -488,13 +739,16 @@ spec:
|
|||
type: object
|
||||
streams:
|
||||
items:
|
||||
description: Stream defines properties for creating FabricEventStream
|
||||
resources
|
||||
properties:
|
||||
applicationId:
|
||||
type: string
|
||||
batchSize:
|
||||
format: int32
|
||||
type: integer
|
||||
cpu:
|
||||
pattern: '^(\d+m|\d+(\.\d{1,3})?)$'
|
||||
pattern: ^(\d+m|\d+(\.\d{1,3})?)$
|
||||
type: string
|
||||
database:
|
||||
type: string
|
||||
|
|
@ -505,10 +759,12 @@ spec:
|
|||
type: string
|
||||
type: object
|
||||
memory:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
tables:
|
||||
additionalProperties:
|
||||
description: StreamTable defines properties of outbox tables
|
||||
for FabricEventStreams
|
||||
properties:
|
||||
eventType:
|
||||
type: string
|
||||
|
|
@ -533,6 +789,7 @@ spec:
|
|||
teamId:
|
||||
type: string
|
||||
tls:
|
||||
description: TLSDescription specs TLS properties
|
||||
properties:
|
||||
caFile:
|
||||
type: string
|
||||
|
|
@ -549,31 +806,51 @@ spec:
|
|||
type: object
|
||||
tolerations:
|
||||
items:
|
||||
description: |-
|
||||
The pod this Toleration is attached to tolerates any taint that matches
|
||||
the triple <key,value,effect> using the matching operator <operator>.
|
||||
properties:
|
||||
effect:
|
||||
enum:
|
||||
- NoExecute
|
||||
- NoSchedule
|
||||
- PreferNoSchedule
|
||||
description: |-
|
||||
Effect indicates the taint effect to match. Empty means match all taint effects.
|
||||
When specified, allowed values are NoSchedule, PreferNoSchedule and NoExecute.
|
||||
type: string
|
||||
key:
|
||||
description: |-
|
||||
Key is the taint key that the toleration applies to. Empty means match all taint keys.
|
||||
If the key is empty, operator must be Exists; this combination means to match all values and all keys.
|
||||
type: string
|
||||
operator:
|
||||
enum:
|
||||
- Equal
|
||||
- Exists
|
||||
description: |-
|
||||
Operator represents a key's relationship to the value.
|
||||
Valid operators are Exists and Equal. Defaults to Equal.
|
||||
Exists is equivalent to wildcard for value, so that a pod can
|
||||
tolerate all taints of a particular category.
|
||||
type: string
|
||||
tolerationSeconds:
|
||||
description: |-
|
||||
TolerationSeconds represents the period of time the toleration (which must be
|
||||
of effect NoExecute, otherwise this field is ignored) tolerates the taint. By default,
|
||||
it is not set, which means tolerate the taint forever (do not evict). Zero and
|
||||
negative values will be treated as 0 (evict immediately) by the system.
|
||||
format: int64
|
||||
type: integer
|
||||
value:
|
||||
description: |-
|
||||
Value is the taint value the toleration matches to.
|
||||
If the operator is Exists, the value should be empty, otherwise just a regular string.
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
useLoadBalancer:
|
||||
description: deprecated
|
||||
description: |-
|
||||
deprecated load balancer settings maintained for backward compatibility
|
||||
see "Load balancers" operator docs
|
||||
type: boolean
|
||||
users:
|
||||
additionalProperties:
|
||||
description: UserFlags defines flags (such as superuser, nologin)
|
||||
that could be assigned to individual users
|
||||
items:
|
||||
enum:
|
||||
- bypassrls
|
||||
|
|
@ -605,7 +882,6 @@ spec:
|
|||
- nosuperuser
|
||||
- NOSUPERUSER
|
||||
type: string
|
||||
nullable: true
|
||||
type: array
|
||||
type: object
|
||||
usersIgnoringSecretRotation:
|
||||
|
|
@ -624,65 +900,94 @@ spec:
|
|||
nullable: true
|
||||
type: array
|
||||
volume:
|
||||
description: Volume describes a single volume in the manifest.
|
||||
properties:
|
||||
iops:
|
||||
format: int64
|
||||
type: integer
|
||||
isSubPathExpr:
|
||||
type: boolean
|
||||
selector:
|
||||
description: |-
|
||||
A label selector is a label query over a set of resources. The result of matchLabels and
|
||||
matchExpressions are ANDed. An empty label selector matches all objects. A null
|
||||
label selector matches no objects.
|
||||
properties:
|
||||
matchExpressions:
|
||||
description: matchExpressions is a list of label selector
|
||||
requirements. The requirements are ANDed.
|
||||
items:
|
||||
description: |-
|
||||
A label selector requirement is a selector that contains values, a key, and an operator that
|
||||
relates the key and values.
|
||||
properties:
|
||||
key:
|
||||
description: key is the label key that the selector
|
||||
applies to.
|
||||
type: string
|
||||
operator:
|
||||
enum:
|
||||
- DoesNotExist
|
||||
- Exists
|
||||
- In
|
||||
- NotIn
|
||||
description: |-
|
||||
operator represents a key's relationship to a set of values.
|
||||
Valid operators are In, NotIn, Exists and DoesNotExist.
|
||||
type: string
|
||||
values:
|
||||
description: |-
|
||||
values is an array of string values. If the operator is In or NotIn,
|
||||
the values array must be non-empty. If the operator is Exists or DoesNotExist,
|
||||
the values array must be empty. This array is replaced during a strategic
|
||||
merge patch.
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
required:
|
||||
- key
|
||||
- operator
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-type: atomic
|
||||
matchLabels:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: |-
|
||||
matchLabels is a map of {key,value} pairs. A single {key,value} in the matchLabels
|
||||
map is equivalent to an element of matchExpressions, whose key field is "key", the
|
||||
operator is "In", and the values array contains only "value". The requirements are ANDed.
|
||||
type: object
|
||||
x-kubernetes-preserve-unknown-fields: true
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
size:
|
||||
pattern: '^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$'
|
||||
# Note: the value specified here must not be zero.
|
||||
|
||||
pattern: ^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$
|
||||
type: string
|
||||
storageClass:
|
||||
type: string
|
||||
subPath:
|
||||
type: string
|
||||
throughput:
|
||||
format: int64
|
||||
type: integer
|
||||
type:
|
||||
type: string
|
||||
required:
|
||||
- size
|
||||
type: object
|
||||
required:
|
||||
- numberOfInstances
|
||||
- teamId
|
||||
- postgresql
|
||||
- teamId
|
||||
- volume
|
||||
type: object
|
||||
status:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: PostgresStatus contains status of the PostgreSQL cluster
|
||||
(running, creation failed etc.)
|
||||
properties:
|
||||
PostgresClusterStatus:
|
||||
type: string
|
||||
required:
|
||||
- PostgresClusterStatus
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- apiVersion
|
||||
- metadata
|
||||
- spec
|
||||
type: object
|
||||
served: true
|
||||
|
|
|
|||
|
|
@ -11,13 +11,25 @@ import (
|
|||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// Postgresql defines PostgreSQL Custom Resource Definition Object.
|
||||
// +kubebuilder:resource:categories=all,shortName=pg,scope=Namespaced
|
||||
// +kubebuilder:printcolumn:name="Team",type=string,JSONPath=`.spec.teamId`,description="Team responsible for Postgres cluster"
|
||||
// +kubebuilder:printcolumn:name="Version",type=string,JSONPath=`.spec.postgresql.version`,description="PostgreSQL version"
|
||||
// +kubebuilder:printcolumn:name="Pods",type=integer,JSONPath=`.spec.numberOfInstances`,description="Number of Pods per Postgres cluster"
|
||||
// +kubebuilder:printcolumn:name="Volume",type=string,JSONPath=`.spec.volume.size`,description="Size of the bound volume"
|
||||
// +kubebuilder:printcolumn:name="CPU-Request",type=string,JSONPath=`.spec.resources.requests.cpu`,description="Requested CPU for Postgres containers"
|
||||
// +kubebuilder:printcolumn:name="Memory-Request",type=string,JSONPath=`.spec.resources.requests.memory`,description="Requested memory for Postgres containers"
|
||||
// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`,description="Age of the PostgreSQL cluster"
|
||||
// +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.PostgresClusterStatus`,description="Current sync status of postgresql resource"
|
||||
// +kubebuilder:subresource:status
|
||||
type Postgresql struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
metav1.ObjectMeta `json:"metadata"`
|
||||
|
||||
Spec PostgresSpec `json:"spec"`
|
||||
Spec PostgresSpec `json:"spec"`
|
||||
// +optional
|
||||
Status PostgresStatus `json:"status"`
|
||||
Error string `json:"-"`
|
||||
}
|
||||
|
|
@ -25,9 +37,10 @@ type Postgresql struct {
|
|||
// PostgresSpec defines the specification for the PostgreSQL TPR.
|
||||
type PostgresSpec struct {
|
||||
PostgresqlParam `json:"postgresql"`
|
||||
Volume `json:"volume,omitempty"`
|
||||
Patroni `json:"patroni,omitempty"`
|
||||
*Resources `json:"resources,omitempty"`
|
||||
Volume `json:"volume"`
|
||||
// +optional
|
||||
Patroni `json:"patroni"`
|
||||
*Resources `json:"resources,omitempty"`
|
||||
|
||||
EnableConnectionPooler *bool `json:"enableConnectionPooler,omitempty"`
|
||||
EnableReplicaConnectionPooler *bool `json:"enableReplicaConnectionPooler,omitempty"`
|
||||
|
|
@ -52,35 +65,59 @@ type PostgresSpec struct {
|
|||
|
||||
// deprecated load balancer settings maintained for backward compatibility
|
||||
// see "Load balancers" operator docs
|
||||
UseLoadBalancer *bool `json:"useLoadBalancer,omitempty"`
|
||||
UseLoadBalancer *bool `json:"useLoadBalancer,omitempty"`
|
||||
// deprecated
|
||||
ReplicaLoadBalancer *bool `json:"replicaLoadBalancer,omitempty"`
|
||||
|
||||
// load balancers' source ranges are the same for master and replica services
|
||||
// +nullable
|
||||
// +kubebuilder:validation:items: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])$`
|
||||
// +optional
|
||||
AllowedSourceRanges []string `json:"allowedSourceRanges"`
|
||||
|
||||
Users map[string]UserFlags `json:"users,omitempty"`
|
||||
UsersIgnoringSecretRotation []string `json:"usersIgnoringSecretRotation,omitempty"`
|
||||
UsersWithSecretRotation []string `json:"usersWithSecretRotation,omitempty"`
|
||||
UsersWithInPlaceSecretRotation []string `json:"usersWithInPlaceSecretRotation,omitempty"`
|
||||
Users map[string]UserFlags `json:"users,omitempty"`
|
||||
// +nullable
|
||||
UsersIgnoringSecretRotation []string `json:"usersIgnoringSecretRotation,omitempty"`
|
||||
// +nullable
|
||||
UsersWithSecretRotation []string `json:"usersWithSecretRotation,omitempty"`
|
||||
// +nullable
|
||||
UsersWithInPlaceSecretRotation []string `json:"usersWithInPlaceSecretRotation,omitempty"`
|
||||
|
||||
NumberOfInstances int32 `json:"numberOfInstances"`
|
||||
MaintenanceWindows []MaintenanceWindow `json:"maintenanceWindows,omitempty"`
|
||||
Clone *CloneDescription `json:"clone,omitempty"`
|
||||
Databases map[string]string `json:"databases,omitempty"`
|
||||
PreparedDatabases map[string]PreparedDatabase `json:"preparedDatabases,omitempty"`
|
||||
SchedulerName *string `json:"schedulerName,omitempty"`
|
||||
NodeAffinity *v1.NodeAffinity `json:"nodeAffinity,omitempty"`
|
||||
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
|
||||
Sidecars []Sidecar `json:"sidecars,omitempty"`
|
||||
InitContainers []v1.Container `json:"initContainers,omitempty"`
|
||||
PodPriorityClassName string `json:"podPriorityClassName,omitempty"`
|
||||
ShmVolume *bool `json:"enableShmVolume,omitempty"`
|
||||
EnableLogicalBackup bool `json:"enableLogicalBackup,omitempty"`
|
||||
LogicalBackupRetention string `json:"logicalBackupRetention,omitempty"`
|
||||
LogicalBackupSchedule string `json:"logicalBackupSchedule,omitempty"`
|
||||
StandbyCluster *StandbyDescription `json:"standby,omitempty"`
|
||||
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
|
||||
ServiceAnnotations map[string]string `json:"serviceAnnotations,omitempty"`
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
NumberOfInstances int32 `json:"numberOfInstances"`
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +kubebuilder:validation:Type=array
|
||||
// +kubebuilde:validation:items:Type=string
|
||||
MaintenanceWindows []MaintenanceWindow `json:"maintenanceWindows,omitempty"`
|
||||
Clone *CloneDescription `json:"clone,omitempty"`
|
||||
// Note: usernames specified here as database owners must be declared
|
||||
// in the users key of the spec key.
|
||||
Databases map[string]string `json:"databases,omitempty"`
|
||||
PreparedDatabases map[string]PreparedDatabase `json:"preparedDatabases,omitempty"`
|
||||
SchedulerName *string `json:"schedulerName,omitempty"`
|
||||
NodeAffinity *v1.NodeAffinity `json:"nodeAffinity,omitempty"`
|
||||
Tolerations []v1.Toleration `json:"tolerations,omitempty"`
|
||||
// +kubebuilder:validation:Type=array
|
||||
// +kubebuilder:validation:Items:Type=object
|
||||
// +kubebuilder:validation:Items:XPreserveUnknownFields
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +nullable
|
||||
Sidecars []Sidecar `json:"sidecars,omitempty"`
|
||||
// +kubebuilder:validation:Type=array
|
||||
// +kubebuilder:validation:Items:Type=object
|
||||
// +kubebuilder:validation:Items:XPreserveUnknownFields
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +nullable
|
||||
InitContainers []v1.Container `json:"initContainers,omitempty"`
|
||||
PodPriorityClassName string `json:"podPriorityClassName,omitempty"`
|
||||
ShmVolume *bool `json:"enableShmVolume,omitempty"`
|
||||
EnableLogicalBackup bool `json:"enableLogicalBackup,omitempty"`
|
||||
LogicalBackupRetention string `json:"logicalBackupRetention,omitempty"`
|
||||
// +kubebuilder:validation:Pattern=`^(\d+|\*)(/\d+)?(\s+(\d+|\*)(/\d+)?){4}$`
|
||||
LogicalBackupSchedule string `json:"logicalBackupSchedule,omitempty"`
|
||||
StandbyCluster *StandbyDescription `json:"standby,omitempty"`
|
||||
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
|
||||
ServiceAnnotations map[string]string `json:"serviceAnnotations,omitempty"`
|
||||
// MasterServiceAnnotations takes precedence over ServiceAnnotations for master role if not empty
|
||||
MasterServiceAnnotations map[string]string `json:"masterServiceAnnotations,omitempty"`
|
||||
// ReplicaServiceAnnotations takes precedence over ServiceAnnotations for replica role if not empty
|
||||
|
|
@ -88,11 +125,20 @@ type PostgresSpec struct {
|
|||
TLS *TLSDescription `json:"tls,omitempty"`
|
||||
AdditionalVolumes []AdditionalVolume `json:"additionalVolumes,omitempty"`
|
||||
Streams []Stream `json:"streams,omitempty"`
|
||||
Env []v1.EnvVar `json:"env,omitempty"`
|
||||
// +kubebuilder:validation:Type=array
|
||||
// +kubebuilder:validation:Items:Type=object
|
||||
// +kubebuilder:validation:Items:XPreserveUnknownFields
|
||||
// +kubebuilder:validation:Schemaless
|
||||
// +nullable
|
||||
Env []v1.EnvVar `json:"env,omitempty"`
|
||||
|
||||
// deprecated json tags
|
||||
InitContainersOld []v1.Container `json:"init_containers,omitempty"`
|
||||
PodPriorityClassNameOld string `json:"pod_priority_class_name,omitempty"`
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
// +kubebuilder:validation:Type=object
|
||||
// +kubebuilder:validation:Schemaless
|
||||
InitContainersOld []v1.Container `json:"init_containers,omitempty"`
|
||||
// deprecated
|
||||
PodPriorityClassNameOld string `json:"pod_priority_class_name,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
|
@ -123,50 +169,84 @@ type PreparedSchema struct {
|
|||
type MaintenanceWindow struct {
|
||||
Everyday bool `json:"everyday,omitempty"`
|
||||
Weekday time.Weekday `json:"weekday,omitempty"`
|
||||
StartTime metav1.Time `json:"startTime,omitempty"`
|
||||
EndTime metav1.Time `json:"endTime,omitempty"`
|
||||
StartTime metav1.Time `json:"startTime"`
|
||||
EndTime metav1.Time `json:"endTime"`
|
||||
}
|
||||
|
||||
// Volume describes a single volume in the manifest.
|
||||
type Volume struct {
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
||||
Size string `json:"size"`
|
||||
StorageClass string `json:"storageClass,omitempty"`
|
||||
SubPath string `json:"subPath,omitempty"`
|
||||
IsSubPathExpr *bool `json:"isSubPathExpr,omitempty"`
|
||||
Iops *int64 `json:"iops,omitempty"`
|
||||
Throughput *int64 `json:"throughput,omitempty"`
|
||||
VolumeType string `json:"type,omitempty"`
|
||||
Selector *metav1.LabelSelector `json:"selector,omitempty"`
|
||||
// +kubebuilder:validation:Pattern=`^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$`
|
||||
Size string `json:"size"`
|
||||
StorageClass string `json:"storageClass,omitempty"`
|
||||
SubPath string `json:"subPath,omitempty"`
|
||||
IsSubPathExpr *bool `json:"isSubPathExpr,omitempty"`
|
||||
Iops *int64 `json:"iops,omitempty"`
|
||||
Throughput *int64 `json:"throughput,omitempty"`
|
||||
VolumeType string `json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// AdditionalVolume specs additional optional volumes for statefulset
|
||||
type AdditionalVolume struct {
|
||||
Name string `json:"name"`
|
||||
MountPath string `json:"mountPath"`
|
||||
SubPath string `json:"subPath,omitempty"`
|
||||
IsSubPathExpr *bool `json:"isSubPathExpr,omitempty"`
|
||||
TargetContainers []string `json:"targetContainers"`
|
||||
VolumeSource v1.VolumeSource `json:"volumeSource"`
|
||||
Name string `json:"name"`
|
||||
MountPath string `json:"mountPath"`
|
||||
SubPath string `json:"subPath,omitempty"`
|
||||
IsSubPathExpr *bool `json:"isSubPathExpr,omitempty"`
|
||||
// +nullable
|
||||
// +optional
|
||||
TargetContainers []string `json:"targetContainers"`
|
||||
// +kubebuilder:validation:XPreserveUnknownFields
|
||||
// +kubebuilder:validation:Type=object
|
||||
// +kubebuilder:validation:Schemaless
|
||||
VolumeSource v1.VolumeSource `json:"volumeSource"`
|
||||
}
|
||||
|
||||
// PostgresqlParam describes PostgreSQL version and pairs of configuration parameter name - values.
|
||||
type PostgresqlParam struct {
|
||||
// +kubebuilder:validation:Enum=13;14;15;16;17
|
||||
PgVersion string `json:"version"`
|
||||
Parameters map[string]string `json:"parameters,omitempty"`
|
||||
}
|
||||
|
||||
// ResourceDescription describes CPU and memory resources defined for a cluster.
|
||||
type ResourceDescription struct {
|
||||
CPU *string `json:"cpu,omitempty"`
|
||||
Memory *string `json:"memory,omitempty"`
|
||||
// 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
|
||||
//
|
||||
// Note: the value specified here must not be zero or be lower
|
||||
// than the corresponding request.
|
||||
// +kubebuilder:validation:Pattern=`^(\d+m|\d+(\.\d{1,3})?)$`
|
||||
CPU *string `json:"cpu,omitempty"`
|
||||
// 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
|
||||
//
|
||||
// Note: the value specified here must not be zero or be higher
|
||||
// than the corresponding limit.
|
||||
// +kubebuilder:validation:Pattern=`^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$`
|
||||
Memory *string `json:"memory,omitempty"`
|
||||
// +kubebuilder:validation:Pattern=`^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$`
|
||||
HugePages2Mi *string `json:"hugepages-2Mi,omitempty"`
|
||||
// +kubebuilder:validation:Pattern=`^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$`
|
||||
HugePages1Gi *string `json:"hugepages-1Gi,omitempty"`
|
||||
}
|
||||
|
||||
// Resources describes requests and limits for the cluster resouces.
|
||||
type Resources struct {
|
||||
ResourceRequests ResourceDescription `json:"requests,omitempty"`
|
||||
ResourceLimits ResourceDescription `json:"limits,omitempty"`
|
||||
// +optional
|
||||
ResourceRequests ResourceDescription `json:"requests"`
|
||||
// +optional
|
||||
ResourceLimits ResourceDescription `json:"limits"`
|
||||
}
|
||||
|
||||
// Patroni contains Patroni-specific configuration
|
||||
|
|
@ -176,7 +256,7 @@ type Patroni struct {
|
|||
TTL uint32 `json:"ttl,omitempty"`
|
||||
LoopWait uint32 `json:"loop_wait,omitempty"`
|
||||
RetryTimeout uint32 `json:"retry_timeout,omitempty"`
|
||||
MaximumLagOnFailover float32 `json:"maximum_lag_on_failover,omitempty"` // float32 because https://github.com/kubernetes/kubernetes/issues/30213
|
||||
MaximumLagOnFailover int64 `json:"maximum_lag_on_failover,omitempty"`
|
||||
Slots map[string]map[string]string `json:"slots,omitempty"`
|
||||
SynchronousMode bool `json:"synchronous_mode,omitempty"`
|
||||
SynchronousModeStrict bool `json:"synchronous_mode_strict,omitempty"`
|
||||
|
|
@ -185,6 +265,7 @@ type Patroni struct {
|
|||
}
|
||||
|
||||
// StandbyDescription contains remote primary config or s3/gs wal path
|
||||
// +kubebuilder:validation:ExactlyOneOf=s3_wal_path;gs_wal_path;standby_host
|
||||
type StandbyDescription struct {
|
||||
S3WalPath string `json:"s3_wal_path,omitempty"`
|
||||
GSWalPath string `json:"gs_wal_path,omitempty"`
|
||||
|
|
@ -194,6 +275,7 @@ type StandbyDescription struct {
|
|||
|
||||
// TLSDescription specs TLS properties
|
||||
type TLSDescription struct {
|
||||
// +required
|
||||
SecretName string `json:"secretName,omitempty"`
|
||||
CertificateFile string `json:"certificateFile,omitempty"`
|
||||
PrivateKeyFile string `json:"privateKeyFile,omitempty"`
|
||||
|
|
@ -203,8 +285,14 @@ type TLSDescription struct {
|
|||
|
||||
// CloneDescription describes which cluster the new should clone and up to which point in time
|
||||
type CloneDescription struct {
|
||||
ClusterName string `json:"cluster,omitempty"`
|
||||
UID string `json:"uid,omitempty"`
|
||||
// +required
|
||||
ClusterName string `json:"cluster,omitempty"`
|
||||
// +kubebuilder:validation:Format=uuid
|
||||
UID string `json:"uid,omitempty"`
|
||||
// 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
|
||||
// +kubebuilder:validation: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]+)?(([+-]([01][0-9]|2[0-3]):[0-5][0-9]))$`
|
||||
EndTimestamp string `json:"timestamp,omitempty"`
|
||||
S3WalPath string `json:"s3_wal_path,omitempty"`
|
||||
S3Endpoint string `json:"s3_endpoint,omitempty"`
|
||||
|
|
@ -224,6 +312,8 @@ type Sidecar struct {
|
|||
}
|
||||
|
||||
// UserFlags defines flags (such as superuser, nologin) that could be assigned to individual users
|
||||
// +kubebuilder:validation:items: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
|
||||
// +nullable
|
||||
type UserFlags []string
|
||||
|
||||
// PostgresStatus contains status of the PostgreSQL cluster (running, creation failed etc.)
|
||||
|
|
@ -242,26 +332,30 @@ type PostgresStatus struct {
|
|||
// makes sense to expose. E.g. pool size (min/max boundaries), max client
|
||||
// connections etc.
|
||||
type ConnectionPooler struct {
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
NumberOfInstances *int32 `json:"numberOfInstances,omitempty"`
|
||||
Schema string `json:"schema,omitempty"`
|
||||
User string `json:"user,omitempty"`
|
||||
Mode string `json:"mode,omitempty"`
|
||||
DockerImage string `json:"dockerImage,omitempty"`
|
||||
MaxDBConnections *int32 `json:"maxDBConnections,omitempty"`
|
||||
// +kubebuilder:validation:Enum=session;transaction
|
||||
Mode string `json:"mode,omitempty"`
|
||||
DockerImage string `json:"dockerImage,omitempty"`
|
||||
MaxDBConnections *int32 `json:"maxDBConnections,omitempty"`
|
||||
|
||||
*Resources `json:"resources,omitempty"`
|
||||
}
|
||||
|
||||
// Stream defines properties for creating FabricEventStream resources
|
||||
type Stream struct {
|
||||
ApplicationId string `json:"applicationId"`
|
||||
Database string `json:"database"`
|
||||
Tables map[string]StreamTable `json:"tables"`
|
||||
Filter map[string]*string `json:"filter,omitempty"`
|
||||
BatchSize *uint32 `json:"batchSize,omitempty"`
|
||||
CPU *string `json:"cpu,omitempty"`
|
||||
Memory *string `json:"memory,omitempty"`
|
||||
EnableRecovery *bool `json:"enableRecovery,omitempty"`
|
||||
ApplicationId string `json:"applicationId"`
|
||||
Database string `json:"database"`
|
||||
Tables map[string]StreamTable `json:"tables"`
|
||||
Filter map[string]*string `json:"filter,omitempty"`
|
||||
BatchSize *uint32 `json:"batchSize,omitempty"`
|
||||
// +kubebuilder:validation:Pattern=`^(\d+m|\d+(\.\d{1,3})?)$`
|
||||
CPU *string `json:"cpu,omitempty"`
|
||||
// +kubebuilder:validation:Pattern=`^(\d+(e\d+)?|\d+(\.\d+)?(e\d+)?[EPTGMK]i?)$`
|
||||
Memory *string `json:"memory,omitempty"`
|
||||
EnableRecovery *bool `json:"enableRecovery,omitempty"`
|
||||
}
|
||||
|
||||
// StreamTable defines properties of outbox tables for FabricEventStreams
|
||||
|
|
|
|||
|
|
@ -412,7 +412,7 @@ PatroniInitDBParams:
|
|||
}
|
||||
|
||||
if patroni.MaximumLagOnFailover >= 0 {
|
||||
config.Bootstrap.DCS.MaximumLagOnFailover = patroni.MaximumLagOnFailover
|
||||
config.Bootstrap.DCS.MaximumLagOnFailover = float32(patroni.MaximumLagOnFailover)
|
||||
}
|
||||
if patroni.LoopWait != 0 {
|
||||
config.Bootstrap.DCS.LoopWait = patroni.LoopWait
|
||||
|
|
|
|||
Loading…
Reference in New Issue