From 9c5bdd4b5c67024412a84e5fb09033cd38d21e9d Mon Sep 17 00:00:00 2001 From: David Eads Date: Tue, 29 May 2018 10:46:54 -0400 Subject: [PATCH] add resource builder flags --- pkg/kubectl/cmd/wait/wait.go | 9 +- pkg/kubectl/cmd/wait/wait_test.go | 4 +- .../genericclioptions/builder_flags.go | 98 ++++++++++++++++--- .../genericclioptions/builder_flags_fake.go | 2 +- 4 files changed, 92 insertions(+), 21 deletions(-) diff --git a/pkg/kubectl/cmd/wait/wait.go b/pkg/kubectl/cmd/wait/wait.go index 9ccf3cb735e..37b5a4b66d1 100644 --- a/pkg/kubectl/cmd/wait/wait.go +++ b/pkg/kubectl/cmd/wait/wait.go @@ -53,9 +53,12 @@ type WaitFlags struct { // NewWaitFlags returns a default WaitFlags func NewWaitFlags(restClientGetter genericclioptions.RESTClientGetter, streams genericclioptions.IOStreams) *WaitFlags { return &WaitFlags{ - RESTClientGetter: restClientGetter, - PrintFlags: genericclioptions.NewPrintFlags("condition met"), - ResourceBuilderFlags: genericclioptions.NewResourceBuilderFlags(), + RESTClientGetter: restClientGetter, + PrintFlags: genericclioptions.NewPrintFlags("condition met"), + ResourceBuilderFlags: genericclioptions.NewResourceBuilderFlags(). + WithLabelSelector(""). + WithAllNamespaces(false). + WithLatest(), Timeout: 30 * time.Second, diff --git a/pkg/kubectl/cmd/wait/wait_test.go b/pkg/kubectl/cmd/wait/wait_test.go index 77d98e8d459..27446e840f6 100644 --- a/pkg/kubectl/cmd/wait/wait_test.go +++ b/pkg/kubectl/cmd/wait/wait_test.go @@ -219,7 +219,7 @@ func TestWaitForDeletion(t *testing.T) { t.Run(test.name, func(t *testing.T) { fakeClient := test.fakeClient() o := &WaitOptions{ - ResourceFinder: genericclioptions.NewSimpleResourceFinder(test.info), + ResourceFinder: genericclioptions.NewSimpleFakeResourceFinder(test.info), DynamicClient: fakeClient, Timeout: test.timeout, @@ -451,7 +451,7 @@ func TestWaitForCondition(t *testing.T) { t.Run(test.name, func(t *testing.T) { fakeClient := test.fakeClient() o := &WaitOptions{ - ResourceFinder: genericclioptions.NewSimpleResourceFinder(test.info), + ResourceFinder: genericclioptions.NewSimpleFakeResourceFinder(test.info), DynamicClient: fakeClient, Timeout: test.timeout, diff --git a/pkg/kubectl/genericclioptions/builder_flags.go b/pkg/kubectl/genericclioptions/builder_flags.go index 4648751c315..ad0ec7a6376 100644 --- a/pkg/kubectl/genericclioptions/builder_flags.go +++ b/pkg/kubectl/genericclioptions/builder_flags.go @@ -18,6 +18,7 @@ package genericclioptions import ( "github.com/spf13/pflag" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/kubernetes/pkg/kubectl/genericclioptions/resource" ) @@ -29,8 +30,11 @@ type ResourceBuilderFlags struct { LabelSelector *string FieldSelector *string AllNamespaces *bool + All *bool + Local *bool - All bool + Scheme *runtime.Scheme + Latest bool } // NewResourceBuilderFlags returns a default ResourceBuilderFlags @@ -43,17 +47,54 @@ func NewResourceBuilderFlags() *ResourceBuilderFlags { Filenames: &filenames, Recursive: boolPtr(true), }, - - LabelSelector: strPtr(""), - AllNamespaces: boolPtr(false), } } +func (o *ResourceBuilderFlags) WithFile(recurse bool, files ...string) *ResourceBuilderFlags { + o.FileNameFlags = &FileNameFlags{ + Usage: "identifying the resource.", + Filenames: &files, + Recursive: boolPtr(recurse), + } + + return o +} + +func (o *ResourceBuilderFlags) WithLabelSelector(selector string) *ResourceBuilderFlags { + o.LabelSelector = &selector + return o +} + func (o *ResourceBuilderFlags) WithFieldSelector(selector string) *ResourceBuilderFlags { o.FieldSelector = &selector return o } +func (o *ResourceBuilderFlags) WithAllNamespaces(defaultVal bool) *ResourceBuilderFlags { + o.AllNamespaces = &defaultVal + return o +} + +func (o *ResourceBuilderFlags) WithAll(defaultVal bool) *ResourceBuilderFlags { + o.All = &defaultVal + return o +} + +func (o *ResourceBuilderFlags) WithLocal(defaultVal bool) *ResourceBuilderFlags { + o.Local = &defaultVal + return o +} + +func (o *ResourceBuilderFlags) WithScheme(scheme *runtime.Scheme) *ResourceBuilderFlags { + o.Scheme = scheme + return o +} + +func (o *ResourceBuilderFlags) WithLatest() *ResourceBuilderFlags { + o.Latest = true + return o +} + // AddFlags registers flags for finding resources func (o *ResourceBuilderFlags) AddFlags(flagset *pflag.FlagSet) { o.FileNameFlags.AddFlags(flagset) @@ -67,6 +108,12 @@ func (o *ResourceBuilderFlags) AddFlags(flagset *pflag.FlagSet) { if o.AllNamespaces != nil { flagset.BoolVar(o.AllNamespaces, "all-namespaces", *o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.") } + if o.All != nil { + flagset.BoolVar(o.All, "all", *o.All, "Select all resources in the namespace of the specified resource types") + } + if o.Local != nil { + flagset.BoolVar(o.Local, "local", *o.Local, "If true, annotation will NOT contact api-server but run locally.") + } } // ToBuilder gives you back a resource finder to visit resources that are located @@ -74,24 +121,45 @@ func (o *ResourceBuilderFlags) ToBuilder(restClientGetter RESTClientGetter, reso namespace, enforceNamespace, namespaceErr := restClientGetter.ToRawKubeConfigLoader().Namespace() builder := resource.NewBuilder(restClientGetter). - Unstructured(). - NamespaceParam(namespace).DefaultNamespace(). - ResourceTypeOrNameArgs(o.All, resources...) + NamespaceParam(namespace).DefaultNamespace() + + if o.Scheme != nil { + builder.WithScheme(o.Scheme, o.Scheme.PrioritizedVersionsAllGroups()...) + } else { + builder.Unstructured() + } + if o.FileNameFlags != nil { opts := o.FileNameFlags.ToOptions() - builder = builder.FilenameParam(enforceNamespace, &opts) + builder.FilenameParam(enforceNamespace, &opts) } - if o.LabelSelector != nil { - builder = builder.LabelSelectorParam(*o.LabelSelector) - } - if o.FieldSelector != nil { - builder = builder.FieldSelectorParam(*o.FieldSelector) + + if o.Local == nil || !*o.Local { + // resource type/name tuples only work non-local + if o.All != nil { + builder.ResourceTypeOrNameArgs(*o.All, resources...) + } else { + builder.ResourceTypeOrNameArgs(false, resources...) + } + // label selectors only work non-local (for now) + if o.LabelSelector != nil { + builder.LabelSelectorParam(*o.LabelSelector) + } + // field selectors only work non-local (forever) + if o.FieldSelector != nil { + builder.FieldSelectorParam(*o.FieldSelector) + } + // latest only works non-local (forever) + if o.Latest { + builder.Latest() + } + } else { + builder.Local() } return &ResourceFindBuilderWrapper{ builder: builder. - Latest(). - Flatten(). + Flatten(). // I think we're going to recommend this everywhere AddError(namespaceErr), } } diff --git a/pkg/kubectl/genericclioptions/builder_flags_fake.go b/pkg/kubectl/genericclioptions/builder_flags_fake.go index 15137c9e797..de968d8e5d7 100644 --- a/pkg/kubectl/genericclioptions/builder_flags_fake.go +++ b/pkg/kubectl/genericclioptions/builder_flags_fake.go @@ -21,7 +21,7 @@ import ( ) // NewSimpleResourceFinder builds a super simple ResourceFinder that just iterates over the objects you provided -func NewSimpleResourceFinder(infos ...*resource.Info) ResourceFinder { +func NewSimpleFakeResourceFinder(infos ...*resource.Info) ResourceFinder { return &fakeResourceFinder{ Infos: infos, }