mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 10:51:29 +00:00
cmd/*: fail on unrecognized flags/arguments for component CLI
In case a malformed flag is passed to k8s components such as "–foo", where "–" is not an ASCII dash character, the components currently silently ignore the flag and treat it as a positional argument. Make k8s components/commands exit with an error if a positional argument that is not empty is found. Include a custom error message for all components except kubeadm, as cobra.NoArgs is used in a lot of places already (can be fixed in a followup). The kubelet already handles this properly - e.g.: 'unknown command: "–foo"' This change affects: - cloud-controller-manager - kube-apiserver - kube-controller-manager - kube-proxy - kubeadm {alpha|config|token|version} - kubemark Signed-off-by: Monis Khan <mok@vmware.com> Signed-off-by: Lubomir I. Ivanov <lubomirivanov@vmware.com>
This commit is contained in:
parent
60559bc919
commit
fc4f91f10b
@ -80,6 +80,14 @@ the cloud specific control loops shipped with Kubernetes.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
|
for _, arg := range args {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fs := cmd.Flags()
|
fs := cmd.Flags()
|
||||||
|
@ -117,6 +117,14 @@ cluster's shared state through which all other components interact.`,
|
|||||||
|
|
||||||
return Run(completedOptions, genericapiserver.SetupSignalHandler())
|
return Run(completedOptions, genericapiserver.SetupSignalHandler())
|
||||||
},
|
},
|
||||||
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
|
for _, arg := range args {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fs := cmd.Flags()
|
fs := cmd.Flags()
|
||||||
|
@ -119,6 +119,14 @@ controller, and serviceaccounts controller.`,
|
|||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
|
for _, arg := range args {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
fs := cmd.Flags()
|
fs := cmd.Flags()
|
||||||
|
@ -294,10 +294,7 @@ func (o *Options) processHostnameOverrideFlag() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Validate validates all the required options.
|
// Validate validates all the required options.
|
||||||
func (o *Options) Validate(args []string) error {
|
func (o *Options) Validate() error {
|
||||||
if len(args) != 0 {
|
|
||||||
return errors.New("no arguments are supported")
|
|
||||||
}
|
|
||||||
if errs := validation.Validate(o.config); len(errs) != 0 {
|
if errs := validation.Validate(o.config); len(errs) != 0 {
|
||||||
return errs.ToAggregate()
|
return errs.ToAggregate()
|
||||||
}
|
}
|
||||||
@ -490,7 +487,7 @@ with the apiserver API to configure the proxy.`,
|
|||||||
if err := opts.Complete(); err != nil {
|
if err := opts.Complete(); err != nil {
|
||||||
klog.Fatalf("failed complete: %v", err)
|
klog.Fatalf("failed complete: %v", err)
|
||||||
}
|
}
|
||||||
if err := opts.Validate(args); err != nil {
|
if err := opts.Validate(); err != nil {
|
||||||
klog.Fatalf("failed validate: %v", err)
|
klog.Fatalf("failed validate: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -498,6 +495,14 @@ with the apiserver API to configure the proxy.`,
|
|||||||
klog.Exit(err)
|
klog.Exit(err)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
|
for _, arg := range args {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
@ -27,7 +27,7 @@ import (
|
|||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
|
||||||
"k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
||||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||||
@ -83,11 +83,19 @@ kube-scheduler is the reference implementation.
|
|||||||
See [scheduling](https://kubernetes.io/docs/concepts/scheduling/)
|
See [scheduling](https://kubernetes.io/docs/concepts/scheduling/)
|
||||||
for more information about scheduling and the kube-scheduler component.`,
|
for more information about scheduling and the kube-scheduler component.`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
if err := runCommand(cmd, args, opts, registryOptions...); err != nil {
|
if err := runCommand(cmd, opts, registryOptions...); err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "%v\n", err)
|
fmt.Fprintf(os.Stderr, "%v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
|
for _, arg := range args {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
fs := cmd.Flags()
|
fs := cmd.Flags()
|
||||||
namedFlagSets := opts.Flags()
|
namedFlagSets := opts.Flags()
|
||||||
@ -114,14 +122,14 @@ for more information about scheduling and the kube-scheduler component.`,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// runCommand runs the scheduler.
|
// runCommand runs the scheduler.
|
||||||
func runCommand(cmd *cobra.Command, args []string, opts *options.Options, registryOptions ...Option) error {
|
func runCommand(cmd *cobra.Command, opts *options.Options, registryOptions ...Option) error {
|
||||||
verflag.PrintAndExitIfRequested()
|
verflag.PrintAndExitIfRequested()
|
||||||
cliflag.PrintFlags(cmd.Flags())
|
cliflag.PrintFlags(cmd.Flags())
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
cc, sched, err := Setup(ctx, args, opts, registryOptions...)
|
cc, sched, err := Setup(ctx, opts, registryOptions...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -298,11 +306,7 @@ func WithPlugin(name string, factory framework.PluginFactory) Option {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Setup creates a completed config and a scheduler based on the command args and options
|
// Setup creates a completed config and a scheduler based on the command args and options
|
||||||
func Setup(ctx context.Context, args []string, opts *options.Options, outOfTreeRegistryOptions ...Option) (*schedulerserverconfig.CompletedConfig, *scheduler.Scheduler, error) {
|
func Setup(ctx context.Context, opts *options.Options, outOfTreeRegistryOptions ...Option) (*schedulerserverconfig.CompletedConfig, *scheduler.Scheduler, error) {
|
||||||
if len(args) != 0 {
|
|
||||||
fmt.Fprint(os.Stderr, "arguments are not supported\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if errs := opts.Validate(); len(errs) > 0 {
|
if errs := opts.Validate(); len(errs) > 0 {
|
||||||
return nil, nil, utilerrors.NewAggregate(errs)
|
return nil, nil, utilerrors.NewAggregate(errs)
|
||||||
}
|
}
|
||||||
|
@ -373,10 +373,9 @@ profiles:
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var args []string
|
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
cc, sched, err := Setup(ctx, args, opts)
|
cc, sched, err := Setup(ctx, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -114,7 +114,7 @@ func StartTestServer(t Logger, customFlags []string) (result TestServer, err err
|
|||||||
t.Logf("kube-scheduler will listen insecurely on port %d...", opts.CombinedInsecureServing.BindPort)
|
t.Logf("kube-scheduler will listen insecurely on port %d...", opts.CombinedInsecureServing.BindPort)
|
||||||
}
|
}
|
||||||
|
|
||||||
cc, sched, err := app.Setup(ctx, []string{}, opts)
|
cc, sched, err := app.Setup(ctx, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return result, fmt.Errorf("failed to create config from options: %v", err)
|
return result, fmt.Errorf("failed to create config from options: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,7 @@ func NewCmdCertificateKey() *cobra.Command {
|
|||||||
fmt.Println(key)
|
fmt.Println(key)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +196,7 @@ func getRenewSubCommands(out io.Writer, kdir string) []*cobra.Command {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
addRenewFlags(allCmd, flags)
|
addRenewFlags(allCmd, flags)
|
||||||
|
|
||||||
@ -378,6 +380,7 @@ func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command {
|
|||||||
w.Flush()
|
w.Flush()
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
addExpirationFlags(cmd, flags)
|
addExpirationFlags(cmd, flags)
|
||||||
|
|
||||||
|
@ -94,6 +94,7 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
|
|||||||
// Otherwise, write a kubeconfig file with a generate client cert
|
// Otherwise, write a kubeconfig file with a generate client cert
|
||||||
return kubeconfigphase.WriteKubeConfigWithClientCert(out, internalcfg, clientName, organizations)
|
return kubeconfigphase.WriteKubeConfigWithClientCert(out, internalcfg, clientName, organizations)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add ClusterConfiguration backed flags to the command
|
// Add ClusterConfiguration backed flags to the command
|
||||||
|
@ -104,6 +104,7 @@ func newCmdKubeletConfigEnableDynamic() *cobra.Command {
|
|||||||
|
|
||||||
return kubeletphase.EnableDynamicConfigForNode(client, nodeName, kubeletVersion)
|
return kubeletphase.EnableDynamicConfigForNode(client, nodeName, kubeletVersion)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile)
|
options.AddKubeConfigFlag(cmd.Flags(), &kubeConfigFile)
|
||||||
|
@ -136,6 +136,7 @@ func getSelfhostingSubCommand(in io.Reader) *cobra.Command {
|
|||||||
waiter := apiclient.NewKubeWaiter(client, 2*time.Minute, os.Stdout)
|
waiter := apiclient.NewKubeWaiter(client, 2*time.Minute, os.Stdout)
|
||||||
return selfhosting.CreateSelfHostedControlPlane(constants.GetStaticPodDirectory(), constants.KubernetesDir, internalcfg, client, waiter, false, certsInSecrets)
|
return selfhosting.CreateSelfHostedControlPlane(constants.GetStaticPodDirectory(), constants.KubernetesDir, internalcfg, client, waiter, false, certsInSecrets)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add flags to the command
|
// Add flags to the command
|
||||||
|
@ -140,6 +140,7 @@ func newCmdConfigPrintActionDefaults(out io.Writer, action string, configBytesPr
|
|||||||
}
|
}
|
||||||
return runConfigPrintActionDefaults(out, groups, configBytesProc)
|
return runConfigPrintActionDefaults(out, groups, configBytesProc)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
cmd.Flags().StringSliceVar(&kinds, "component-configs", kinds,
|
cmd.Flags().StringSliceVar(&kinds, "component-configs", kinds,
|
||||||
fmt.Sprintf("A comma-separated list for component config API objects to print the default values for. Available values: %v. If this flag is not set, no component configs will be printed.", getSupportedComponentConfigKinds()))
|
fmt.Sprintf("A comma-separated list for component config API objects to print the default values for. Available values: %v. If this flag is not set, no component configs will be printed.", getSupportedComponentConfigKinds()))
|
||||||
@ -295,6 +296,7 @@ func NewCmdConfigMigrate(out io.Writer) *cobra.Command {
|
|||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
cmd.Flags().StringVar(&oldCfgPath, "old-config", "", "Path to the kubeadm config file that is using an old API version and should be converted. This flag is mandatory.")
|
cmd.Flags().StringVar(&oldCfgPath, "old-config", "", "Path to the kubeadm config file that is using an old API version and should be converted. This flag is mandatory.")
|
||||||
cmd.Flags().StringVar(&newCfgPath, "new-config", "", "Path to the resulting equivalent kubeadm config file using the new API version. Optional, if not specified output will be sent to STDOUT.")
|
cmd.Flags().StringVar(&newCfgPath, "new-config", "", "Path to the resulting equivalent kubeadm config file using the new API version. Optional, if not specified output will be sent to STDOUT.")
|
||||||
@ -335,6 +337,7 @@ func NewCmdConfigView(out io.Writer, kubeConfigFile *string) *cobra.Command {
|
|||||||
|
|
||||||
return RunConfigView(out, client)
|
return RunConfigView(out, client)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,6 +378,7 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co
|
|||||||
klog.V(1).Infof("[config] uploading configuration")
|
klog.V(1).Infof("[config] uploading configuration")
|
||||||
return uploadconfig.UploadConfiguration(internalcfg, client)
|
return uploadconfig.UploadConfiguration(internalcfg, client)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
options.AddConfigFlag(cmd.Flags(), &cfgPath)
|
options.AddConfigFlag(cmd.Flags(), &cfgPath)
|
||||||
return cmd
|
return cmd
|
||||||
@ -429,6 +433,7 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C
|
|||||||
klog.V(1).Infof("[config] uploading configuration")
|
klog.V(1).Infof("[config] uploading configuration")
|
||||||
return uploadconfig.UploadConfiguration(internalcfg, client)
|
return uploadconfig.UploadConfiguration(internalcfg, client)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
AddInitConfigFlags(cmd.PersistentFlags(), initCfg)
|
AddInitConfigFlags(cmd.PersistentFlags(), initCfg)
|
||||||
AddClusterConfigFlags(cmd.PersistentFlags(), clusterCfg, &featureGatesString)
|
AddClusterConfigFlags(cmd.PersistentFlags(), clusterCfg, &featureGatesString)
|
||||||
@ -487,6 +492,7 @@ func NewCmdConfigImagesPull() *cobra.Command {
|
|||||||
}
|
}
|
||||||
return PullControlPlaneImages(containerRuntime, &internalcfg.ClusterConfiguration)
|
return PullControlPlaneImages(containerRuntime, &internalcfg.ClusterConfiguration)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalClusterCfg, &cfgPath, &featureGatesString)
|
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalClusterCfg, &cfgPath, &featureGatesString)
|
||||||
cmdutil.AddCRISocketFlag(cmd.PersistentFlags(), &externalInitCfg.NodeRegistration.CRISocket)
|
cmdutil.AddCRISocketFlag(cmd.PersistentFlags(), &externalInitCfg.NodeRegistration.CRISocket)
|
||||||
@ -556,6 +562,7 @@ func NewCmdConfigImagesList(out io.Writer, mockK8sVersion *string) *cobra.Comman
|
|||||||
|
|
||||||
return imagesList.Run(out, printer)
|
return imagesList.Run(out, printer)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
outputFlags.AddFlags(cmd)
|
outputFlags.AddFlags(cmd)
|
||||||
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalcfg, &cfgPath, &featureGatesString)
|
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalcfg, &cfgPath, &featureGatesString)
|
||||||
|
@ -173,6 +173,7 @@ func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
|
|||||||
|
|
||||||
return RunListTokens(out, errW, client, printer)
|
return RunListTokens(out, errW, client, printer)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
|
|
||||||
outputFlags.AddFlags(listCmd)
|
outputFlags.AddFlags(listCmd)
|
||||||
@ -226,6 +227,7 @@ func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
|
|||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return RunGenerateToken(out)
|
return RunGenerateToken(out)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@ func NewCmdVersion(out io.Writer) *cobra.Command {
|
|||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
return RunVersion(out, cmd)
|
return RunVersion(out, cmd)
|
||||||
},
|
},
|
||||||
|
Args: cobra.NoArgs,
|
||||||
}
|
}
|
||||||
cmd.Flags().StringP("output", "o", "", "Output format; available options are 'yaml', 'json' and 'short'")
|
cmd.Flags().StringP("output", "o", "", "Output format; available options are 'yaml', 'json' and 'short'")
|
||||||
return cmd
|
return cmd
|
||||||
|
@ -48,7 +48,11 @@ func TestCmdVersion(t *testing.T) {
|
|||||||
kubeadmPath := getKubeadmPath()
|
kubeadmPath := getKubeadmPath()
|
||||||
for _, rt := range versionTest {
|
for _, rt := range versionTest {
|
||||||
t.Run(rt.name, func(t *testing.T) {
|
t.Run(rt.name, func(t *testing.T) {
|
||||||
stdout, _, _, actual := RunCmd(kubeadmPath, "version", rt.args)
|
args := []string{"version"}
|
||||||
|
if len(rt.args) > 0 {
|
||||||
|
args = append(args, rt.args)
|
||||||
|
}
|
||||||
|
stdout, _, _, actual := RunCmd(kubeadmPath, args...)
|
||||||
if (actual == nil) != rt.expected {
|
if (actual == nil) != rt.expected {
|
||||||
t.Errorf(
|
t.Errorf(
|
||||||
"failed CmdVersion running 'kubeadm version %s' with an error: %v\n\texpected: %t\n\t actual: %t",
|
"failed CmdVersion running 'kubeadm version %s' with an error: %v\n\texpected: %t\n\t actual: %t",
|
||||||
|
@ -148,6 +148,14 @@ func newHollowNodeCommand() *cobra.Command {
|
|||||||
verflag.PrintAndExitIfRequested()
|
verflag.PrintAndExitIfRequested()
|
||||||
run(s)
|
run(s)
|
||||||
},
|
},
|
||||||
|
Args: func(cmd *cobra.Command, args []string) error {
|
||||||
|
for _, arg := range args {
|
||||||
|
if len(arg) > 0 {
|
||||||
|
return fmt.Errorf("%q does not take any arguments, got %q", cmd.CommandPath(), args)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
s.addFlags(cmd.Flags())
|
s.addFlags(cmd.Flags())
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user