Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit c71315f

Browse files
committed
Make ImageVolumeSource.Reference required via OpenAPI
OpenAPI validation does not count toward the CRD XValidation CEL budget.
1 parent da69a57 commit c71315f

File tree

12 files changed

+185
-98
lines changed

12 files changed

+185
-98
lines changed

‎config/crd/bases/postgres-operator.crunchydata.com_pgadmins.yaml‎

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2629,6 +2629,11 @@ spec:
26292629
Never: the kubelet never pulls the reference and only uses a local image or artifact. Container creation will fail if the reference isn't present.
26302630
IfNotPresent: the kubelet pulls if the reference isn't already present on disk. Container creation will fail if the reference isn't present and the pull fails.
26312631
Defaults to Always if :latest tag is specified, or IfNotPresent otherwise.
2632+
enum:
2633+
- Always
2634+
- Never
2635+
- IfNotPresent
2636+
maxLength: 12
26322637
type: string
26332638
reference:
26342639
description: |-
@@ -2638,7 +2643,10 @@ spec:
26382643
More info: https://kubernetes.io/docs/concepts/containers/images
26392644
This field is optional to allow higher level config management to default or override
26402645
container images in workload controllers like Deployments and StatefulSets.
2646+
minLength: 1
26412647
type: string
2648+
required:
2649+
- reference
26422650
type: object
26432651
name:
26442652
description: |-
@@ -2659,11 +2667,8 @@ spec:
26592667
x-kubernetes-validations:
26602668
- message: you must set only one of image or claimName
26612669
rule: has(self.claimName) != has(self.image)
2662-
- message: readOnly cannot be set false when using an ImageVolumeSource
2670+
- message: image volumes must be readOnly
26632671
rule: '!has(self.image) || !has(self.readOnly) || self.readOnly'
2664-
- message: if using an ImageVolumeSource, you must set a reference
2665-
rule: '!has(self.image) || (self.?image.reference.hasValue()
2666-
&& self.image.reference.size() > 0)'
26672672
maxItems: 10
26682673
type: array
26692674
x-kubernetes-list-map-keys:

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

Lines changed: 126 additions & 84 deletions
Large diffs are not rendered by default.

‎internal/crd/post-process.jq‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,26 @@
33
# SPDX-License-Identifier: Apache-2.0
44
#
55
# This [jq] filter modifies a Kubernetes CustomResourceDefinition.
6+
# Use the controller-gen "+kubebuilder:title" marker to identify schemas that need special manipulation.
67
#
78
# [jq]: https://jqlang.org
89

910
# merge recursively combines a stream of objects.
1011
# https://jqlang.org/manual#multiplication-division-modulo
1112
def merge(stream): reduce stream as $i ({}; . * $i);
1213

14+
# https://pkg.go.dev/k8s.io/api/core/v1#ImageVolumeSource
15+
reduce paths(try .title == "$corev1.ImageVolumeSource") as $path (.;
16+
getpath($path) as $schema |
17+
setpath($path; $schema * {
18+
required: (["reference"] + ($schema.required // []) | sort),
19+
properties: {
20+
pullPolicy: { enum: ["Always", "Never", "IfNotPresent"] },
21+
reference: { minLength: 1 }
22+
}
23+
} | del(.title))
24+
) |
25+
1326
# Kubernetes assumes the evaluation cost of an enum value is very large: https://issue.k8s.io/119511
1427
# Look at every schema that has a populated "enum" property.
1528
reduce paths(try .enum | length > 0) as $path (.;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

‎internal/testing/validation/postgrescluster_test.go‎ renamed to ‎internal/crd/validation/postgrescluster_test.go‎

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"sigs.k8s.io/controller-runtime/pkg/client"
1515
"sigs.k8s.io/yaml"
1616

17+
"github.com/crunchydata/postgres-operator/internal/testing/cmp"
1718
"github.com/crunchydata/postgres-operator/internal/testing/require"
1819
v1 "github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1"
1920
"github.com/crunchydata/postgres-operator/pkg/apis/postgres-operator.crunchydata.com/v1beta1"
@@ -110,6 +111,7 @@ func TestPostgresUserInterfaceAcrossVersions(t *testing.T) {
110111
func TestAdditionalVolumes(t *testing.T) {
111112
ctx := context.Background()
112113
cc := require.KubernetesAtLeast(t, "1.30")
114+
dryrun := client.NewDryRunClient(cc)
113115
t.Parallel()
114116

115117
namespace := require.Namespace(t, cc)
@@ -154,8 +156,13 @@ func TestAdditionalVolumes(t *testing.T) {
154156
}]
155157
}
156158
}]`, "spec", "instances")
157-
err := cc.Create(ctx, tmp.DeepCopy(), client.DryRunAll)
159+
160+
err := dryrun.Create(ctx, tmp.DeepCopy())
158161
assert.Assert(t, apierrors.IsInvalid(err))
162+
163+
details := require.StatusErrorDetails(t, err)
164+
assert.Assert(t, cmp.Len(details.Causes, 1))
165+
assert.Equal(t, details.Causes[0].Field, "spec.instances[0].volumes.additional[0]")
159166
assert.ErrorContains(t, err, "you must set only one of image or claimName")
160167
})
161168

@@ -178,9 +185,14 @@ func TestAdditionalVolumes(t *testing.T) {
178185
}]
179186
}
180187
}]`, "spec", "instances")
181-
err := cc.Create(ctx, tmp.DeepCopy(), client.DryRunAll)
188+
189+
err := dryrun.Create(ctx, tmp.DeepCopy())
182190
assert.Assert(t, apierrors.IsInvalid(err))
183-
assert.ErrorContains(t, err, "readOnly cannot be set false when using an ImageVolumeSource")
191+
192+
details := require.StatusErrorDetails(t, err)
193+
assert.Assert(t, cmp.Len(details.Causes, 1))
194+
assert.Equal(t, details.Causes[0].Field, "spec.instances[0].volumes.additional[0]")
195+
assert.ErrorContains(t, err, "image volumes must be readOnly")
184196
})
185197

186198
t.Run("Reference must be set when using image volume", func(t *testing.T) {
@@ -201,9 +213,15 @@ func TestAdditionalVolumes(t *testing.T) {
201213
}]
202214
}
203215
}]`, "spec", "instances")
204-
err := cc.Create(ctx, tmp.DeepCopy(), client.DryRunAll)
216+
217+
err := dryrun.Create(ctx, tmp.DeepCopy())
205218
assert.Assert(t, apierrors.IsInvalid(err))
206-
assert.ErrorContains(t, err, "if using an ImageVolumeSource, you must set a reference")
219+
220+
details := require.StatusErrorDetails(t, err)
221+
assert.Assert(t, cmp.Len(details.Causes, 2))
222+
assert.Assert(t, cmp.Equal(details.Causes[0].Field, "spec.instances[0].volumes.additional[0].image.reference"))
223+
assert.Assert(t, cmp.Equal(details.Causes[0].Type, "FieldValueRequired"))
224+
assert.ErrorContains(t, err, "Required")
207225
})
208226

209227
t.Run("Reference cannot be an empty string when using image volume", func(t *testing.T) {
@@ -225,9 +243,15 @@ func TestAdditionalVolumes(t *testing.T) {
225243
}]
226244
}
227245
}]`, "spec", "instances")
228-
err := cc.Create(ctx, tmp.DeepCopy(), client.DryRunAll)
246+
247+
err := dryrun.Create(ctx, tmp.DeepCopy())
229248
assert.Assert(t, apierrors.IsInvalid(err))
230-
assert.ErrorContains(t, err, "if using an ImageVolumeSource, you must set a reference")
249+
250+
details := require.StatusErrorDetails(t, err)
251+
assert.Assert(t, cmp.Len(details.Causes, 1))
252+
assert.Assert(t, cmp.Equal(details.Causes[0].Field, "spec.instances[0].volumes.additional[0].image.reference"))
253+
assert.Assert(t, cmp.Equal(details.Causes[0].Type, "FieldValueInvalid"))
254+
assert.ErrorContains(t, err, "at least 1 chars long")
231255
})
232256

233257
t.Run("ReadOnly can be omitted or set true when using image volume", func(t *testing.T) {
@@ -265,6 +289,6 @@ func TestAdditionalVolumes(t *testing.T) {
265289
}]
266290
}
267291
}]`, "spec", "instances")
268-
assert.NilError(t, cc.Create(ctx, tmp.DeepCopy(), client.DryRunAll))
292+
assert.NilError(t, dryrun.Create(ctx, tmp.DeepCopy()))
269293
})
270294
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /