Skip to content

Commit e31cd19

Browse files
committed
Add test case summary and open questions
1 parent d882c04 commit e31cd19

File tree

1 file changed

+63
-16
lines changed
  • keps/sig-api-machinery/1027-api-unions

1 file changed

+63
-16
lines changed

keps/sig-api-machinery/1027-api-unions/README.md

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,24 +12,22 @@
1212
- [User Stories (Optional)](#user-stories-optional)
1313
- [Story 1](#story-1)
1414
- [Story 2](#story-2)
15+
- [Story 3](#story-3)
1516
- [Notes/Constraints/Caveats (Optional)](#notesconstraintscaveats-optional)
1617
- [Risks and Mitigations](#risks-and-mitigations)
1718
- [Design Details](#design-details)
19+
- [Discriminator Field](#discriminator-field)
1820
- [Go tags](#go-tags)
1921
- [OpenAPI](#openapi)
20-
- [Discriminator](#discriminator)
21-
- [Normalizing on updates](#normalizing-on-updates)
22-
- ["At most one" versus "exactly one"](#at-most-one-versus-exactly-one)
23-
- [Clearing all the fields](#clearing-all-the-fields)
24-
- [Backward compatibilities properties](#backward-compatibilities-properties)
25-
- [Validation](#validation)
22+
- [Normalization and Validation](#normalization-and-validation)
23+
- [Open Questions](#open-questions)
2624
- [Test Plan](#test-plan)
2725
- [Prerequisite testing updates](#prerequisite-testing-updates)
2826
- [Unit tests](#unit-tests)
2927
- [Integration tests](#integration-tests)
3028
- [e2e tests](#e2e-tests)
3129
- [Graduation Criteria](#graduation-criteria)
32-
- [Beta -> GA Graduation](#beta---ga-graduation)
30+
- [Alpha Graduation](#alpha-graduation)
3331
- [Upgrade / Downgrade Strategy](#upgrade--downgrade-strategy)
3432
- [Version Skew Strategy](#version-skew-strategy)
3533
- [Production Readiness Review Questionnaire](#production-readiness-review-questionnaire)
@@ -39,7 +37,6 @@
3937
- [Dependencies](#dependencies)
4038
- [Scalability](#scalability)
4139
- [Troubleshooting](#troubleshooting)
42-
- [Future Work](#future-work)
4340
- [Implementation History](#implementation-history)
4441
- [Drawbacks](#drawbacks)
4542
- [Alternatives](#alternatives)
@@ -144,8 +141,6 @@ discriminator should continue to not need a discriminator)
144141
In order to support unions in a backward compatible way in kubernetes, we're
145142
proposing the following changes.
146143

147-
Note that this proposes unions to be "at most one of". Whether exactly one is
148-
supported or not should be implemented by the validation logic.
149144

150145
### User Stories (Optional)
151146

@@ -206,6 +201,41 @@ Consider including folks who also work outside the SIG or subproject.
206201

207202
## Design Details
208203

204+
### Discriminator Field
205+
206+
We propose that all new unions maintain a "discriminator". This is a field that
207+
points to which of the other "union member" fields is to be respected as the
208+
truly desired union field in the case that there are any conflicts.
209+
210+
In order to demonstrate the need for the discriminator, we developed an
211+
extensive [test matrix](https://docs.google.com/spreadsheets/d/1dIOOqgrgvMI9b2412eVuRSydEaOxhYOoqk6bUjZOY9c/edit?resourcekey=0-wlOfJTC_EX-qpU680STHMA#gid=3601413) that looks at various configurations of the performing
212+
REST operations on a union where the client or server is unaware of a newly
213+
added field to the union (due to version skew).
214+
215+
We present a [guide doc](https://docs.google.com/document/d/1Wruosjo0ELLl1yxauzpsUjgH2fK9KdgXDmOdJ5sG7Kg/edit?resourcekey=0-8Pwzx6EvsFR7VQoXzCTY4Q) on how to interpret the test matrix, but the major
216+
conclusions are as follows (along with the test case number from the test matrix):
217+
218+
* (Case #22 and #27) If an unstructured client is unaware of field on the union, but wants to clear
219+
the union entirely (assuming the union is optional), it will have no way of doing
220+
so without a discriminator. With a discriminator, the client can express its
221+
intention by setting the discriminator to the empty value and the server can
222+
respects it intentions and clear any fields the client is unaware of.
223+
* (Case #12 and #16) If a structured client is unaware of a field in the union that is set and it
224+
just wants to echo back the union it received in a get request (such as when
225+
updating other parts of the object), a client without a discriminator will
226+
silently drop the currently set field, while a client with the discriminator
227+
will not change the discriminator value, indicating to the client that no
228+
changes are desired in the union.
229+
* (Case #34 and #39) If a client sets a union field that the server is not aware of, the server
230+
will silently drop it and attempt to clear the object of the union field. With
231+
a discriminator, the server will see the unrecognized discriminator value and
232+
can fail loudly.
233+
* (Case #23 and #28) When a client goes to set a field it knows of, but a separate field it doesn't
234+
know about is currently set, the server can simply know to always respect the
235+
discriminator. Without a discriminator, the server will have to do convoluted
236+
logic to detect that the previously set field has not been modified and that
237+
only one of the other union fields has been.
238+
209239
### Go tags
210240

211241
We're proposing a new type of tags for go types (in-tree types, and also
@@ -339,14 +369,24 @@ currently done for existing union types.
339369

340370
Objects must be validated AFTER the normalization process.
341371

342-
### Test Plan
372+
### Open Questions
343373

344-
There are mostly 3 aspects to this plan:
345-
- [x] Core functionality, isolated from all other components: https://github.com/kubernetes-sigs/structured-merge-diff/blob/master/typed/union_test.go
346-
- [x] Functionality as part of server-side apply: How human and robot interactions work: https://github.com/kubernetes-sigs/structured-merge-diff/blob/master/typed/union_test.go
347-
- [x] Integration in kubernetes: https://github.com/kubernetes/kubernetes/pull/77370/files#diff-4ac5831d494b1b52c7c7be81e552a458
374+
A few open questions exist with the design that need to be resolved with SIG API
375+
Machinery before moving forward.
348376

349-
[ ] I/we understand the owners of the involved components may require updates to
377+
1. When a server receives an update request with empty data in the member fields
378+
but a validly set discriminator pointing to the object's union member field
379+
that was previously set, should the server error and inform the client that
380+
the field pointed to by the discriminator is currently empty, or should the
381+
server retain the previous value it knows was set to the field being pointed
382+
to by the discriminator?
383+
2. What should the value of the discriminator be when no field in the union is
384+
to be set. A couple options inclued an empty string, an field common to all
385+
union (e.g. "NONE"), or a field specified on a per union basis.
386+
387+
### Test Plan
388+
389+
[x] I/we understand the owners of the involved components may require updates to
350390
existing tests to make this code solid enough prior to committing the changes necessary
351391
to implement this enhancement.
352392

@@ -457,6 +497,9 @@ enhancement:
457497
cluster required to make on upgrade, in order to make use of the enhancement?
458498
-->
459499

500+
At first, Only new union types will follow the prescribed guinance, so no upgrades/downgrades are possible for types
501+
that don't exist yet.
502+
460503
### Version Skew Strategy
461504

462505
<!--
@@ -472,6 +515,10 @@ enhancement:
472515
CRI or CNI may require updating that component before the kubelet.
473516
-->
474517

518+
See test matrix and commentary about discriminators. It clearly documents how
519+
the server will use the discriminator to understand the client's intention even
520+
if the client is not aware of all union fields because of version skew.
521+
475522
## Production Readiness Review Questionnaire
476523

477524
<!--

0 commit comments

Comments
 (0)