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

Allow kubectl get to fetch multiple resource types by label #3004

Merged

Conversation

smarterclayton
Copy link
Contributor

Like Delete, which can now run over multiple types:

kubectl delete pods,services -l name=foo

Get should be able to span items for label selection

kubectl get pods,services -l name=foo

Not yet complete, want feedback from @bgrant0607.

Follow up to #2751

@smarterclayton smarterclayton changed the title Allow kubectl get to fetch multiple resource types by label WIP - Allow kubectl get to fetch multiple resource types by label Dec 17, 2014
@smarterclayton smarterclayton force-pushed the allow_get_to_span_resources branch from f20c2f2 to 3bd6717 Compare December 18, 2014 00:26
@bgrant0607
Copy link
Member

@smarterclayton What exactly would you like feedback on at this point? I think the capability makes a lot of sense, and the example syntax looks fine (modulo the issue that -l increases confusion regarding the difference between labels and selectors, IMO).

I'd also like to be able to get all kinds of objects within a namespace matching a label selector, though that would require resolving #2057.

@smarterclayton
Copy link
Contributor Author

And #991. We could handle that with storing config locally for all the endpoints and resources we know about.

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

@smarterclayton What exactly would you like feedback on at this point? I
think the capability makes a lot of sense, and the example syntax looks fine
(modulo the issue that -l increases confusion regarding the difference
between labels and selectors, IMO).

I'd also like to be able to get all kinds of objects within a namespace
matching a label selector, though that would require resolving #2057.


Reply to this email directly or view it on GitHub:
#3004 (comment)

@smarterclayton
Copy link
Contributor Author

Have it now so that you can do:

kubectl get services,rc -l provider=kubernetes -o json

and get

{
    "kind": "List",
    "creationTimestamp": null,
    "apiVersion": "v1beta1",
    "items": [
        {
            "kind": "Service",
            "id": "kubernetes-ro",
            "uid": "cf26c187-86ff-11e4-95de-080027ce4245",
            "creationTimestamp": "2014-12-18T16:49:57-05:00",
            "selfLink": "/api/v1beta1/services/kubernetes-ro?namespace=default",
            "resourceVersion": 3,
            "apiVersion": "v1beta1",
            "namespace": "default",
            "port": 80,
            "protocol": "TCP",
            "labels": {
                "component": "apiserver",
                "provider": "kubernetes"
            },
            "selector": null,
            "containerPort": 0,
            "portalIP": "10.0.0.61"
        },
        {
            "kind": "Service",
            "id": "kubernetes",
            "uid": "cf27b128-86ff-11e4-95de-080027ce4245",
            "creationTimestamp": "2014-12-18T16:49:57-05:00",
            "selfLink": "/api/v1beta1/services/kubernetes?namespace=default",
            "resourceVersion": 4,
            "apiVersion": "v1beta1",
            "namespace": "default",
            "port": 443,
            "protocol": "TCP",
            "labels": {
                "component": "apiserver",
                "provider": "kubernetes"
            },
            "selector": null,
            "containerPort": 0,
            "portalIP": "10.0.0.232"
        }
    ]
}

which you can then pipe to enscope or to something that would strip specifics.

@smarterclayton smarterclayton force-pushed the allow_get_to_span_resources branch from 3bd6717 to eb5d3b6 Compare December 18, 2014 22:05
@smarterclayton smarterclayton force-pushed the allow_get_to_span_resources branch from eb5d3b6 to c3c7ca8 Compare December 26, 2014 22:34
@smarterclayton smarterclayton force-pushed the allow_get_to_span_resources branch 3 times, most recently from 53ce361 to b026f9e Compare December 31, 2014 01:17
@smarterclayton
Copy link
Contributor Author

Only the last commit is belongs to this pull, the others are part of #3152

@smarterclayton smarterclayton changed the title WIP - Allow kubectl get to fetch multiple resource types by label Allow kubectl get to fetch multiple resource types by label Dec 31, 2014
@smarterclayton
Copy link
Contributor Author

Barring changes to the predecessor pull based on API design, this roughly reflects the desired functionality. resource.Builder absorbs most of the work of taking user input (parameters, arguments) and normalizing and converting that output. The watch functionality in Get is the most complicated part (due to the current limitations of watch, and avoiding trying to solve mux'ing multiple watches, and ensuring the right resource version is set by the builder). This is a good demonstration of the most complex use of resource.Builder. Create and Update will use it for input only, and Delete will need to filter out items that were deleted by the server. Other commands can leverage parts of it for similar use as Delete.

@bgrant0607
Copy link
Member

Cool. Looks reasonable to me. We definitely need this functionality. Will wait for merge of #3152 before merging.

@smarterclayton smarterclayton force-pushed the allow_get_to_span_resources branch 6 times, most recently from 976928c to 1fb7fcd Compare January 9, 2015 17:18
@smarterclayton
Copy link
Contributor Author

This is now ready for merge, as are the commits above it (except maybe delete, Tim needs to ack the change).

w, err := restHelper.Watch(namespace, rv, labelSelector, labels.Everything())
checkErr(err)
// use the default printer for each object
err = b.Do().Visit(func(r *resource.Info) error {
Copy link
Member

Choose a reason for hiding this comment

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

FYI: I'd eventually like it to be possible to invoke all of the business logic of kubectl via library call, not just through the command line. That will facilitate programmatic use of Kubernetes, such as to manage dataflow pipelines, CI pipelines, background worker pools, sophisticated rollouts, etc.

Command-line processing obviously has to be coupled to cobra and the kubectl command. Input/output should be less coupled. All the actual processing and client calls should be completely independently callable.

This particular batch of PRs don't need to be changed, but please keep this in mind as we evolve kubectl functionality.

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, builder has two types of arguments *Arg/*Param which indicates it comes from a command line argument (so different failure rules apply), and programmatic "*" calls. The error messages on Do() and Visit() should eventually distinguish between those cases, so you get a different error message when you specify FilenameParam(...) vs ResourceTypeOrArgs vs URL or Stream.

@bgrant0607 bgrant0607 assigned thockin and unassigned bgrant0607 Jan 9, 2015
@bgrant0607
Copy link
Member

LGTM. Reassigned to Tim for a look.

return nil, err
}
if ok {
printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, outputVersion(cmd))
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@lavalamp note I moved versioning to a wrapped printer so that I could precisely control versioning here. You may want to take a look at the watch behavior and see whether it still makes sense.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry I didn't see this mention of me. This breaks the template uses in cluster/kube-validate.sh. I'm still trying to figure out what happened here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Which ones?

On Jan 13, 2015, at 5:47 PM, Daniel Smith notifications@github.com wrote:

In pkg/kubectl/cmd/get.go:

  • templateFile := GetFlagString(cmd, "template")
  • if len(outputFormat) == 0 && len(templateFile) != 0 {
  •   outputFormat = "template"
    
  • }
  • return kubectl.GetPrinter(outputFormat, templateFile)
    +}

+// printerForMapping returns a printer suitable for displaying the provided resource type.
+func printerForMapping(f *Factory, cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.ResourcePrinter, error) {

  • printer, ok, err := printerForCommand(cmd)
  • if err != nil {
  •   return nil, err
    
  • }
  • if ok {
  •   printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, outputVersion(cmd))
    
    Sorry I didn't see this mention of me. This breaks the template uses in cluster/kube-validate.sh. I'm still trying to figure out what happened here.


Reply to this email directly or view it on GitHub.

Copy link
Member

Choose a reason for hiding this comment

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

At least the first one. It's giving either internal structs or v1beta3 structs, not sure yet

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 be back at my desk in a few minutes

On Jan 13, 2015, at 5:51 PM, Daniel Smith notifications@github.com wrote:

In pkg/kubectl/cmd/get.go:

  • templateFile := GetFlagString(cmd, "template")
  • if len(outputFormat) == 0 && len(templateFile) != 0 {
  •   outputFormat = "template"
    
  • }
  • return kubectl.GetPrinter(outputFormat, templateFile)
    +}

+// printerForMapping returns a printer suitable for displaying the provided resource type.
+func printerForMapping(f *Factory, cmd *cobra.Command, mapping *meta.RESTMapping) (kubectl.ResourcePrinter, error) {

  • printer, ok, err := printerForCommand(cmd)
  • if err != nil {
  •   return nil, err
    
  • }
  • if ok {
  •   printer = kubectl.NewVersionedPrinter(printer, mapping.ObjectConvertor, outputVersion(cmd))
    
    At least the first one. It's giving either internal structs or v1beta3 structs, not sure yet


Reply to this email directly or view it on GitHub.

Like Delete, which can now run over multiple types:

    kubectl delete pods,services -l name=foo

Get should be able to span items for label selection

    kubectl get pods,services -l name=foo
@bgrant0607
Copy link
Member

Rerunning Travis. Will merge after it passes, assuming this doesn't need to be rebased.

@bgrant0607 bgrant0607 assigned bgrant0607 and unassigned thockin Jan 13, 2015
@smarterclayton
Copy link
Contributor Author

Green across the board

bgrant0607 added a commit that referenced this pull request Jan 13, 2015
Allow kubectl get to fetch multiple resource types by label
@bgrant0607 bgrant0607 merged commit bb140d6 into kubernetes:master Jan 13, 2015

// VersionedPrinter takes runtime objects and ensures they are converted to a given API version
// prior to being passed to a nested printer.
type VersionedPrinter struct {
Copy link
Member

Choose a reason for hiding this comment

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

I maintain that it shouldn't be possible to make a non-versioned printer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All the regular printers are not versioned

On Jan 13, 2015, at 5:50 PM, Daniel Smith notifications@github.com wrote:

In pkg/kubectl/resource_printer.go:

-// JSONPrinter is an implementation of ResourcePrinter which outputs an object as JSON.
-// The input object is assumed to be in the internal version of an API and is converted
-// to the given version first.
-type JSONPrinter struct {

  • version string
    +// ResourcePrinterFunc is a function that can print objects
    +type ResourcePrinterFunc func(runtime.Object, io.Writer) error

+// PrintObj implements ResourcePrinter
+func (fn ResourcePrinterFunc) PrintObj(obj runtime.Object, w io.Writer) error {

  • return fn(obj, w)
    +}

+// VersionedPrinter takes runtime objects and ensures they are converted to a given API version
+// prior to being passed to a nested printer.
+type VersionedPrinter struct {
I maintain that it shouldn't be possible to make a non-versioned printer.


Reply to this email directly or view it on GitHub.

Copy link
Member

Choose a reason for hiding this comment

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

They were when I last touched this code! In fact the last thing I did to this code was to fix this very problem...

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 should put that example into test-cmd.sh then. :)

-o json should be outputting a minionlist - is it?

On Jan 13, 2015, at 5:56 PM, Daniel Smith notifications@github.com wrote:

In pkg/kubectl/resource_printer.go:

-// JSONPrinter is an implementation of ResourcePrinter which outputs an object as JSON.
-// The input object is assumed to be in the internal version of an API and is converted
-// to the given version first.
-type JSONPrinter struct {

  • version string
    +// ResourcePrinterFunc is a function that can print objects
    +type ResourcePrinterFunc func(runtime.Object, io.Writer) error

+// PrintObj implements ResourcePrinter
+func (fn ResourcePrinterFunc) PrintObj(obj runtime.Object, w io.Writer) error {

  • return fn(obj, w)
    +}

+// VersionedPrinter takes runtime objects and ensures they are converted to a given API version
+// prior to being passed to a nested printer.
+type VersionedPrinter struct {
They were when I last touched this code! In fact the last thing I did to this code was to fix this very problem...


Reply to this email directly or view it on GitHub.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

VersionedPrinter may be getting empty string?

On Jan 13, 2015, at 5:56 PM, Daniel Smith notifications@github.com wrote:

In pkg/kubectl/resource_printer.go:

-// JSONPrinter is an implementation of ResourcePrinter which outputs an object as JSON.
-// The input object is assumed to be in the internal version of an API and is converted
-// to the given version first.
-type JSONPrinter struct {

  • version string
    +// ResourcePrinterFunc is a function that can print objects
    +type ResourcePrinterFunc func(runtime.Object, io.Writer) error

+// PrintObj implements ResourcePrinter
+func (fn ResourcePrinterFunc) PrintObj(obj runtime.Object, w io.Writer) error {

  • return fn(obj, w)
    +}

+// VersionedPrinter takes runtime objects and ensures they are converted to a given API version
+// prior to being passed to a nested printer.
+type VersionedPrinter struct {
They were when I last touched this code! In fact the last thing I did to this code was to fix this very problem...


Reply to this email directly or view it on GitHub.

@smarterclayton smarterclayton deleted the allow_get_to_span_resources branch February 11, 2015 02:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants