summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClayton Coleman <ccoleman@redhat.com>2017-02-12 22:30:38 -0500
committerClayton Coleman <ccoleman@redhat.com>2017-05-11 12:57:22 -0400
commit550ae37a5b2064215cbef135cd72a2f1769685ce (patch)
tree79b9795798f0f213de3da9d2c3ac6d1accfdde2b
parent26d03a097ffc3dd8cadbdbd154fd55659434367e (diff)
Server-side get proposal
Discuss how to move `kubectl get` to the server.
-rw-r--r--contributors/design-proposals/server-get.md183
1 files changed, 183 insertions, 0 deletions
diff --git a/contributors/design-proposals/server-get.md b/contributors/design-proposals/server-get.md
new file mode 100644
index 00000000..fb508a3c
--- /dev/null
+++ b/contributors/design-proposals/server-get.md
@@ -0,0 +1,183 @@
+# Expose `get` output from the server
+
+Today, all clients must reproduce the tabular and describe output implemented in `kubectl` to perform simple lists
+of objects. This logic in many cases is non-trivial and condenses multiple fields into succinct output. It also requires
+that every client provide rendering logic for every possible type, including those provided by API aggregation or third
+party resources which may not be known at compile time.
+
+This proposal covers moving `get` and `describe` to the server to reduce total work for all clients and centralize these
+core display options for better reuse and extension.
+
+
+## Background
+
+`kubectl get` is a simple tabular representation of one or more instances of a particular resource type. It is the primary
+listing mechanism and so must be implemented for each type. Today, we have a single generic implementation for unrecognized
+types that attempts to load information from the `metadata` field (assuming the object follows the metav1 Kubernetes API
+schema). `get` supports a `wide` mode that includes additional columns. Users can add additional columns for labels via a
+flag. Headers corresponding to the columns are optionally displayed.
+
+`kubectl describe` shows a textual representation of individual objects that describes individual fields as subsequent
+lines and uses indendation and nested tables to convey deeper structure on the resource (such as events for a pod or
+each container). It sometimes retrieves related objects like events, pods for a replication controller, or autoscalers
+for a deployment. It supports no significant flags.
+
+The implementation of both is modeled as a registered function that takes an object or list of objects and outputs
+semi-structured text.
+
+## Goals
+
+* Make it easy for a simple client to get a list of resources for a web UI or CLI output
+* Support all existing options, leave open the door for future extension and experimentation
+* Allow new API extensions and third party resources to be implemented server side, removing the need to version
+ schemes for retrieving data from the server
+* Keep implementation of `get` and `describe` simple
+* Ease internationalization of `get` and `describe` output for all clients
+
+## Non-Goals
+
+* Deep customization of the returned output by the client
+
+
+## Specification of server-side `get`
+
+The server would return a `Table` object (working-name) that contains metadata for columns and one or more
+rows composed of cells for each column. Some additional data may be relevant for each row and returned by the
+server. Since every object should have a `Table` representation, treat this as part of content negotiation
+as described in [the alternative representations of objects proposal](alternate-api-representations.md).
+
+Example request:
+
+```
+$ curl https://localhost:8443/api/v1/pods -H "Accept: application/json+vnd.kubernetes.as+meta.k8s.io+v1alpha1+Table"
+{
+ "kind": "Table",
+ "apiVersion": "meta.k8s.io/v1alpha1",
+ "headers": [
+ {"name": "Name", "type": "string", "description": "The name of the pod, must be unique ..."},
+ {"name": "Status", "type": "string", "description": "Describes the current state of the pod"},
+ ...
+ ],
+ "items": [
+ {"cells": ["pod1", "Failed - unable to start", ...]},
+ {"cells": ["pod2", "Init 0/2", ...]},
+ ...
+ ]
+}
+```
+
+This representation is also possible to return from a watch. The watch can omit headers on subsequent queries.
+
+```
+$ curl https://localhost:8443/api/v1/pods?watch=1 -H "Accept: application/json+vnd.kubernetes.as+meta.k8s.io+v1alpha1+Table"
+{
+ "kind": "Table",
+ "apiVersion": "meta.k8s.io/v1alpha1",
+ // headers are printed first, in case the watch holds
+ "headers": [
+ {"name": "Name", "type": "string", "description": "The name of the pod, must be unique ..."},
+ {"name": "Status", "type": "string", "description": "Describes the current state of the pod"},
+ ...
+ ]
+}
+{
+ "kind": "Table",
+ "apiVersion": "meta.k8s.io/v1alpha1",
+ // headers are not returned here
+ "items": [
+ {"cells": ["pod1", "Failed - unable to start", ...]},
+ ...
+ ]
+}
+```
+
+It can also be returned in CSV form:
+
+```
+$ curl https://localhost:8443/api/v1/pods -H "Accept: text/csv+vnd.kubernetes.as+meta.k8s.io+v1alpha1+Table"
+Name,Status,...
+pod1,"Failed - unable to start",...
+pod2,"Init 0/2",...
+...
+```
+
+To support "wide" format, columns may be marked with an optional priority field of increasing integers (default
+priority 0):
+
+```
+{
+ "kind": "Table",
+ "apiVersion": "meta.k8s.io/v1alpha1",
+ "headers": [
+ ...
+ {"name": "Node Name", "type": "string", "description": "The node the pod is scheduled on, empty if the pod is not yet scheduled", "priority": 1},
+ ...
+ ],
+ ...
+}
+```
+
+To allow label columns, and to enable integrators to build effective UIs, each row may contain an `object` field that
+is either `PartialObjectMetadata` (a standard object containing only ObjectMeta) or the object itself. Clients may request
+this field be set by specifying `?includeObject=None|Metadata|Self` on the query parameter.
+
+```
+GET ...?includeObject=Metadata
+{
+ "kind": "Table",
+ "apiVersion": "meta.k8s.io/v1alpha1",
+ "items": [
+ ...
+ {"cells": [...], "object": {"kind": "PartialObjectMetadata", "apiVersion":"meta.k8s.io/v1alpha1", "metadata": {"name": "pod1", "namespace": "pod2", "labels": {"a": "1"}, ...}},
+ ...
+ ]
+}
+```
+
+The `Metadata` value would be the default. Clients that wish to print in an advanced manner may use `Self` to get the full
+object and perform arbitrary transformations.
+
+All fields on the server side are candidates for translation and localization changes can be delivered more
+quickly and to all clients.
+
+Third-party resources can more easily implement `get` in this fashion - instead of web dashboards and
+`kubectl` both implementing their own logic to parse a particular version of Swagger or OpenAPI, the server
+component performs the transformation. The server encapsulates the details of printing. Aggregated resources
+automatically provide this behavior when possible.
+
+
+### Specific features in `kubectl get`
+
+Feature | Implementation
+--- | ---
+sort-by | Continue to implement client-side (no server side sort planned)
+custom-column (jsonpath) | Implement client-side by requesting object `?includeObject=Self` and parsing
+custom-column (label) | Implement client-side by getting labels from metadata returned with each row
+show-kind | Implement client-side by using the discovery info associated with the object (rather than being returned by server)
+template | Implement client-side, bypass receiving table output and get raw objects
+watch | Request Table output via the watch endpoint
+export | Implement client-side, bypass receiving table output and get exported object
+wide | Server should indicate which columns are "additional" via a field on on the header column - client then shows those columns if it wants to
+color (proposed) | Rows which should be highlighted should have a semantic field on the row - e.g. `alert: [{type: Warning, message: "This pod has been deleted"}]`. Cells could be selected by adding an additional field `alert: [{type: Warning, ..., cells: [0, 1]}]`.
+
+
+## Future considerations
+
+* When we introduce server side paging, Table would be paged similar to how PodList or other types are paged. https://issues.k8s.io/2349
+* More advanced output could in the future be provided by an external call-out or an aggregation API on the server side.
+* `describe` could be managed on the server as well, with a similar generic format, and external outbound links used to reference other objects.
+
+
+## Migration
+
+Old clients will continue retrieving the primary representation. Clients can begin using the optional `Accept`
+header to indicate they want the simpler version, and if they receive a Table perform the new path, otherwise
+fall back to client side functions.
+
+Server side code would reuse the existing display functions but replace TabWriter with either a structured writer
+or the tabular form.
+
+
+<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
+[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/docs/proposals/server-get.md?pixel)]()
+<!-- END MUNGE: GENERATED_ANALYTICS -->