Skip to content

Commit

Permalink
Add XValidations CRD marker for KEP-2876 support.
Browse files Browse the repository at this point in the history
This allows generation of the x-kubernetes-validations extension for
expression-based validation rules.
  • Loading branch information
benluddy committed Jan 31, 2022
1 parent c796d03 commit 7e083a3
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
20 changes: 20 additions & 0 deletions pkg/crd/markers/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ var ValidationMarkers = mustMakeAllWithPrefix("kubebuilder:validation", markers.
XPreserveUnknownFields{},
XEmbeddedResource{},
XIntOrString{},
XValidations{},
)

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

// +controllertools:marker:generateHelp:category="CRD validation"
// XValidations marks a field as requiring a value for which a given
// expression evaluates to true.
//
// This marker may be repeated to specify multiple expressions, all of
// which must evaluate to true.
type XValidations struct {
Rule string
Message string `marker:",optional"`
}

func (m Maximum) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
if schema.Type != "integer" {
return fmt.Errorf("must apply maximum to an integer")
Expand Down Expand Up @@ -428,3 +440,11 @@ func (m XIntOrString) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
}

func (m XIntOrString) ApplyFirst() {}

func (m XValidations) ApplyToSchema(schema *apiext.JSONSchemaProps) error {
schema.XValidations = append(schema.XValidations, apiext.ValidationRule{
Rule: m.Rule,
Message: m.Message,
})
return nil
}
20 changes: 20 additions & 0 deletions pkg/crd/markers/zz_generated.markerhelp.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions pkg/crd/testdata/cronjob_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,11 @@ type CronJobSpec struct {

// Maps of arrays of things-that-aren’t-strings are permitted
MapOfArraysOfFloats map[string][]bool `json:"mapOfArraysOfFloats,omitempty"`

// Test of the expression-based validation rule marker, with optional message.
// +kubebuilder:validation:XValidations:rule="self.size() % 2 == 0",message="must have even length"
// +kubebuilder:validation:XValidations:rule="true"
StringWithEvenLength string `json:"stringWithEvenLength,omitempty"`
}

type ContainsNestedMap struct {
Expand Down
8 changes: 8 additions & 0 deletions pkg/crd/testdata/testdata.kubebuilder.io_cronjobs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7259,6 +7259,14 @@ spec:
type: array
description: This tests string slices are allowed as map values.
type: object
stringWithEvenLength:
description: Test of the expression-based validation rule marker,
with optional message.
type: string
x-kubernetes-validations:
- message: must have even length
rule: self.size() % 2 == 0
- rule: "true"
structWithSeveralFields:
description: A struct that can only be entirely replaced
properties:
Expand Down

0 comments on commit 7e083a3

Please sign in to comment.