Kubectl command headers in requests: KEP 859

Kubernetes-commit: 211fc12b67ea2d04a46b24ef245b3513f2cfeb03
This commit is contained in:
Sean Sullivan 2021-02-09 23:09:22 -08:00 committed by Kubernetes Publisher
parent b40c77f0f1
commit 76c2cf7eb6
1 changed files with 44 additions and 2 deletions

View File

@ -20,6 +20,7 @@ import (
"flag"
"fmt"
"io"
"net/http"
"os"
"os/exec"
"runtime"
@ -322,6 +323,8 @@ __kubectl_custom_func() {
`
)
const kubectlCmdHeaders = "KUBECTL_COMMAND_HEADERS"
var (
bashCompletionFlags = map[string]string{
"namespace": "__kubectl_get_resource_namespace",
@ -469,7 +472,6 @@ func HandlePluginCommand(pluginHandler PluginHandler, cmdArgs []string) error {
func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
warningHandler := rest.NewWarningWriter(err, rest.WarningWriterOptions{Deduplicate: true, Color: term.AllowsColorOutput(err)})
warningsAsErrors := false
// Parent command to which all subcommands are added.
cmds := &cobra.Command{
Use: "kubectl",
@ -521,6 +523,8 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
kubeConfigFlags.AddFlags(flags)
matchVersionKubeConfigFlags := cmdutil.NewMatchVersionFlags(kubeConfigFlags)
matchVersionKubeConfigFlags.AddFlags(cmds.PersistentFlags())
// Updates hooks to add kubectl command headers: SIG CLI KEP 859.
addCmdHeaderHooks(cmds, kubeConfigFlags)
cmds.PersistentFlags().AddGoFlagSet(flag.CommandLine)
@ -538,6 +542,12 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
ioStreams := genericclioptions.IOStreams{In: in, Out: out, ErrOut: err}
// Proxy command is incompatible with CommandHeaderRoundTripper, so
// clear the WrapConfigFn before running proxy command.
proxyCmd := proxy.NewCmdProxy(f, ioStreams)
proxyCmd.PreRun = func(cmd *cobra.Command, args []string) {
kubeConfigFlags.WrapConfigFn = nil
}
groups := templates.CommandGroups{
{
Message: "Basic Commands (Beginner):",
@ -585,7 +595,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
attach.NewCmdAttach(f, ioStreams),
cmdexec.NewCmdExec(f, ioStreams),
portforward.NewCmdPortForward(f, ioStreams),
proxy.NewCmdProxy(f, ioStreams),
proxyCmd,
cp.NewCmdCp(f, ioStreams),
auth.NewCmdAuth(f, ioStreams),
debug.NewCmdDebug(f, ioStreams),
@ -646,6 +656,38 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
return cmds
}
// addCmdHeaderHooks performs updates on two hooks:
// 1) Modifies the passed "cmds" persistent pre-run function to parse command headers.
// These headers will be subsequently added as X-headers to every
// REST call.
// 2) Adds CommandHeaderRoundTripper as a wrapper around the standard
// RoundTripper. CommandHeaderRoundTripper adds X-Headers then delegates
// to standard RoundTripper.
// For alpha, these hooks are only updated if the KUBECTL_COMMAND_HEADERS
// environment variable is set.
// See SIG CLI KEP 859 for more information:
// https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/859-kubectl-headers
func addCmdHeaderHooks(cmds *cobra.Command, kubeConfigFlags *genericclioptions.ConfigFlags) {
if _, exists := os.LookupEnv(kubectlCmdHeaders); !exists {
return
}
crt := &genericclioptions.CommandHeaderRoundTripper{}
existingPreRunE := cmds.PersistentPreRunE
// Add command parsing to the existing persistent pre-run function.
cmds.PersistentPreRunE = func(cmd *cobra.Command, args []string) error {
crt.ParseCommandHeaders(cmd, args)
return existingPreRunE(cmd, args)
}
// Wraps CommandHeaderRoundTripper around standard RoundTripper.
kubeConfigFlags.WrapConfigFn = func(c *rest.Config) *rest.Config {
c.Wrap(func(rt http.RoundTripper) http.RoundTripper {
crt.Delegate = rt
return crt
})
return c
}
}
func runHelp(cmd *cobra.Command, args []string) {
cmd.Help()
}