mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 18:24:07 +00:00
Plugins are loaded under the 'kubectl plugin' command
This commit is contained in:
parent
2b178ad608
commit
2158473474
@ -73,6 +73,7 @@ docs/man/man1/kubectl-label.1
|
|||||||
docs/man/man1/kubectl-logs.1
|
docs/man/man1/kubectl-logs.1
|
||||||
docs/man/man1/kubectl-options.1
|
docs/man/man1/kubectl-options.1
|
||||||
docs/man/man1/kubectl-patch.1
|
docs/man/man1/kubectl-patch.1
|
||||||
|
docs/man/man1/kubectl-plugin.1
|
||||||
docs/man/man1/kubectl-port-forward.1
|
docs/man/man1/kubectl-port-forward.1
|
||||||
docs/man/man1/kubectl-proxy.1
|
docs/man/man1/kubectl-proxy.1
|
||||||
docs/man/man1/kubectl-replace.1
|
docs/man/man1/kubectl-replace.1
|
||||||
@ -162,6 +163,7 @@ docs/user-guide/kubectl/kubectl_label.md
|
|||||||
docs/user-guide/kubectl/kubectl_logs.md
|
docs/user-guide/kubectl/kubectl_logs.md
|
||||||
docs/user-guide/kubectl/kubectl_options.md
|
docs/user-guide/kubectl/kubectl_options.md
|
||||||
docs/user-guide/kubectl/kubectl_patch.md
|
docs/user-guide/kubectl/kubectl_patch.md
|
||||||
|
docs/user-guide/kubectl/kubectl_plugin.md
|
||||||
docs/user-guide/kubectl/kubectl_port-forward.md
|
docs/user-guide/kubectl/kubectl_port-forward.md
|
||||||
docs/user-guide/kubectl/kubectl_proxy.md
|
docs/user-guide/kubectl/kubectl_proxy.md
|
||||||
docs/user-guide/kubectl/kubectl_replace.md
|
docs/user-guide/kubectl/kubectl_replace.md
|
||||||
@ -211,6 +213,7 @@ docs/yaml/kubectl/kubectl_label.yaml
|
|||||||
docs/yaml/kubectl/kubectl_logs.yaml
|
docs/yaml/kubectl/kubectl_logs.yaml
|
||||||
docs/yaml/kubectl/kubectl_options.yaml
|
docs/yaml/kubectl/kubectl_options.yaml
|
||||||
docs/yaml/kubectl/kubectl_patch.yaml
|
docs/yaml/kubectl/kubectl_patch.yaml
|
||||||
|
docs/yaml/kubectl/kubectl_plugin.yaml
|
||||||
docs/yaml/kubectl/kubectl_port-forward.yaml
|
docs/yaml/kubectl/kubectl_port-forward.yaml
|
||||||
docs/yaml/kubectl/kubectl_proxy.yaml
|
docs/yaml/kubectl/kubectl_proxy.yaml
|
||||||
docs/yaml/kubectl/kubectl_replace.yaml
|
docs/yaml/kubectl/kubectl_replace.yaml
|
||||||
|
3
docs/man/man1/kubectl-plugin.1
Normal file
3
docs/man/man1/kubectl-plugin.1
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
3
docs/user-guide/kubectl/kubectl_plugin.md
Normal file
3
docs/user-guide/kubectl/kubectl_plugin.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
3
docs/yaml/kubectl/kubectl_plugin.yaml
Normal file
3
docs/yaml/kubectl/kubectl_plugin.yaml
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
This file is autogenerated, but we've stopped checking such files into the
|
||||||
|
repository to reduce the need for rebases. Please run hack/generate-docs.sh to
|
||||||
|
populate this file.
|
@ -3684,19 +3684,25 @@ __EOF__
|
|||||||
###########
|
###########
|
||||||
kube::log::status "Testing kubectl plugins"
|
kube::log::status "Testing kubectl plugins"
|
||||||
|
|
||||||
# single plugins path
|
# top-level plugin command
|
||||||
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins kubectl -h 2>&1)
|
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins kubectl -h 2>&1)
|
||||||
|
kube::test::if_has_string "${output_message}" 'plugin\s\+Runs a command-line plugin'
|
||||||
|
|
||||||
|
# no plugins
|
||||||
|
output_message=$(! kubectl plugin 2>&1)
|
||||||
|
kube::test::if_has_string "${output_message}" 'no plugins installed'
|
||||||
|
|
||||||
|
# single plugins path
|
||||||
|
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins kubectl plugin 2>&1)
|
||||||
kube::test::if_has_string "${output_message}" 'echo\s\+Echoes for test-cmd'
|
kube::test::if_has_string "${output_message}" 'echo\s\+Echoes for test-cmd'
|
||||||
kube::test::if_has_string "${output_message}" 'get\s\+The wonderful new plugin-based get!'
|
kube::test::if_has_string "${output_message}" 'get\s\+The wonderful new plugin-based get!'
|
||||||
kube::test::if_has_string "${output_message}" 'error\s\+The tremendous plugin that always fails!'
|
kube::test::if_has_string "${output_message}" 'error\s\+The tremendous plugin that always fails!'
|
||||||
kube::test::if_has_not_string "${output_message}" 'The hello plugin'
|
kube::test::if_has_not_string "${output_message}" 'The hello plugin'
|
||||||
kube::test::if_has_not_string "${output_message}" 'Incomplete plugin'
|
kube::test::if_has_not_string "${output_message}" 'Incomplete plugin'
|
||||||
|
kube::test::if_has_not_string "${output_message}" 'no plugins installed'
|
||||||
# when overriding existing command, both appear in help. TODO handle this to not register plugins that override existing cmd.
|
|
||||||
kube::test::if_has_string "${output_message}" 'get\s\+Display one or many resources'
|
|
||||||
|
|
||||||
# multiple plugins path
|
# multiple plugins path
|
||||||
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/:test/fixtures/pkg/kubectl/plugins2/ kubectl -h 2>&1)
|
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/:test/fixtures/pkg/kubectl/plugins2/ kubectl plugin -h 2>&1)
|
||||||
kube::test::if_has_string "${output_message}" 'echo\s\+Echoes for test-cmd'
|
kube::test::if_has_string "${output_message}" 'echo\s\+Echoes for test-cmd'
|
||||||
kube::test::if_has_string "${output_message}" 'get\s\+The wonderful new plugin-based get!'
|
kube::test::if_has_string "${output_message}" 'get\s\+The wonderful new plugin-based get!'
|
||||||
kube::test::if_has_string "${output_message}" 'error\s\+The tremendous plugin that always fails!'
|
kube::test::if_has_string "${output_message}" 'error\s\+The tremendous plugin that always fails!'
|
||||||
@ -3709,18 +3715,18 @@ __EOF__
|
|||||||
kube::test::if_has_not_string "$output_message{output_message}" 'The wonderful new plugin-based get'
|
kube::test::if_has_not_string "$output_message{output_message}" 'The wonderful new plugin-based get'
|
||||||
|
|
||||||
# plugin help
|
# plugin help
|
||||||
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/:test/fixtures/pkg/kubectl/plugins2/ kubectl hello -h 2>&1)
|
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/:test/fixtures/pkg/kubectl/plugins2/ kubectl plugin hello -h 2>&1)
|
||||||
kube::test::if_has_string "${output_message}" 'The hello plugin is a new plugin used by test-cmd to test multiple plugin locations.'
|
kube::test::if_has_string "${output_message}" 'The hello plugin is a new plugin used by test-cmd to test multiple plugin locations.'
|
||||||
kube::test::if_has_string "${output_message}" 'Usage:'
|
kube::test::if_has_string "${output_message}" 'Usage:'
|
||||||
|
|
||||||
# run plugin
|
# run plugin
|
||||||
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/:test/fixtures/pkg/kubectl/plugins2/ kubectl hello 2>&1)
|
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/:test/fixtures/pkg/kubectl/plugins2/ kubectl plugin hello 2>&1)
|
||||||
kube::test::if_has_string "${output_message}" '#hello#'
|
kube::test::if_has_string "${output_message}" '#hello#'
|
||||||
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/:test/fixtures/pkg/kubectl/plugins2/ kubectl echo 2>&1)
|
output_message=$(KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/:test/fixtures/pkg/kubectl/plugins2/ kubectl plugin echo 2>&1)
|
||||||
kube::test::if_has_string "${output_message}" 'This plugin works!'
|
kube::test::if_has_string "${output_message}" 'This plugin works!'
|
||||||
output_message=$(! KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/ kubectl hello 2>&1)
|
output_message=$(! KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/ kubectl plugin hello 2>&1)
|
||||||
kube::test::if_has_string "${output_message}" 'unknown command'
|
kube::test::if_has_string "${output_message}" 'unknown command'
|
||||||
output_message=$(! KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/ kubectl error 2>&1)
|
output_message=$(! KUBECTL_PLUGINS_PATH=test/fixtures/pkg/kubectl/plugins/ kubectl plugin error 2>&1)
|
||||||
kube::test::if_has_string "${output_message}" 'error: exit status 1'
|
kube::test::if_has_string "${output_message}" 'error: exit status 1'
|
||||||
|
|
||||||
kube::test::clear_all
|
kube::test::clear_all
|
||||||
|
@ -347,24 +347,6 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loads plugins and create commands for each plugin identified
|
|
||||||
loadedPlugins, loadErr := f.PluginLoader().Load()
|
|
||||||
if loadErr != nil {
|
|
||||||
glog.V(1).Infof("Unable to load plugins: %v", loadErr)
|
|
||||||
}
|
|
||||||
pluginRunner := f.PluginRunner()
|
|
||||||
if len(loadedPlugins) > 0 {
|
|
||||||
pluginCmds := []*cobra.Command{}
|
|
||||||
for _, p := range loadedPlugins {
|
|
||||||
pluginCmds = append(pluginCmds, NewCmdForPlugin(p, pluginRunner, in, out, err))
|
|
||||||
}
|
|
||||||
groups = append(groups, templates.CommandGroup{
|
|
||||||
Message: "Plugins:",
|
|
||||||
Commands: pluginCmds,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
groups.Add(cmds)
|
groups.Add(cmds)
|
||||||
|
|
||||||
filters := []string{
|
filters := []string{
|
||||||
@ -386,6 +368,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
|
|||||||
}
|
}
|
||||||
|
|
||||||
cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), out, err))
|
cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), out, err))
|
||||||
|
cmds.AddCommand(NewCmdPlugin(f, in, out, err))
|
||||||
cmds.AddCommand(NewCmdVersion(f, out))
|
cmds.AddCommand(NewCmdVersion(f, out))
|
||||||
cmds.AddCommand(NewCmdApiVersions(f, out))
|
cmds.AddCommand(NewCmdApiVersions(f, out))
|
||||||
cmds.AddCommand(NewCmdOptions())
|
cmds.AddCommand(NewCmdOptions())
|
||||||
|
@ -17,15 +17,57 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/golang/glog"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||||
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
||||||
|
"k8s.io/kubernetes/pkg/util/i18n"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
plugin_long = templates.LongDesc(`
|
||||||
|
Runs a command-line plugin.
|
||||||
|
|
||||||
|
Plugins are subcommands that are not part of the major command-line distribution
|
||||||
|
and can even be provided by third-parties. Please refer to the documentation and
|
||||||
|
examples for more information about how to install and write your own plugins.`)
|
||||||
|
)
|
||||||
|
|
||||||
|
// NewCmdPlugin creates the command that is the top-level for plugin commands.
|
||||||
|
func NewCmdPlugin(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
|
||||||
|
// Loads plugins and create commands for each plugin identified
|
||||||
|
loadedPlugins, loadErr := f.PluginLoader().Load()
|
||||||
|
if loadErr != nil {
|
||||||
|
glog.V(1).Infof("Unable to load plugins: %v", loadErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd := &cobra.Command{
|
||||||
|
Use: "plugin NAME",
|
||||||
|
Short: i18n.T("Runs a command-line plugin"),
|
||||||
|
Long: plugin_long,
|
||||||
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
|
if len(loadedPlugins) == 0 {
|
||||||
|
cmdutil.CheckErr(fmt.Errorf("no plugins installed."))
|
||||||
|
}
|
||||||
|
cmdutil.DefaultSubCommandRun(err)(cmd, args)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(loadedPlugins) > 0 {
|
||||||
|
pluginRunner := f.PluginRunner()
|
||||||
|
for _, p := range loadedPlugins {
|
||||||
|
cmd.AddCommand(NewCmdForPlugin(p, pluginRunner, in, out, err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return cmd
|
||||||
|
}
|
||||||
|
|
||||||
// NewCmdForPlugin creates a command capable of running the provided plugin.
|
// NewCmdForPlugin creates a command capable of running the provided plugin.
|
||||||
func NewCmdForPlugin(plugin *plugins.Plugin, runner plugins.PluginRunner, in io.Reader, out, errout io.Writer) *cobra.Command {
|
func NewCmdForPlugin(plugin *plugins.Plugin, runner plugins.PluginRunner, in io.Reader, out, errout io.Writer) *cobra.Command {
|
||||||
if !plugin.IsValid() {
|
if !plugin.IsValid() {
|
||||||
|
Loading…
Reference in New Issue
Block a user