Skip to content

Commit 79c6898

Browse files
committed
Add subresources section
1 parent 61abddc commit 79c6898

File tree

1 file changed

+68
-0
lines changed
  • keps/sig-api-machinery/5073-declarative-validation-with-validation-gen

1 file changed

+68
-0
lines changed

keps/sig-api-machinery/5073-declarative-validation-with-validation-gen/README.md

+68
Original file line numberDiff line numberDiff line change
@@ -944,6 +944,74 @@ The linter, as previously described, will enforce rules to address valid zero-va
944944

945945
The linter will flag any violations of these rules, ensuring consistent zero-value handling and preventing related errors. This automated enforcement is crucial for catching issues early in the development process.
946946

947+
### Subresources
948+
949+
#### Status style subresources
950+
951+
These are subresources that:
952+
953+
- Share the root resource. (Same Kind, same storage object).
954+
- Typically, have constraints on which fields may be updated.
955+
- In some cases, may allow updates not otherwise allowed.
956+
957+
Examples:
958+
959+
- `pods/status` may update to the `metadata` and `status` stanzas, but not the `spec` stanza.
960+
- `resourceclaims/status` may only update the `status` stanza, but not the `metadata` or `spec` stanza.
961+
- `pods/resize` may update `spec.container[*].resources` fields, which are immutable via the root `pods` resource.
962+
- `certificatesigningrequests/approval` may add/remove/modify the Approved/Denied status conditions.
963+
964+
To validate these fields, Declarative Validation will:
965+
966+
- Does NOT constraint which fields a subresource operation is allowed to write. This will
967+
responsibility of "field wiping". Field wiping logic is expected to be handled in resource
968+
strategies by modifying (wiping) the incoming object before it is validated.
969+
- Validates the entire resource using same declarative validation as used to validate the root
970+
resource. But, allows validation tags to perform conditional validation based on the subresource.
971+
- Uses ratcheting to skip validation of unchanged fields. Combined with field wiping, this
972+
isolates the actual validation performed to the subset of fields that are allowed to be updated
973+
via the subresource.
974+
975+
Examples:
976+
977+
- `pods/status` will be validated with the same declarative validation tags as the root `pods` resource after field wiping has been applied to the `spec`.
978+
- `pods/resize` will be validated with the same declarative validation tags as the root `pods`, but the root resource validation will consult the
979+
subresource parameter when validating `spec.container[*].resources` to ensure immutability unless updated via the `pods/resize` subresource via
980+
a rule such as: `+k8s:if('subresources != ["resize"]')=+k8s:immutable`
981+
982+
To support these types of subresources, declarative validation will be extended to:
983+
984+
- Provide a "subresources" parameter that is accessible via validation tags so that conditional validation is possible.
985+
986+
#### Scale style subresources
987+
988+
These are subresources that:
989+
990+
- Have a different Kind than the root resource.
991+
- Share the storage object of the root resource. (updates to the subresource fields result in writes to corresponding stored to fields of the root resource).
992+
993+
Examples:
994+
995+
- Update to `pods/scale` may modify `spec.replicas` to cause an update to the `spec.replicas` field of the root `pods` resource.
996+
- Create of `pods/binding` provides a `target` to cause the `pod.spec.nodeName` to be set on the root `pods` resource (but only if nodeName is not already set).
997+
998+
To validate these fields, Declarative Validation will (in the storage layer of an API definition):
999+
1000+
- Validates the subresource declaratively.
1001+
- Relies on the resource's storage layer to apply the write to the root resource.
1002+
- Validates the root resource normally.
1003+
- Uses ratcheting to skip validation of unchanged fields.
1004+
1005+
To support these types of subresources, declarative validation will be extended to:
1006+
1007+
- Accept the mapping from internal type to versioned type of scale style subresources so that a `ValidateDeclaratively(..., internal.Scale, ...)` request
1008+
is mapped to the same Scale group/version as the request (for example, `autoscaling.k8s.io/v1`) and then validated.
1009+
- https://github.com/jpbetz/kubernetes/pull/141 provides an example of how to migrate a resource to scale subresource declarative validation.
1010+
1011+
#### Streaming subresources
1012+
1013+
Streaming endpoints such as `pod/exec`, `pod/attach` and `pod/portForward` are not validated normally and will not be migrated to declarative validation.
1014+
9471015
### Ratcheting
9481016

9491017
As `validation-gen`‘s go validation code has old object access we can write any transition rule we want for validation ratcheting. `validation-gen` has access to the old and new state of obj for any field. This gives us a building block to make any flavor of ratcheting we would need in theory. We can think the basic form of ratcheting as - “allow old value to be written in updates even if now not valid as long as it doesn’t change -> easy to test”. If old = new -> short circuit validation (don’t care if it failed). If certain ratcheting needs syntactic sugar, we can add that as well based ont the current `validation-gen` design. An example of what ratcheting validation logic might look like for `validation-gen` is below:

0 commit comments

Comments
 (0)