diff options
| author | Phillip Wittrock <pwittroc+github@google.com> | 2017-06-01 09:59:18 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2017-06-01 09:59:18 -0700 |
| commit | fb47a5a8716b735511e6ae643170f09d2e250c4d (patch) | |
| tree | 144f4a5edd2f350e13d3e1e3638e4bdca2472df6 | |
| parent | 3a1e6d22f812751ee88eccf7c59101852de63d5b (diff) | |
| parent | af507712b9160ed43f47d378fe9505e35783c51d (diff) | |
Merge pull request #308 from pwittrock/get-describe-extensions
`kubectl get` and `kubectl describe` extensions
| -rw-r--r-- | contributors/design-proposals/sig-cli/get-describe-apiserver-extensions.md | 192 |
1 files changed, 192 insertions, 0 deletions
diff --git a/contributors/design-proposals/sig-cli/get-describe-apiserver-extensions.md b/contributors/design-proposals/sig-cli/get-describe-apiserver-extensions.md new file mode 100644 index 00000000..42884990 --- /dev/null +++ b/contributors/design-proposals/sig-cli/get-describe-apiserver-extensions.md @@ -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. |
