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

Expose versioned query parameters and make watch an operation on List #5763

Merged

Conversation

smarterclayton
Copy link
Contributor

Sub-resources are needed to properly secure proxying to the node (as per agreement in authz discussions), because we need to tie "resource" and "verb" to an action. The /proxy endpoint is too open to give to anyone but cluster admins. As part of #3481 and the general "bastioning" of the API server, we want to introduce new sub resources that allow specific, typed access to a backend. Examples:

  • Proxy to a pod's port: /pods/foo/proxy/5000/some/resource
  • Proxy to a service's port: /services/foo/proxy/5000/some/resource/path
  • Expose logs for a pod: /pods/foo/logs?container=test -> returns "text/plain" stream
  • Expose logs for a resource backed by a pod /jobs/foo/logs ->
  • Parameterize pod logs with query options: /pods/foo/logs?container=test&since=30s
  • Handle remote execution: /pods/foo/exec?container=test&cmd=/bin/bash&arg=-c&arg=echo+$foo -> upgrades connection to SPDY/HTTP2
  • Handle portforwarding: /pods/foo/portforward/5000?container=test
  • Allow binaries to be posted to an endpoint (with a given type) and converted by RESTStorage or apiserver into the underlying object - essentially hand off the request body to storage.

This requires three pieces of function:

  • Allow query parameters to be properly versioned across a set of distinct resources and verbs
  • Return an input stream from a RESTStorage Get or Post call
  • Upgrade an HTTP connection to a higher protocol (exec) or hijack it (port forward) or use it to proxy other requests (proxy)

Ideally we would also ensure we have methods that allow proper introspection through swagger

  • Handle content type negotiation when returning an input stream
  • Annotate request parameters with metadata for query params

This pull request will contain the changes to enable that functionality through a set of targeted refactors. @csrwng @lavalamp @bgrant0607 @liggitt

@googlebot
Copy link

Thanks for your pull request.

It looks like this may be your first contribution to a Google open source project, in which case you'll need to sign a Contributor License Agreement (CLA) at https://cla.developers.google.com/.

If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check the information on your CLA or see this help article on setting the email on your git commits.

Once you've done that, please reply here to let us know. If you signed the CLA as a corporation, please let us know the company's name.

@smarterclayton smarterclayton changed the title WIP - Handle versioning query parameters via conversions WIP - Enable apiserver to handle more types of input and output Mar 22, 2015
@smarterclayton smarterclayton force-pushed the get_input_parameters_versioned branch 2 times, most recently from d1e7208 to 7382414 Compare March 23, 2015 03:08
@smarterclayton
Copy link
Contributor Author

A bunch of these commits are in other pulls, only the last few are specific.

@bgrant0607
Copy link
Member

I just have to ref. #3652. :-)

@smarterclayton
Copy link
Contributor Author

This pull request now changes watch from being a separate resource (although it's still exposed for legacy purposes at the old paths) to GET /api/v1beta1/pods?watch=true&resourceVersion=10. I will change the v1beta3 clients to handle this behavior.

@@ -28,12 +30,48 @@ import (
var Codec = runtime.CodecFor(Scheme, "")

func init() {
Scheme.AddDefaultingFuncs(
Copy link
Member

Choose a reason for hiding this comment

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

Why is this necessary? I'd like to nuke this whole file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Smart defaulting for ListOptions deserialized from an incoming request. Rather than make all people using it set those to empty and risk doing something wrong.

----- Original Message -----

@@ -28,12 +30,48 @@ import (
var Codec = runtime.CodecFor(Scheme, "")

func init() {

  • Scheme.AddDefaultingFuncs(

Why is this necessary? I'd like to nuke this whole file.


Reply to this email directly or view it on GitHub:
https://github.com/GoogleCloudPlatform/kubernetes/pull/5763/files#r27089694

@@ -23,6 +23,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
)

// TODO: move me to pkg/api/meta
Copy link
Member

Choose a reason for hiding this comment

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

What belongs in pkg/runtime vs. elsewhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Originally pkg/runtime was an opinionated part of conversion. Things strictly related to decoding generic objects in JSON showed up here. I think where we are today is that we want to have the core "smart object" model (pkg/smartobjects) which can do defaulting, conversion, new, etc, and then a set of serialization choices (JSON, query, protobufs, msgpack, whatever) laid on top of that (orthogonal to). The things in pkg/runtime that relate to the "scheme" (conversion, defaults) should move to smart objects. The things related to JSON serialization should be split out. I'm still torn on what we should do w.r.t. interfaces for helpful methods.

Ideally, I would think the smart objects code would have the ability to generate boilerplate helper methods (like ObjectMeta() or SetObjectMeta(...)) to your scheme. That would reduce the amount of code in api/meta (which is really about just having a common interface on all of our api objects to get and set metadata). We had just balked at adding one getter per type as being painful and hadn't got further.

@bgrant0607
Copy link
Member

I'm basically ok with the changes in this PR so far.

I'm also 100% on board with the shift towards subresources as opposed to API prefixes, and am more or less ok with the proposed API paths.

The difference between proxy and portforward is http vs. tcp? Why does portforward need a container name and not just a port? Do you also intend to support fd forwarding, for stdin/stdout/stderr (aka attach - #1521)?

I'd like to see an /endpoints subresource on services, pods, and nodes, and perhaps even on replication controllers. I could see proxy, etc. building upon that functionality.

An argument could be made that we should put the container name in the path, such as /pods/foo/containers/test/logs. Container subresources have been proposed before -- #1900. We don't necessarily need to allow mutation via that path right now, however.

We could similarly put ports in the path: /pods/foo/ports/5000.

Not directly related to this PR, but for proxy, we'll need to resolve the problems mentioned in #4440 at some point. The rewriting performed by the golang library only works for links within the same server, but not for links to other intra-cluster resources.

@smarterclayton
Copy link
Contributor Author

The difference between proxy and portforward is http vs. tcp?

Yes I think so

Why does portforward need a container name and not just a port?

Good point, port is sufficient

Do you also intend to support fd forwarding, for stdin/stdout/stderr (aka attach - #1521)?

Exec does. One problem with all "upgrade" endpoints is that you have to full represent your request via query parameters or request headers, or you have to introduce custom client framing into the connection establishment protocol. It was non-obvious what the best solution was (an example is passing a remote exec that has a massive argument list - 64kb or more, which exceeds the amount of data you'll be able to send via headers even in http2).

An argument could be made that we should put the container name in the path, such as /pods/foo/containers/test/logs. Container subresources have been proposed before -- #1900. We don't necessarily need to allow mutation via that path right now, however.

It should be possible in api_installer to extract the subpath for a sub resource (below it) and pass that into the sub resource. Just hadn't hit the use case yet.

@smarterclayton smarterclayton changed the title WIP - Enable apiserver to handle more types of input and output Expose versioned query parameters and make watch an operation on List Mar 25, 2015
@smarterclayton
Copy link
Contributor Author

Comments addressed, ptal

@smarterclayton
Copy link
Contributor Author

poke :)

@bgrant0607
Copy link
Member

LGTM.

(Sorry, was OOO yesterday).

Needs to be rebased, unfortunately.

@bgrant0607 bgrant0607 added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 26, 2015
Convert url.Values -> an object, with appropriate versioning. ListOptions
should also expose parameter names to swagger.
    GET /pods?watch=true&resourceVersion=10

will now function equivalent to GET /watch/pods.
Formalize v1beta1 and v1beta3 style APIs in our test cases.
@smarterclayton
Copy link
Contributor Author

Travis was a flake.

@bgrant0607
Copy link
Member

Merging.

@@ -14,6 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

// TODO: move everything in this file to pkg/api/rest
Copy link
Contributor

Choose a reason for hiding this comment

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

@smarterclayton Sorry to refer this old PR and disturb you. I saw this todo and want to fix it, but I didn't catch why this file belongs to rest package, not meta package? Could you explain this? Thanks very much!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will try to respond tomorrow

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/api Indicates an issue on api area. area/apiserver lgtm "Looks good to me", indicates that a PR is ready to be merged.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants