Merge pull request #124123 from sttts/sttts-kubectl-plugin-positional
kubectl: fix plugin lookup with positional arguments Kubernetes-commit: ca4a864336bdb1d61bc19e90a9c81ac6c661e6d7
This commit is contained in:
commit
54dfe4c559
4
go.mod
4
go.mod
|
|
@ -30,8 +30,8 @@ require (
|
||||||
github.com/stretchr/testify v1.8.4
|
github.com/stretchr/testify v1.8.4
|
||||||
golang.org/x/sys v0.18.0
|
golang.org/x/sys v0.18.0
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
k8s.io/api v0.0.0-20240418013359-a819b1d9bd16
|
k8s.io/api v0.0.0-20240418093414-76b6c7ce02a4
|
||||||
k8s.io/apimachinery v0.0.0-20240418093209-8c36da9e60f7
|
k8s.io/apimachinery v0.0.0-20240418133208-ea31e5150286
|
||||||
k8s.io/cli-runtime v0.0.0-20240404041703-9ad5569b61bc
|
k8s.io/cli-runtime v0.0.0-20240404041703-9ad5569b61bc
|
||||||
k8s.io/client-go v0.0.0-20240418093651-9990b0b122c9
|
k8s.io/client-go v0.0.0-20240418093651-9990b0b122c9
|
||||||
k8s.io/component-base v0.0.0-20240418094434-57ba0489bfa6
|
k8s.io/component-base v0.0.0-20240418094434-57ba0489bfa6
|
||||||
|
|
|
||||||
8
go.sum
8
go.sum
|
|
@ -276,10 +276,10 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
k8s.io/api v0.0.0-20240418013359-a819b1d9bd16 h1:DXJla1ulezom5N0QIRlZetozcxtRPdS7U+muHDJuiO4=
|
k8s.io/api v0.0.0-20240418093414-76b6c7ce02a4 h1:Aoz6y1eO+GKFC27cTyO+VJkbaEyQsGec2IhAYYaN7IU=
|
||||||
k8s.io/api v0.0.0-20240418013359-a819b1d9bd16/go.mod h1:a1YU16kjsAapUzg1LYaOqTnbMlo87NXy9bSeWjRmfoo=
|
k8s.io/api v0.0.0-20240418093414-76b6c7ce02a4/go.mod h1:sbi+6EMV/95qn9kNfIj4HSNs4jcBqkcBxEAD+AKHUHY=
|
||||||
k8s.io/apimachinery v0.0.0-20240418093209-8c36da9e60f7 h1:SydhMcp6AJkjqqVcd0o0uz7ntTcs/QyIgIHAFYfIm7E=
|
k8s.io/apimachinery v0.0.0-20240418133208-ea31e5150286 h1:pGpFsAFMSxtFe98HpTcgDgblsARQhckNfASAgCmlXS4=
|
||||||
k8s.io/apimachinery v0.0.0-20240418093209-8c36da9e60f7/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
k8s.io/apimachinery v0.0.0-20240418133208-ea31e5150286/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc=
|
||||||
k8s.io/cli-runtime v0.0.0-20240404041703-9ad5569b61bc h1:a12ozjrLRSgKfGuGr0tFr7Aw+jheNPDo6jh/Y1AOkhU=
|
k8s.io/cli-runtime v0.0.0-20240404041703-9ad5569b61bc h1:a12ozjrLRSgKfGuGr0tFr7Aw+jheNPDo6jh/Y1AOkhU=
|
||||||
k8s.io/cli-runtime v0.0.0-20240404041703-9ad5569b61bc/go.mod h1:XYjtKcGQuoX/UlaQtuRlfn9WIdSSrwDwKAkUx4OdbTk=
|
k8s.io/cli-runtime v0.0.0-20240404041703-9ad5569b61bc/go.mod h1:XYjtKcGQuoX/UlaQtuRlfn9WIdSSrwDwKAkUx4OdbTk=
|
||||||
k8s.io/client-go v0.0.0-20240418093651-9990b0b122c9 h1:eC8SD8kFISw8xhx2kTsXpIuB4qOGtCUdnK+ciXaJeEA=
|
k8s.io/client-go v0.0.0-20240418093651-9990b0b122c9 h1:eC8SD8kFISw8xhx2kTsXpIuB4qOGtCUdnK+ciXaJeEA=
|
||||||
|
|
|
||||||
|
|
@ -136,7 +136,7 @@ func NewDefaultKubectlCommandWithArgs(o KubectlOptions) *cobra.Command {
|
||||||
case "help", cobra.ShellCompRequestCmd, cobra.ShellCompNoDescRequestCmd:
|
case "help", cobra.ShellCompRequestCmd, cobra.ShellCompNoDescRequestCmd:
|
||||||
// Don't search for a plugin
|
// Don't search for a plugin
|
||||||
default:
|
default:
|
||||||
if err := HandlePluginCommand(o.PluginHandler, cmdPathPieces, false); err != nil {
|
if err := HandlePluginCommand(o.PluginHandler, cmdPathPieces, 1); err != nil {
|
||||||
fmt.Fprintf(o.IOStreams.ErrOut, "Error: %v\n", err)
|
fmt.Fprintf(o.IOStreams.ErrOut, "Error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ func NewDefaultKubectlCommandWithArgs(o KubectlOptions) *cobra.Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
if !builtinSubcmdExist {
|
if !builtinSubcmdExist {
|
||||||
if err := HandlePluginCommand(o.PluginHandler, cmdPathPieces, true); err != nil {
|
if err := HandlePluginCommand(o.PluginHandler, cmdPathPieces, len(cmdPathPieces)-len(foundArgs)+1); err != nil {
|
||||||
fmt.Fprintf(o.IOStreams.ErrOut, "Error: %v\n", err)
|
fmt.Fprintf(o.IOStreams.ErrOut, "Error: %v\n", err)
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
@ -259,7 +259,7 @@ func (h *DefaultPluginHandler) Execute(executablePath string, cmdArgs, environme
|
||||||
|
|
||||||
// HandlePluginCommand receives a pluginHandler and command-line arguments and attempts to find
|
// HandlePluginCommand receives a pluginHandler and command-line arguments and attempts to find
|
||||||
// a plugin executable on the PATH that satisfies the given arguments.
|
// a plugin executable on the PATH that satisfies the given arguments.
|
||||||
func HandlePluginCommand(pluginHandler PluginHandler, cmdArgs []string, exactMatch bool) error {
|
func HandlePluginCommand(pluginHandler PluginHandler, cmdArgs []string, minArgs int) error {
|
||||||
var remainingArgs []string // all "non-flag" arguments
|
var remainingArgs []string // all "non-flag" arguments
|
||||||
for _, arg := range cmdArgs {
|
for _, arg := range cmdArgs {
|
||||||
if strings.HasPrefix(arg, "-") {
|
if strings.HasPrefix(arg, "-") {
|
||||||
|
|
@ -279,13 +279,14 @@ func HandlePluginCommand(pluginHandler PluginHandler, cmdArgs []string, exactMat
|
||||||
for len(remainingArgs) > 0 {
|
for len(remainingArgs) > 0 {
|
||||||
path, found := pluginHandler.Lookup(strings.Join(remainingArgs, "-"))
|
path, found := pluginHandler.Lookup(strings.Join(remainingArgs, "-"))
|
||||||
if !found {
|
if !found {
|
||||||
if exactMatch {
|
remainingArgs = remainingArgs[:len(remainingArgs)-1]
|
||||||
// if exactMatch is true, we shouldn't continue searching with shorter names.
|
if len(remainingArgs) < minArgs {
|
||||||
|
// we shouldn't continue searching with shorter names.
|
||||||
// this is especially for not searching kubectl-create plugin
|
// this is especially for not searching kubectl-create plugin
|
||||||
// when kubectl-create-foo plugin is not found.
|
// when kubectl-create-foo plugin is not found.
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
remainingArgs = remainingArgs[:len(remainingArgs)-1]
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -196,6 +196,18 @@ func TestKubectlCommandHandlesPlugins(t *testing.T) {
|
||||||
expectPlugin: "plugin/testdata/kubectl-foo",
|
expectPlugin: "plugin/testdata/kubectl-foo",
|
||||||
expectPluginArgs: []string{"--bar"},
|
expectPluginArgs: []string{"--bar"},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "test that a plugin executable is found based on command args with positional argument",
|
||||||
|
args: []string{"kubectl", "foo", "positional", "--bar"},
|
||||||
|
expectPlugin: "plugin/testdata/kubectl-foo",
|
||||||
|
expectPluginArgs: []string{"positional", "--bar"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "test that an allowed subcommand plugin executable is found based on command args with positional argument",
|
||||||
|
args: []string{"kubectl", "create", "foo", "positional", "--bar"},
|
||||||
|
expectPlugin: "plugin/testdata/kubectl-create-foo",
|
||||||
|
expectPluginArgs: []string{"positional", "--bar"},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "test that a plugin does not execute over an existing command by the same name",
|
name: "test that a plugin does not execute over an existing command by the same name",
|
||||||
args: []string{"kubectl", "version", "--client=true"},
|
args: []string{"kubectl", "version", "--client=true"},
|
||||||
|
|
@ -330,6 +342,7 @@ func (h *testPluginHandler) Lookup(filename string) (string, bool) {
|
||||||
for _, p := range plugins {
|
for _, p := range plugins {
|
||||||
filenameWithSuportedPrefix = fmt.Sprintf("%s-%s", prefix, filename)
|
filenameWithSuportedPrefix = fmt.Sprintf("%s-%s", prefix, filename)
|
||||||
if p.Name() == filenameWithSuportedPrefix {
|
if p.Name() == filenameWithSuportedPrefix {
|
||||||
|
h.lookupErr = nil
|
||||||
return fmt.Sprintf("%s/%s", h.pluginsDirectory, p.Name()), true
|
return fmt.Sprintf("%s/%s", h.pluginsDirectory, p.Name()), true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue