Skip to content

Commit

Permalink
WIP.
Browse files Browse the repository at this point in the history
  • Loading branch information
jiahuif committed Sep 2, 2021
1 parent 0b840b0 commit cc9d300
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 29 deletions.
127 changes: 114 additions & 13 deletions keps/sig-api-machinery/2887-openapi-enum-types/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,11 @@ updates.
[documentation style guide]: https://github.com/kubernetes/community/blob/master/contributors/guide/style-guide.md
-->

This KEP defines Enum Types support for OpenAPI. Currently, types in our API have fields
that are actually enums but represented as plain string. This KEP proposes a `+enum`
annotation to type aliases that represent enums. The OpenAPI generator will have
the capability to recognize the annotation and auto-detect possible values for an enum.

## Motivation

<!--
Expand All @@ -180,22 +185,130 @@ demonstrate the interest in a KEP within the wider Kubernetes community.
[experience reports]: https://github.com/golang/go/wiki/ExperienceReports
-->

Currently, types that are actually enums are represented as plain strings. For example,
here is the definition of `Protocol`, which must be one of `TCP`, `UDP`, and `SCTP`.
```go
package core
// ...

// Protocol defines network protocols supported for things like container ports.
type Protocol string

const (
// ProtocolTCP is the TCP protocol.
ProtocolTCP Protocol = "TCP"
// ProtocolUDP is the UDP protocol.
ProtocolUDP Protocol = "UDP"
// ProtocolSCTP is the SCTP protocol.
ProtocolSCTP Protocol = "SCTP"
)


// ContainerPort represents a network port in a single container
type ContainerPort struct {
// ...

// Required: Supports "TCP", "UDP" and "SCTP"
// +optional
Protocol Protocol

// ...
}
```

In order to convey that the `Protocol` type is an enum, a comment stating its values
will be needed every time a type refers the field, like `ContainerPort` does.
Validation code needs to check the actual value is one of the defined possible ones,
and UI-based tools cannot recognize it as an enum or display a dropdown for the field.

Users, API authors, and maintainers of third-party tools can reduce their maintenance
cost and adaptation friction due to the improved expressiveness of many enum types.

### Goals

<!--
List the specific goals of the KEP. What is it trying to achieve? How will we
know that this has succeeded?
-->

- Add an annotation that indicates a field as an enum.
- Make the Kubernetes OpenAPI generator recognize the annotation.
- Auto-detect possible values of an enum types.

### Non-Goals

<!--
What is out of scope for this KEP? Listing non-goals helps to focus discussion
and make progress.
-->

This KEP does not require removal of existing validation of enum types. While OpenAPI-based
of enum types can simplify this type of validation, retiring custom-made validations is out
of scope.

This proposal does not intend to change the enum syntax for third-party tools like `kubebuilder`.
The implementation should only suggest changes to internal APIs.

## Proposal

As part of the OpenAPI v3 KEP, when generating OpenAPI schema,
the de facto enum types should be reflected as enums in the resulting schema.
We define enum types with following properties:
- All enum types are closed, i.e., the type defines
a finite number of possible values.
- All enum types should be string. There can be no enum integers, floats, etc

Additionally, This KEP makes the following assumptions on the implementation:
- All enum types have their own type alias. i.e. , no raw string enums.
- The canonical definition of a type is written in go and follows the standard
Kubernetes convention.

### Enum Pattern

The Enum Pattern of a type, appearing in a go source file, is defined as follows:
```go
package internal

// FooType define sa type alias, underlying type must be string
type FooType string

// in the same package, define constants with the alias
const (
BarConst FooType = "Bar"
BazConst FooType = "Baz"
)

// in one or more resources or nested objects, one of the field is of
// the defined alias type.

// ExampleResource should refer FooType
type ExampleResource struct {
FooField FooType
}

```

### Enum Tag
The Enum Tag is the annotation `// +enum` that must be in the closest comment blocks
of an enum type following Enum Pattern.

```go
package internal

// FooType define sa type alias, underlying type must be string
// +enum
type FooType string
```

An actual example looks like
```go
package core

// Protocol defines network protocols supported for things like container ports.
// +enum
type Protocol string
```

<!--
This is where we get down to the specifics of what the proposal actually is.
This should have enough detail that reviewers can understand exactly what
Expand All @@ -205,19 +318,6 @@ The "Design Details" section below is for the real
nitty-gritty.
-->

### User Stories (Optional)

<!--
Detail the things that people will be able to do if this KEP is implemented.
Include as much detail as possible so that people can understand the "how" of
the system. The goal here is to make this feel real for users without getting
bogged down.
-->

#### Story 1

#### Story 2

### Notes/Constraints/Caveats (Optional)

<!--
Expand All @@ -241,6 +341,7 @@ How will UX be reviewed, and by whom?
Consider including folks who also work outside the SIG or subproject.
-->


## Design Details

<!--
Expand Down
24 changes: 8 additions & 16 deletions keps/sig-api-machinery/2887-openapi-enum-types/kep.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,17 @@ authors:
- "@jiahuif"
owning-sig: sig-api-machinery
participating-sigs: []
status: provisional
status: implementable
creation-date: 2021-08-20
reviewers:
- TBD
- '@jpbetz'
- '@apelisse'
approvers:
- TBD
- '@jpbetz'

##### WARNING !!! ######
# prr-approvers has been moved to its own location
# You should create your own in keps/prod-readiness
# Please make a copy of keps/prod-readiness/template/nnnn.yaml
# to keps/prod-readiness/sig-xxxxx/00000.yaml (replace with kep number)
#prr-approvers:

see-also: [] #TBD
replaces:
see-also:
- https://github.com/kubernetes/enhancements/issues/2896
replaces: []

# The target maturity stage in the current dev cycle for this KEP.
stage: alpha
Expand All @@ -32,16 +27,13 @@ latest-milestone: "v1.23"
# The milestone at which this feature was, or is targeted to be, at each stage.
milestone:
alpha: "v1.23"
beta: "v1.24"
stable: "v1.25"

# The following PRR answers are required at alpha release
# List the feature gate name and the components for which it must be enabled
feature-gates:
- name: OpenAPIEnumTypes
- name: OpenAPIv3Enabled # inherited from the main KEP, #2896
components:
- kube-apiserver
- kube-controller-manager
disable-supported: true

# The following PRR answers are required at beta release
Expand Down

0 comments on commit cc9d300

Please sign in to comment.