diff --git a/pkg/kubectl/cmd/get.go b/pkg/kubectl/cmd/get.go index 6daece57a6c..9f6c98a17a0 100644 --- a/pkg/kubectl/cmd/get.go +++ b/pkg/kubectl/cmd/get.go @@ -130,6 +130,7 @@ func NewCmdGet(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comman cmd.Flags().BoolP("watch", "w", false, "After listing/getting the requested object, watch for changes.") cmd.Flags().Bool("watch-only", false, "Watch for changes to the requested object(s), without listing/getting first.") cmd.Flags().Bool("show-kind", false, "If present, list the resource type for the requested object(s).") + cmd.Flags().Bool("include-uninitialized", false, "If present, list uninitialized resource(s).") cmd.Flags().Bool("all-namespaces", false, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.") cmd.Flags().BoolVar(&options.IgnoreNotFound, "ignore-not-found", false, "Treat \"resource not found\" as a successful retrieval.") cmd.Flags().StringSliceP("label-columns", "L", []string{}, "Accepts a comma separated list of labels that are going to be presented as columns. Names are case-sensitive. You can also use multiple flag options like -L label1 -L label2...") @@ -195,6 +196,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ } export := cmdutil.GetFlagBool(cmd, "export") + includeUninitialized := cmdutil.GetFlagBool(cmd, "include-uninitialized") filterFuncs := f.DefaultResourceFilterFunc() filterOpts := f.DefaultResourceFilterOptions(cmd, allNamespaces) @@ -212,6 +214,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). ExportParam(export). + IncludeUninitialized(includeUninitialized). ResourceTypeOrNameArgs(true, args...). SingleResourceType(). Latest(). @@ -301,6 +304,7 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [ FilenameParam(enforceNamespace, &options.FilenameOptions). SelectorParam(selector). ExportParam(export). + IncludeUninitialized(includeUninitialized). ResourceTypeOrNameArgs(true, args...). ContinueOnError(). Latest(). diff --git a/pkg/kubectl/resource/builder.go b/pkg/kubectl/resource/builder.go index eb563fb51bf..8908bc2ef30 100644 --- a/pkg/kubectl/resource/builder.go +++ b/pkg/kubectl/resource/builder.go @@ -51,8 +51,9 @@ type Builder struct { stream bool dir bool - selector labels.Selector - selectAll bool + selector labels.Selector + selectAll bool + includeUninitialized bool resources []string @@ -279,6 +280,12 @@ func (b *Builder) ExportParam(export bool) *Builder { return b } +// IncludeUninitialized accepts the include-uninitialized boolean for these resources +func (b *Builder) IncludeUninitialized(includeUninitialized bool) *Builder { + b.includeUninitialized = includeUninitialized + return b +} + // NamespaceParam accepts the namespace that these resources should be // considered under from - used by DefaultNamespace() and RequireNamespace() func (b *Builder) NamespaceParam(namespace string) *Builder { @@ -607,7 +614,7 @@ func (b *Builder) visitBySelector() *Result { if mapping.Scope.Name() != meta.RESTScopeNameNamespace { selectorNamespace = "" } - visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, b.selector, b.export)) + visitors = append(visitors, NewSelector(client, mapping, selectorNamespace, b.selector, b.export, b.includeUninitialized)) } if b.continueOnError { result.visitor = EagerVisitorList(visitors) diff --git a/pkg/kubectl/resource/helper.go b/pkg/kubectl/resource/helper.go index e6452244b67..940387295ad 100644 --- a/pkg/kubectl/resource/helper.go +++ b/pkg/kubectl/resource/helper.go @@ -65,7 +65,7 @@ func (m *Helper) Get(namespace, name string, export bool) (runtime.Object, error } // TODO: add field selector -func (m *Helper) List(namespace, apiVersion string, selector labels.Selector, export bool) (runtime.Object, error) { +func (m *Helper) List(namespace, apiVersion string, selector labels.Selector, export, includeUninitialized bool) (runtime.Object, error) { req := m.RESTClient.Get(). NamespaceIfScoped(namespace, m.NamespaceScoped). Resource(m.Resource). @@ -76,6 +76,9 @@ func (m *Helper) List(namespace, apiVersion string, selector labels.Selector, ex // TODO: I should be part of ListOptions req.Param("export", strconv.FormatBool(export)) } + if includeUninitialized { + req.Param("includeUninitialized", strconv.FormatBool(includeUninitialized)) + } return req.Do().Get() } diff --git a/pkg/kubectl/resource/helper_test.go b/pkg/kubectl/resource/helper_test.go index 2829ffaeaf9..00208bdf389 100644 --- a/pkg/kubectl/resource/helper_test.go +++ b/pkg/kubectl/resource/helper_test.go @@ -358,7 +358,7 @@ func TestHelperList(t *testing.T) { RESTClient: client, NamespaceScoped: true, } - obj, err := modifier.List("bar", api.Registry.GroupOrDie(api.GroupName).GroupVersion.String(), labels.SelectorFromSet(labels.Set{"foo": "baz"}), false) + obj, err := modifier.List("bar", api.Registry.GroupOrDie(api.GroupName).GroupVersion.String(), labels.SelectorFromSet(labels.Set{"foo": "baz"}), false, false) if (err != nil) != test.Err { t.Errorf("unexpected error: %t %v", test.Err, err) } diff --git a/pkg/kubectl/resource/selector.go b/pkg/kubectl/resource/selector.go index 49431fb79fa..6faed0f4784 100644 --- a/pkg/kubectl/resource/selector.go +++ b/pkg/kubectl/resource/selector.go @@ -27,27 +27,29 @@ import ( // Selector is a Visitor for resources that match a label selector. type Selector struct { - Client RESTClient - Mapping *meta.RESTMapping - Namespace string - Selector labels.Selector - Export bool + Client RESTClient + Mapping *meta.RESTMapping + Namespace string + Selector labels.Selector + Export bool + IncludeUninitialized bool } // NewSelector creates a resource selector which hides details of getting items by their label selector. -func NewSelector(client RESTClient, mapping *meta.RESTMapping, namespace string, selector labels.Selector, export bool) *Selector { +func NewSelector(client RESTClient, mapping *meta.RESTMapping, namespace string, selector labels.Selector, export, includeUninitialized bool) *Selector { return &Selector{ - Client: client, - Mapping: mapping, - Namespace: namespace, - Selector: selector, - Export: export, + Client: client, + Mapping: mapping, + Namespace: namespace, + Selector: selector, + Export: export, + IncludeUninitialized: includeUninitialized, } } // Visit implements Visitor func (r *Selector) Visit(fn VisitorFunc) error { - list, err := NewHelper(r.Client, r.Mapping).List(r.Namespace, r.ResourceMapping().GroupVersionKind.GroupVersion().String(), r.Selector, r.Export) + list, err := NewHelper(r.Client, r.Mapping).List(r.Namespace, r.ResourceMapping().GroupVersionKind.GroupVersion().String(), r.Selector, r.Export, r.IncludeUninitialized) if err != nil { if errors.IsBadRequest(err) || errors.IsNotFound(err) { if se, ok := err.(*errors.StatusError); ok {