Skip to content

Commit

Permalink
Merge pull request #50497 from dixudx/kubectl-include-uninitialized
Browse files Browse the repository at this point in the history
Automatic merge from submit-queue (batch tested with PRs 51301, 50497, 50112, 48184, 50993)

Introduce new flag "--include-uninitialized" to kubectl

**What this PR does / why we need it**:

Introduce `--include-uninitialized` as a global flag to kubectl

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #49035

**Special notes for your reviewer**:
/assign @caesarxuchao @smarterclayton @ahmetb @deads2k 

**Release note**:

```release-note
Add flag "--include-uninitialized" to kubectl annotate, apply, edit-last-applied, delete, describe, edit, get, label, set. "--include-uninitialized=true" makes kubectl commands apply to uninitialized objects, which by default are ignored if the names of the objects are not provided. "--all" also makes kubectl commands apply to uninitialized objects. Please see the [initializer](https://kubernetes.io/docs/admin/extensible-admission-controllers/) doc for more details.
```
  • Loading branch information
Kubernetes Submit Queue committed Sep 3, 2017
2 parents 6d32783 + d80ff0f commit 5c0b265
Show file tree
Hide file tree
Showing 28 changed files with 487 additions and 54 deletions.
268 changes: 268 additions & 0 deletions hack/make-rules/test-cmd-util.sh

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions hack/testdata/initializer-clusterrolebinding.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
name: super-admin
initializers:
pending:
- name: podimage.initializer.com
labels:
clusterrolebinding: super
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: super-admin
25 changes: 25 additions & 0 deletions hack/testdata/initializer-deployments.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: web
initializers:
pending:
- name: podimage.initializer.com
labels:
run: web
spec:
replicas: 5
selector:
matchLabels:
run: web
template:
metadata:
labels:
run: web
spec:
containers:
- image: nginx:1.10
name: web
ports:
- containerPort: 80
protocol: TCP
19 changes: 19 additions & 0 deletions hack/testdata/initializer-redis-master-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: redis-master
labels:
app: redis
role: master
tier: backend
initializers:
pending:
- name: podimage.initializer.com
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
role: master
tier: backend
7 changes: 5 additions & 2 deletions pkg/kubectl/cmd/annotate.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,10 +128,11 @@ func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
ArgAliases: argAliases,
}
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)
cmd.Flags().Bool("overwrite", false, "If true, allow annotations to be overwritten, otherwise reject annotation updates that overwrite existing annotations.")
cmd.Flags().Bool("local", false, "If true, annotation will NOT contact api-server but run locally.")
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().Bool("all", false, "Select all resources in the namespace of the specified resource types")
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2).")
cmd.Flags().Bool("all", false, "Select all resources, including uninitialized ones, in the namespace of the specified resource types.")
cmd.Flags().String("resource-version", "", i18n.T("If non-empty, the annotation update will only succeed if this is the current resource-version for the object. Only valid when specifying a single resource."))
usage := "identifying the resource to update the annotation"
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
Expand Down Expand Up @@ -190,10 +191,12 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro
return err
}

includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
b := builder.
ContinueOnError().
NamespaceParam(namespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
IncludeUninitialized(includeUninitialized).
Flatten()

if !o.local {
Expand Down
16 changes: 11 additions & 5 deletions pkg/kubectl/cmd/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ func NewCmdApply(baseName string, f cmdutil.Factory, out, errOut io.Writer) *cob
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.MarkFlagRequired("filename")
cmd.Flags().Bool("overwrite", true, "Automatically resolve conflicts between the modified and live configuration by using values from the modified configuration")
cmd.Flags().BoolVar(&options.Prune, "prune", false, "Automatically delete resource objects that do not appear in the configs and are created by either apply or create --save-config. Should be used with either -l or --all.")
cmd.Flags().BoolVar(&options.Prune, "prune", false, "Automatically delete resource objects, including the uninitialized ones, that do not appear in the configs and are created by either apply or create --save-config. Should be used with either -l or --all.")
cmd.Flags().BoolVar(&options.Cascade, "cascade", true, "Only relevant during a prune or a force apply. If true, cascade the deletion of the resources managed by pruned or deleted resources (e.g. Pods created by a ReplicationController).")
cmd.Flags().IntVar(&options.GracePeriod, "grace-period", -1, "Only relevant during a prune or a force apply. Period of time in seconds given to pruned or deleted resources to terminate gracefully. Ignored if negative.")
cmd.Flags().BoolVar(&options.Force, "force", false, fmt.Sprintf("Delete and re-create the specified resource, when PATCH encounters conflict and has retried for %d times.", maxPatchRetry))
Expand All @@ -131,6 +131,7 @@ func NewCmdApply(baseName string, f cmdutil.Factory, out, errOut io.Writer) *cob
cmdutil.AddPrinterFlags(cmd)
cmdutil.AddRecordFlag(cmd)
cmdutil.AddInclude3rdPartyFlags(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)

// apply subcommands
cmd.AddCommand(NewCmdApplyViewLastApplied(f, out, errOut))
Expand Down Expand Up @@ -214,12 +215,17 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti
return err
}

// include the uninitialized objects by default if --prune is true
// unless explicitly set --include-uninitialized=false
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, options.Prune)

r := builder.
Schema(schema).
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &options.FilenameOptions).
SelectorParam(options.Selector).
IncludeUninitialized(includeUninitialized).
Flatten().
Do()
err = r.Err()
Expand Down Expand Up @@ -381,13 +387,13 @@ func RunApply(f cmdutil.Factory, cmd *cobra.Command, out, errOut io.Writer, opti

for n := range visitedNamespaces {
for _, m := range namespacedRESTMappings {
if err := p.prune(n, m, shortOutput); err != nil {
if err := p.prune(n, m, shortOutput, includeUninitialized); err != nil {
return fmt.Errorf("error pruning namespaced object %v: %v", m.GroupVersionKind, err)
}
}
}
for _, m := range nonNamespacedRESTMappings {
if err := p.prune(metav1.NamespaceNone, m, shortOutput); err != nil {
if err := p.prune(metav1.NamespaceNone, m, shortOutput, includeUninitialized); err != nil {
return fmt.Errorf("error pruning nonNamespaced object %v: %v", m.GroupVersionKind, err)
}
}
Expand Down Expand Up @@ -460,13 +466,13 @@ type pruner struct {
out io.Writer
}

func (p *pruner) prune(namespace string, mapping *meta.RESTMapping, shortOutput bool) error {
func (p *pruner) prune(namespace string, mapping *meta.RESTMapping, shortOutput, includeUninitialized bool) error {
c, err := p.clientFunc(mapping)
if err != nil {
return err
}

objList, err := resource.NewHelper(c, mapping).List(namespace, mapping.GroupVersionKind.Version, p.selector, false)
objList, err := resource.NewHelper(c, mapping).List(namespace, mapping.GroupVersionKind.Version, p.selector, false, includeUninitialized)
if err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion pkg/kubectl/cmd/apply_edit_last_applied.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func NewCmdApplyEditLastApplied(f cmdutil.Factory, out, errOut io.Writer) *cobra
Example: applyEditLastAppliedExample,
Run: func(cmd *cobra.Command, args []string) {
options.ChangeCause = f.Command(cmd, false)
if err := options.Complete(f, out, errOut, args); err != nil {
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
cmdutil.CheckErr(err)
}
if err := options.Run(); err != nil {
Expand All @@ -99,6 +99,7 @@ func NewCmdApplyEditLastApplied(f cmdutil.Factory, out, errOut io.Writer) *cobra
cmd.Flags().BoolVar(&options.WindowsLineEndings, "windows-line-endings", runtime.GOOS == "windows",
"Defaults to the line ending native to your platform.")
cmdutil.AddRecordVarFlag(cmd, &options.Record)
cmdutil.AddIncludeUninitializedFlag(cmd)

return cmd
}
2 changes: 1 addition & 1 deletion pkg/kubectl/cmd/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ func RunEditOnCreate(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Comman
ChangeCause: f.Command(cmd, false),
Include3rdParty: cmdutil.GetFlagBool(cmd, "include-extended-apis"),
}
err := editOptions.Complete(f, out, errOut, []string{})
err := editOptions.Complete(f, out, errOut, []string{}, cmd)
if err != nil {
return err
}
Expand Down
11 changes: 7 additions & 4 deletions pkg/kubectl/cmd/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
Example: delete_example,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
if err := options.Complete(f, out, errOut, args); err != nil {
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
cmdutil.CheckErr(err)
}
if err := options.Validate(cmd); err != nil {
Expand All @@ -149,8 +149,8 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
}
usage := "containing the resource to delete."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on.")
cmd.Flags().BoolVar(&options.DeleteAll, "all", false, "Select all resources in the namespace of the specified resource types.")
cmd.Flags().StringVarP(&options.Selector, "selector", "l", "", "Selector (label query) to filter on, not including uninitialized ones.")
cmd.Flags().BoolVar(&options.DeleteAll, "all", false, "Delete all resources, including uninitialized ones, in the namespace of the specified resource types.")
cmd.Flags().BoolVar(&options.IgnoreNotFound, "ignore-not-found", false, "Treat \"resource not found\" as a successful delete. Defaults to \"true\" when --all is specified.")
cmd.Flags().BoolVar(&options.Cascade, "cascade", true, "If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.")
cmd.Flags().IntVar(&options.GracePeriod, "grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
Expand All @@ -159,10 +159,11 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
cmd.Flags().DurationVar(&options.Timeout, "timeout", 0, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object")
cmdutil.AddOutputVarFlagsForMutation(cmd, &options.Output)
cmdutil.AddInclude3rdPartyVarFlags(cmd, &options.Include3rdParty)
cmdutil.AddIncludeUninitializedFlag(cmd)
return cmd
}

func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args []string) error {
func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args []string, cmd *cobra.Command) error {
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
return err
Expand All @@ -180,11 +181,13 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
}

o.Mapper = mapper
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
r := builder.
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, &o.FilenameOptions).
SelectorParam(o.Selector).
IncludeUninitialized(includeUninitialized).
SelectAllParam(o.DeleteAll).
ResourceTypeOrNameArgs(false, args...).RequireObject(false).
Flatten().
Expand Down
17 changes: 13 additions & 4 deletions pkg/kubectl/cmd/delete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ import (
"testing"
"time"

"github.com/spf13/cobra"

"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand All @@ -41,6 +43,13 @@ import (

var unstructuredSerializer = dynamic.ContentConfig().NegotiatedSerializer

var fakecmd = &cobra.Command{
Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])",
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
},
}

func TestDeleteObjectByTuple(t *testing.T) {
initTestErrorHandler(t)
_, _, rc := testData()
Expand Down Expand Up @@ -345,7 +354,7 @@ func TestDeleteObjectNotFound(t *testing.T) {
Cascade: false,
Output: "name",
}
err := options.Complete(f, buf, errBuf, []string{})
err := options.Complete(f, buf, errBuf, []string{}, fakecmd)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
Expand Down Expand Up @@ -426,7 +435,7 @@ func TestDeleteAllNotFound(t *testing.T) {
IgnoreNotFound: false,
Output: "name",
}
err := options.Complete(f, buf, errBuf, []string{"services"})
err := options.Complete(f, buf, errBuf, []string{"services"}, fakecmd)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
Expand Down Expand Up @@ -546,7 +555,7 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
Cascade: false,
Output: "name",
}
err := options.Complete(f, buf, errBuf, []string{})
err := options.Complete(f, buf, errBuf, []string{}, fakecmd)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
Expand Down Expand Up @@ -714,7 +723,7 @@ func TestResourceErrors(t *testing.T) {
Cascade: false,
Output: "name",
}
err := options.Complete(f, buf, errBuf, testCase.args)
err := options.Complete(f, buf, errBuf, testCase.args, fakecmd)
if !testCase.errFn(err) {
t.Errorf("%s: unexpected error: %v", k, err)
continue
Expand Down
7 changes: 7 additions & 0 deletions pkg/kubectl/cmd/describe.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import (
var (
describe_long = templates.LongDesc(`
Show details of a specific resource or group of resources.
It includes the uninitialized objects, unless --include-uninitialized=false is explicitly set.
This command joins many API calls together to form a detailed description of a
given resource or group of resources.
Expand Down Expand Up @@ -97,6 +98,7 @@ func NewCmdDescribe(f cmdutil.Factory, out, cmdErr io.Writer) *cobra.Command {
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(&describerSettings.ShowEvents, "show-events", true, "If true, display events related to the described object.")
cmdutil.AddInclude3rdPartyFlags(cmd)
cmdutil.AddIncludeUninitializedFlag(cmd)
return cmd
}

Expand All @@ -120,11 +122,16 @@ func RunDescribe(f cmdutil.Factory, out, cmdErr io.Writer, cmd *cobra.Command, a
return err
}

// include the uninitialized objects by default
// unless user explicitly set --include-uninitialized=false
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, true)

r := builder.
ContinueOnError().
NamespaceParam(cmdNamespace).DefaultNamespace().AllNamespaces(allNamespaces).
FilenameParam(enforceNamespace, options).
SelectorParam(selector).
IncludeUninitialized(includeUninitialized).
ResourceTypeOrNameArgs(true, args...).
Flatten().
Do()
Expand Down
3 changes: 2 additions & 1 deletion pkg/kubectl/cmd/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ func NewCmdEdit(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
Example: fmt.Sprintf(editExample),
Run: func(cmd *cobra.Command, args []string) {
options.ChangeCause = f.Command(cmd, false)
if err := options.Complete(f, out, errOut, args); err != nil {
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
cmdutil.CheckErr(err)
}
if err := options.Run(); err != nil {
Expand All @@ -115,5 +115,6 @@ func NewCmdEdit(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
cmdutil.AddApplyAnnotationVarFlags(cmd, &options.ApplyAnnotation)
cmdutil.AddRecordVarFlag(cmd, &options.Record)
cmdutil.AddInclude3rdPartyVarFlags(cmd, &options.Include3rdParty)
cmdutil.AddIncludeUninitializedFlag(cmd)
return cmd
}
17 changes: 15 additions & 2 deletions pkg/kubectl/cmd/get.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ var (
This command will hide resources that have completed, such as pods that are
in the Succeeded or Failed phases. You can see the full results for any
resource by providing the '--show-all' flag.
resource by providing the '--show-all' flag, but this flag does not include
the uninitialized objects by default, unless '--include-uninitialized' is explicitly set.
By specifying the output as 'template' and providing a Go template as the value
of the --template flag, you can filter the attributes of the fetched resources.`)
Expand Down Expand Up @@ -127,7 +128,8 @@ func NewCmdGet(f cmdutil.Factory, out io.Writer, errOut io.Writer) *cobra.Comman
}
cmdutil.AddPrinterFlags(cmd)
cmd.Flags().StringP("selector", "l", "", "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().BoolP("watch", "w", false, "After listing/getting the requested object, watch for changes.")
cmdutil.AddIncludeUninitializedFlag(cmd)
cmd.Flags().BoolP("watch", "w", false, "After listing/getting the requested object, watch for changes. Uninitialized objects are excluded if no object name is provided.")
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("all-namespaces", false, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
Expand Down Expand Up @@ -200,6 +202,15 @@ func RunGet(f cmdutil.Factory, out, errOut io.Writer, cmd *cobra.Command, args [

// handle watch separately since we cannot watch multiple resource types
isWatch, isWatchOnly := cmdutil.GetFlagBool(cmd, "watch"), cmdutil.GetFlagBool(cmd, "watch-only")

var includeUninitialized bool
if isWatch && len(args) == 2 {
// include the uninitialized one for watching on a single object
// unless explicitly set --include-uninitialized=false
includeUninitialized = true
}
includeUninitialized = cmdutil.ShouldIncludeUninitialized(cmd, includeUninitialized)

if isWatch || isWatchOnly {
builder, err := f.NewUnstructuredBuilder(true)
if err != nil {
Expand All @@ -211,6 +222,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().
Expand Down Expand Up @@ -300,6 +312,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().
Expand Down

0 comments on commit 5c0b265

Please sign in to comment.