mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 10:19:50 +00:00
Merge pull request #14161 from feihujiang/letKubectlExecFollowDashRule
Auto commit by PR queue bot
This commit is contained in:
commit
cadb6c06be
@ -59,7 +59,8 @@ func NewCmdExec(f *cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *
|
|||||||
Long: "Execute a command in a container.",
|
Long: "Execute a command in a container.",
|
||||||
Example: exec_example,
|
Example: exec_example,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
argsLenAtDash := cmd.ArgsLenAtDash()
|
||||||
|
cmdutil.CheckErr(options.Complete(f, cmd, args, argsLenAtDash))
|
||||||
cmdutil.CheckErr(options.Validate())
|
cmdutil.CheckErr(options.Validate())
|
||||||
cmdutil.CheckErr(options.Run())
|
cmdutil.CheckErr(options.Run())
|
||||||
},
|
},
|
||||||
@ -107,8 +108,9 @@ type ExecOptions struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Complete verifies command line arguments and loads data from the command environment
|
// Complete verifies command line arguments and loads data from the command environment
|
||||||
func (p *ExecOptions) Complete(f *cmdutil.Factory, cmd *cobra.Command, argsIn []string) error {
|
func (p *ExecOptions) Complete(f *cmdutil.Factory, cmd *cobra.Command, argsIn []string, argsLenAtDash int) error {
|
||||||
if len(p.PodName) == 0 && len(argsIn) == 0 {
|
// Let kubectl exec follow rules for `--`, see #13004 issue
|
||||||
|
if len(p.PodName) == 0 && (len(argsIn) == 0 || argsLenAtDash == 0) {
|
||||||
return cmdutil.UsageError(cmd, "POD is required for exec")
|
return cmdutil.UsageError(cmd, "POD is required for exec")
|
||||||
}
|
}
|
||||||
if len(p.PodName) != 0 {
|
if len(p.PodName) != 0 {
|
||||||
|
@ -48,6 +48,7 @@ func (f *fakeRemoteExecutor) Execute(method string, url *url.URL, config *client
|
|||||||
func TestPodAndContainer(t *testing.T) {
|
func TestPodAndContainer(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
args []string
|
args []string
|
||||||
|
argsLenAtDash int
|
||||||
p *ExecOptions
|
p *ExecOptions
|
||||||
name string
|
name string
|
||||||
expectError bool
|
expectError bool
|
||||||
@ -56,43 +57,65 @@ func TestPodAndContainer(t *testing.T) {
|
|||||||
expectedArgs []string
|
expectedArgs []string
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
p: &ExecOptions{},
|
p: &ExecOptions{},
|
||||||
expectError: true,
|
argsLenAtDash: -1,
|
||||||
name: "empty",
|
expectError: true,
|
||||||
|
name: "empty",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: &ExecOptions{PodName: "foo"},
|
p: &ExecOptions{PodName: "foo"},
|
||||||
expectError: true,
|
argsLenAtDash: -1,
|
||||||
name: "no cmd",
|
expectError: true,
|
||||||
|
name: "no cmd",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: &ExecOptions{PodName: "foo", ContainerName: "bar"},
|
p: &ExecOptions{PodName: "foo", ContainerName: "bar"},
|
||||||
expectError: true,
|
argsLenAtDash: -1,
|
||||||
name: "no cmd, w/ container",
|
expectError: true,
|
||||||
|
name: "no cmd, w/ container",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: &ExecOptions{PodName: "foo"},
|
p: &ExecOptions{PodName: "foo"},
|
||||||
args: []string{"cmd"},
|
args: []string{"cmd"},
|
||||||
expectedPod: "foo",
|
argsLenAtDash: -1,
|
||||||
expectedArgs: []string{"cmd"},
|
expectedPod: "foo",
|
||||||
name: "pod in flags",
|
expectedArgs: []string{"cmd"},
|
||||||
|
name: "pod in flags",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: &ExecOptions{},
|
p: &ExecOptions{},
|
||||||
args: []string{"foo"},
|
args: []string{"foo", "cmd"},
|
||||||
expectError: true,
|
argsLenAtDash: 0,
|
||||||
name: "no cmd, w/o flags",
|
expectError: true,
|
||||||
|
name: "no pod, pod name is behind dash",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: &ExecOptions{},
|
p: &ExecOptions{},
|
||||||
args: []string{"foo", "cmd"},
|
args: []string{"foo"},
|
||||||
expectedPod: "foo",
|
argsLenAtDash: -1,
|
||||||
expectedArgs: []string{"cmd"},
|
expectError: true,
|
||||||
name: "cmd, w/o flags",
|
name: "no cmd, w/o flags",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
p: &ExecOptions{},
|
||||||
|
args: []string{"foo", "cmd"},
|
||||||
|
argsLenAtDash: -1,
|
||||||
|
expectedPod: "foo",
|
||||||
|
expectedArgs: []string{"cmd"},
|
||||||
|
name: "cmd, w/o flags",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
p: &ExecOptions{},
|
||||||
|
args: []string{"foo", "cmd"},
|
||||||
|
argsLenAtDash: 1,
|
||||||
|
expectedPod: "foo",
|
||||||
|
expectedArgs: []string{"cmd"},
|
||||||
|
name: "cmd, cmd is behind dash",
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
p: &ExecOptions{ContainerName: "bar"},
|
p: &ExecOptions{ContainerName: "bar"},
|
||||||
args: []string{"foo", "cmd"},
|
args: []string{"foo", "cmd"},
|
||||||
|
argsLenAtDash: -1,
|
||||||
expectedPod: "foo",
|
expectedPod: "foo",
|
||||||
expectedContainer: "bar",
|
expectedContainer: "bar",
|
||||||
expectedArgs: []string{"cmd"},
|
expectedArgs: []string{"cmd"},
|
||||||
@ -110,7 +133,7 @@ func TestPodAndContainer(t *testing.T) {
|
|||||||
|
|
||||||
cmd := &cobra.Command{}
|
cmd := &cobra.Command{}
|
||||||
options := test.p
|
options := test.p
|
||||||
err := options.Complete(f, cmd, test.args)
|
err := options.Complete(f, cmd, test.args, test.argsLenAtDash)
|
||||||
if test.expectError && err == nil {
|
if test.expectError && err == nil {
|
||||||
t.Errorf("unexpected non-error (%s)", test.name)
|
t.Errorf("unexpected non-error (%s)", test.name)
|
||||||
}
|
}
|
||||||
@ -189,7 +212,8 @@ func TestExec(t *testing.T) {
|
|||||||
Executor: ex,
|
Executor: ex,
|
||||||
}
|
}
|
||||||
cmd := &cobra.Command{}
|
cmd := &cobra.Command{}
|
||||||
if err := params.Complete(f, cmd, []string{"test", "command"}); err != nil {
|
args := []string{"test", "command"}
|
||||||
|
if err := params.Complete(f, cmd, args, -1); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
err := params.Run()
|
err := params.Run()
|
||||||
|
Loading…
Reference in New Issue
Block a user