Skip to content

Commit 183d9df

Browse files
committed
Replace our CRD validation patch with CEL rules
The JSON patch was awkward to maintain, and we forgot to update it when we added PVCs to our APIs. I considered defining these rules on a shared Go type in our API package, but I did not like the type conversion it requires in our controller and test code. Issue: PGO-1748
1 parent 287e715 commit 183d9df

File tree

5 files changed

+98
-94
lines changed

5 files changed

+98
-94
lines changed

build/crd/postgresclusters/kustomization.yaml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,6 @@ resources:
55
- generated/postgres-operator.crunchydata.com_postgresclusters.yaml
66

77
patches:
8-
- target:
9-
group: apiextensions.k8s.io
10-
version: v1
11-
kind: CustomResourceDefinition
12-
name: postgresclusters.postgres-operator.crunchydata.com
13-
path: validation.yaml
148
- target:
159
group: apiextensions.k8s.io
1610
version: v1

build/crd/postgresclusters/validation.yaml

Lines changed: 0 additions & 63 deletions
This file was deleted.

config/crd/bases/postgres-operator.crunchydata.com_postgresclusters.yaml

Lines changed: 53 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2913,7 +2913,6 @@ spec:
29132913
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
29142914
items:
29152915
type: string
2916-
minItems: 1
29172916
type: array
29182917
x-kubernetes-list-type: atomic
29192918
dataSource:
@@ -3027,11 +3026,7 @@ spec:
30273026
If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
30283027
otherwise to an implementation-defined value. Requests cannot exceed Limits.
30293028
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
3030-
required:
3031-
- storage
30323029
type: object
3033-
required:
3034-
- requests
30353030
type: object
30363031
selector:
30373032
description: selector is a label query over
@@ -3110,10 +3105,18 @@ spec:
31103105
description: volumeName is the binding reference
31113106
to the PersistentVolume backing this claim.
31123107
type: string
3113-
required:
3114-
- accessModes
3115-
- resources
31163108
type: object
3109+
x-kubernetes-validations:
3110+
- fieldPath: .accessModes
3111+
message: missing accessModes
3112+
reason: FieldValueRequired
3113+
rule: has(self.accessModes) && size(self.accessModes)
3114+
> 0
3115+
- fieldPath: .resources.requests.storage
3116+
message: missing storage request
3117+
reason: FieldValueRequired
3118+
rule: has(self.resources) && has(self.resources.requests)
3119+
&& has(self.resources.requests.storage)
31173120
required:
31183121
- volumeClaimSpec
31193122
type: object
@@ -6365,6 +6368,17 @@ spec:
63656368
to the PersistentVolume backing this claim.
63666369
type: string
63676370
type: object
6371+
x-kubernetes-validations:
6372+
- fieldPath: .accessModes
6373+
message: missing accessModes
6374+
reason: FieldValueRequired
6375+
rule: has(self.accessModes) && size(self.accessModes)
6376+
> 0
6377+
- fieldPath: .resources.requests.storage
6378+
message: missing storage request
6379+
reason: FieldValueRequired
6380+
rule: has(self.resources) && has(self.resources.requests)
6381+
&& has(self.resources.requests.storage)
63686382
required:
63696383
- volumeClaimSpec
63706384
type: object
@@ -10039,7 +10053,6 @@ spec:
1003910053
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
1004010054
items:
1004110055
type: string
10042-
minItems: 1
1004310056
type: array
1004410057
x-kubernetes-list-type: atomic
1004510058
dataSource:
@@ -10149,11 +10162,7 @@ spec:
1014910162
If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
1015010163
otherwise to an implementation-defined value. Requests cannot exceed Limits.
1015110164
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
10152-
required:
10153-
- storage
1015410165
type: object
10155-
required:
10156-
- requests
1015710166
type: object
1015810167
selector:
1015910168
description: selector is a label query over volumes to consider
@@ -10231,10 +10240,17 @@ spec:
1023110240
description: volumeName is the binding reference to the
1023210241
PersistentVolume backing this claim.
1023310242
type: string
10234-
required:
10235-
- accessModes
10236-
- resources
1023710243
type: object
10244+
x-kubernetes-validations:
10245+
- fieldPath: .accessModes
10246+
message: missing accessModes
10247+
reason: FieldValueRequired
10248+
rule: has(self.accessModes) && size(self.accessModes) > 0
10249+
- fieldPath: .resources.requests.storage
10250+
message: missing storage request
10251+
reason: FieldValueRequired
10252+
rule: has(self.resources) && has(self.resources.requests)
10253+
&& has(self.resources.requests.storage)
1023810254
metadata:
1023910255
description: Metadata contains metadata for custom resources
1024010256
properties:
@@ -10602,6 +10618,17 @@ spec:
1060210618
the PersistentVolume backing this claim.
1060310619
type: string
1060410620
type: object
10621+
x-kubernetes-validations:
10622+
- fieldPath: .accessModes
10623+
message: missing accessModes
10624+
reason: FieldValueRequired
10625+
rule: has(self.accessModes) && size(self.accessModes)
10626+
> 0
10627+
- fieldPath: .resources.requests.storage
10628+
message: missing storage request
10629+
reason: FieldValueRequired
10630+
rule: has(self.resources) && has(self.resources.requests)
10631+
&& has(self.resources.requests.storage)
1060510632
name:
1060610633
description: |-
1060710634
The name for the tablespace, used as the path name for the volume.
@@ -10848,7 +10875,6 @@ spec:
1084810875
More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1
1084910876
items:
1085010877
type: string
10851-
minItems: 1
1085210878
type: array
1085310879
x-kubernetes-list-type: atomic
1085410880
dataSource:
@@ -10958,11 +10984,7 @@ spec:
1095810984
If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
1095910985
otherwise to an implementation-defined value. Requests cannot exceed Limits.
1096010986
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
10961-
required:
10962-
- storage
1096310987
type: object
10964-
required:
10965-
- requests
1096610988
type: object
1096710989
selector:
1096810990
description: selector is a label query over volumes to consider
@@ -11040,10 +11062,17 @@ spec:
1104011062
description: volumeName is the binding reference to the
1104111063
PersistentVolume backing this claim.
1104211064
type: string
11043-
required:
11044-
- accessModes
11045-
- resources
1104611065
type: object
11066+
x-kubernetes-validations:
11067+
- fieldPath: .accessModes
11068+
message: missing accessModes
11069+
reason: FieldValueRequired
11070+
rule: has(self.accessModes) && size(self.accessModes) > 0
11071+
- fieldPath: .resources.requests.storage
11072+
message: missing storage request
11073+
reason: FieldValueRequired
11074+
rule: has(self.resources) && has(self.resources.requests)
11075+
&& has(self.resources.requests.storage)
1104711076
required:
1104811077
- dataVolumeClaimSpec
1104911078
type: object

pkg/apis/postgres-operator.crunchydata.com/v1beta1/pgbackrest_types.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,18 @@ type RepoHostStatus struct {
342342
type RepoPVC struct {
343343

344344
// Defines a PersistentVolumeClaim spec used to create and/or bind a volume
345+
// ---
345346
// +kubebuilder:validation:Required
347+
//
348+
// NOTE(validation): Every PVC must have at least one accessMode. NOTE(KEP-4153)
349+
// - https://releases.k8s.io/v1.25.0/pkg/apis/core/validation/validation.go#L2098-L2100
350+
// - https://releases.k8s.io/v1.31.0/pkg/apis/core/validation/validation.go#L2292-L2294
351+
// +kubebuilder:validation:XValidation:rule=`has(self.accessModes) && size(self.accessModes) > 0`,message=`missing accessModes`,fieldPath=`.accessModes`,reason="FieldValueRequired"
352+
//
353+
// NOTE(validation): Every PVC must have a positive storage request. NOTE(KEP-4153)
354+
// - https://releases.k8s.io/v1.25.0/pkg/apis/core/validation/validation.go#L2126-L2133
355+
// - https://releases.k8s.io/v1.31.0/pkg/apis/core/validation/validation.go#L2318-L2325
356+
// +kubebuilder:validation:XValidation:rule=`has(self.resources) && has(self.resources.requests) && has(self.resources.requests.storage)`,message=`missing storage request`,fieldPath=`.resources.requests.storage`,reason="FieldValueRequired"
346357
VolumeClaimSpec corev1.PersistentVolumeClaimSpec `json:"volumeClaimSpec"`
347358
}
348359

pkg/apis/postgres-operator.crunchydata.com/v1beta1/postgrescluster_types.go

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,18 @@ type PostgresInstanceSetSpec struct {
450450

451451
// Defines a PersistentVolumeClaim for PostgreSQL data.
452452
// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes
453+
// ---
453454
// +kubebuilder:validation:Required
455+
//
456+
// NOTE(validation): Every PVC must have at least one accessMode. NOTE(KEP-4153)
457+
// - https://releases.k8s.io/v1.25.0/pkg/apis/core/validation/validation.go#L2098-L2100
458+
// - https://releases.k8s.io/v1.31.0/pkg/apis/core/validation/validation.go#L2292-L2294
459+
// +kubebuilder:validation:XValidation:rule=`has(self.accessModes) && size(self.accessModes) > 0`,message=`missing accessModes`,fieldPath=`.accessModes`,reason="FieldValueRequired"
460+
//
461+
// NOTE(validation): Every PVC must have a positive storage request. NOTE(KEP-4153)
462+
// - https://releases.k8s.io/v1.25.0/pkg/apis/core/validation/validation.go#L2126-L2133
463+
// - https://releases.k8s.io/v1.31.0/pkg/apis/core/validation/validation.go#L2318-L2325
464+
// +kubebuilder:validation:XValidation:rule=`has(self.resources) && has(self.resources.requests) && has(self.resources.requests.storage)`,message=`missing storage request`,fieldPath=`.resources.requests.storage`,reason="FieldValueRequired"
454465
DataVolumeClaimSpec corev1.PersistentVolumeClaimSpec `json:"dataVolumeClaimSpec"`
455466

456467
// Priority class name for the PostgreSQL pod. Changing this value causes
@@ -491,7 +502,18 @@ type PostgresInstanceSetSpec struct {
491502

492503
// Defines a separate PersistentVolumeClaim for PostgreSQL's write-ahead log.
493504
// More info: https://www.postgresql.org/docs/current/wal.html
494-
// +optional
505+
// ---
506+
// +kubebuilder:validation:Optional
507+
//
508+
// NOTE(validation): Every PVC must have at least one accessMode. NOTE(KEP-4153)
509+
// - https://releases.k8s.io/v1.25.0/pkg/apis/core/validation/validation.go#L2098-L2100
510+
// - https://releases.k8s.io/v1.31.0/pkg/apis/core/validation/validation.go#L2292-L2294
511+
// +kubebuilder:validation:XValidation:rule=`has(self.accessModes) && size(self.accessModes) > 0`,message=`missing accessModes`,fieldPath=`.accessModes`,reason="FieldValueRequired"
512+
//
513+
// NOTE(validation): Every PVC must have a positive storage request. NOTE(KEP-4153)
514+
// - https://releases.k8s.io/v1.25.0/pkg/apis/core/validation/validation.go#L2126-L2133
515+
// - https://releases.k8s.io/v1.31.0/pkg/apis/core/validation/validation.go#L2318-L2325
516+
// +kubebuilder:validation:XValidation:rule=`has(self.resources) && has(self.resources.requests) && has(self.resources.requests.storage)`,message=`missing storage request`,fieldPath=`.resources.requests.storage`,reason="FieldValueRequired"
495517
WALVolumeClaimSpec *corev1.PersistentVolumeClaimSpec `json:"walVolumeClaimSpec,omitempty"`
496518

497519
// The list of tablespaces volumes to mount for this postgrescluster
@@ -520,7 +542,18 @@ type TablespaceVolume struct {
520542

521543
// Defines a PersistentVolumeClaim for a tablespace.
522544
// More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes
545+
// ---
523546
// +kubebuilder:validation:Required
547+
//
548+
// NOTE(validation): Every PVC must have at least one accessMode. NOTE(KEP-4153)
549+
// - https://releases.k8s.io/v1.25.0/pkg/apis/core/validation/validation.go#L2098-L2100
550+
// - https://releases.k8s.io/v1.31.0/pkg/apis/core/validation/validation.go#L2292-L2294
551+
// +kubebuilder:validation:XValidation:rule=`has(self.accessModes) && size(self.accessModes) > 0`,message=`missing accessModes`,fieldPath=`.accessModes`,reason="FieldValueRequired"
552+
//
553+
// NOTE(validation): Every PVC must have a positive storage request. NOTE(KEP-4153)
554+
// - https://releases.k8s.io/v1.25.0/pkg/apis/core/validation/validation.go#L2126-L2133
555+
// - https://releases.k8s.io/v1.31.0/pkg/apis/core/validation/validation.go#L2318-L2325
556+
// +kubebuilder:validation:XValidation:rule=`has(self.resources) && has(self.resources.requests) && has(self.resources.requests.storage)`,message=`missing storage request`,fieldPath=`.resources.requests.storage`,reason="FieldValueRequired"
524557
DataVolumeClaimSpec corev1.PersistentVolumeClaimSpec `json:"dataVolumeClaimSpec"`
525558
}
526559

0 commit comments

Comments
 (0)