Merge pull request #308 from pwittrock/get-describe-extensions
`kubectl get` and `kubectl describe` extensions
This commit is contained in:
commit
fb47a5a871
|
@ -0,0 +1,192 @@
|
||||||
|
# Provide open-api extensions for kubectl get / kubectl describe columns
|
||||||
|
|
||||||
|
Status: Pending
|
||||||
|
|
||||||
|
Version: Alpha
|
||||||
|
|
||||||
|
## Motivation
|
||||||
|
|
||||||
|
`kubectl get` and `kubectl describe` do not provide a rich experience
|
||||||
|
for resources retrieved through federated apiservers and types not
|
||||||
|
compiled into the kubectl binary. Kubectl should support printing
|
||||||
|
columns configured per-type without having the types compiled in.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
Allow the apiserver to define the type specific columns that will be
|
||||||
|
printed using the open-api swagger.json spec already fetched by kubectl.
|
||||||
|
This provides a limited describe to only print out fields on the object
|
||||||
|
and related events.
|
||||||
|
|
||||||
|
**Note:** This solution will only work for types compiled into the apiserver
|
||||||
|
providing the open-api swagger.json to kubectl. This solution will
|
||||||
|
not work for TPR, though TPR could possibly be solved in a similar
|
||||||
|
way by apply an annotation with the same key / value to the TPR.
|
||||||
|
|
||||||
|
## User Experience
|
||||||
|
|
||||||
|
### Use Cases
|
||||||
|
|
||||||
|
- As a user, when I run `kubectl get` on sig-service-catalog resources
|
||||||
|
defined in a federated apiserver, I want to see more than just the
|
||||||
|
name and the type of the resource.
|
||||||
|
- As a user, when I run `kubectl describe` on sig-service-catalog
|
||||||
|
resources defined in a federated apiserver, I want the command
|
||||||
|
to succeed, and to see events for the resource along with important
|
||||||
|
fields of the resource.
|
||||||
|
|
||||||
|
## Implementation
|
||||||
|
|
||||||
|
Define the open-api extensions `x-kubernetes-kubectl-get-columns` and
|
||||||
|
`x-kubernetes-kubectl-describe-columns`. These extensions have a
|
||||||
|
string value containing the columns to be printed by kubectl. The
|
||||||
|
string format is the same as the `--custom-columns` for `kubectl get`.
|
||||||
|
|
||||||
|
### Apiserver
|
||||||
|
|
||||||
|
- Populate the open-api extension value for resource types.
|
||||||
|
|
||||||
|
This is done by hardcoding the extension for types compiled into
|
||||||
|
the api server. As such this is only a solution for types
|
||||||
|
implemented using federated apiservers.
|
||||||
|
|
||||||
|
### Kubectl
|
||||||
|
|
||||||
|
Overview:
|
||||||
|
|
||||||
|
- In `kubectl get` use the `x-kubernetes-kubectl-get-columns` value
|
||||||
|
when printing an object iff 1) it is defined and 2) the output type
|
||||||
|
is "" (empty string) or "wide".
|
||||||
|
|
||||||
|
- In `kubectl describe` use the `x-kubernetes-kubectl-describe-columns` value
|
||||||
|
when printing an object iff 1) it is defined
|
||||||
|
|
||||||
|
|
||||||
|
#### Option 1: Re-parse the open-api swagger.json in a kubectl library
|
||||||
|
|
||||||
|
Re-parse the open-api swagger.json schema and build a map of group version kind -> columns
|
||||||
|
parsed from the schema. For this would look similar to validation/schema.go
|
||||||
|
|
||||||
|
In get.go and describe.go: After fetching the "Infos" from the
|
||||||
|
resource builder, lookup the group version kind from the populated map.
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Simple and straightforward solution
|
||||||
|
- Scope of impacted Kubernetes components is minimal
|
||||||
|
- Doable in 1.6
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- Hacky solution
|
||||||
|
- Can not be cleanly extended to support TPR
|
||||||
|
|
||||||
|
#### Option 2: Modify api-machinery RestMapper
|
||||||
|
|
||||||
|
Modify the api-machinery RestMapper to parse extensions prefixed
|
||||||
|
with `x-kubernetes` and include them in the *RestMapping* used by the resource builder.
|
||||||
|
|
||||||
|
```go
|
||||||
|
type RESTMapping struct {
|
||||||
|
// Resource is a string representing the name of this resource as a REST client would see it
|
||||||
|
Resource string
|
||||||
|
|
||||||
|
GroupVersionKind schema.GroupVersionKind
|
||||||
|
|
||||||
|
// Scope contains the information needed to deal with REST Resources that are in a resource hierarchy
|
||||||
|
Scope RESTScope
|
||||||
|
|
||||||
|
runtime.ObjectConvertor
|
||||||
|
MetadataAccessor
|
||||||
|
|
||||||
|
// Extensions
|
||||||
|
ApiExtensions ApiExtensions
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApiExtensions struct {
|
||||||
|
Extensions map[string]interface{}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The tags would then be easily accessible from the kubectl get / describe
|
||||||
|
functions through: `resource.Builder -> Infos -> Mapping -> DisplayOptions`
|
||||||
|
|
||||||
|
**Pros:**
|
||||||
|
- Clean + generalized solution
|
||||||
|
- The same strategy can be applied to support TPR
|
||||||
|
- Can support exposing future extensions such as patchStrategy and mergeKey
|
||||||
|
- Can be used by other clients / tools
|
||||||
|
|
||||||
|
**Cons:**
|
||||||
|
- Fields are only loosely tied to rest
|
||||||
|
- Complicated due to the broad scope and impact
|
||||||
|
- May not be doable in 1.6
|
||||||
|
|
||||||
|
#### Considerations
|
||||||
|
|
||||||
|
What should be used for oth an open-api extension columns tag AND a
|
||||||
|
compiled in printer exist for a type?
|
||||||
|
|
||||||
|
- Apiserver only provides `describe` for types that are never compiled in
|
||||||
|
- Compiled in `describe` is much more rich - aggregating data across many other types.
|
||||||
|
e.g. Node describe aggregating Pod data
|
||||||
|
- kubectl will not be able to provide any `describe` information for new types when version skewed against a newer server
|
||||||
|
- Always use the extensions if present
|
||||||
|
- Allows server to control columns. Adds new columns for types on old clients that maybe missing the columns.
|
||||||
|
- Always use the compiled in commands if present
|
||||||
|
- The compiled in `describe` is richer and provides aggregated information about many types.
|
||||||
|
- Always use the `get` extension if present. Always use the `describe` compiled in code if present.
|
||||||
|
- Inconsistent behavior across how extensions are handled
|
||||||
|
|
||||||
|
### Client/Server Backwards/Forwards compatibility
|
||||||
|
|
||||||
|
#### Newer client
|
||||||
|
|
||||||
|
Client doesn't find the open-api extensions. Fallback on 1.5 behavior.
|
||||||
|
|
||||||
|
In the future, this will provide stronger backwards / forwards compability
|
||||||
|
as it will allow clients to print objects
|
||||||
|
|
||||||
|
#### Newer server
|
||||||
|
|
||||||
|
Client doesn't respect open-api extensions. Uses 1.5 behavior.
|
||||||
|
|
||||||
|
## Alternatives considered
|
||||||
|
|
||||||
|
### Fork Kubectl and compile in go types
|
||||||
|
|
||||||
|
Fork kubectl and compile in the go types. Implement get / describe
|
||||||
|
for the new types in the forked version.
|
||||||
|
|
||||||
|
**Pros:** *This is what will happen for sig-service catalog if we take no action in 1.6*
|
||||||
|
|
||||||
|
**Cons:** Bad user experience. No clear solution for patching forked kubectl.
|
||||||
|
User has to use a separate kubectl binary per-apiserver. Bad president.
|
||||||
|
|
||||||
|
I really don't want this solution to be used.
|
||||||
|
|
||||||
|
### Kubectl describe fully implemented in the server
|
||||||
|
|
||||||
|
Implement a sub-resource "/describe" in the apiserver. This executes
|
||||||
|
the describe business logic for the object and returns either a string
|
||||||
|
or json blob for kubectl to print.
|
||||||
|
|
||||||
|
**Pros:** Higher fidelity. Can aggregate data and fetch other objects.
|
||||||
|
|
||||||
|
**Cons:** Higher complexity. Requires more api changes.
|
||||||
|
|
||||||
|
### Write per-type columns to kubectl.config or another local file
|
||||||
|
|
||||||
|
Support checking a local file containing per-type information including
|
||||||
|
the columns to print.
|
||||||
|
|
||||||
|
**Pros:** Simplest solution. Easy for user to override values.
|
||||||
|
|
||||||
|
**Cons:** Requires manual configuration on user side. Does not provide a consistent experience across clients.
|
||||||
|
|
||||||
|
### Write per-type go templates to kubectl.config or another local file
|
||||||
|
|
||||||
|
Support checking a local file containing per-type information including
|
||||||
|
the go template.
|
||||||
|
|
||||||
|
**Pros:** Higher fidelity. Easy for user to override values.
|
||||||
|
|
||||||
|
**Cons:** Higher complexity. Requires manual configuration on user side. Does not provide a consistent experience across clients.
|
Loading…
Reference in New Issue