Skip to content

Commit d9bfbf2

Browse files
authored
Merge pull request #8560 from aaron-prindle/dv-documentation
docs: update api_changes.md and api_conventions.md with declarative validation information
2 parents 246fa86 + ef59b1b commit d9bfbf2

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

contributors/devel/sig-architecture/api-conventions.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1953,7 +1953,9 @@ the future, an HTTP/2 implementation will be exposed that deprecates SPDY.
19531953

19541954
## Validation
19551955

1956-
API objects are validated upon receipt by the apiserver. Validation errors are
1956+
API objects are validated upon receipt by the apiserver.
1957+
Validation can be implemented in two ways: declaratively, using tags on the Go type definitions, or manually, by writing validation functions.
1958+
For all new APIs, declarative validation is the preferred approach for the validation rules it supports. For more information see the [declarative validation documentation](api_changes.md#declarative-validation). Validation errors are
19571959
flagged and returned to the caller in a `Failure` status with `reason` set to
19581960
`Invalid`. In order to facilitate consistent error messages, we ask that
19591961
validation logic adheres to the following guidelines whenever possible (though

contributors/devel/sig-architecture/api_changes.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,67 @@ optionality of fields.
645645

646646
Of course, code needs tests - `pkg/apis/<group>/validation/validation_test.go`.
647647

648+
### Declarative Validation
649+
650+
For new APIs, developers should use declarative validation for all validation rules that declarative validation supports.
651+
See the [declarative validation tag catalog](https://kubernetes.io/docs/reference/using-api/declarative-validation/) for the list of supported validation rules.
652+
This allows you to define validation rules directly on the API types using special Go comment tags.
653+
These validation rules are easier to write, review, and maintain as they live alongside the type and field definitions.
654+
655+
A new code generator, `validation-gen`, processes these tags to produce the validation logic automatically, reducing the need to write manual validation code in `validation.go`.
656+
657+
658+
Setting up validation code generation involves the following steps.
659+
For APIs already using declarative validation, the first 2 plumbing steps can be skipped:
660+
- Register the desired API group with validation-gen, similar to other code generators([Example PR doc.go change](https://github.com/kubernetes/kubernetes/pull/130724))
661+
- Wire up the `strategy.go` for the desired API group to use declarative validation ([Example PR strategy.go change](https://github.com/kubernetes/kubernetes/pull/130724))
662+
- Add declarative validation tags to the types and fields of the registered package ([Example PR types.go change](https://github.com/kubernetes/kubernetes/pull/130725))
663+
- Run the validation-gen code generator (see below)
664+
665+
Below is an example of how to register an API group with validation-gen:
666+
667+
`pkg/apis/core/v1/doc.go`
668+
```go
669+
...
670+
// +k8s:validation-gen=TypeMeta
671+
// +k8s:validation-gen-input=k8s.io/api/core/v1
672+
673+
// Package v1 is the v1 version of the API.
674+
package v1
675+
```
676+
677+
Below is an example of how to use declarative validation tags in a `types.go` file:
678+
679+
```go
680+
// ReplicationControllerSpec is the specification of a replication controller.
681+
type ReplicationControllerSpec struct {
682+
// Replicas is the number of desired replicas.
683+
// This is a pointer to distinguish between explicit zero and not specified.
684+
// +k8s:optional
685+
// +k8s:minimum=0
686+
Replicas *int32 `json:"replicas,omitempty"`
687+
688+
// Minimum number of seconds for which a newly created pod should be ready
689+
// without any of its container crashing, for it to be considered available.
690+
// +k8s:optional
691+
// +k8s:minimum=0
692+
MinReadySeconds int32 `json:"minReadySeconds,omitempty"`
693+
}
694+
```
695+
696+
In this example, the `+k8s:optional` and `+k8s:minimum=0` tags specify that the `Replicas` and `MinReadySeconds` fields are optional and must have a value of at least 0 if present.
697+
698+
After adding these tags to your types, you will need to run the code generator to create or update the validation functions.
699+
This is typically done by running `make update` or `hack/update-codegen.sh`.
700+
To only run the declarative validation code generator, use `hack/update-codegen.sh validation`.
701+
Running the validation-gen code generator will create a `zz_generated.validations.go` file for the declarative validations of the associated tagged API types and fields.
702+
The generated validation methods in this file are then called via the modified `strategy.go` file in the above steps.
703+
704+
Testing the validation logic for the behaviour of a type is identical to the testing that would be done for hand-written validation code.
705+
Users will need to write go unit tests similar to what is done for hand-written validation logic that verify specific cases are allowed, disallowed, etc and the validation behaviour is as expected.
706+
707+
While the goal is to express as much validation declaratively as possible, some complex or validation rules might still require manual implementation in `validation.go`.
708+
648709
## Edit version conversions
649710

650711
At this point you have both the versioned API changes and the internal
@@ -698,6 +759,7 @@ workaround is to remove the files causing errors and rerun the command.
698759

699760
Apart from the `defaulter-gen`, `deepcopy-gen`, `conversion-gen` and
700761
`openapi-gen`, there are a few other generators:
762+
- `validation-gen` (for generating validation functions from declarative tags)
701763
- `go-to-protobuf`
702764
- `client-gen`
703765
- `lister-gen`

0 commit comments

Comments
 (0)