mirror of
				https://github.com/optim-enterprises-bv/kubernetes.git
				synced 2025-11-04 04:08:16 +00:00 
			
		
		
		
	Document Unions, conventions for adding to Unions.
This commit is contained in:
		@@ -53,6 +53,7 @@ using resources with kubectl can be found in [Working with resources](../user-gu
 | 
				
			|||||||
      - [Lists of named subobjects preferred over maps](#lists-of-named-subobjects-preferred-over-maps)
 | 
					      - [Lists of named subobjects preferred over maps](#lists-of-named-subobjects-preferred-over-maps)
 | 
				
			||||||
      - [Primitive types](#primitive-types)
 | 
					      - [Primitive types](#primitive-types)
 | 
				
			||||||
      - [Constants](#constants)
 | 
					      - [Constants](#constants)
 | 
				
			||||||
 | 
					      - [Unions](#unions)
 | 
				
			||||||
    - [Lists and Simple kinds](#lists-and-simple-kinds)
 | 
					    - [Lists and Simple kinds](#lists-and-simple-kinds)
 | 
				
			||||||
  - [Differing Representations](#differing-representations)
 | 
					  - [Differing Representations](#differing-representations)
 | 
				
			||||||
  - [Verbs on Resources](#verbs-on-resources)
 | 
					  - [Verbs on Resources](#verbs-on-resources)
 | 
				
			||||||
@@ -263,6 +264,15 @@ This rule maintains the invariant that all JSON/YAML keys are fields in API obje
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
Some fields will have a list of allowed values (enumerations). These values will be strings, and they will be in CamelCase, with an initial uppercase letter. Examples: "ClusterFirst", "Pending", "ClientIP".
 | 
					Some fields will have a list of allowed values (enumerations). These values will be strings, and they will be in CamelCase, with an initial uppercase letter. Examples: "ClusterFirst", "Pending", "ClientIP".
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#### Unions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sometimes, at most one of a set of fields can be set.  For example, the [volumes] field of a PodSpec has 17 different volume type-specific
 | 
				
			||||||
 | 
					fields, such as `nfs` and `iscsi`.  All fields in the set should be [Optional](#optional-vs-required).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Sometimes, when a new type is created, the api designer may anticipate that a union will be needed in the future, even if only one field is
 | 
				
			||||||
 | 
					allowed initially.  In this case, be sure to make the field [Optional](#optional-vs-required) optional.  In the validation, you may
 | 
				
			||||||
 | 
					still return an error if the sole field is unset.  Do not set a default value for that field.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
### Lists and Simple kinds
 | 
					### Lists and Simple kinds
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Every list or simple kind SHOULD have the following metadata in a nested object field called "metadata":
 | 
					Every list or simple kind SHOULD have the following metadata in a nested object field called "metadata":
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,38 @@ Documentation for other releases can be found at
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<!-- END MUNGE: UNVERSIONED_WARNING -->
 | 
					<!-- END MUNGE: UNVERSIONED_WARNING -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*This document is oriented at developers who want to change existing APIs.
 | 
				
			||||||
 | 
					A set of API conventions, which applies to new APIs and to changes, can be
 | 
				
			||||||
 | 
					found at [API Conventions](api-conventions.md).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Table of Contents**
 | 
				
			||||||
 | 
					<!-- BEGIN MUNGE: GENERATED_TOC -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- [So you want to change the API?](#so-you-want-to-change-the-api)
 | 
				
			||||||
 | 
					  - [Operational overview](#operational-overview)
 | 
				
			||||||
 | 
					  - [On compatibility](#on-compatibility)
 | 
				
			||||||
 | 
					  - [Incompatible API changes](#incompatible-api-changes)
 | 
				
			||||||
 | 
					  - [Changing versioned APIs](#changing-versioned-apis)
 | 
				
			||||||
 | 
					    - [Edit types.go](#edit-typesgo)
 | 
				
			||||||
 | 
					    - [Edit defaults.go](#edit-defaultsgo)
 | 
				
			||||||
 | 
					    - [Edit conversion.go](#edit-conversiongo)
 | 
				
			||||||
 | 
					  - [Changing the internal structures](#changing-the-internal-structures)
 | 
				
			||||||
 | 
					    - [Edit types.go](#edit-typesgo)
 | 
				
			||||||
 | 
					  - [Edit validation.go](#edit-validationgo)
 | 
				
			||||||
 | 
					  - [Edit version conversions](#edit-version-conversions)
 | 
				
			||||||
 | 
					  - [Edit deep copy files](#edit-deep-copy-files)
 | 
				
			||||||
 | 
					  - [Edit json (un)marshaling code](#edit-json-unmarshaling-code)
 | 
				
			||||||
 | 
					  - [Making a new API Group](#making-a-new-api-group)
 | 
				
			||||||
 | 
					  - [Update the fuzzer](#update-the-fuzzer)
 | 
				
			||||||
 | 
					  - [Update the semantic comparisons](#update-the-semantic-comparisons)
 | 
				
			||||||
 | 
					  - [Implement your change](#implement-your-change)
 | 
				
			||||||
 | 
					  - [Write end-to-end tests](#write-end-to-end-tests)
 | 
				
			||||||
 | 
					  - [Examples and docs](#examples-and-docs)
 | 
				
			||||||
 | 
					  - [Alpha, Beta, and Stable Versions](#alpha-beta-and-stable-versions)
 | 
				
			||||||
 | 
					    - [Adding Unstable Features to Stable Versions](#adding-unstable-features-to-stable-versions)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<!-- END MUNGE: GENERATED_TOC -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# So you want to change the API?
 | 
					# So you want to change the API?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Before attempting a change to the API, you should familiarize yourself
 | 
					Before attempting a change to the API, you should familiarize yourself
 | 
				
			||||||
@@ -273,6 +305,11 @@ enumerated set *can* be a compatible change, if handled properly (treat the
 | 
				
			|||||||
removed value as deprecated but allowed). This is actually a special case of
 | 
					removed value as deprecated but allowed). This is actually a special case of
 | 
				
			||||||
a new representation, discussed above.
 | 
					a new representation, discussed above.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For [Unions](api-conventions.md), sets of fields where at most one should be set,
 | 
				
			||||||
 | 
					it is acceptible to add a new option to the union if the [appropriate conventions]
 | 
				
			||||||
 | 
					were followed in the original object.  Removing an option requires following
 | 
				
			||||||
 | 
					the deprecation process.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Incompatible API changes
 | 
					## Incompatible API changes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
There are times when this might be OK, but mostly we want changes that
 | 
					There are times when this might be OK, but mostly we want changes that
 | 
				
			||||||
@@ -549,10 +586,6 @@ hack/update-swagger-spec.sh
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
The API spec changes should be in a commit separate from your other changes.
 | 
					The API spec changes should be in a commit separate from your other changes.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Adding new REST objects
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
TODO(smarterclayton): write this.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
## Alpha, Beta, and Stable Versions
 | 
					## Alpha, Beta, and Stable Versions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
New feature development proceeds through a series of stages of increasing maturity:
 | 
					New feature development proceeds through a series of stages of increasing maturity:
 | 
				
			||||||
@@ -617,6 +650,82 @@ New feature development proceeds through a series of stages of increasing maturi
 | 
				
			|||||||
  - Support: API version will continue to be present for many subsequent software releases;
 | 
					  - Support: API version will continue to be present for many subsequent software releases;
 | 
				
			||||||
  - Recommended Use Cases: any
 | 
					  - Recommended Use Cases: any
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Adding Unstable Features to Stable Versions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When adding a feature to an object which is already Stable, the new fields and new behaviors
 | 
				
			||||||
 | 
					need to meet the Stable level requirements.  If these cannot be met, then the new
 | 
				
			||||||
 | 
					field cannot be added to the object.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For example, consider the following object:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					// API v6.
 | 
				
			||||||
 | 
					type Frobber struct {
 | 
				
			||||||
 | 
						Height int    `json:"height"`
 | 
				
			||||||
 | 
						Param  string `json:"param"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A developer is considering adding a new `Width` parameter, like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					// API v6.
 | 
				
			||||||
 | 
					type Frobber struct {
 | 
				
			||||||
 | 
						Height int    `json:"height"`
 | 
				
			||||||
 | 
						Width int    `json:"height"`
 | 
				
			||||||
 | 
						Param  string `json:"param"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					However, the new feature is not stable enough to be used in a stable version (`v6`).
 | 
				
			||||||
 | 
					Some reasons for this might include:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- the final representation is undecided (e.g. should it be called `Width` or `Breadth`?)
 | 
				
			||||||
 | 
					- the implementation is not stable enough for general use (e.g. the `Area()` routine sometimes overflows.)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The developer cannot add the new field until stability is met.  However, sometimes stability
 | 
				
			||||||
 | 
					cannot be met until some users try the new feature, and some users are only able or willing
 | 
				
			||||||
 | 
					to accept a released version of Kubernetes.  In that case, the developer has a few options,
 | 
				
			||||||
 | 
					both of which require staging work over several releases.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A preferred option is to first make a release where the new value (`Width` in this example)
 | 
				
			||||||
 | 
					is specified via an annotation, like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					kind: frobber
 | 
				
			||||||
 | 
					version: v6
 | 
				
			||||||
 | 
					metadata:
 | 
				
			||||||
 | 
					  name: myfrobber
 | 
				
			||||||
 | 
					  annotations:
 | 
				
			||||||
 | 
					    frobbing.alpha.kubernetes.io/width: 2
 | 
				
			||||||
 | 
					height: 4
 | 
				
			||||||
 | 
					param: "green and blue"
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This format allows users to specify the new field, but makes it clear
 | 
				
			||||||
 | 
					that they are using a Alpha feature when they do, since the word `alpha`
 | 
				
			||||||
 | 
					is in the annotation key.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Another option is to introduce a new type with an new `alpha` or `beta` version
 | 
				
			||||||
 | 
					designator, like this:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					// API v6alpha2
 | 
				
			||||||
 | 
					type Frobber struct {
 | 
				
			||||||
 | 
						Height int    `json:"height"`
 | 
				
			||||||
 | 
						Width int    `json:"height"`
 | 
				
			||||||
 | 
						Param  string `json:"param"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The latter requires that all objects in the same API group as `Frobber` to be replicated in
 | 
				
			||||||
 | 
					the new version, `v6alpha2`.   This also requires user to use a new client which uses the
 | 
				
			||||||
 | 
					other version.    Therefore, this is not a preferred option.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					A releated issue is how a cluster manager can roll back from a new version
 | 
				
			||||||
 | 
					with a new feature, that is already being used by users.  See https://github.com/kubernetes/kubernetes/issues/4855.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
 | 
					<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
 | 
				
			||||||
[]()
 | 
					[]()
 | 
				
			||||||
<!-- END MUNGE: GENERATED_ANALYTICS -->
 | 
					<!-- END MUNGE: GENERATED_ANALYTICS -->
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user