Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Alternate API representations for resources #123

Merged
merged 1 commit into from
Oct 12, 2017

Conversation

smarterclayton
Copy link
Contributor

Supports server side handling of transformation of resources.

From kubernetes/kubernetes#33900

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Dec 1, 2016
which would authorization
* We wish to support retrieving object representations in multiple schemas - JSON for
simple clients and Protobuf for clients concerned with efficiency.
* Most clients will wish to retrieve the more efficient / simpler object, but for
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "more efficient" == "simpler"? This seems to contradict with the bullet point above.

there are at least 6 known web-ui or CLI implementations that need to display some
information about third party resources or additional API groups registered with a server
without requiring each of them to change. Providing a server side implementation will
allow clietns to retrieve meaningful information for the `get` and `describe` style
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo

to a particular resource in a given namespace should be limited regardless of
the representation in use.
* Allowing "all namespaces" to be listed would require us to create "fake" resources
which would authorization
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

require?

}
}

200 OK
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this section forgotten copy/paste from the GET example above? Or is this supposed to be the reply to the PUT (in which case "replicas" should be 2)?


| Name | Value | Default | Description |
| ---- | ----- | ------- | ----------- |
| kind | The kind of parameters being sent | `ListOptions` (GET), `DeleteOptions` (DELETE) | The kind of the serialized struct, defaults to ListOptions on GET and DeleteOptions on DELETE. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now also have GetOptions. Have we considered merging with ListOptions? Why do we need two separate *Options for listing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't allow filtering of a Get via labels or fields today. It's possible we might in the future. Not required here.

@smarterclayton
Copy link
Contributor Author

Updated with all outstanding feedback and one additional suggestion from @liggitt to have a "shortcut" for common media types, which would show up in swagger (making it easier to discover new types).

Prototype of server side GET is in kubernetes/kubernetes#40848 and helped refine some of the options here. A proposal for server side GET will follow shortly.

metadata needed by the generic Garbage Collector or the Namespace Lifecycle Controller
* Dealing with generic operations like `Scale` correctly from a client across multiple API
groups, versions, or servers
* Return a simple tabular representation of an object or list of objects for naive
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From all the use cases described here, this one seems wrong to me. I'm not gonna block this proposal on it, but I find it hard to reason about it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we could suggest clients which fields are mandatory and which contains extended data as a sort of annotation in the openapi spec (if possible), instead doing this? I'm worried this will cause us some headaches in the long run.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another benefit of the approach I'm proposing is the ease of using that information with TPR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of our fields are simple. If you look at get describers, the location of that code is arbitrarily in kubectl, but it really belongs on the server. You don't have to use that format, but most clients want it. OpenAPI isn't enough for the use cases we have today, but yes, simple implementations could exist. But having them on the client isn't really helping.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, comment on the GET proposal.

we introduce the `api.k8s.io` group with version `v1` that grandfathers all existing resources
currently described as "unversioned". A generic client may request that responses be applied
in this version. The contents of a particular API group version would continue to be bound into
other group versions (`status.v1.api.k8s.io` would be bound as `Status` into all existing
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why status.v1.api.k8s.io and not status.api.k8s.io/v1? Seems odd to have the version number being part of the group name, or am I missing something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just arbitrary representation.

@derekwaynecarr
Copy link
Member

Is it worth calling out any special behavior if you do a watch?

For example, do tabular formats not repeat column headers?

For things like kubectl --output=wide, is that an entirely different representation and media type I assume?

@smarterclayton
Copy link
Contributor Author

See the get proposal.

@soltysh
Copy link
Contributor

soltysh commented Feb 22, 2017

I'll move my comments to get proposal, this LGTM.

@bgrant0607
Copy link
Member

cc @pwittrock

Copy link
Member

@lavalamp lavalamp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems really close to being ready, sorry it took me so long to look at it.

* Return a simple tabular representation of an object or list of objects for naive
web or command-line clients to display (for `kubectl get`)
* Return a simple description of an object that can be displayed in a wide range of clients
(for `kubectl describe`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you intend to allow server-side fan out? Or just express links in a way easy for clients to follow.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the foreseeable future, client side fan out. Maybe someone could write a describe-o-lator that aggregates.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

might be good to directly state that.

web or command-line clients to display (for `kubectl get`)
* Return a simple description of an object that can be displayed in a wide range of clients
(for `kubectl describe`)
* Return the object with fields set by the server cleared (as `kubectl export`)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Defaults are easy, but what about fields set by other system components? Knowing the list of fields to clear seems hard.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Export was described in kubernetes/kubernetes#24855 and initial implementation was done in kubernetes/kubernetes#17483

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List of field has to be on the server side and vary by type. We have lots of cases where base export is insufficient (the context of what scope to extract - namespace, cluster, version of Kube needs to be also provided).

parameters or media type parameters.

In order to ensure that generic clients can properly deal with many different group versions,
we introduce the `api.k8s.io` group with version `v1` that grandfathers all existing resources
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did this evolve into the meta group?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, will update

which would complicate authorization
* We wish to support retrieving object representations in multiple schemas - JSON for
simple clients and Protobuf for clients concerned with efficiency.
* Most clients will wish to retrieve a newer format, but for older servers will desire
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for clarity, in particular, you're not suggesting we remove the version from the URL path for resources, nor that we add it for subresources.

Are you saying that a resource with the version in the path should actually still accept/return multiple versions? It would be really hard to explain that to people.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the challenge is something like Scale:

  1. Scale has a server wide version that we version independent of a resource like a pod
  2. Adding v2 pod does not mean that v2 scale is added
  3. The version number in the path applies to the primary object, but all sub resources have no mechanism to control version

I think it would be unusual to say GET /api/v1/namespace/foo/pods/bar -H "Accept: ... as v2". But not unusual to say GET /api/v1/namespace/foo/pods/bar/resources -H "Accept: as resourcesv1.Scale"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, we're in violent agreement.

| as | Kind name | None | If specified, transform the resource into the following kind (including the group and version parameters). |
| sv | The server group (`api.k8s.io`) version that should be applied to generic resources returned by this endpoint | Matching server version for the current group and version | If specified, the server should transform generic responses into this version of the server API group. |
| export | `1` | None | If specified, transform the resource prior to returning to omit defaulted fields. Additional arguments allowed in the query parameter. For legacy reasons, `?export=1` will continue to be supported on the request |
| pretty | `0`/`1` | `1` | If specified, apply formatting to the returned response that makes the serialization readable (for JSON, use indentation) |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you illustrate more combinations of these in the list below?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or any combinations, actually, since the list below is for shortcuts.

| Name | Value | Default | Description |
| ---- | ----- | ------- | ----------- |
| kind | The kind of parameters being sent | `ListOptions` (GET), `DeleteOptions` (DELETE) | The kind of the serialized struct, defaults to ListOptions on GET and DeleteOptions on DELETE. |
| apiVersion | The API version of the parameter struct | `api.k8s.io/v1` | May be altered to match the expected version. Because we have not yet versioned ListOptions, this is safe to alter. |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These need clearer names. No one is going to expect that these refer to the options rather than the data. I suggest optionsVersion. It's not obvious that we'll need to overload the kind? Maybe we can reserve the appropriate name and say we'll implement it in the future if a use case appears.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reservation sounds good - I'd like to reserve both to prevent use. This isn't strictly necessary now, but design of body = query equivalence is well established, and i would prefer not to clutter our endpoints with flags and arguments that mutate returned object for as long as we can.

a few limited subsets, and thus retrieving an object into a few known schemas can be made
much more efficient. In addition, arbitrary transformation of the object provides
opportunities for supporting forward "partial" migration - for instance, returning a
ReplicationController as a ReplicaSet to simplify a transition across resource types.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also it's a bad idea to generalize without a few concrete implementations. We can always add this later, but adding it now would sign us up for a lot of maintenance costs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah not proposing to add now, just examples.

@bgrant0607
Copy link
Member

@erictune Had a suggestion that maybe we could put info into OpenAPI or our discovery API that would enable generic get+describe rendering in kubectl. Computations currently done in the client, such as printPodBase, would still have to move to API fields, of course.

@erictune
Copy link
Member

erictune commented Mar 16, 2017

We could also have conventions that we document, and clients can implement, like:

  • for all objects, show metadata.name
  • if showing multiple namespaces, show metadata.namespace
  • if the object has a /scale subresource then show replicas as a column.

A couple of things I like about this approach

  • If we add subresource support to TPRs, then people will get useful columns for their subresources without needing to think about implementing a server side getter.
  • We should add more subresources like /readiness and /completion, which would partly address Proposal: Introduce Available Pods (MinReadySeconds in the PodSpec) #194. As we add those, then AAs or TPRs that have that subresource get useful columns without writing server side getter code.

@bgrant0607
Copy link
Member

Related: kubernetes/kubernetes#34363

In general, many generic clients need to reason about the K8s API at a meta level, not just kubectl.

@smarterclayton
Copy link
Contributor Author

Need to merge this.

@lavalamp
Copy link
Member

lavalamp commented Jun 4, 2017

I think I was waiting for a couple updates promised above? :)

@smarterclayton
Copy link
Contributor Author

Updated with all outstanding feedback (mostly just clarifications).

@bgrant0607
Copy link
Member

cc @kubernetes/sig-cli-proposals @kubernetes/sig-api-machinery-proposals

@k8s-ci-robot k8s-ci-robot added sig/cli Categorizes an issue or PR as relevant to SIG CLI. kind/design Categorizes issue or PR as related to design. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. labels Oct 3, 2017
@bgrant0607 bgrant0607 mentioned this pull request Oct 7, 2017
@castrojo
Copy link
Member

This change is Reviewable

* ???


<!-- BEGIN MUNGE: GENERATED_ANALYTICS -->
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The url is wrong.

I think we've given up on analytics for these docs and could just delete this.

### Old servers

Because old Kubernetes servers are not selective about the content type parameters they
accept, we may wish to patch the 1.3 and 1.4 server versions to explicitly bypass content
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we still considering patching older releases? Anyway, we should delete the concrete numbers.

@bgrant0607
Copy link
Member

I made a couple minor comments, but think we should merge ASAP and iterate if necessary, since this is already implemented.

Supports server side handling of transformation of resources.
@smarterclayton
Copy link
Contributor Author

Updated

@bgrant0607
Copy link
Member

thanks
/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Oct 12, 2017
@k8s-github-robot
Copy link

Automatic merge from submit-queue.

@k8s-github-robot k8s-github-robot merged commit 65ef42f into kubernetes:master Oct 12, 2017
rmohr pushed a commit to rmohr/community that referenced this pull request May 4, 2022
…on. (kubernetes#123)

New draft created per discussion with Fabian and David.
Update per feedback from Dan.
Removed inactive maintainers per Fabian.
Added new maintainers per Fabian and Roman.

Signed-off-by: Josh Berkus <[email protected]>
danehans pushed a commit to danehans/community that referenced this pull request Jul 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/design Categorizes issue or PR as related to design. lgtm "Looks good to me", indicates that a PR is ready to be merged. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/cli Categorizes an issue or PR as relevant to SIG CLI. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants