summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhillip Wittrock <pwittroc+github@google.com>2017-06-01 09:59:18 -0700
committerGitHub <noreply@github.com>2017-06-01 09:59:18 -0700
commitfb47a5a8716b735511e6ae643170f09d2e250c4d (patch)
tree144f4a5edd2f350e13d3e1e3638e4bdca2472df6
parent3a1e6d22f812751ee88eccf7c59101852de63d5b (diff)
parentaf507712b9160ed43f47d378fe9505e35783c51d (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.md192
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.