6.6 KiB
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 thex-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 thex-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.
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
- Compiled in
- 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.
- The compiled in
- Always use the
get
extension if present. Always use thedescribe
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.