diff --git a/pkg/kubectl/cmd/annotate/annotate.go b/pkg/kubectl/cmd/annotate/annotate.go index 860cc10050..fe8d15dc92 100644 --- a/pkg/kubectl/cmd/annotate/annotate.go +++ b/pkg/kubectl/cmd/annotate/annotate.go @@ -208,7 +208,7 @@ func (o AnnotateOptions) Validate() error { if o.all && len(o.fieldSelector) > 0 { return fmt.Errorf("cannot set --all and --field-selector at the same time") } - if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { + if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) { return fmt.Errorf("one or more resources must be specified as or /") } if len(o.newAnnotations) < 1 && len(o.removeAnnotations) < 1 { diff --git a/pkg/kubectl/cmd/apply/apply.go b/pkg/kubectl/cmd/apply/apply.go index 11ed554822..99393101b1 100644 --- a/pkg/kubectl/cmd/apply/apply.go +++ b/pkg/kubectl/cmd/apply/apply.go @@ -115,6 +115,9 @@ var ( # Apply the configuration in pod.json to a pod. kubectl apply -f ./pod.json + # Apply resources from a directory containing kustomization.yaml - e.g. dir/kustomization.yaml. + kubectl apply -k dir/ + # Apply the JSON passed into stdin to a pod. cat pod.json | kubectl apply -f - @@ -152,7 +155,7 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions o.cmdBaseName = baseName cmd := &cobra.Command{ - Use: "apply -f FILENAME", + Use: "apply (-f FILENAME | -k DIRECTORY)", DisableFlagsInUseLine: true, Short: i18n.T("Apply a configuration to a resource by filename or stdin"), Long: applyLong, @@ -170,7 +173,6 @@ func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions o.RecordFlags.AddFlags(cmd) o.PrintFlags.AddFlags(cmd) - cmd.MarkFlagRequired("filename") cmd.Flags().BoolVar(&o.Overwrite, "overwrite", o.Overwrite, "Automatically resolve conflicts between the modified and live configuration by using values from the modified configuration") cmd.Flags().BoolVar(&o.Prune, "prune", o.Prune, "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.") cmdutil.AddValidateFlags(cmd) @@ -237,6 +239,10 @@ func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { return err } o.DeleteOptions = o.DeleteFlags.ToOptions(dynamicClient, o.IOStreams) + err = o.DeleteOptions.FilenameOptions.RequireFilenameOrKustomize() + if err != nil { + return err + } o.OpenAPISchema, _ = f.OpenAPISchema() o.Validator, err = f.Validator(cmdutil.GetFlagBool(cmd, "validate")) diff --git a/pkg/kubectl/cmd/auth/reconcile.go b/pkg/kubectl/cmd/auth/reconcile.go index 950192d8e9..b9de9d2efb 100644 --- a/pkg/kubectl/cmd/auth/reconcile.go +++ b/pkg/kubectl/cmd/auth/reconcile.go @@ -107,13 +107,16 @@ func NewCmdReconcile(f cmdutil.Factory, streams genericclioptions.IOStreams) *co cmd.Flags().BoolVar(&o.DryRun, "dry-run", o.DryRun, "If true, display results but do not submit changes") cmd.Flags().BoolVar(&o.RemoveExtraPermissions, "remove-extra-permissions", o.RemoveExtraPermissions, "If true, removes extra permissions added to roles") cmd.Flags().BoolVar(&o.RemoveExtraSubjects, "remove-extra-subjects", o.RemoveExtraSubjects, "If true, removes extra subjects added to rolebindings") - cmd.MarkFlagRequired("filename") return cmd } // Complete completes all the required options func (o *ReconcileOptions) Complete(cmd *cobra.Command, f cmdutil.Factory, args []string) error { + if err := o.FilenameOptions.RequireFilenameOrKustomize(); err != nil { + return err + } + if len(args) > 0 { return errors.New("no arguments are allowed") } diff --git a/pkg/kubectl/cmd/certificates/certificates.go b/pkg/kubectl/cmd/certificates/certificates.go index fb537f2dd6..bd8d370763 100644 --- a/pkg/kubectl/cmd/certificates/certificates.go +++ b/pkg/kubectl/cmd/certificates/certificates.go @@ -104,7 +104,7 @@ func (o *CertificateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, arg } func (o *CertificateOptions) Validate() error { - if len(o.csrNames) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { + if len(o.csrNames) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) { return fmt.Errorf("one or more CSRs must be specified as or -f ") } return nil diff --git a/pkg/kubectl/cmd/convert/convert.go b/pkg/kubectl/cmd/convert/convert.go index 506b736577..b34a4aff91 100644 --- a/pkg/kubectl/cmd/convert/convert.go +++ b/pkg/kubectl/cmd/convert/convert.go @@ -107,12 +107,15 @@ func NewCmdConvert(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *co cmdutil.AddValidateFlags(cmd) cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, "to need to get converted.") - cmd.MarkFlagRequired("filename") return cmd } // Complete collects information required to run Convert command from command line. func (o *ConvertOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) (err error) { + err = o.FilenameOptions.RequireFilenameOrKustomize() + if err != nil { + return err + } o.builder = f.NewBuilder o.Namespace, _, err = f.ToRawKubeConfigLoader().Namespace() diff --git a/pkg/kubectl/cmd/create/create.go b/pkg/kubectl/cmd/create/create.go index 1a8f230bc2..f005ee37e2 100644 --- a/pkg/kubectl/cmd/create/create.go +++ b/pkg/kubectl/cmd/create/create.go @@ -103,7 +103,8 @@ func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cob Long: createLong, Example: createExample, Run: func(cmd *cobra.Command, args []string) { - if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) { + if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) { + ioStreams.ErrOut.Write([]byte("Error: must specify one of -f and -k\n\n")) defaultRunFunc := cmdutil.DefaultSubCommandRun(ioStreams.ErrOut) defaultRunFunc(cmd, args) return @@ -119,7 +120,6 @@ func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cob usage := "to use to create the resource" cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage) - cmd.MarkFlagRequired("filename") cmdutil.AddValidateFlags(cmd) cmd.Flags().BoolVar(&o.EditBeforeCreate, "edit", o.EditBeforeCreate, "Edit the API resource before creating") cmd.Flags().Bool("windows-line-endings", runtime.GOOS == "windows", @@ -184,7 +184,6 @@ func (o *CreateOptions) ValidateArgs(cmd *cobra.Command, args []string) error { // Complete completes all the required options func (o *CreateOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { var err error - o.RecordFlags.Complete(cmd) o.Recorder, err = o.RecordFlags.ToRecorder() if err != nil { diff --git a/pkg/kubectl/cmd/delete/delete.go b/pkg/kubectl/cmd/delete/delete.go index eabc6c6df0..0eedd20551 100644 --- a/pkg/kubectl/cmd/delete/delete.go +++ b/pkg/kubectl/cmd/delete/delete.go @@ -71,6 +71,9 @@ var ( # Delete a pod using the type and name specified in pod.json. kubectl delete -f ./pod.json + # Delete resources from a directory containing kustomization.yaml - e.g. dir/kustomization.yaml. + kubectl delete -k dir + # Delete a pod based on the type and name in the JSON passed into stdin. cat pod.json | kubectl delete -f - @@ -119,7 +122,7 @@ func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra deleteFlags := NewDeleteCommandFlags("containing the resource to delete.") cmd := &cobra.Command{ - Use: "delete ([-f FILENAME] | TYPE [(NAME | -l label | --all)])", + Use: "delete ([-f FILENAME] | [-k DIRECTORY] | TYPE [(NAME | -l label | --all)])", DisableFlagsInUseLine: true, Short: i18n.T("Delete resources by filenames, stdin, resources and names, or by resources and label selector"), Long: deleteLong, diff --git a/pkg/kubectl/cmd/describe/describe.go b/pkg/kubectl/cmd/describe/describe.go index b0f9cb1d48..bd85780902 100644 --- a/pkg/kubectl/cmd/describe/describe.go +++ b/pkg/kubectl/cmd/describe/describe.go @@ -131,7 +131,7 @@ func (o *DescribeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [ o.EnforceNamespace = false } - if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) { + if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) { return fmt.Errorf("You must specify the type of resource to describe. %s\n", cmdutil.SuggestAPIResources(o.CmdParent)) } diff --git a/pkg/kubectl/cmd/diff/diff.go b/pkg/kubectl/cmd/diff/diff.go index e64e8a0990..5f68198767 100644 --- a/pkg/kubectl/cmd/diff/diff.go +++ b/pkg/kubectl/cmd/diff/diff.go @@ -118,7 +118,6 @@ func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.C usage := "contains the configuration to diff" cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage) cmdutil.AddServerSideApplyFlags(cmd) - cmd.MarkFlagRequired("filename") return cmd } @@ -395,6 +394,11 @@ func isConflict(err error) bool { func (o *DiffOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error { var err error + err = o.FilenameOptions.RequireFilenameOrKustomize() + if err != nil { + return err + } + o.ServerSideApply = cmdutil.GetServerSideApplyFlag(cmd) o.ForceConflicts = cmdutil.GetForceConflictsFlag(cmd) if o.ForceConflicts && !o.ServerSideApply { diff --git a/pkg/kubectl/cmd/get/get.go b/pkg/kubectl/cmd/get/get.go index 73a450d36f..b3fa41b3c5 100644 --- a/pkg/kubectl/cmd/get/get.go +++ b/pkg/kubectl/cmd/get/get.go @@ -115,6 +115,9 @@ var ( # List a pod identified by type and name specified in "pod.yaml" in JSON output format. kubectl get -f pod.yaml -o json + # List resources from a directory with kustomization.yaml - e.g. dir/kustomization.yaml. + kubectl get -k dir/ + # Return only the phase value of the specified pod. kubectl get -o template pod/web-pod-13je7 --template={{.status.phase}} @@ -257,7 +260,7 @@ func (o *GetOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []stri switch { case o.Watch || o.WatchOnly: default: - if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { + if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) { fmt.Fprintf(o.ErrOut, "You must specify the type of resource to get. %s\n\n", cmdutil.SuggestAPIResources(o.CmdParent)) fullCmdName := cmd.Parent().CommandPath() usageString := "Required resource not specified." diff --git a/pkg/kubectl/cmd/label/label.go b/pkg/kubectl/cmd/label/label.go index 63781453f5..eca1fbbbed 100644 --- a/pkg/kubectl/cmd/label/label.go +++ b/pkg/kubectl/cmd/label/label.go @@ -205,7 +205,7 @@ func (o *LabelOptions) Validate() error { if o.all && len(o.fieldSelector) > 0 { return fmt.Errorf("cannot set --all and --field-selector at the same time") } - if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) { + if len(o.resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) { return fmt.Errorf("one or more resources must be specified as or /") } if len(o.newLabels) < 1 && len(o.removeLabels) < 1 && !o.list { diff --git a/pkg/kubectl/cmd/replace/replace.go b/pkg/kubectl/cmd/replace/replace.go index dd329160e9..9c3456074b 100644 --- a/pkg/kubectl/cmd/replace/replace.go +++ b/pkg/kubectl/cmd/replace/replace.go @@ -117,7 +117,6 @@ func NewCmdReplace(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobr o.DeleteFlags.AddFlags(cmd) o.RecordFlags.AddFlags(cmd) - cmd.MarkFlagRequired("filename") cmdutil.AddValidateFlags(cmd) cmdutil.AddApplyAnnotationFlags(cmd) @@ -163,6 +162,11 @@ func (o *ReplaceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args [] } o.DeleteOptions = deleteOpts + err = o.DeleteOptions.FilenameOptions.RequireFilenameOrKustomize() + if err != nil { + return err + } + schema, err := f.Validator(o.validate) if err != nil { return err @@ -189,7 +193,7 @@ func (o *ReplaceOptions) Validate(cmd *cobra.Command) error { return fmt.Errorf("--timeout must have --force specified") } - if cmdutil.IsFilenameSliceEmpty(o.DeleteOptions.FilenameOptions.Filenames) { + if cmdutil.IsFilenameSliceEmpty(o.DeleteOptions.FilenameOptions.Filenames, o.DeleteOptions.FilenameOptions.Kustomize) { return cmdutil.UsageErrorf(cmd, "Must specify --filename to replace") } diff --git a/pkg/kubectl/cmd/rollout/rollout_history.go b/pkg/kubectl/cmd/rollout/rollout_history.go index d924550818..3661a62400 100644 --- a/pkg/kubectl/cmd/rollout/rollout_history.go +++ b/pkg/kubectl/cmd/rollout/rollout_history.go @@ -123,7 +123,7 @@ func (o *RolloutHistoryOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, // Validate makes sure all the provided values for command-line options are valid func (o *RolloutHistoryOptions) Validate() error { - if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { + if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) { return fmt.Errorf("required resource not specified") } if o.Revision < 0 { diff --git a/pkg/kubectl/cmd/rollout/rollout_pause.go b/pkg/kubectl/cmd/rollout/rollout_pause.go index b29963d649..56dd4e1c8c 100644 --- a/pkg/kubectl/cmd/rollout/rollout_pause.go +++ b/pkg/kubectl/cmd/rollout/rollout_pause.go @@ -117,7 +117,7 @@ func (o *PauseOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []st } func (o *PauseOptions) Validate() error { - if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { + if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) { return fmt.Errorf("required resource not specified") } return nil diff --git a/pkg/kubectl/cmd/rollout/rollout_resume.go b/pkg/kubectl/cmd/rollout/rollout_resume.go index f1f9e4e33d..d46e9a6ec8 100644 --- a/pkg/kubectl/cmd/rollout/rollout_resume.go +++ b/pkg/kubectl/cmd/rollout/rollout_resume.go @@ -121,7 +121,7 @@ func (o *ResumeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s } func (o *ResumeOptions) Validate() error { - if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { + if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) { return fmt.Errorf("required resource not specified") } return nil diff --git a/pkg/kubectl/cmd/rollout/rollout_status.go b/pkg/kubectl/cmd/rollout/rollout_status.go index fde72df1d8..38a16af914 100644 --- a/pkg/kubectl/cmd/rollout/rollout_status.go +++ b/pkg/kubectl/cmd/rollout/rollout_status.go @@ -148,7 +148,7 @@ func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error // Validate makes sure all the provided values for command-line options are valid func (o *RolloutStatusOptions) Validate() error { - if len(o.BuilderArgs) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) { + if len(o.BuilderArgs) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames, o.FilenameOptions.Kustomize) { return fmt.Errorf("required resource not specified") } diff --git a/pkg/kubectl/cmd/rollout/rollout_undo.go b/pkg/kubectl/cmd/rollout/rollout_undo.go index c4db88af20..a06e5c5fec 100644 --- a/pkg/kubectl/cmd/rollout/rollout_undo.go +++ b/pkg/kubectl/cmd/rollout/rollout_undo.go @@ -126,7 +126,7 @@ func (o *UndoOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []str } func (o *UndoOptions) Validate() error { - if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { + if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) { return fmt.Errorf("required resource not specified") } return nil diff --git a/pkg/kubectl/cmd/set/set_image.go b/pkg/kubectl/cmd/set/set_image.go index ef422879ba..7cf1b13f36 100644 --- a/pkg/kubectl/cmd/set/set_image.go +++ b/pkg/kubectl/cmd/set/set_image.go @@ -198,7 +198,7 @@ func (o *SetImageOptions) Validate() error { if o.All && len(o.Selector) > 0 { errors = append(errors, fmt.Errorf("cannot set --all and --selector at the same time")) } - if len(o.Resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames) { + if len(o.Resources) < 1 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) { errors = append(errors, fmt.Errorf("one or more resources must be specified as or /")) } if len(o.ContainerImages) < 1 {