mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-20 18:31:15 +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()
|
||||
|
@ -117,6 +117,14 @@ cluster's shared state through which all other components interact.`,
|
||||
|
||||
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()
|
||||
|
@ -119,6 +119,14 @@ controller, and serviceaccounts controller.`,
|
||||
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()
|
||||
|
@ -294,10 +294,7 @@ func (o *Options) processHostnameOverrideFlag() error {
|
||||
}
|
||||
|
||||
// Validate validates all the required options.
|
||||
func (o *Options) Validate(args []string) error {
|
||||
if len(args) != 0 {
|
||||
return errors.New("no arguments are supported")
|
||||
}
|
||||
func (o *Options) Validate() error {
|
||||
if errs := validation.Validate(o.config); len(errs) != 0 {
|
||||
return errs.ToAggregate()
|
||||
}
|
||||
@ -490,7 +487,7 @@ with the apiserver API to configure the proxy.`,
|
||||
if err := opts.Complete(); err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -498,6 +495,14 @@ with the apiserver API to configure the proxy.`,
|
||||
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
|
||||
|
@ -27,7 +27,7 @@ import (
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
eventsv1beta1 "k8s.io/api/events/v1beta1"
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apiserver/pkg/authentication/authenticator"
|
||||
@ -83,11 +83,19 @@ kube-scheduler is the reference implementation.
|
||||
See [scheduling](https://kubernetes.io/docs/concepts/scheduling/)
|
||||
for more information about scheduling and the kube-scheduler component.`,
|
||||
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)
|
||||
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()
|
||||
namedFlagSets := opts.Flags()
|
||||
@ -114,14 +122,14 @@ for more information about scheduling and the kube-scheduler component.`,
|
||||
}
|
||||
|
||||
// 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()
|
||||
cliflag.PrintFlags(cmd.Flags())
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
|
||||
cc, sched, err := Setup(ctx, args, opts, registryOptions...)
|
||||
cc, sched, err := Setup(ctx, opts, registryOptions...)
|
||||
if err != nil {
|
||||
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
|
||||
func Setup(ctx context.Context, args []string, opts *options.Options, outOfTreeRegistryOptions ...Option) (*schedulerserverconfig.CompletedConfig, *scheduler.Scheduler, error) {
|
||||
if len(args) != 0 {
|
||||
fmt.Fprint(os.Stderr, "arguments are not supported\n")
|
||||
}
|
||||
|
||||
func Setup(ctx context.Context, opts *options.Options, outOfTreeRegistryOptions ...Option) (*schedulerserverconfig.CompletedConfig, *scheduler.Scheduler, error) {
|
||||
if errs := opts.Validate(); len(errs) > 0 {
|
||||
return nil, nil, utilerrors.NewAggregate(errs)
|
||||
}
|
||||
|
@ -373,10 +373,9 @@ profiles:
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
var args []string
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel()
|
||||
cc, sched, err := Setup(ctx, args, opts)
|
||||
cc, sched, err := Setup(ctx, opts)
|
||||
if err != nil {
|
||||
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)
|
||||
}
|
||||
|
||||
cc, sched, err := app.Setup(ctx, []string{}, opts)
|
||||
cc, sched, err := app.Setup(ctx, opts)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("failed to create config from options: %v", err)
|
||||
}
|
||||
|
@ -100,6 +100,7 @@ func NewCmdCertificateKey() *cobra.Command {
|
||||
fmt.Println(key)
|
||||
return nil
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +196,7 @@ func getRenewSubCommands(out io.Writer, kdir string) []*cobra.Command {
|
||||
}
|
||||
return nil
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
addRenewFlags(allCmd, flags)
|
||||
|
||||
@ -378,6 +380,7 @@ func newCmdCertsExpiration(out io.Writer, kdir string) *cobra.Command {
|
||||
w.Flush()
|
||||
return nil
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
addExpirationFlags(cmd, flags)
|
||||
|
||||
|
@ -94,6 +94,7 @@ func newCmdUserKubeConfig(out io.Writer) *cobra.Command {
|
||||
// Otherwise, write a kubeconfig file with a generate client cert
|
||||
return kubeconfigphase.WriteKubeConfigWithClientCert(out, internalcfg, clientName, organizations)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
// Add ClusterConfiguration backed flags to the command
|
||||
|
@ -104,6 +104,7 @@ func newCmdKubeletConfigEnableDynamic() *cobra.Command {
|
||||
|
||||
return kubeletphase.EnableDynamicConfigForNode(client, nodeName, kubeletVersion)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
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)
|
||||
return selfhosting.CreateSelfHostedControlPlane(constants.GetStaticPodDirectory(), constants.KubernetesDir, internalcfg, client, waiter, false, certsInSecrets)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
// Add flags to the command
|
||||
|
@ -140,6 +140,7 @@ func newCmdConfigPrintActionDefaults(out io.Writer, action string, configBytesPr
|
||||
}
|
||||
return runConfigPrintActionDefaults(out, groups, configBytesProc)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
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()))
|
||||
@ -295,6 +296,7 @@ func NewCmdConfigMigrate(out io.Writer) *cobra.Command {
|
||||
}
|
||||
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(&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)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
}
|
||||
|
||||
@ -375,6 +378,7 @@ func NewCmdConfigUploadFromFile(out io.Writer, kubeConfigFile *string) *cobra.Co
|
||||
klog.V(1).Infof("[config] uploading configuration")
|
||||
return uploadconfig.UploadConfiguration(internalcfg, client)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
options.AddConfigFlag(cmd.Flags(), &cfgPath)
|
||||
return cmd
|
||||
@ -429,6 +433,7 @@ func NewCmdConfigUploadFromFlags(out io.Writer, kubeConfigFile *string) *cobra.C
|
||||
klog.V(1).Infof("[config] uploading configuration")
|
||||
return uploadconfig.UploadConfiguration(internalcfg, client)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
AddInitConfigFlags(cmd.PersistentFlags(), initCfg)
|
||||
AddClusterConfigFlags(cmd.PersistentFlags(), clusterCfg, &featureGatesString)
|
||||
@ -487,6 +492,7 @@ func NewCmdConfigImagesPull() *cobra.Command {
|
||||
}
|
||||
return PullControlPlaneImages(containerRuntime, &internalcfg.ClusterConfiguration)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
AddImagesCommonConfigFlags(cmd.PersistentFlags(), externalClusterCfg, &cfgPath, &featureGatesString)
|
||||
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)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
outputFlags.AddFlags(cmd)
|
||||
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)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
|
||||
outputFlags.AddFlags(listCmd)
|
||||
@ -226,6 +227,7 @@ func NewCmdTokenGenerate(out io.Writer) *cobra.Command {
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
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 {
|
||||
return RunVersion(out, cmd)
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
}
|
||||
cmd.Flags().StringP("output", "o", "", "Output format; available options are 'yaml', 'json' and 'short'")
|
||||
return cmd
|
||||
|
@ -48,7 +48,11 @@ func TestCmdVersion(t *testing.T) {
|
||||
kubeadmPath := getKubeadmPath()
|
||||
for _, rt := range versionTest {
|
||||
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 {
|
||||
t.Errorf(
|
||||
"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()
|
||||
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())
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user