猿问

kubectl插件里面,提示输入?

我正在编写一个kubectl插件来对用户进行身份验证,我想在调用插件后提示用户输入密码。据我了解,从 STDIN 获取输入相当简单,但我很难看到写入 STDOUT 的消息。目前我的代码如下所示:


在 cmd/kubectl-myauth.go 中:


// This is mostly boilerplate, but it's needed for the MRE

// https://stackoverflow.com/help/minimal-reproducible-example

package myauth

import (...)

func main() {

    pflag.CommandLine = pflag.NewFlagSet("kubectl-myauth", pflag.ExitOnError)

    root := cmd.NewCmdAuthOp(genericclioptions.IOStreams{In: os.Stdin, Out: os.Stdout, ErrOut: os.Stderr})

    if err := root.Execute(); err != nil {

        os.Exit(1)

    }

}

在 pkg/cmd/auth.go 中:


package cmd

...

type AuthOpOptions struct {

    configFlags *genericclioptions.ConfigFlags

    resultingContext *api.Context

    rawConfig       api.Config

    args            []string

    ...

    genericclioptions.IOStreams

}

func NewAuthOpOptions(streams genericclioptions.IOStreams) *AuthOpOptions {

    return &AuthOpOptions{

        configFlags: genericclioptions.NewConfigFlags(true),

        IOStreams: streams,

    }

}

func NewCmdAuthOp(streams genericclioptions.IOStreams) *cobra.Command {

    o := NewAuthOpOptions(streams)

    cmd := &cobra.Command{

        RunE: func(c *cobra.Command, args []string) error {

            return o.Run()

        },

    }

    return cmd

}

func (o *AuthOpOptions) Run() error {

    pass, err := getPassword(o)

    if err != nil {

        return err

    }

    // Do Auth Stuff

    // Eventually print an ExecCredential to STDOUT

    return nil

}

当从上下文外部运行时,这按照我期望的方式工作kubectl- 即,它打印字符串,提示输入,然后继续。然而,从上下文内部来看kubectl,我相信前两个全大写注释([1] 和 [2])之间的打印内容正在被kubectlSTDOUT 上的监听所吞没。我可以通过打印到 STDERR 来解决这个问题,但这感觉......错误。有没有办法可以绕过kubectlSTDOUT 的消耗来与用户通信?


TL;DR:kubectl似乎正在吞噬kubectl插件的所有 STDOUT,但我想提示用户输入 - 有没有一种简单的方法可以做到这一点?


炎炎设计
浏览 111回答 1
1回答

qq_笑_17

以下是步骤:git clone https://github.com/kubernetes/kubernetes.git重复sample-cli-plugin为test-cli-plugin(这涉及在暂存/发布下修复 import-restrictions.yaml、rules-godeps.yaml 和 Rules.yaml - 也许没有必要,但这样更安全)将 kubectl-ns.go 更改为 kubectl-test.go:package mainimport (        "os"        "github.com/spf13/pflag"        "k8s.io/cli-runtime/pkg/genericclioptions"        "k8s.io/test-cli-plugin/pkg/cmd")func main() {        flags := pflag.NewFlagSet("kubectl-test", pflag.ExitOnError)        pflag.CommandLine = flags        root := cmd.NewCmdTest(genericclioptions.IOStreams{In: os.Stdin,                                                            Out: os.Stdout,                                                           ErrOut: os.Stderr})        if err := root.Execute(); err != nil {                os.Exit(1)        }}将 ns.go 更改为 test.go:package cmdimport (        "fmt"        "os"        "github.com/spf13/cobra"        "k8s.io/cli-runtime/pkg/genericclioptions")type TestOptions struct {        configFlags *genericclioptions.ConfigFlags        genericclioptions.IOStreams}func NewTestOptions(streams genericclioptions.IOStreams) *TestOptions {        return &TestOptions{                configFlags: genericclioptions.NewConfigFlags(true),                IOStreams:   streams,        }}func NewCmdTest(streams genericclioptions.IOStreams) *cobra.Command {        o := NewTestOptions(streams)        cmd := &cobra.Command{                Use:          "test",                Short:        "Test plugin",                SilenceUsage: true,                RunE: func(c *cobra.Command, args []string) error {                        o.Run()                        return nil                },        }        return cmd}func (o *TestOptions) Run() error {        fmt.Fprintf(os.Stderr, "Testing Fprintf Stderr\n")        fmt.Fprintf(os.Stdout, "Testing Fprintf Stdout\n")        fmt.Printf("Testing Printf\n")        fmt.Fprintf(o.IOStreams.Out, "Testing Fprintf o.IOStreams.Out\n")        return nil}相应地修复 BUILD 文件构建插件跑步make复制kubectl-test到/usr/local/bin运行编译后的二进制kubectl文件:~/k8s/_output/bin$ ./kubectl 测试测试 Fprintf 标准错误测试 Fprintf 标准输出测试 Printf测试 Fprintf o.IOStreams.Out
随时随地看视频慕课网APP

相关分类

Go
我要回答