Merge pull request #106159 from soltysh/config_wrapper

Switch from arguments to an input structure for kubectl command

Kubernetes-commit: 763916aa2d7cca2f334037785e4d84136fdf6d11
This commit is contained in:
Kubernetes Publisher 2021-11-12 10:24:28 -08:00
commit 8833384768
4 changed files with 89 additions and 78 deletions

12
go.mod
View File

@ -33,13 +33,13 @@ require (
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.0.0-20211111072600-2d1f8bde0d9a k8s.io/api v0.0.0-20211111072600-2d1f8bde0d9a
k8s.io/apimachinery v0.0.0-20211111072039-19377c9f105d k8s.io/apimachinery v0.0.0-20211111072039-19377c9f105d
k8s.io/cli-runtime v0.0.0-20211111084148-919d79b4776a k8s.io/cli-runtime v0.0.0-20211112202458-df9f5587248d
k8s.io/client-go v0.0.0-20211111073227-e627be7959e7 k8s.io/client-go v0.0.0-20211111073227-e627be7959e7
k8s.io/component-base v0.0.0-20211111075655-ae7620c245bc k8s.io/component-base v0.0.0-20211111075655-ae7620c245bc
k8s.io/component-helpers v0.0.0-20211111080017-45265b0beef7 k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda
k8s.io/klog/v2 v2.30.0 k8s.io/klog/v2 v2.30.0
k8s.io/kube-openapi v0.0.0-20211105084753-ee342a809c29 k8s.io/kube-openapi v0.0.0-20211105084753-ee342a809c29
k8s.io/metrics v0.0.0-20211111083834-95851fdda3ca k8s.io/metrics v0.0.0-20211111231549-670a06559996
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b
sigs.k8s.io/kustomize/kustomize/v4 v4.2.0 sigs.k8s.io/kustomize/kustomize/v4 v4.2.0
sigs.k8s.io/kustomize/kyaml v0.11.0 sigs.k8s.io/kustomize/kyaml v0.11.0
@ -49,10 +49,10 @@ require (
replace ( replace (
k8s.io/api => k8s.io/api v0.0.0-20211111072600-2d1f8bde0d9a k8s.io/api => k8s.io/api v0.0.0-20211111072600-2d1f8bde0d9a
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20211111072039-19377c9f105d k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20211111072039-19377c9f105d
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20211111084148-919d79b4776a k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20211112202458-df9f5587248d
k8s.io/client-go => k8s.io/client-go v0.0.0-20211111073227-e627be7959e7 k8s.io/client-go => k8s.io/client-go v0.0.0-20211111073227-e627be7959e7
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20211111071655-7b5df4132daf k8s.io/code-generator => k8s.io/code-generator v0.0.0-20211111071655-7b5df4132daf
k8s.io/component-base => k8s.io/component-base v0.0.0-20211111075655-ae7620c245bc k8s.io/component-base => k8s.io/component-base v0.0.0-20211111075655-ae7620c245bc
k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20211111080017-45265b0beef7 k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda
k8s.io/metrics => k8s.io/metrics v0.0.0-20211111083834-95851fdda3ca k8s.io/metrics => k8s.io/metrics v0.0.0-20211111231549-670a06559996
) )

12
go.sum
View File

@ -913,15 +913,15 @@ k8s.io/api v0.0.0-20211111072600-2d1f8bde0d9a h1:MbPJiiG2XCMeh1IySIFlmF9Eu2JksfH
k8s.io/api v0.0.0-20211111072600-2d1f8bde0d9a/go.mod h1:E/YSMnKP4hG73T35MZ3pw2P2Hy9cFo7KBeUkEPevRjk= k8s.io/api v0.0.0-20211111072600-2d1f8bde0d9a/go.mod h1:E/YSMnKP4hG73T35MZ3pw2P2Hy9cFo7KBeUkEPevRjk=
k8s.io/apimachinery v0.0.0-20211111072039-19377c9f105d h1:rhNn3FjXMzfNpZLAQSrkW0YQoBEKl+d69o5F2Qw6ONs= k8s.io/apimachinery v0.0.0-20211111072039-19377c9f105d h1:rhNn3FjXMzfNpZLAQSrkW0YQoBEKl+d69o5F2Qw6ONs=
k8s.io/apimachinery v0.0.0-20211111072039-19377c9f105d/go.mod h1:/fTTuFZJpMy6M4dc6F6QbWWj88D/Yd/ZdqJMvTIcbkE= k8s.io/apimachinery v0.0.0-20211111072039-19377c9f105d/go.mod h1:/fTTuFZJpMy6M4dc6F6QbWWj88D/Yd/ZdqJMvTIcbkE=
k8s.io/cli-runtime v0.0.0-20211111084148-919d79b4776a h1:4OW7gCPnS6pmzrJ7tT3UwkFLeLevhNwxbO+87KmIYCo= k8s.io/cli-runtime v0.0.0-20211112202458-df9f5587248d h1:gR1idnDAzEeIiSay3/tF1yekMynx0qZjfCibytuO7Rk=
k8s.io/cli-runtime v0.0.0-20211111084148-919d79b4776a/go.mod h1:av2zR9Yv/we5rQoS0/qTvzhzXt/q4dGOJyTPmdRzSYQ= k8s.io/cli-runtime v0.0.0-20211112202458-df9f5587248d/go.mod h1:av2zR9Yv/we5rQoS0/qTvzhzXt/q4dGOJyTPmdRzSYQ=
k8s.io/client-go v0.0.0-20211111073227-e627be7959e7 h1:M/jv2hr7VfZjKhWEs6oIDJgnolKw9IUMZIJowcQ3T9Q= k8s.io/client-go v0.0.0-20211111073227-e627be7959e7 h1:M/jv2hr7VfZjKhWEs6oIDJgnolKw9IUMZIJowcQ3T9Q=
k8s.io/client-go v0.0.0-20211111073227-e627be7959e7/go.mod h1:vbhSM158IevUkKoqIxagoDYdB9XfHacEyDtKBlug+3g= k8s.io/client-go v0.0.0-20211111073227-e627be7959e7/go.mod h1:vbhSM158IevUkKoqIxagoDYdB9XfHacEyDtKBlug+3g=
k8s.io/code-generator v0.0.0-20211111071655-7b5df4132daf/go.mod h1:elIIhU8sF9q1YQFV7vZBy0EXwIqmRQ1K0HjPRxMHdEQ= k8s.io/code-generator v0.0.0-20211111071655-7b5df4132daf/go.mod h1:elIIhU8sF9q1YQFV7vZBy0EXwIqmRQ1K0HjPRxMHdEQ=
k8s.io/component-base v0.0.0-20211111075655-ae7620c245bc h1:KzQZPIniySd4WlVRJ2XOo71Dlagq4hwDAlr5SIgMpwg= k8s.io/component-base v0.0.0-20211111075655-ae7620c245bc h1:KzQZPIniySd4WlVRJ2XOo71Dlagq4hwDAlr5SIgMpwg=
k8s.io/component-base v0.0.0-20211111075655-ae7620c245bc/go.mod h1:1FNCGI8+JFGNYTnOJidyT0C6gBaT3hZp0P5Nv/9NKr8= k8s.io/component-base v0.0.0-20211111075655-ae7620c245bc/go.mod h1:1FNCGI8+JFGNYTnOJidyT0C6gBaT3hZp0P5Nv/9NKr8=
k8s.io/component-helpers v0.0.0-20211111080017-45265b0beef7 h1:ntBTsLR5AsN9aIwaw1xkZwrHDYMe25/BgQg0VbnmqBE= k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda h1:xRczbjh1GdYEWIB5fSfhtp0BrPxlgdTU5Kg1Qcis47g=
k8s.io/component-helpers v0.0.0-20211111080017-45265b0beef7/go.mod h1:l09fxADyldPge7DGxb+fkLNcs3yj0OR9w/NVY76ejB8= k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda/go.mod h1:l09fxADyldPge7DGxb+fkLNcs3yj0OR9w/NVY76ejB8=
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
@ -931,8 +931,8 @@ k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw=
k8s.io/kube-openapi v0.0.0-20211105084753-ee342a809c29 h1:SgxutK76kGA2O/LIjRjoJ2ABggpGJlaJOiLyOdCjEsU= k8s.io/kube-openapi v0.0.0-20211105084753-ee342a809c29 h1:SgxutK76kGA2O/LIjRjoJ2ABggpGJlaJOiLyOdCjEsU=
k8s.io/kube-openapi v0.0.0-20211105084753-ee342a809c29/go.mod h1:X90lRFlqk35/w9FG4WIvZqMPfG3WrZGzdlSaL6uh7rc= k8s.io/kube-openapi v0.0.0-20211105084753-ee342a809c29/go.mod h1:X90lRFlqk35/w9FG4WIvZqMPfG3WrZGzdlSaL6uh7rc=
k8s.io/metrics v0.0.0-20211111083834-95851fdda3ca h1:geQPH7wjlMCffvVLugzq+xTkWLj+4YdTlt30SYFXVwU= k8s.io/metrics v0.0.0-20211111231549-670a06559996 h1:FjoTIPhFePhKnhTxBjpeRr0Z5yu6w6FJxzjuE5vFpyo=
k8s.io/metrics v0.0.0-20211111083834-95851fdda3ca/go.mod h1:U223BQblZweDx/GR/JnaB2RdAXVNsUY8w4LhxJdaNnY= k8s.io/metrics v0.0.0-20211111231549-670a06559996/go.mod h1:U223BQblZweDx/GR/JnaB2RdAXVNsUY8w4LhxJdaNnY=
k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b h1:wxEMGetGMur3J1xuGLQY7GEQYg9bZxKn3tKo5k/eYcs=
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA=

View File

@ -18,7 +18,6 @@ package cmd
import ( import (
"fmt" "fmt"
"io"
"net/http" "net/http"
"os" "os"
"os/exec" "os/exec"
@ -82,21 +81,34 @@ import (
const kubectlCmdHeaders = "KUBECTL_COMMAND_HEADERS" const kubectlCmdHeaders = "KUBECTL_COMMAND_HEADERS"
type KubectlOptions struct {
PluginHandler PluginHandler
Arguments []string
ConfigFlags *genericclioptions.ConfigFlags
genericclioptions.IOStreams
}
// NewDefaultKubectlCommand creates the `kubectl` command with default arguments // NewDefaultKubectlCommand creates the `kubectl` command with default arguments
func NewDefaultKubectlCommand() *cobra.Command { func NewDefaultKubectlCommand() *cobra.Command {
return NewDefaultKubectlCommandWithArgs(NewDefaultPluginHandler(plugin.ValidPluginFilenamePrefixes), os.Args, os.Stdin, os.Stdout, os.Stderr) return NewDefaultKubectlCommandWithArgs(KubectlOptions{
PluginHandler: NewDefaultPluginHandler(plugin.ValidPluginFilenamePrefixes),
Arguments: os.Args,
ConfigFlags: genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag(),
IOStreams: genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr},
})
} }
// NewDefaultKubectlCommandWithArgs creates the `kubectl` command with arguments // NewDefaultKubectlCommandWithArgs creates the `kubectl` command with arguments
func NewDefaultKubectlCommandWithArgs(pluginHandler PluginHandler, args []string, in io.Reader, out, errout io.Writer) *cobra.Command { func NewDefaultKubectlCommandWithArgs(o KubectlOptions) *cobra.Command {
cmd := NewKubectlCommand(in, out, errout) cmd := NewKubectlCommand(o)
if pluginHandler == nil { if o.PluginHandler == nil {
return cmd return cmd
} }
if len(args) > 1 { if len(o.Arguments) > 1 {
cmdPathPieces := args[1:] cmdPathPieces := o.Arguments[1:]
// only look for suitable extension executables if // only look for suitable extension executables if
// the specified command does not already exist // the specified command does not already exist
@ -116,8 +128,8 @@ func NewDefaultKubectlCommandWithArgs(pluginHandler PluginHandler, args []string
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(pluginHandler, cmdPathPieces); err != nil { if err := HandlePluginCommand(o.PluginHandler, cmdPathPieces); err != nil {
fmt.Fprintf(errout, "Error: %v\n", err) fmt.Fprintf(o.IOStreams.ErrOut, "Error: %v\n", err)
os.Exit(1) os.Exit(1)
} }
} }
@ -233,8 +245,8 @@ func HandlePluginCommand(pluginHandler PluginHandler, cmdArgs []string) error {
} }
// NewKubectlCommand creates the `kubectl` command and its nested children. // NewKubectlCommand creates the `kubectl` command and its nested children.
func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command { func NewKubectlCommand(o KubectlOptions) *cobra.Command {
warningHandler := rest.NewWarningWriter(err, rest.WarningWriterOptions{Deduplicate: true, Color: term.AllowsColorOutput(err)}) warningHandler := rest.NewWarningWriter(o.IOStreams.ErrOut, rest.WarningWriterOptions{Deduplicate: true, Color: term.AllowsColorOutput(o.IOStreams.ErrOut)})
warningsAsErrors := false warningsAsErrors := false
// Parent command to which all subcommands are added. // Parent command to which all subcommands are added.
cmds := &cobra.Command{ cmds := &cobra.Command{
@ -280,7 +292,10 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
flags.BoolVar(&warningsAsErrors, "warnings-as-errors", warningsAsErrors, "Treat warnings received from the server as errors and exit with a non-zero exit code") flags.BoolVar(&warningsAsErrors, "warnings-as-errors", warningsAsErrors, "Treat warnings received from the server as errors and exit with a non-zero exit code")
kubeConfigFlags := genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag() kubeConfigFlags := o.ConfigFlags
if kubeConfigFlags == nil {
kubeConfigFlags = genericclioptions.NewConfigFlags(true).WithDeprecatedPasswordFlag()
}
kubeConfigFlags.AddFlags(flags) kubeConfigFlags.AddFlags(flags)
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags) matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)
matchVersionKubeConfigFlags.AddFlags(flags) matchVersionKubeConfigFlags.AddFlags(flags)
@ -296,11 +311,9 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
// the language, instead of just loading from the LANG env. variable. // the language, instead of just loading from the LANG env. variable.
i18n.LoadTranslations("kubectl", nil) i18n.LoadTranslations("kubectl", nil)
ioStreams := genericclioptions.IOStreams{In: in, Out: out, ErrOut: err}
// Proxy command is incompatible with CommandHeaderRoundTripper, so // Proxy command is incompatible with CommandHeaderRoundTripper, so
// clear the WrapConfigFn before running proxy command. // clear the WrapConfigFn before running proxy command.
proxyCmd := proxy.NewCmdProxy(f, ioStreams) proxyCmd := proxy.NewCmdProxy(f, o.IOStreams)
proxyCmd.PreRun = func(cmd *cobra.Command, args []string) { proxyCmd.PreRun = func(cmd *cobra.Command, args []string) {
kubeConfigFlags.WrapConfigFn = nil kubeConfigFlags.WrapConfigFn = nil
} }
@ -308,72 +321,72 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
{ {
Message: "Basic Commands (Beginner):", Message: "Basic Commands (Beginner):",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
create.NewCmdCreate(f, ioStreams), create.NewCmdCreate(f, o.IOStreams),
expose.NewCmdExposeService(f, ioStreams), expose.NewCmdExposeService(f, o.IOStreams),
run.NewCmdRun(f, ioStreams), run.NewCmdRun(f, o.IOStreams),
set.NewCmdSet(f, ioStreams), set.NewCmdSet(f, o.IOStreams),
}, },
}, },
{ {
Message: "Basic Commands (Intermediate):", Message: "Basic Commands (Intermediate):",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
explain.NewCmdExplain("kubectl", f, ioStreams), explain.NewCmdExplain("kubectl", f, o.IOStreams),
get.NewCmdGet("kubectl", f, ioStreams), get.NewCmdGet("kubectl", f, o.IOStreams),
edit.NewCmdEdit(f, ioStreams), edit.NewCmdEdit(f, o.IOStreams),
delete.NewCmdDelete(f, ioStreams), delete.NewCmdDelete(f, o.IOStreams),
}, },
}, },
{ {
Message: "Deploy Commands:", Message: "Deploy Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
rollout.NewCmdRollout(f, ioStreams), rollout.NewCmdRollout(f, o.IOStreams),
scale.NewCmdScale(f, ioStreams), scale.NewCmdScale(f, o.IOStreams),
autoscale.NewCmdAutoscale(f, ioStreams), autoscale.NewCmdAutoscale(f, o.IOStreams),
}, },
}, },
{ {
Message: "Cluster Management Commands:", Message: "Cluster Management Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
certificates.NewCmdCertificate(f, ioStreams), certificates.NewCmdCertificate(f, o.IOStreams),
clusterinfo.NewCmdClusterInfo(f, ioStreams), clusterinfo.NewCmdClusterInfo(f, o.IOStreams),
top.NewCmdTop(f, ioStreams), top.NewCmdTop(f, o.IOStreams),
drain.NewCmdCordon(f, ioStreams), drain.NewCmdCordon(f, o.IOStreams),
drain.NewCmdUncordon(f, ioStreams), drain.NewCmdUncordon(f, o.IOStreams),
drain.NewCmdDrain(f, ioStreams), drain.NewCmdDrain(f, o.IOStreams),
taint.NewCmdTaint(f, ioStreams), taint.NewCmdTaint(f, o.IOStreams),
}, },
}, },
{ {
Message: "Troubleshooting and Debugging Commands:", Message: "Troubleshooting and Debugging Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
describe.NewCmdDescribe("kubectl", f, ioStreams), describe.NewCmdDescribe("kubectl", f, o.IOStreams),
logs.NewCmdLogs(f, ioStreams), logs.NewCmdLogs(f, o.IOStreams),
attach.NewCmdAttach(f, ioStreams), attach.NewCmdAttach(f, o.IOStreams),
cmdexec.NewCmdExec(f, ioStreams), cmdexec.NewCmdExec(f, o.IOStreams),
portforward.NewCmdPortForward(f, ioStreams), portforward.NewCmdPortForward(f, o.IOStreams),
proxyCmd, proxyCmd,
cp.NewCmdCp(f, ioStreams), cp.NewCmdCp(f, o.IOStreams),
auth.NewCmdAuth(f, ioStreams), auth.NewCmdAuth(f, o.IOStreams),
debug.NewCmdDebug(f, ioStreams), debug.NewCmdDebug(f, o.IOStreams),
}, },
}, },
{ {
Message: "Advanced Commands:", Message: "Advanced Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
diff.NewCmdDiff(f, ioStreams), diff.NewCmdDiff(f, o.IOStreams),
apply.NewCmdApply("kubectl", f, ioStreams), apply.NewCmdApply("kubectl", f, o.IOStreams),
patch.NewCmdPatch(f, ioStreams), patch.NewCmdPatch(f, o.IOStreams),
replace.NewCmdReplace(f, ioStreams), replace.NewCmdReplace(f, o.IOStreams),
wait.NewCmdWait(f, ioStreams), wait.NewCmdWait(f, o.IOStreams),
kustomize.NewCmdKustomize(ioStreams), kustomize.NewCmdKustomize(o.IOStreams),
}, },
}, },
{ {
Message: "Settings Commands:", Message: "Settings Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
label.NewCmdLabel(f, ioStreams), label.NewCmdLabel(f, o.IOStreams),
annotate.NewCmdAnnotate("kubectl", f, ioStreams), annotate.NewCmdAnnotate("kubectl", f, o.IOStreams),
completion.NewCmdCompletion(ioStreams.Out, ""), completion.NewCmdCompletion(o.IOStreams.Out, ""),
}, },
}, },
} }
@ -382,7 +395,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
filters := []string{"options"} filters := []string{"options"}
// Hide the "alpha" subcommand if there are no alpha commands in this build. // Hide the "alpha" subcommand if there are no alpha commands in this build.
alpha := NewCmdAlpha(f, ioStreams) alpha := NewCmdAlpha(f, o.IOStreams)
if !alpha.HasSubCommands() { if !alpha.HasSubCommands() {
filters = append(filters, alpha.Name()) filters = append(filters, alpha.Name())
} }
@ -393,12 +406,12 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
registerCompletionFuncForGlobalFlags(cmds, f) registerCompletionFuncForGlobalFlags(cmds, f)
cmds.AddCommand(alpha) cmds.AddCommand(alpha)
cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), ioStreams)) cmds.AddCommand(cmdconfig.NewCmdConfig(clientcmd.NewDefaultPathOptions(), o.IOStreams))
cmds.AddCommand(plugin.NewCmdPlugin(ioStreams)) cmds.AddCommand(plugin.NewCmdPlugin(o.IOStreams))
cmds.AddCommand(version.NewCmdVersion(f, ioStreams)) cmds.AddCommand(version.NewCmdVersion(f, o.IOStreams))
cmds.AddCommand(apiresources.NewCmdAPIVersions(f, ioStreams)) cmds.AddCommand(apiresources.NewCmdAPIVersions(f, o.IOStreams))
cmds.AddCommand(apiresources.NewCmdAPIResources(f, ioStreams)) cmds.AddCommand(apiresources.NewCmdAPIResources(f, o.IOStreams))
cmds.AddCommand(options.NewCmdOptions(ioStreams.Out)) cmds.AddCommand(options.NewCmdOptions(o.IOStreams.Out))
// Stop warning about normalization of flags. That makes it possible to // Stop warning about normalization of flags. That makes it possible to
// add the klog flags later. // add the klog flags later.
@ -433,8 +446,12 @@ func addCmdHeaderHooks(cmds *cobra.Command, kubeConfigFlags *genericclioptions.C
crt.ParseCommandHeaders(cmd, args) crt.ParseCommandHeaders(cmd, args)
return existingPreRunE(cmd, args) return existingPreRunE(cmd, args)
} }
wrapConfigFn := kubeConfigFlags.WrapConfigFn
// Wraps CommandHeaderRoundTripper around standard RoundTripper. // Wraps CommandHeaderRoundTripper around standard RoundTripper.
kubeConfigFlags.WrapConfigFn = func(c *rest.Config) *rest.Config { kubeConfigFlags.WrapConfigFn = func(c *rest.Config) *rest.Config {
if wrapConfigFn != nil {
c = wrapConfigFn(c)
}
c.Wrap(func(rt http.RoundTripper) http.RoundTripper { c.Wrap(func(rt http.RoundTripper) http.RoundTripper {
// Must be separate RoundTripper; not "crt" closure. // Must be separate RoundTripper; not "crt" closure.
// Fixes: https://github.com/kubernetes/kubectl/issues/1098 // Fixes: https://github.com/kubernetes/kubectl/issues/1098

View File

@ -25,12 +25,11 @@ import (
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/cli-runtime/pkg/genericclioptions" "k8s.io/cli-runtime/pkg/genericclioptions"
cmdutil "k8s.io/kubectl/pkg/cmd/util"
) )
func TestNormalizationFuncGlobalExistence(t *testing.T) { func TestNormalizationFuncGlobalExistence(t *testing.T) {
// This test can be safely deleted when we will not support multiple flag formats // This test can be safely deleted when we will not support multiple flag formats
root := NewKubectlCommand(os.Stdin, os.Stdout, os.Stderr) root := NewKubectlCommand(KubectlOptions{IOStreams: genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr}})
if root.Parent() != nil { if root.Parent() != nil {
t.Fatal("We expect the root command to be returned") t.Fatal("We expect the root command to be returned")
@ -129,14 +128,9 @@ func TestKubectlCommandHandlesPlugins(t *testing.T) {
pluginsHandler := &testPluginHandler{ pluginsHandler := &testPluginHandler{
pluginsDirectory: "plugin/testdata", pluginsDirectory: "plugin/testdata",
} }
_, in, out, errOut := genericclioptions.NewTestIOStreams() ioStreams, _, _, _ := genericclioptions.NewTestIOStreams()
cmdutil.BehaviorOnFatal(func(str string, code int) { root := NewDefaultKubectlCommandWithArgs(KubectlOptions{PluginHandler: pluginsHandler, Arguments: test.args, IOStreams: ioStreams})
errOut.Write([]byte(str))
})
root := NewDefaultKubectlCommandWithArgs(pluginsHandler, test.args, in, out, errOut)
root.SetOut(out)
if err := root.Execute(); err != nil { if err := root.Execute(); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }