Skip to content

Commit 99e7fbc

Browse files
authored
Merge pull request #653 from benluddy/xvalidations-crd-marker
✨ Add XValidation CRD marker for KEP-2876 support.
2 parents cf1ea27 + b0d2867 commit 99e7fbc

File tree

4 files changed

+54
-1
lines changed

4 files changed

+54
-1
lines changed

pkg/crd/markers/validation.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ var ValidationMarkers = mustMakeAllWithPrefix("kubebuilder:validation", markers.
6767
XPreserveUnknownFields{},
6868
XEmbeddedResource{},
6969
XIntOrString{},
70+
XValidation{},
7071
)
7172

7273
// FieldOnlyMarkers list field-specific validation markers (i.e. those markers that don't make
@@ -251,6 +252,17 @@ type XIntOrString struct{}
251252
// to be used only as a last resort.
252253
type Schemaless struct{}
253254

255+
// +controllertools:marker:generateHelp:category="CRD validation"
256+
// XValidation marks a field as requiring a value for which a given
257+
// expression evaluates to true.
258+
//
259+
// This marker may be repeated to specify multiple expressions, all of
260+
// which must evaluate to true.
261+
type XValidation struct {
262+
Rule string
263+
Message string `marker:",optional"`
264+
}
265+
254266
func (m Maximum) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
255267
if schema.Type != "integer" {
256268
return fmt.Errorf("must apply maximum to an integer")
@@ -428,3 +440,11 @@ func (m XIntOrString) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
428440
}
429441

430442
func (m XIntOrString) ApplyFirst() {}
443+
444+
func (m XValidation) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
445+
schema.XValidations = append(schema.XValidations, apiext.ValidationRule{
446+
Rule: m.Rule,
447+
Message: m.Message,
448+
})
449+
return nil
450+
}

pkg/crd/markers/zz_generated.markerhelp.go

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/crd/testdata/cronjob_types.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,12 @@ type CronJobSpec struct {
187187

188188
// This tests that both unexported and exported inline fields are not skipped in the schema generation
189189
unexportedStruct `json:",inline"`
190-
ExportedStruct `json:",inline"`
190+
ExportedStruct `json:",inline"`
191+
192+
// Test of the expression-based validation rule marker, with optional message.
193+
// +kubebuilder:validation:XValidation:rule="self.size() % 2 == 0",message="must have even length"
194+
// +kubebuilder:validation:XValidation:rule="true"
195+
StringWithEvenLength string `json:"stringWithEvenLength,omitempty"`
191196
}
192197

193198
type ContainsNestedMap struct {

pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7267,6 +7267,14 @@ spec:
72677267
type: array
72687268
description: This tests string slices are allowed as map values.
72697269
type: object
7270+
stringWithEvenLength:
7271+
description: Test of the expression-based validation rule marker,
7272+
with optional message.
7273+
type: string
7274+
x-kubernetes-validations:
7275+
- message: must have even length
7276+
rule: self.size() % 2 == 0
7277+
- rule: "true"
72707278
structWithSeveralFields:
72717279
description: A struct that can only be entirely replaced
72727280
properties:

0 commit comments

Comments
 (0)