mirror of https://github.com/k3s-io/k3s
use IOStreams for cli commands
parent
8d064823bb
commit
facd04be43
|
@ -17,17 +17,16 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
|
||||
// NewCmdAlpha creates a command that acts as an alternate root command for features in alpha
|
||||
func NewCmdAlpha(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
|
||||
func NewCmdAlpha(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "alpha",
|
||||
Short: i18n.T("Commands for features in alpha"),
|
||||
|
@ -37,7 +36,7 @@ func NewCmdAlpha(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Com
|
|||
// Alpha commands should be added here. As features graduate from alpha they should move
|
||||
// from here to the CommandGroups defined by NewKubeletCommand() in cmd.go.
|
||||
//cmd.AddCommand(NewCmdDebug(f, in, out, err))
|
||||
cmd.AddCommand(NewCmdDiff(f, out, err))
|
||||
cmd.AddCommand(NewCmdDiff(f, streams))
|
||||
|
||||
// NewKubeletCommand() will hide the alpha command if it has no subcommands. Overriding
|
||||
// the help function ensures a reasonable message if someone types the hidden command anyway.
|
||||
|
|
|
@ -197,7 +197,7 @@ func (o *ApplyOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
|||
return err
|
||||
}
|
||||
|
||||
o.DeleteOptions = o.DeleteFlags.ToOptions(o.Out, o.ErrOut)
|
||||
o.DeleteOptions = o.DeleteFlags.ToOptions(o.IOStreams)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
|
||||
|
@ -60,12 +61,10 @@ const (
|
|||
defaultPodLogsTimeout = 20 * time.Second
|
||||
)
|
||||
|
||||
func NewCmdAttach(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
|
||||
options := &AttachOptions{
|
||||
func NewCmdAttach(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := &AttachOptions{
|
||||
StreamOptions: StreamOptions{
|
||||
In: cmdIn,
|
||||
Out: cmdOut,
|
||||
Err: cmdErr,
|
||||
IOStreams: streams,
|
||||
},
|
||||
|
||||
Attach: &DefaultRemoteAttach{},
|
||||
|
@ -77,15 +76,15 @@ func NewCmdAttach(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer)
|
|||
Long: "Attach to a process that is already running inside an existing container.",
|
||||
Example: attachExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(options.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(options.Validate())
|
||||
cmdutil.CheckErr(options.Run())
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
cmdutil.CheckErr(o.Run())
|
||||
},
|
||||
}
|
||||
cmdutil.AddPodRunningTimeoutFlag(cmd, defaultPodAttachTimeout)
|
||||
cmd.Flags().StringVarP(&options.ContainerName, "container", "c", options.ContainerName, "Container name. If omitted, the first container in the pod will be chosen")
|
||||
cmd.Flags().BoolVarP(&options.Stdin, "stdin", "i", options.Stdin, "Pass stdin to the container")
|
||||
cmd.Flags().BoolVarP(&options.TTY, "tty", "t", options.TTY, "Stdin is a TTY")
|
||||
cmd.Flags().StringVarP(&o.ContainerName, "container", "c", o.ContainerName, "Container name. If omitted, the first container in the pod will be chosen")
|
||||
cmd.Flags().BoolVarP(&o.Stdin, "stdin", "i", o.Stdin, "Pass stdin to the container")
|
||||
cmd.Flags().BoolVarP(&o.TTY, "tty", "t", o.TTY, "Stdin is a TTY")
|
||||
return cmd
|
||||
}
|
||||
|
||||
|
@ -203,7 +202,7 @@ func (p *AttachOptions) Validate() error {
|
|||
if len(p.PodName) == 0 {
|
||||
allErrs = append(allErrs, errors.New("pod name must be specified"))
|
||||
}
|
||||
if p.Out == nil || p.Err == nil {
|
||||
if p.Out == nil || p.ErrOut == nil {
|
||||
allErrs = append(allErrs, errors.New("both output and error output must be provided"))
|
||||
}
|
||||
if p.Attach == nil || p.PodClient == nil || p.Config == nil {
|
||||
|
@ -236,8 +235,8 @@ func (p *AttachOptions) Run() error {
|
|||
}
|
||||
if p.TTY && !containerToAttach.TTY {
|
||||
p.TTY = false
|
||||
if p.Err != nil {
|
||||
fmt.Fprintf(p.Err, "Unable to use a TTY - container %s did not allocate one\n", containerToAttach.Name)
|
||||
if p.ErrOut != nil {
|
||||
fmt.Fprintf(p.ErrOut, "Unable to use a TTY - container %s did not allocate one\n", containerToAttach.Name)
|
||||
}
|
||||
} else if !p.TTY && containerToAttach.TTY {
|
||||
// the container was launched with a TTY, so we have to force a TTY here, otherwise you'll get
|
||||
|
@ -249,7 +248,7 @@ func (p *AttachOptions) Run() error {
|
|||
t := p.setupTTY()
|
||||
|
||||
// save p.Err so we can print the command prompt message below
|
||||
stderr := p.Err
|
||||
stderr := p.ErrOut
|
||||
|
||||
var sizeQueue remotecommand.TerminalSizeQueue
|
||||
if t.Raw {
|
||||
|
@ -266,7 +265,7 @@ func (p *AttachOptions) Run() error {
|
|||
|
||||
// unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is
|
||||
// true
|
||||
p.Err = nil
|
||||
p.ErrOut = nil
|
||||
}
|
||||
|
||||
fn := func() error {
|
||||
|
@ -284,11 +283,11 @@ func (p *AttachOptions) Run() error {
|
|||
Container: containerToAttach.Name,
|
||||
Stdin: p.Stdin,
|
||||
Stdout: p.Out != nil,
|
||||
Stderr: p.Err != nil,
|
||||
Stderr: p.ErrOut != nil,
|
||||
TTY: t.Raw,
|
||||
}, legacyscheme.ParameterCodec)
|
||||
|
||||
return p.Attach.Attach("POST", req.URL(), p.Config, p.In, p.Out, p.Err, t.Raw, sizeQueue)
|
||||
return p.Attach.Attach("POST", req.URL(), p.Config, p.In, p.Out, p.ErrOut, t.Raw, sizeQueue)
|
||||
}
|
||||
|
||||
if !p.Quiet && stderr != nil {
|
||||
|
@ -322,8 +321,8 @@ func (p *AttachOptions) containerToAttachTo(pod *api.Pod) (*api.Container, error
|
|||
}
|
||||
|
||||
if len(p.SuggestedCmdUsage) > 0 {
|
||||
fmt.Fprintf(p.Err, "Defaulting container name to %s.\n", pod.Spec.Containers[0].Name)
|
||||
fmt.Fprintf(p.Err, "%s\n", p.SuggestedCmdUsage)
|
||||
fmt.Fprintf(p.ErrOut, "Defaulting container name to %s.\n", pod.Spec.Containers[0].Name)
|
||||
fmt.Fprintf(p.ErrOut, "%s\n", p.SuggestedCmdUsage)
|
||||
}
|
||||
|
||||
glog.V(4).Infof("defaulting container name to %s", pod.Spec.Containers[0].Name)
|
||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
@ -38,6 +37,7 @@ import (
|
|||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
)
|
||||
|
||||
|
@ -249,9 +249,6 @@ func TestAttach(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
|
||||
bufOut := bytes.NewBuffer([]byte{})
|
||||
bufErr := bytes.NewBuffer([]byte{})
|
||||
bufIn := bytes.NewBuffer([]byte{})
|
||||
remoteAttach := &fakeRemoteAttach{}
|
||||
if test.remoteAttachErr {
|
||||
remoteAttach.err = fmt.Errorf("attach error")
|
||||
|
@ -259,9 +256,7 @@ func TestAttach(t *testing.T) {
|
|||
params := &AttachOptions{
|
||||
StreamOptions: StreamOptions{
|
||||
ContainerName: test.container,
|
||||
In: bufIn,
|
||||
Out: bufOut,
|
||||
Err: bufErr,
|
||||
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||
},
|
||||
Attach: remoteAttach,
|
||||
GetPodTimeout: 1000,
|
||||
|
@ -342,16 +337,12 @@ func TestAttachWarnings(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = &restclient.Config{APIPath: "/api", ContentConfig: restclient.ContentConfig{NegotiatedSerializer: legacyscheme.Codecs, GroupVersion: &schema.GroupVersion{Version: test.version}}}
|
||||
bufOut := bytes.NewBuffer([]byte{})
|
||||
bufErr := bytes.NewBuffer([]byte{})
|
||||
bufIn := bytes.NewBuffer([]byte{})
|
||||
streams, _, _, bufErr := genericclioptions.NewTestIOStreams()
|
||||
ex := &fakeRemoteAttach{}
|
||||
params := &AttachOptions{
|
||||
StreamOptions: StreamOptions{
|
||||
ContainerName: test.container,
|
||||
In: bufIn,
|
||||
Out: bufOut,
|
||||
Err: bufErr,
|
||||
IOStreams: streams,
|
||||
Stdin: test.stdin,
|
||||
TTY: test.tty,
|
||||
},
|
||||
|
|
|
@ -275,7 +275,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||
NewCmdExplain("kubectl", f, ioStreams),
|
||||
get.NewCmdGet("kubectl", f, ioStreams),
|
||||
NewCmdEdit(f, ioStreams),
|
||||
NewCmdDelete(f, out, err),
|
||||
NewCmdDelete(f, ioStreams),
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -292,7 +292,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||
Commands: []*cobra.Command{
|
||||
NewCmdCertificate(f, ioStreams),
|
||||
NewCmdClusterInfo(f, ioStreams),
|
||||
NewCmdTop(f, out, err),
|
||||
NewCmdTop(f, ioStreams),
|
||||
NewCmdCordon(f, ioStreams),
|
||||
NewCmdUncordon(f, ioStreams),
|
||||
NewCmdDrain(f, ioStreams),
|
||||
|
@ -303,11 +303,11 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||
Message: "Troubleshooting and Debugging Commands:",
|
||||
Commands: []*cobra.Command{
|
||||
NewCmdDescribe("kubectl", f, ioStreams),
|
||||
NewCmdLogs(f, out, err),
|
||||
NewCmdAttach(f, in, out, err),
|
||||
NewCmdExec(f, in, out, err),
|
||||
NewCmdPortForward(f, out, err),
|
||||
NewCmdProxy(f, out),
|
||||
NewCmdLogs(f, ioStreams),
|
||||
NewCmdAttach(f, ioStreams),
|
||||
NewCmdExec(f, ioStreams),
|
||||
NewCmdPortForward(f, ioStreams),
|
||||
NewCmdProxy(f, ioStreams),
|
||||
NewCmdCp(f, ioStreams),
|
||||
auth.NewCmdAuth(f, ioStreams),
|
||||
},
|
||||
|
@ -317,7 +317,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||
Commands: []*cobra.Command{
|
||||
NewCmdApply("kubectl", f, ioStreams),
|
||||
NewCmdPatch(f, ioStreams),
|
||||
NewCmdReplace(f, out, err),
|
||||
NewCmdReplace(f, ioStreams),
|
||||
NewCmdConvert(f, ioStreams),
|
||||
},
|
||||
},
|
||||
|
@ -326,7 +326,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||
Commands: []*cobra.Command{
|
||||
NewCmdLabel(f, ioStreams),
|
||||
NewCmdAnnotate("kubectl", f, ioStreams),
|
||||
NewCmdCompletion(out, ""),
|
||||
NewCmdCompletion(ioStreams.Out, ""),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -335,7 +335,7 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||
filters := []string{"options"}
|
||||
|
||||
// Hide the "alpha" subcommand if there are no alpha commands in this build.
|
||||
alpha := NewCmdAlpha(f, in, out, err)
|
||||
alpha := NewCmdAlpha(f, ioStreams)
|
||||
if !alpha.HasSubCommands() {
|
||||
filters = append(filters, alpha.Name())
|
||||
}
|
||||
|
@ -356,11 +356,11 @@ func NewKubectlCommand(in io.Reader, out, err io.Writer) *cobra.Command {
|
|||
|
||||
cmds.AddCommand(alpha)
|
||||
cmds.AddCommand(cmdconfig.NewCmdConfig(f, clientcmd.NewDefaultPathOptions(), ioStreams))
|
||||
cmds.AddCommand(NewCmdPlugin(f, in, out, err))
|
||||
cmds.AddCommand(NewCmdPlugin(f, ioStreams))
|
||||
cmds.AddCommand(NewCmdVersion(f, ioStreams))
|
||||
cmds.AddCommand(NewCmdApiVersions(f, ioStreams))
|
||||
cmds.AddCommand(NewCmdApiResources(f, ioStreams))
|
||||
cmds.AddCommand(NewCmdOptions(out))
|
||||
cmds.AddCommand(NewCmdOptions(ioStreams.Out))
|
||||
|
||||
return cmds
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
@ -35,6 +34,8 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
|
||||
"bytes"
|
||||
|
||||
"github.com/renstrom/dedent"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
@ -194,8 +195,10 @@ func (o *CopyOptions) Run(args []string) error {
|
|||
func (o *CopyOptions) checkDestinationIsDir(dest fileSpec) error {
|
||||
options := &ExecOptions{
|
||||
StreamOptions: StreamOptions{
|
||||
Out: bytes.NewBuffer([]byte{}),
|
||||
Err: bytes.NewBuffer([]byte{}),
|
||||
IOStreams: genericclioptions.IOStreams{
|
||||
Out: bytes.NewBuffer([]byte{}),
|
||||
ErrOut: bytes.NewBuffer([]byte{}),
|
||||
},
|
||||
|
||||
Namespace: dest.PodNamespace,
|
||||
PodName: dest.PodName,
|
||||
|
@ -240,9 +243,11 @@ func (o *CopyOptions) copyToPod(src, dest fileSpec) error {
|
|||
|
||||
options := &ExecOptions{
|
||||
StreamOptions: StreamOptions{
|
||||
In: reader,
|
||||
Out: o.Out,
|
||||
Err: o.ErrOut,
|
||||
IOStreams: genericclioptions.IOStreams{
|
||||
In: reader,
|
||||
Out: o.Out,
|
||||
ErrOut: o.ErrOut,
|
||||
},
|
||||
Stdin: true,
|
||||
|
||||
Namespace: dest.PodNamespace,
|
||||
|
@ -263,9 +268,11 @@ func (o *CopyOptions) copyFromPod(src, dest fileSpec) error {
|
|||
reader, outStream := io.Pipe()
|
||||
options := &ExecOptions{
|
||||
StreamOptions: StreamOptions{
|
||||
In: nil,
|
||||
Out: outStream,
|
||||
Err: o.Out,
|
||||
IOStreams: genericclioptions.IOStreams{
|
||||
In: nil,
|
||||
Out: outStream,
|
||||
ErrOut: o.Out,
|
||||
},
|
||||
|
||||
Namespace: src.PodNamespace,
|
||||
PodName: src.PodName,
|
||||
|
|
|
@ -18,7 +18,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
@ -31,6 +30,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
|
@ -109,11 +109,10 @@ type DeleteOptions struct {
|
|||
Mapper meta.RESTMapper
|
||||
Result *resource.Result
|
||||
|
||||
Out io.Writer
|
||||
ErrOut io.Writer
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||
func NewCmdDelete(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
deleteFlags := NewDeleteCommandFlags("containing the resource to delete.")
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
@ -123,14 +122,14 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||
Long: delete_long,
|
||||
Example: delete_example,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
options := deleteFlags.ToOptions(out, errOut)
|
||||
if err := options.Complete(f, out, errOut, args, cmd); err != nil {
|
||||
o := deleteFlags.ToOptions(streams)
|
||||
if err := o.Complete(f, args, cmd); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
}
|
||||
if err := options.Validate(cmd); err != nil {
|
||||
if err := o.Validate(cmd); err != nil {
|
||||
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, err.Error()))
|
||||
}
|
||||
if err := options.RunDelete(); err != nil {
|
||||
if err := o.RunDelete(); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
}
|
||||
},
|
||||
|
@ -143,7 +142,7 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args []string, cmd *cobra.Command) error {
|
||||
func (o *DeleteOptions) Complete(f cmdutil.Factory, args []string, cmd *cobra.Command) error {
|
||||
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -175,10 +174,6 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
|
|||
return err
|
||||
}
|
||||
|
||||
// Set up writer
|
||||
o.Out = out
|
||||
o.ErrOut = errOut
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
)
|
||||
|
||||
|
@ -72,10 +72,9 @@ type DeleteFlags struct {
|
|||
Output *string
|
||||
}
|
||||
|
||||
func (f *DeleteFlags) ToOptions(out, errOut io.Writer) *DeleteOptions {
|
||||
func (f *DeleteFlags) ToOptions(streams genericclioptions.IOStreams) *DeleteOptions {
|
||||
options := &DeleteOptions{
|
||||
Out: out,
|
||||
ErrOut: errOut,
|
||||
IOStreams: streams,
|
||||
}
|
||||
|
||||
// add filename options
|
||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
|
@ -38,6 +37,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
)
|
||||
|
@ -84,8 +84,8 @@ func TestDeleteObjectByTuple(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -95,8 +95,8 @@ func TestDeleteObjectByTuple(t *testing.T) {
|
|||
}
|
||||
|
||||
// Test cascading delete of object without client-side reaper doesn't make GET requests
|
||||
buf, errBuf = bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
cmd = NewCmdDelete(tf, buf, errBuf)
|
||||
streams, _, buf, _ = genericclioptions.NewTestIOStreams()
|
||||
cmd = NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Flags().Set("output", "name")
|
||||
cmd.Run(cmd, []string{"secrets/mysecret"})
|
||||
|
@ -147,8 +147,8 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) {
|
|||
// DeleteOptions.OrphanDependents should be false, when cascade is true (default).
|
||||
falseVar := false
|
||||
expectedOrphanDependents = &falseVar
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Flags().Set("output", "name")
|
||||
cmd.Run(cmd, []string{"secrets/mysecret"})
|
||||
|
@ -159,8 +159,8 @@ func TestOrphanDependentsInDeleteObject(t *testing.T) {
|
|||
// Test that delete options should be set to orphan when cascade is false.
|
||||
trueVar := true
|
||||
expectedOrphanDependents = &trueVar
|
||||
buf, errBuf = bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
cmd = NewCmdDelete(tf, buf, errBuf)
|
||||
streams, _, buf, _ = genericclioptions.NewTestIOStreams()
|
||||
cmd = NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -202,8 +202,8 @@ func TestDeleteNamedObject(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -213,8 +213,8 @@ func TestDeleteNamedObject(t *testing.T) {
|
|||
}
|
||||
|
||||
// Test cascading delete of object without client-side reaper doesn't make GET requests
|
||||
buf, errBuf = bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
cmd = NewCmdDelete(tf, buf, errBuf)
|
||||
streams, _, buf, _ = genericclioptions.NewTestIOStreams()
|
||||
cmd = NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -246,9 +246,9 @@ func TestDeleteObject(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -318,11 +318,11 @@ func TestDeleteObjectGraceZero(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
|
||||
reaper := &fakeReaper{}
|
||||
fake := &fakeReaperFactory{Factory: tf, reaper: reaper}
|
||||
cmd := NewCmdDelete(fake, buf, errBuf)
|
||||
streams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
cmd := NewCmdDelete(fake, streams)
|
||||
cmd.Flags().Set("output", "name")
|
||||
cmd.Flags().Set("grace-period", "0")
|
||||
cmd.Run(cmd, []string{"pods/nginx"})
|
||||
|
@ -357,7 +357,6 @@ func TestDeleteObjectNotFound(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
|
||||
options := &DeleteOptions{
|
||||
FilenameOptions: resource.FilenameOptions{
|
||||
|
@ -366,8 +365,9 @@ func TestDeleteObjectNotFound(t *testing.T) {
|
|||
GracePeriod: -1,
|
||||
Cascade: false,
|
||||
Output: "name",
|
||||
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||
}
|
||||
err := options.Complete(tf, buf, errBuf, []string{}, fakecmd())
|
||||
err := options.Complete(tf, []string{}, fakecmd())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -395,9 +395,9 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("ignore-not-found", "true")
|
||||
|
@ -438,7 +438,6 @@ func TestDeleteAllNotFound(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
|
||||
// Make sure we can explicitly choose to fail on NotFound errors, even with --all
|
||||
options := &DeleteOptions{
|
||||
|
@ -448,8 +447,9 @@ func TestDeleteAllNotFound(t *testing.T) {
|
|||
DeleteAll: true,
|
||||
IgnoreNotFound: false,
|
||||
Output: "name",
|
||||
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||
}
|
||||
err := options.Complete(tf, buf, errBuf, []string{"services"}, fakecmd())
|
||||
err := options.Complete(tf, []string{"services"}, fakecmd())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -489,9 +489,9 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("all", "true")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -526,9 +526,9 @@ func TestDeleteMultipleObject(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
|
@ -564,7 +564,7 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
options := &DeleteOptions{
|
||||
FilenameOptions: resource.FilenameOptions{
|
||||
|
@ -573,8 +573,9 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
|
|||
GracePeriod: -1,
|
||||
Cascade: false,
|
||||
Output: "name",
|
||||
IOStreams: streams,
|
||||
}
|
||||
err := options.Complete(tf, buf, errBuf, []string{}, fakecmd())
|
||||
err := options.Complete(tf, []string{}, fakecmd())
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
@ -616,9 +617,9 @@ func TestDeleteMultipleResourcesWithTheSameName(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -650,9 +651,9 @@ func TestDeleteDirectory(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -697,9 +698,9 @@ func TestDeleteMultipleSelector(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdDelete(tf, buf, errBuf)
|
||||
cmd := NewCmdDelete(tf, streams)
|
||||
cmd.Flags().Set("selector", "a=b")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -742,15 +743,15 @@ func TestResourceErrors(t *testing.T) {
|
|||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
|
||||
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
|
||||
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
options := &DeleteOptions{
|
||||
FilenameOptions: resource.FilenameOptions{},
|
||||
GracePeriod: -1,
|
||||
Cascade: false,
|
||||
Output: "name",
|
||||
IOStreams: streams,
|
||||
}
|
||||
err := options.Complete(tf, buf, errBuf, testCase.args, fakecmd())
|
||||
err := options.Complete(tf, testCase.args, fakecmd())
|
||||
if !testCase.errFn(err) {
|
||||
t.Errorf("%s: unexpected error: %v", k, err)
|
||||
return
|
||||
|
|
|
@ -34,6 +34,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/kubectl/apply/strategy"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/resource"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
"k8s.io/utils/exec"
|
||||
|
@ -101,12 +102,11 @@ func parseDiffArguments(args []string) (string, string, error) {
|
|||
return from, to, nil
|
||||
}
|
||||
|
||||
func NewCmdDiff(f cmdutil.Factory, stdout, stderr io.Writer) *cobra.Command {
|
||||
func NewCmdDiff(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
var options DiffOptions
|
||||
diff := DiffProgram{
|
||||
Exec: exec.New(),
|
||||
Stdout: stdout,
|
||||
Stderr: stderr,
|
||||
Exec: exec.New(),
|
||||
IOStreams: streams,
|
||||
}
|
||||
cmd := &cobra.Command{
|
||||
Use: "diff -f FILENAME",
|
||||
|
@ -132,9 +132,8 @@ func NewCmdDiff(f cmdutil.Factory, stdout, stderr io.Writer) *cobra.Command {
|
|||
// KUBERNETES_EXTERNAL_DIFF environment variable will be used a diff
|
||||
// program. By default, `diff(1)` will be used.
|
||||
type DiffProgram struct {
|
||||
Exec exec.Interface
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
Exec exec.Interface
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
func (d *DiffProgram) getCommand(args ...string) exec.Cmd {
|
||||
|
@ -147,8 +146,8 @@ func (d *DiffProgram) getCommand(args ...string) exec.Cmd {
|
|||
}
|
||||
|
||||
cmd := d.Exec.Command(diff, args...)
|
||||
cmd.SetStdout(d.Stdout)
|
||||
cmd.SetStderr(d.Stderr)
|
||||
cmd.SetStdout(d.Out)
|
||||
cmd.SetStderr(d.ErrOut)
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/utils/exec"
|
||||
)
|
||||
|
||||
|
@ -137,11 +138,10 @@ func TestArguments(t *testing.T) {
|
|||
|
||||
func TestDiffProgram(t *testing.T) {
|
||||
os.Setenv("KUBERNETES_EXTERNAL_DIFF", "echo")
|
||||
stdout := bytes.Buffer{}
|
||||
streams, _, stdout, _ := genericclioptions.NewTestIOStreams()
|
||||
diff := DiffProgram{
|
||||
Stdout: &stdout,
|
||||
Stderr: &bytes.Buffer{},
|
||||
Exec: exec.New(),
|
||||
IOStreams: streams,
|
||||
Exec: exec.New(),
|
||||
}
|
||||
err := diff.Run("one", "two")
|
||||
if err != nil {
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/term"
|
||||
"k8s.io/kubernetes/pkg/util/interrupt"
|
||||
|
@ -62,12 +63,10 @@ const (
|
|||
execUsageStr = "expected 'exec POD_NAME COMMAND [ARG1] [ARG2] ... [ARGN]'.\nPOD_NAME and COMMAND are required arguments for the exec command"
|
||||
)
|
||||
|
||||
func NewCmdExec(f cmdutil.Factory, cmdIn io.Reader, cmdOut, cmdErr io.Writer) *cobra.Command {
|
||||
func NewCmdExec(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
options := &ExecOptions{
|
||||
StreamOptions: StreamOptions{
|
||||
In: cmdIn,
|
||||
Out: cmdOut,
|
||||
Err: cmdErr,
|
||||
IOStreams: streams,
|
||||
},
|
||||
|
||||
Executor: &DefaultRemoteExecutor{},
|
||||
|
@ -125,9 +124,8 @@ type StreamOptions struct {
|
|||
Quiet bool
|
||||
// InterruptParent, if set, is used to handle interrupts while attached
|
||||
InterruptParent *interrupt.Handler
|
||||
In io.Reader
|
||||
Out io.Writer
|
||||
Err io.Writer
|
||||
|
||||
genericclioptions.IOStreams
|
||||
|
||||
// for testing
|
||||
overrideStreams func() (io.ReadCloser, io.Writer, io.Writer)
|
||||
|
@ -155,7 +153,7 @@ func (p *ExecOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, argsIn []s
|
|||
return cmdutil.UsageErrorf(cmd, execUsageStr)
|
||||
}
|
||||
if len(p.PodName) != 0 {
|
||||
printDeprecationWarning(p.Err, "exec POD_NAME", "-p POD_NAME")
|
||||
printDeprecationWarning(p.ErrOut, "exec POD_NAME", "-p POD_NAME")
|
||||
if len(argsIn) < 1 {
|
||||
return cmdutil.UsageErrorf(cmd, execUsageStr)
|
||||
}
|
||||
|
@ -205,7 +203,7 @@ func (p *ExecOptions) Validate() error {
|
|||
if len(p.Command) == 0 {
|
||||
return fmt.Errorf("you must specify at least one command for the container")
|
||||
}
|
||||
if p.Out == nil || p.Err == nil {
|
||||
if p.Out == nil || p.ErrOut == nil {
|
||||
return fmt.Errorf("both output and error output must be provided")
|
||||
}
|
||||
if p.Executor == nil || p.PodClient == nil || p.Config == nil {
|
||||
|
@ -240,8 +238,8 @@ func (o *StreamOptions) setupTTY() term.TTY {
|
|||
if !o.isTerminalIn(t) {
|
||||
o.TTY = false
|
||||
|
||||
if o.Err != nil {
|
||||
fmt.Fprintln(o.Err, "Unable to use a TTY - input is not a terminal or the right kind of file")
|
||||
if o.ErrOut != nil {
|
||||
fmt.Fprintln(o.ErrOut, "Unable to use a TTY - input is not a terminal or the right kind of file")
|
||||
}
|
||||
|
||||
return t
|
||||
|
@ -284,7 +282,7 @@ func (p *ExecOptions) Run() error {
|
|||
if len(p.SuggestedCmdUsage) > 0 {
|
||||
usageString = fmt.Sprintf("%s\n%s", usageString, p.SuggestedCmdUsage)
|
||||
}
|
||||
fmt.Fprintf(p.Err, "%s\n", usageString)
|
||||
fmt.Fprintf(p.ErrOut, "%s\n", usageString)
|
||||
}
|
||||
containerName = pod.Spec.Containers[0].Name
|
||||
}
|
||||
|
@ -299,7 +297,7 @@ func (p *ExecOptions) Run() error {
|
|||
|
||||
// unset p.Err if it was previously set because both stdout and stderr go over p.Out when tty is
|
||||
// true
|
||||
p.Err = nil
|
||||
p.ErrOut = nil
|
||||
}
|
||||
|
||||
fn := func() error {
|
||||
|
@ -320,11 +318,11 @@ func (p *ExecOptions) Run() error {
|
|||
Command: p.Command,
|
||||
Stdin: p.Stdin,
|
||||
Stdout: p.Out != nil,
|
||||
Stderr: p.Err != nil,
|
||||
Stderr: p.ErrOut != nil,
|
||||
TTY: t.Raw,
|
||||
}, legacyscheme.ParameterCodec)
|
||||
|
||||
return p.Executor.Execute("POST", req.URL(), p.Config, p.In, p.Out, p.Err, t.Raw, sizeQueue)
|
||||
return p.Executor.Execute("POST", req.URL(), p.Config, p.In, p.Out, p.ErrOut, t.Raw, sizeQueue)
|
||||
}
|
||||
|
||||
if err := t.Safe(fn); err != nil {
|
||||
|
|
|
@ -36,6 +36,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/term"
|
||||
)
|
||||
|
@ -145,7 +146,7 @@ func TestPodAndContainer(t *testing.T) {
|
|||
|
||||
cmd := &cobra.Command{}
|
||||
options := test.p
|
||||
options.Err = bytes.NewBuffer([]byte{})
|
||||
options.ErrOut = bytes.NewBuffer([]byte{})
|
||||
err := options.Complete(tf, cmd, test.args, test.argsLenAtDash)
|
||||
if test.expectError && err == nil {
|
||||
t.Errorf("%s: unexpected non-error", test.name)
|
||||
|
@ -213,9 +214,6 @@ func TestExec(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
bufOut := bytes.NewBuffer([]byte{})
|
||||
bufErr := bytes.NewBuffer([]byte{})
|
||||
bufIn := bytes.NewBuffer([]byte{})
|
||||
ex := &fakeRemoteExecutor{}
|
||||
if test.execErr {
|
||||
ex.execErr = fmt.Errorf("exec error")
|
||||
|
@ -224,9 +222,7 @@ func TestExec(t *testing.T) {
|
|||
StreamOptions: StreamOptions{
|
||||
PodName: "foo",
|
||||
ContainerName: "bar",
|
||||
In: bufIn,
|
||||
Out: bufOut,
|
||||
Err: bufErr,
|
||||
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||
},
|
||||
Executor: ex,
|
||||
}
|
||||
|
@ -277,16 +273,14 @@ func execPod() *api.Pod {
|
|||
}
|
||||
|
||||
func TestSetupTTY(t *testing.T) {
|
||||
stderr := &bytes.Buffer{}
|
||||
streams, _, _, stderr := genericclioptions.NewTestIOStreams()
|
||||
|
||||
// test 1 - don't attach stdin
|
||||
o := &StreamOptions{
|
||||
// InterruptParent: ,
|
||||
Stdin: false,
|
||||
In: &bytes.Buffer{},
|
||||
Out: &bytes.Buffer{},
|
||||
Err: stderr,
|
||||
TTY: true,
|
||||
Stdin: false,
|
||||
IOStreams: streams,
|
||||
TTY: true,
|
||||
}
|
||||
|
||||
tty := o.setupTTY()
|
||||
|
@ -334,7 +328,7 @@ func TestSetupTTY(t *testing.T) {
|
|||
// test 3 - request a TTY, but stdin is not a terminal
|
||||
o.Stdin = true
|
||||
o.In = &bytes.Buffer{}
|
||||
o.Err = stderr
|
||||
o.ErrOut = stderr
|
||||
o.TTY = true
|
||||
|
||||
tty = o.setupTTY()
|
||||
|
|
|
@ -35,6 +35,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/apis/core/validation"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
|
@ -89,12 +90,19 @@ type LogsOptions struct {
|
|||
GetPodTimeout time.Duration
|
||||
LogsForObject func(object, options runtime.Object, timeout time.Duration) (*restclient.Request, error)
|
||||
|
||||
Out io.Writer
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
func NewLogsOptions(streams genericclioptions.IOStreams) *LogsOptions {
|
||||
return &LogsOptions{
|
||||
IOStreams: streams,
|
||||
}
|
||||
}
|
||||
|
||||
// NewCmdLogs creates a new pod logs command
|
||||
func NewCmdLogs(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||
o := &LogsOptions{}
|
||||
func NewCmdLogs(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := NewLogsOptions(streams)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]",
|
||||
DisableFlagsInUseLine: true,
|
||||
|
@ -103,11 +111,11 @@ func NewCmdLogs(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||
Example: logsExample,
|
||||
PreRun: func(cmd *cobra.Command, args []string) {
|
||||
if len(os.Args) > 1 && os.Args[1] == "log" {
|
||||
printDeprecationWarning(errOut, "logs", "log")
|
||||
printDeprecationWarning(o.ErrOut, "logs", "log")
|
||||
}
|
||||
},
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
cmdutil.CheckErr(o.Complete(f, out, cmd, args))
|
||||
cmdutil.CheckErr(o.Complete(f, cmd, args))
|
||||
cmdutil.CheckErr(o.Validate())
|
||||
cmdutil.CheckErr(o.RunLogs())
|
||||
},
|
||||
|
@ -129,7 +137,7 @@ func NewCmdLogs(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
|||
return cmd
|
||||
}
|
||||
|
||||
func (o *LogsOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
|
||||
func (o *LogsOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
containerName := cmdutil.GetFlagString(cmd, "container")
|
||||
selector := cmdutil.GetFlagString(cmd, "selector")
|
||||
o.AllContainers = cmdutil.GetFlagBool(cmd, "all-containers")
|
||||
|
@ -189,7 +197,6 @@ func (o *LogsOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Comm
|
|||
}
|
||||
o.Options = logOptions
|
||||
o.LogsForObject = f.LogsForObject
|
||||
o.Out = out
|
||||
|
||||
if len(selector) != 0 {
|
||||
if logOptions.Follow {
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"bytes"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
@ -31,6 +30,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
)
|
||||
|
||||
|
@ -74,9 +74,9 @@ func TestLog(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdLogs(tf, buf, buf)
|
||||
cmd := NewCmdLogs(tf, streams)
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Run(cmd, []string{"foo"})
|
||||
|
||||
|
@ -144,17 +144,17 @@ func TestValidateLogFlags(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
cmd := NewCmdLogs(f, buf, buf)
|
||||
streams := genericclioptions.NewTestIOStreamsDiscard()
|
||||
cmd := NewCmdLogs(f, streams)
|
||||
out := ""
|
||||
for flag, value := range test.flags {
|
||||
cmd.Flags().Set(flag, value)
|
||||
}
|
||||
// checkErr breaks tests in case of errors, plus we just
|
||||
// need to check errors returned by the command validation
|
||||
o := &LogsOptions{}
|
||||
o := NewLogsOptions(streams)
|
||||
cmd.Run = func(cmd *cobra.Command, args []string) {
|
||||
o.Complete(f, os.Stdout, cmd, args)
|
||||
o.Complete(f, cmd, args)
|
||||
out = o.Validate().Error()
|
||||
}
|
||||
cmd.Run(cmd, test.args)
|
||||
|
@ -205,8 +205,7 @@ func TestLogComplete(t *testing.T) {
|
|||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
cmd := NewCmdLogs(f, buf, buf)
|
||||
cmd := NewCmdLogs(f, genericclioptions.NewTestIOStreamsDiscard())
|
||||
var err error
|
||||
out := ""
|
||||
for flag, value := range test.flags {
|
||||
|
@ -214,8 +213,8 @@ func TestLogComplete(t *testing.T) {
|
|||
}
|
||||
// checkErr breaks tests in case of errors, plus we just
|
||||
// need to check errors returned by the command validation
|
||||
o := &LogsOptions{}
|
||||
err = o.Complete(f, os.Stdout, cmd, test.args)
|
||||
o := NewLogsOptions(genericclioptions.NewTestIOStreamsDiscard())
|
||||
err = o.Complete(f, cmd, test.args)
|
||||
out = err.Error()
|
||||
if !strings.Contains(out, test.expected) {
|
||||
t.Errorf("%s: expected to find:\n\t%s\nfound:\n\t%s\n", test.name, test.expected, out)
|
||||
|
|
|
@ -18,7 +18,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"syscall"
|
||||
|
@ -28,6 +27,7 @@ import (
|
|||
"github.com/spf13/pflag"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
|
@ -42,7 +42,7 @@ var (
|
|||
)
|
||||
|
||||
// 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 {
|
||||
func NewCmdPlugin(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
// Loads plugins and create commands for each plugin identified
|
||||
loadedPlugins, loadErr := f.PluginLoader().Load()
|
||||
if loadErr != nil {
|
||||
|
@ -58,14 +58,14 @@ func NewCmdPlugin(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Co
|
|||
if len(loadedPlugins) == 0 {
|
||||
cmdutil.CheckErr(fmt.Errorf("no plugins installed."))
|
||||
}
|
||||
cmdutil.DefaultSubCommandRun(err)(cmd, args)
|
||||
cmdutil.DefaultSubCommandRun(streams.ErrOut)(cmd, args)
|
||||
},
|
||||
}
|
||||
|
||||
if len(loadedPlugins) > 0 {
|
||||
pluginRunner := f.PluginRunner()
|
||||
for _, p := range loadedPlugins {
|
||||
cmd.AddCommand(NewCmdForPlugin(f, p, pluginRunner, in, out, err))
|
||||
cmd.AddCommand(NewCmdForPlugin(f, p, pluginRunner, streams))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ func NewCmdPlugin(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Co
|
|||
}
|
||||
|
||||
// NewCmdForPlugin creates a command capable of running the provided plugin.
|
||||
func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.PluginRunner, in io.Reader, out, errout io.Writer) *cobra.Command {
|
||||
func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.PluginRunner, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
if !plugin.IsValid() {
|
||||
return nil
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.P
|
|||
Example: templates.Examples(plugin.Example),
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if len(plugin.Command) == 0 {
|
||||
cmdutil.DefaultSubCommandRun(errout)(cmd, args)
|
||||
cmdutil.DefaultSubCommandRun(streams.ErrOut)(cmd, args)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -104,9 +104,7 @@ func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.P
|
|||
}
|
||||
|
||||
runningContext := plugins.RunningContext{
|
||||
In: in,
|
||||
Out: out,
|
||||
ErrOut: errout,
|
||||
IOStreams: streams,
|
||||
Args: args,
|
||||
EnvProvider: envProvider,
|
||||
WorkingDir: plugin.Dir,
|
||||
|
@ -117,7 +115,7 @@ func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.P
|
|||
// check for (and exit with) the correct exit code
|
||||
// from a failed plugin command execution
|
||||
if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
|
||||
fmt.Fprintf(errout, "error: %v\n", err)
|
||||
fmt.Fprintf(streams.ErrOut, "error: %v\n", err)
|
||||
os.Exit(status.ExitStatus())
|
||||
}
|
||||
}
|
||||
|
@ -132,7 +130,7 @@ func NewCmdForPlugin(f cmdutil.Factory, plugin *plugins.Plugin, runner plugins.P
|
|||
}
|
||||
|
||||
for _, childPlugin := range plugin.Tree {
|
||||
cmd.AddCommand(NewCmdForPlugin(f, childPlugin, runner, in, out, errout))
|
||||
cmd.AddCommand(NewCmdForPlugin(f, childPlugin, runner, streams))
|
||||
}
|
||||
|
||||
return cmd
|
||||
|
|
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/plugins"
|
||||
)
|
||||
|
||||
|
@ -81,9 +81,7 @@ func TestPluginCmd(t *testing.T) {
|
|||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
inBuf := bytes.NewBuffer([]byte{})
|
||||
outBuf := bytes.NewBuffer([]byte{})
|
||||
errBuf := bytes.NewBuffer([]byte{})
|
||||
streams, _, outBuf, errBuf := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmdutil.BehaviorOnFatal(func(str string, code int) {
|
||||
errBuf.Write([]byte(str))
|
||||
|
@ -96,7 +94,7 @@ func TestPluginCmd(t *testing.T) {
|
|||
f := cmdtesting.NewTestFactory()
|
||||
defer f.Cleanup()
|
||||
|
||||
cmd := NewCmdForPlugin(f, test.plugin, runner, inBuf, outBuf, errBuf)
|
||||
cmd := NewCmdForPlugin(f, test.plugin, runner, streams)
|
||||
if cmd == nil {
|
||||
if !test.expectedNilCmd {
|
||||
t.Fatalf("%s: command was unexpectedly not registered", test.name)
|
||||
|
|
|
@ -18,7 +18,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
|
@ -38,6 +37,7 @@ import (
|
|||
coreclient "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/typed/core/internalversion"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
|
@ -84,11 +84,10 @@ const (
|
|||
defaultPodPortForwardWaitTimeout = 60 * time.Second
|
||||
)
|
||||
|
||||
func NewCmdPortForward(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command {
|
||||
func NewCmdPortForward(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
opts := &PortForwardOptions{
|
||||
PortForwarder: &defaultPortForwarder{
|
||||
cmdOut: cmdOut,
|
||||
cmdErr: cmdErr,
|
||||
IOStreams: streams,
|
||||
},
|
||||
}
|
||||
cmd := &cobra.Command{
|
||||
|
@ -119,7 +118,7 @@ type portForwarder interface {
|
|||
}
|
||||
|
||||
type defaultPortForwarder struct {
|
||||
cmdOut, cmdErr io.Writer
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
func (f *defaultPortForwarder) ForwardPorts(method string, url *url.URL, opts PortForwardOptions) error {
|
||||
|
@ -128,7 +127,7 @@ func (f *defaultPortForwarder) ForwardPorts(method string, url *url.URL, opts Po
|
|||
return err
|
||||
}
|
||||
dialer := spdy.NewDialer(upgrader, &http.Client{Transport: transport}, method, url)
|
||||
fw, err := portforward.New(dialer, opts.Ports, opts.StopChannel, opts.ReadyChannel, f.cmdOut, f.cmdErr)
|
||||
fw, err := portforward.New(dialer, opts.Ports, opts.StopChannel, opts.ReadyChannel, f.Out, f.ErrOut)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -20,7 +20,6 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
|
@ -32,6 +31,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
)
|
||||
|
||||
|
@ -102,7 +102,7 @@ func testPortForward(t *testing.T, flags map[string]string, args []string) {
|
|||
}
|
||||
|
||||
opts := &PortForwardOptions{}
|
||||
cmd := NewCmdPortForward(tf, os.Stdout, os.Stderr)
|
||||
cmd := NewCmdPortForward(tf, genericclioptions.NewTestIOStreamsDiscard())
|
||||
cmd.Run = func(cmd *cobra.Command, args []string) {
|
||||
if err = opts.Complete(tf, cmd, args); err != nil {
|
||||
return
|
||||
|
|
|
@ -28,6 +28,7 @@ import (
|
|||
"github.com/spf13/cobra"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/proxy"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
)
|
||||
|
@ -69,7 +70,7 @@ var (
|
|||
kubectl proxy --api-prefix=/k8s-api`))
|
||||
)
|
||||
|
||||
func NewCmdProxy(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
||||
func NewCmdProxy(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "proxy [--port=PORT] [--www=static-dir] [--www-prefix=prefix] [--api-prefix=prefix]",
|
||||
DisableFlagsInUseLine: true,
|
||||
|
@ -77,7 +78,7 @@ func NewCmdProxy(f cmdutil.Factory, out io.Writer) *cobra.Command {
|
|||
Long: proxyLong,
|
||||
Example: proxyExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
err := RunProxy(f, out, cmd)
|
||||
err := RunProxy(f, streams.Out, cmd)
|
||||
cmdutil.CheckErr(err)
|
||||
},
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
@ -86,11 +85,10 @@ type ReplaceOptions struct {
|
|||
|
||||
Recorder genericclioptions.Recorder
|
||||
|
||||
Out io.Writer
|
||||
ErrOut io.Writer
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
func NewReplaceOptions(out, errOut io.Writer) *ReplaceOptions {
|
||||
func NewReplaceOptions(streams genericclioptions.IOStreams) *ReplaceOptions {
|
||||
outputFormat := ""
|
||||
|
||||
return &ReplaceOptions{
|
||||
|
@ -102,13 +100,12 @@ func NewReplaceOptions(out, errOut io.Writer) *ReplaceOptions {
|
|||
},
|
||||
DeleteFlags: NewDeleteFlags("to use to replace the resource."),
|
||||
|
||||
Out: out,
|
||||
ErrOut: errOut,
|
||||
IOStreams: streams,
|
||||
}
|
||||
}
|
||||
|
||||
func NewCmdReplace(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||
o := NewReplaceOptions(out, errOut)
|
||||
func NewCmdReplace(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
o := NewReplaceOptions(streams)
|
||||
|
||||
cmd := &cobra.Command{
|
||||
Use: "replace -f FILENAME",
|
||||
|
@ -154,7 +151,7 @@ func (o *ReplaceOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
|||
return printer.PrintObj(obj, o.Out)
|
||||
}
|
||||
|
||||
deleteOpts := o.DeleteFlags.ToOptions(o.Out, o.ErrOut)
|
||||
deleteOpts := o.DeleteFlags.ToOptions(o.IOStreams)
|
||||
|
||||
//Replace will create a resource if it doesn't exist already, so ignore not found error
|
||||
deleteOpts.IgnoreNotFound = true
|
||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
|
@ -26,6 +25,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
)
|
||||
|
||||
|
@ -63,9 +63,9 @@ func TestReplaceObject(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdReplace(tf, buf, buf)
|
||||
cmd := NewCmdReplace(tf, streams)
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||
cmd.Flags().Set("output", "name")
|
||||
cmd.Run(cmd, []string{})
|
||||
|
@ -134,9 +134,9 @@ func TestReplaceMultipleObject(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdReplace(tf, buf, buf)
|
||||
cmd := NewCmdReplace(tf, streams)
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/frontend-service.yaml")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -192,9 +192,9 @@ func TestReplaceDirectory(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdReplace(tf, buf, buf)
|
||||
cmd := NewCmdReplace(tf, streams)
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy")
|
||||
cmd.Flags().Set("namespace", "test")
|
||||
cmd.Flags().Set("output", "name")
|
||||
|
@ -239,9 +239,9 @@ func TestForceReplaceObjectNotFound(t *testing.T) {
|
|||
}),
|
||||
}
|
||||
tf.Namespace = "test"
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdReplace(tf, buf, buf)
|
||||
cmd := NewCmdReplace(tf, streams)
|
||||
cmd.Flags().Set("filename", "../../../test/e2e/testing-manifests/guestbook/legacy/redis-master-controller.yaml")
|
||||
cmd.Flags().Set("force", "true")
|
||||
cmd.Flags().Set("cascade", "false")
|
||||
|
|
|
@ -233,7 +233,7 @@ func (o *RunOptions) Complete(f cmdutil.Factory, cmd *cobra.Command) error {
|
|||
return printer.PrintObj(obj, o.Out)
|
||||
}
|
||||
|
||||
deleteOpts := o.DeleteFlags.ToOptions(o.Out, o.ErrOut)
|
||||
deleteOpts := o.DeleteFlags.ToOptions(o.IOStreams)
|
||||
deleteOpts.IgnoreNotFound = true
|
||||
deleteOpts.WaitForDeletion = false
|
||||
deleteOpts.GracePeriod = -1
|
||||
|
@ -374,12 +374,10 @@ func (o *RunOptions) Run(f cmdutil.Factory, cmd *cobra.Command, args []string) e
|
|||
|
||||
opts := &AttachOptions{
|
||||
StreamOptions: StreamOptions{
|
||||
In: o.In,
|
||||
Out: o.Out,
|
||||
Err: o.ErrOut,
|
||||
Stdin: o.Interactive,
|
||||
TTY: o.TTY,
|
||||
Quiet: o.Quiet,
|
||||
IOStreams: o.IOStreams,
|
||||
Stdin: o.Interactive,
|
||||
TTY: o.TTY,
|
||||
Quiet: o.Quiet,
|
||||
},
|
||||
GetPodTimeout: timeout,
|
||||
CommandName: cmd.Parent().CommandPath() + " attach",
|
||||
|
@ -528,7 +526,7 @@ func handleAttachPod(f cmdutil.Factory, podClient coreclient.PodsGetter, ns, nam
|
|||
opts.Namespace = ns
|
||||
|
||||
// TODO: opts.Run sets opts.Err to nil, we need to find a better way
|
||||
stderr := opts.Err
|
||||
stderr := opts.ErrOut
|
||||
if err := opts.Run(); err != nil {
|
||||
fmt.Fprintf(stderr, "Error attaching, falling back to logs: %v\n", err)
|
||||
return logOpts(f, pod, opts)
|
||||
|
|
|
@ -208,7 +208,7 @@ func TestRunArgsFollowDashRules(t *testing.T) {
|
|||
deleteFlags := NewDeleteFlags("to use to replace the resource.")
|
||||
opts := &RunOptions{
|
||||
PrintFlags: printFlags,
|
||||
DeleteOptions: deleteFlags.ToOptions(os.Stdout, os.Stderr),
|
||||
DeleteOptions: deleteFlags.ToOptions(genericclioptions.NewTestIOStreamsDiscard()),
|
||||
|
||||
IOStreams: genericclioptions.NewTestIOStreamsDiscard(),
|
||||
|
||||
|
@ -377,7 +377,7 @@ func TestGenerateService(t *testing.T) {
|
|||
deleteFlags := NewDeleteFlags("to use to replace the resource.")
|
||||
opts := &RunOptions{
|
||||
PrintFlags: printFlags,
|
||||
DeleteOptions: deleteFlags.ToOptions(os.Stdout, os.Stderr),
|
||||
DeleteOptions: deleteFlags.ToOptions(genericclioptions.NewTestIOStreamsDiscard()),
|
||||
|
||||
IOStreams: ioStreams,
|
||||
|
||||
|
|
|
@ -17,8 +17,6 @@ limitations under the License.
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
|
@ -26,6 +24,7 @@ import (
|
|||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -40,17 +39,17 @@ var (
|
|||
This command requires Heapster to be correctly configured and working on the server. `))
|
||||
)
|
||||
|
||||
func NewCmdTop(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
|
||||
func NewCmdTop(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "top",
|
||||
Short: i18n.T("Display Resource (CPU/Memory/Storage) usage."),
|
||||
Long: topLong,
|
||||
Run: cmdutil.DefaultSubCommandRun(errOut),
|
||||
Run: cmdutil.DefaultSubCommandRun(streams.ErrOut),
|
||||
}
|
||||
|
||||
// create subcommands
|
||||
cmd.AddCommand(NewCmdTopNode(f, nil, out))
|
||||
cmd.AddCommand(NewCmdTopPod(f, nil, out))
|
||||
cmd.AddCommand(NewCmdTopNode(f, nil, streams))
|
||||
cmd.AddCommand(NewCmdTopPod(f, nil, streams))
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ package cmd
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"io"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
|
@ -29,6 +28,7 @@ import (
|
|||
corev1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
|
||||
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/metricsutil"
|
||||
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
|
||||
metricsapi "k8s.io/metrics/pkg/apis/metrics"
|
||||
|
@ -46,6 +46,8 @@ type TopNodeOptions struct {
|
|||
Printer *metricsutil.TopCmdPrinter
|
||||
DiscoveryClient discovery.DiscoveryInterface
|
||||
MetricsClient metricsclientset.Interface
|
||||
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
type HeapsterTopOptions struct {
|
||||
|
@ -89,9 +91,11 @@ var (
|
|||
kubectl top node NODE_NAME`))
|
||||
)
|
||||
|
||||
func NewCmdTopNode(f cmdutil.Factory, options *TopNodeOptions, out io.Writer) *cobra.Command {
|
||||
if options == nil {
|
||||
options = &TopNodeOptions{}
|
||||
func NewCmdTopNode(f cmdutil.Factory, o *TopNodeOptions, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
if o == nil {
|
||||
o = &TopNodeOptions{
|
||||
IOStreams: streams,
|
||||
}
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
@ -101,24 +105,24 @@ func NewCmdTopNode(f cmdutil.Factory, options *TopNodeOptions, out io.Writer) *c
|
|||
Long: topNodeLong,
|
||||
Example: topNodeExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := options.Complete(f, cmd, args, out); err != nil {
|
||||
if err := o.Complete(f, cmd, args); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
}
|
||||
if err := options.Validate(); err != nil {
|
||||
if err := o.Validate(); err != nil {
|
||||
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err))
|
||||
}
|
||||
if err := options.RunTopNode(); err != nil {
|
||||
if err := o.RunTopNode(); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
}
|
||||
},
|
||||
Aliases: []string{"nodes", "no"},
|
||||
}
|
||||
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||
options.HeapsterOptions.Bind(cmd.Flags())
|
||||
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||
o.HeapsterOptions.Bind(cmd.Flags())
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, out io.Writer) error {
|
||||
func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
if len(args) == 1 {
|
||||
o.ResourceName = args[0]
|
||||
} else if len(args) > 1 {
|
||||
|
@ -144,7 +148,7 @@ func (o *TopNodeOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
|
|||
o.NodeClient = clientset.CoreV1()
|
||||
o.Client = metricsutil.NewHeapsterMetricsClient(clientset.CoreV1(), o.HeapsterOptions.Namespace, o.HeapsterOptions.Scheme, o.HeapsterOptions.Service, o.HeapsterOptions.Port)
|
||||
|
||||
o.Printer = metricsutil.NewTopCmdPrinter(out)
|
||||
o.Printer = metricsutil.NewTopCmdPrinter(o.Out)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
core "k8s.io/client-go/testing"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
"k8s.io/kubernetes/pkg/kubectl/scheme"
|
||||
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
||||
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||
|
@ -79,9 +80,9 @@ func TestTopNodeAllMetrics(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdTopNode(tf, nil, buf)
|
||||
cmd := NewCmdTopNode(tf, nil, streams)
|
||||
cmd.Run(cmd, []string{})
|
||||
|
||||
// Check the presence of node names in the output.
|
||||
|
@ -132,7 +133,7 @@ func TestTopNodeAllMetricsCustomDefaults(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
opts := &TopNodeOptions{
|
||||
HeapsterOptions: HeapsterTopOptions{
|
||||
|
@ -140,8 +141,9 @@ func TestTopNodeAllMetricsCustomDefaults(t *testing.T) {
|
|||
Scheme: "https",
|
||||
Service: "custom-heapster-service",
|
||||
},
|
||||
IOStreams: streams,
|
||||
}
|
||||
cmd := NewCmdTopNode(tf, opts, buf)
|
||||
cmd := NewCmdTopNode(tf, opts, streams)
|
||||
cmd.Run(cmd, []string{})
|
||||
|
||||
// Check the presence of node names in the output.
|
||||
|
@ -195,9 +197,9 @@ func TestTopNodeWithNameMetrics(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdTopNode(tf, nil, buf)
|
||||
cmd := NewCmdTopNode(tf, nil, streams)
|
||||
cmd.Run(cmd, []string{expectedMetrics.Name})
|
||||
|
||||
// Check the presence of node names in the output.
|
||||
|
@ -262,9 +264,9 @@ func TestTopNodeWithLabelSelectorMetrics(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdTopNode(tf, nil, buf)
|
||||
cmd := NewCmdTopNode(tf, nil, streams)
|
||||
cmd.Flags().Set("selector", label)
|
||||
cmd.Run(cmd, []string{})
|
||||
|
||||
|
@ -315,14 +317,16 @@ func TestTopNodeAllMetricsFromMetricsServer(t *testing.T) {
|
|||
})
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdTopNode(tf, nil, buf)
|
||||
cmd := NewCmdTopNode(tf, nil, streams)
|
||||
|
||||
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
||||
// TODO then check the particular Run functionality and harvest results from fake clients
|
||||
cmdOptions := &TopNodeOptions{}
|
||||
if err := cmdOptions.Complete(tf, cmd, []string{}, buf); err != nil {
|
||||
cmdOptions := &TopNodeOptions{
|
||||
IOStreams: streams,
|
||||
}
|
||||
if err := cmdOptions.Complete(tf, cmd, []string{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cmdOptions.MetricsClient = fakemetricsClientset
|
||||
|
@ -381,14 +385,16 @@ func TestTopNodeWithNameMetricsFromMetricsServer(t *testing.T) {
|
|||
})
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdTopNode(tf, nil, buf)
|
||||
cmd := NewCmdTopNode(tf, nil, streams)
|
||||
|
||||
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
||||
// TODO then check the particular Run functionality and harvest results from fake clients
|
||||
cmdOptions := &TopNodeOptions{}
|
||||
if err := cmdOptions.Complete(tf, cmd, []string{expectedMetrics.Name}, buf); err != nil {
|
||||
cmdOptions := &TopNodeOptions{
|
||||
IOStreams: streams,
|
||||
}
|
||||
if err := cmdOptions.Complete(tf, cmd, []string{expectedMetrics.Name}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cmdOptions.MetricsClient = fakemetricsClientset
|
||||
|
@ -458,15 +464,17 @@ func TestTopNodeWithLabelSelectorMetricsFromMetricsServer(t *testing.T) {
|
|||
})
|
||||
tf.Namespace = "test"
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdTopNode(tf, nil, buf)
|
||||
cmd := NewCmdTopNode(tf, nil, streams)
|
||||
cmd.Flags().Set("selector", label)
|
||||
|
||||
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
||||
// TODO then check the particular Run functionality and harvest results from fake clients
|
||||
cmdOptions := &TopNodeOptions{}
|
||||
if err := cmdOptions.Complete(tf, cmd, []string{}, buf); err != nil {
|
||||
cmdOptions := &TopNodeOptions{
|
||||
IOStreams: streams,
|
||||
}
|
||||
if err := cmdOptions.Complete(tf, cmd, []string{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cmdOptions.MetricsClient = fakemetricsClientset
|
||||
|
|
|
@ -19,7 +19,6 @@ package cmd
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
|
@ -37,6 +36,7 @@ import (
|
|||
|
||||
"github.com/golang/glog"
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
)
|
||||
|
||||
type TopPodOptions struct {
|
||||
|
@ -51,6 +51,8 @@ type TopPodOptions struct {
|
|||
Printer *metricsutil.TopCmdPrinter
|
||||
DiscoveryClient discovery.DiscoveryInterface
|
||||
MetricsClient metricsclientset.Interface
|
||||
|
||||
genericclioptions.IOStreams
|
||||
}
|
||||
|
||||
const metricsCreationDelay = 2 * time.Minute
|
||||
|
@ -78,9 +80,11 @@ var (
|
|||
kubectl top pod -l name=myLabel`))
|
||||
)
|
||||
|
||||
func NewCmdTopPod(f cmdutil.Factory, options *TopPodOptions, out io.Writer) *cobra.Command {
|
||||
if options == nil {
|
||||
options = &TopPodOptions{}
|
||||
func NewCmdTopPod(f cmdutil.Factory, o *TopPodOptions, streams genericclioptions.IOStreams) *cobra.Command {
|
||||
if o == nil {
|
||||
o = &TopPodOptions{
|
||||
IOStreams: streams,
|
||||
}
|
||||
}
|
||||
|
||||
cmd := &cobra.Command{
|
||||
|
@ -90,26 +94,26 @@ func NewCmdTopPod(f cmdutil.Factory, options *TopPodOptions, out io.Writer) *cob
|
|||
Long: topPodLong,
|
||||
Example: topPodExample,
|
||||
Run: func(cmd *cobra.Command, args []string) {
|
||||
if err := options.Complete(f, cmd, args, out); err != nil {
|
||||
if err := o.Complete(f, cmd, args); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
}
|
||||
if err := options.Validate(); err != nil {
|
||||
if err := o.Validate(); err != nil {
|
||||
cmdutil.CheckErr(cmdutil.UsageErrorf(cmd, "%v", err))
|
||||
}
|
||||
if err := options.RunTopPod(); err != nil {
|
||||
if err := o.RunTopPod(); err != nil {
|
||||
cmdutil.CheckErr(err)
|
||||
}
|
||||
},
|
||||
Aliases: []string{"pods", "po"},
|
||||
}
|
||||
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||
cmd.Flags().BoolVar(&options.PrintContainers, "containers", options.PrintContainers, "If present, print usage of containers within a pod.")
|
||||
cmd.Flags().BoolVar(&options.AllNamespaces, "all-namespaces", options.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
|
||||
options.HeapsterOptions.Bind(cmd.Flags())
|
||||
cmd.Flags().StringVarP(&o.Selector, "selector", "l", o.Selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
|
||||
cmd.Flags().BoolVar(&o.PrintContainers, "containers", o.PrintContainers, "If present, print usage of containers within a pod.")
|
||||
cmd.Flags().BoolVar(&o.AllNamespaces, "all-namespaces", o.AllNamespaces, "If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.")
|
||||
o.HeapsterOptions.Bind(cmd.Flags())
|
||||
return cmd
|
||||
}
|
||||
|
||||
func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string, out io.Writer) error {
|
||||
func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
|
||||
var err error
|
||||
if len(args) == 1 {
|
||||
o.ResourceName = args[0]
|
||||
|
@ -139,7 +143,7 @@ func (o *TopPodOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []s
|
|||
o.PodClient = clientset.CoreV1()
|
||||
o.Client = metricsutil.NewHeapsterMetricsClient(clientset.CoreV1(), o.HeapsterOptions.Namespace, o.HeapsterOptions.Scheme, o.HeapsterOptions.Service, o.HeapsterOptions.Port)
|
||||
|
||||
o.Printer = metricsutil.NewTopCmdPrinter(out)
|
||||
o.Printer = metricsutil.NewTopCmdPrinter(o.Out)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ import (
|
|||
core "k8s.io/client-go/testing"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
||||
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||
metricsfake "k8s.io/metrics/pkg/client/clientset_generated/clientset/fake"
|
||||
|
@ -191,9 +192,9 @@ func TestTopPod(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = testNS
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdTopPod(tf, nil, buf)
|
||||
cmd := NewCmdTopPod(tf, nil, streams)
|
||||
for name, value := range testCase.flags {
|
||||
cmd.Flags().Set(name, value)
|
||||
}
|
||||
|
@ -330,19 +331,20 @@ func TestTopPodWithMetricsServer(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = testNS
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
cmd := NewCmdTopPod(tf, nil, buf)
|
||||
cmd := NewCmdTopPod(tf, nil, streams)
|
||||
var cmdOptions *TopPodOptions
|
||||
if testCase.options != nil {
|
||||
cmdOptions = testCase.options
|
||||
} else {
|
||||
cmdOptions = &TopPodOptions{}
|
||||
}
|
||||
cmdOptions.IOStreams = streams
|
||||
|
||||
// TODO in the long run, we want to test most of our commands like this. Wire the options struct with specific mocks
|
||||
// TODO then check the particular Run functionality and harvest results from fake clients. We probably end up skipping the factory altogether.
|
||||
if err := cmdOptions.Complete(tf, cmd, testCase.args, buf); err != nil {
|
||||
if err := cmdOptions.Complete(tf, cmd, testCase.args); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
cmdOptions.MetricsClient = fakemetricsClientset
|
||||
|
@ -534,7 +536,7 @@ func TestTopPodCustomDefaults(t *testing.T) {
|
|||
}
|
||||
tf.Namespace = testNS
|
||||
tf.ClientConfigVal = defaultClientConfig()
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
opts := &TopPodOptions{
|
||||
HeapsterOptions: HeapsterTopOptions{
|
||||
|
@ -543,8 +545,9 @@ func TestTopPodCustomDefaults(t *testing.T) {
|
|||
Service: "custom-heapster-service",
|
||||
},
|
||||
DiscoveryClient: &fakeDiscovery{},
|
||||
IOStreams: streams,
|
||||
}
|
||||
cmd := NewCmdTopPod(tf, opts, buf)
|
||||
cmd := NewCmdTopPod(tf, opts, streams)
|
||||
for name, value := range testCase.flags {
|
||||
cmd.Flags().Set(name, value)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import (
|
|||
"k8s.io/apimachinery/pkg/api/resource"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
metricsv1alpha1api "k8s.io/metrics/pkg/apis/metrics/v1alpha1"
|
||||
metricsv1beta1api "k8s.io/metrics/pkg/apis/metrics/v1beta1"
|
||||
)
|
||||
|
@ -46,9 +47,7 @@ func TestTopSubcommandsExist(t *testing.T) {
|
|||
f := cmdtesting.NewTestFactory()
|
||||
defer f.Cleanup()
|
||||
|
||||
buf := bytes.NewBuffer([]byte{})
|
||||
|
||||
cmd := NewCmdTop(f, buf, buf)
|
||||
cmd := NewCmdTop(f, genericclioptions.NewTestIOStreamsDiscard())
|
||||
if !cmd.HasSubCommands() {
|
||||
t.Error("top command should have subcommands")
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@ go_library(
|
|||
],
|
||||
importpath = "k8s.io/kubernetes/pkg/kubectl/plugins",
|
||||
deps = [
|
||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||
"//vendor/github.com/ghodss/yaml:go_default_library",
|
||||
"//vendor/github.com/golang/glog:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
|
@ -45,5 +46,8 @@ go_test(
|
|||
"runner_test.go",
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = ["//vendor/github.com/spf13/pflag:go_default_library"],
|
||||
deps = [
|
||||
"//pkg/kubectl/genericclioptions:go_default_library",
|
||||
"//vendor/github.com/spf13/pflag:go_default_library",
|
||||
],
|
||||
)
|
||||
|
|
|
@ -17,12 +17,12 @@ limitations under the License.
|
|||
package plugins
|
||||
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
)
|
||||
|
||||
// PluginRunner is capable of running a plugin in a given running context.
|
||||
|
@ -34,9 +34,7 @@ type PluginRunner interface {
|
|||
// in, out, and err streams, arguments and environment passed to it, and the
|
||||
// working directory.
|
||||
type RunningContext struct {
|
||||
In io.Reader
|
||||
Out io.Writer
|
||||
ErrOut io.Writer
|
||||
genericclioptions.IOStreams
|
||||
Args []string
|
||||
EnvProvider EnvProvider
|
||||
WorkingDir string
|
||||
|
|
|
@ -17,9 +17,10 @@ limitations under the License.
|
|||
package plugins
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
|
||||
)
|
||||
|
||||
func TestExecRunner(t *testing.T) {
|
||||
|
@ -50,7 +51,7 @@ func TestExecRunner(t *testing.T) {
|
|||
defer os.Unsetenv("KUBECTL_PLUGINS_TEST")
|
||||
|
||||
for _, test := range tests {
|
||||
outBuf := bytes.NewBuffer([]byte{})
|
||||
streams, _, outBuf, _ := genericclioptions.NewTestIOStreams()
|
||||
|
||||
plugin := &Plugin{
|
||||
Description: Description{
|
||||
|
@ -61,7 +62,7 @@ func TestExecRunner(t *testing.T) {
|
|||
}
|
||||
|
||||
ctx := RunningContext{
|
||||
Out: outBuf,
|
||||
IOStreams: streams,
|
||||
WorkingDir: ".",
|
||||
EnvProvider: &EmptyEnvProvider{},
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue