provide standard iostream struct for commands

This commit is contained in:
David Eads 2018-04-19 17:43:28 -04:00
parent 9c60fd5242
commit 8ef56776b9
45 changed files with 431 additions and 436 deletions

View File

@ -19,7 +19,6 @@ package cmd
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"io"
jsonpatch "github.com/evanphx/json-patch" jsonpatch "github.com/evanphx/json-patch"
"github.com/golang/glog" "github.com/golang/glog"
@ -60,8 +59,7 @@ type AnnotateOptions struct {
removeAnnotations []string removeAnnotations []string
Recorder genericclioptions.Recorder Recorder genericclioptions.Recorder
// Common share fields genericclioptions.IOStreams
out io.Writer
} }
var ( var (
@ -99,17 +97,17 @@ var (
kubectl annotate pods foo description-`)) kubectl annotate pods foo description-`))
) )
func NewAnnotateOptions(out io.Writer) *AnnotateOptions { func NewAnnotateOptions(ioStreams genericclioptions.IOStreams) *AnnotateOptions {
return &AnnotateOptions{ return &AnnotateOptions{
out: out,
RecordFlags: genericclioptions.NewRecordFlags(), RecordFlags: genericclioptions.NewRecordFlags(),
Recorder: genericclioptions.NoopRecorder{}, Recorder: genericclioptions.NoopRecorder{},
IOStreams: ioStreams,
} }
} }
func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command { func NewCmdAnnotate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewAnnotateOptions(out) o := NewAnnotateOptions(ioStreams)
validArgs := cmdutil.ValidArgList(f) validArgs := cmdutil.ValidArgList(f)
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -283,9 +281,9 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro
} }
if len(o.outputFormat) > 0 { if len(o.outputFormat) > 0 {
return cmdutil.PrintObject(cmd, outputObj, o.out) return cmdutil.PrintObject(cmd, outputObj, o.Out)
} }
cmdutil.PrintSuccess(false, o.out, info.Object, o.dryrun, "annotated") cmdutil.PrintSuccess(false, o.Out, info.Object, o.dryrun, "annotated")
return nil return nil
}) })
} }

View File

@ -17,7 +17,6 @@ limitations under the License.
package cmd package cmd
import ( import (
"bytes"
"net/http" "net/http"
"reflect" "reflect"
"strings" "strings"
@ -30,6 +29,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" 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/scheme"
) )
@ -424,14 +424,14 @@ func TestAnnotateErrors(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{}) iostreams, _, bufOut, bufErr := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate(tf, buf) cmd := NewCmdAnnotate(tf, iostreams)
cmd.SetOutput(buf) cmd.SetOutput(bufOut)
for k, v := range testCase.flags { for k, v := range testCase.flags {
cmd.Flags().Set(k, v) cmd.Flags().Set(k, v)
} }
options := NewAnnotateOptions(buf) options := NewAnnotateOptions(iostreams)
err := options.Complete(tf, cmd, testCase.args) err := options.Complete(tf, cmd, testCase.args)
if err == nil { if err == nil {
err = options.Validate() err = options.Validate()
@ -440,8 +440,11 @@ func TestAnnotateErrors(t *testing.T) {
t.Errorf("%s: unexpected error: %v", k, err) t.Errorf("%s: unexpected error: %v", k, err)
return return
} }
if buf.Len() > 0 { if bufOut.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(buf.Bytes())) t.Errorf("buffer should be empty: %s", string(bufOut.Bytes()))
}
if bufErr.Len() > 0 {
t.Errorf("buffer should be empty: %s", string(bufErr.Bytes()))
} }
}) })
} }
@ -485,10 +488,10 @@ func TestAnnotateObject(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{}) iostreams, _, bufOut, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate(tf, buf) cmd := NewCmdAnnotate(tf, iostreams)
cmd.SetOutput(buf) cmd.SetOutput(bufOut)
options := NewAnnotateOptions(buf) options := NewAnnotateOptions(iostreams)
args := []string{"pods/foo", "a=b", "c-"} args := []string{"pods/foo", "a=b", "c-"}
if err := options.Complete(tf, cmd, args); err != nil { if err := options.Complete(tf, cmd, args); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
@ -539,10 +542,10 @@ func TestAnnotateObjectFromFile(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{}) iostreams, _, bufOut, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate(tf, buf) cmd := NewCmdAnnotate(tf, iostreams)
cmd.SetOutput(buf) cmd.SetOutput(bufOut)
options := NewAnnotateOptions(buf) options := NewAnnotateOptions(iostreams)
options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"} options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
args := []string{"a=b", "c-"} args := []string{"a=b", "c-"}
if err := options.Complete(tf, cmd, args); err != nil { if err := options.Complete(tf, cmd, args); err != nil {
@ -571,9 +574,9 @@ func TestAnnotateLocal(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{}) iostreams, _, _, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate(tf, buf) cmd := NewCmdAnnotate(tf, iostreams)
options := NewAnnotateOptions(buf) options := NewAnnotateOptions(iostreams)
options.local = true options.local = true
options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"} options.Filenames = []string{"../../../test/e2e/testing-manifests/statefulset/cassandra/controller.yaml"}
args := []string{"a=b"} args := []string{"a=b"}
@ -627,10 +630,10 @@ func TestAnnotateMultipleObjects(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{}) iostreams, _, _, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdAnnotate(tf, buf) cmd := NewCmdAnnotate(tf, iostreams)
cmd.SetOutput(buf) cmd.SetOutput(iostreams.Out)
options := NewAnnotateOptions(buf) options := NewAnnotateOptions(iostreams)
options.all = true options.all = true
args := []string{"pods", "a=b", "c-"} args := []string{"pods", "a=b", "c-"}
if err := options.Complete(tf, cmd, args); err != nil { if err := options.Complete(tf, cmd, args); err != nil {

View File

@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/printers" "k8s.io/kubernetes/pkg/printers"
) )
@ -53,12 +54,12 @@ var (
// ApiResourcesOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of // ApiResourcesOptions is the start of the data required to perform the operation. As new fields are added, add them here instead of
// referencing the cmd.Flags() // referencing the cmd.Flags()
type ApiResourcesOptions struct { type ApiResourcesOptions struct {
out io.Writer
Output string Output string
APIGroup string APIGroup string
Namespaced bool Namespaced bool
NoHeaders bool NoHeaders bool
genericclioptions.IOStreams
} }
// groupResource contains the APIGroup and APIResource // groupResource contains the APIGroup and APIResource
@ -67,10 +68,14 @@ type groupResource struct {
APIResource metav1.APIResource APIResource metav1.APIResource
} }
func NewCmdApiResources(f cmdutil.Factory, out io.Writer) *cobra.Command { func NewAPIResourceOptions(ioStreams genericclioptions.IOStreams) *ApiResourcesOptions {
options := &ApiResourcesOptions{ return &ApiResourcesOptions{
out: out, IOStreams: ioStreams,
} }
}
func NewCmdApiResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewAPIResourceOptions(ioStreams)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "api-resources", Use: "api-resources",
@ -78,15 +83,15 @@ func NewCmdApiResources(f cmdutil.Factory, out io.Writer) *cobra.Command {
Long: "Print the supported API resources on the server", Long: "Print the supported API resources on the server",
Example: apiresources_example, Example: apiresources_example,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(cmd)) cmdutil.CheckErr(o.Complete(cmd))
cmdutil.CheckErr(options.Validate(cmd)) cmdutil.CheckErr(o.Validate(cmd))
cmdutil.CheckErr(options.RunApiResources(cmd, f)) cmdutil.CheckErr(o.RunApiResources(cmd, f))
}, },
} }
cmdutil.AddOutputFlags(cmd) cmdutil.AddOutputFlags(cmd)
cmdutil.AddNoHeadersFlags(cmd) cmdutil.AddNoHeadersFlags(cmd)
cmd.Flags().StringVar(&options.APIGroup, "api-group", "", "The API group to use when talking to the server.") cmd.Flags().StringVar(&o.APIGroup, "api-group", "", "The API group to use when talking to the server.")
cmd.Flags().BoolVar(&options.Namespaced, "namespaced", true, "Namespaced indicates if a resource is namespaced or not.") cmd.Flags().BoolVar(&o.Namespaced, "namespaced", true, "Namespaced indicates if a resource is namespaced or not.")
return cmd return cmd
} }
@ -110,7 +115,7 @@ func (o *ApiResourcesOptions) Validate(cmd *cobra.Command) error {
} }
func (o *ApiResourcesOptions) RunApiResources(cmd *cobra.Command, f cmdutil.Factory) error { func (o *ApiResourcesOptions) RunApiResources(cmd *cobra.Command, f cmdutil.Factory) error {
w := printers.GetNewTabWriter(o.out) w := printers.GetNewTabWriter(o.Out)
defer w.Flush() defer w.Flush()
discoveryclient, err := f.DiscoveryClient() discoveryclient, err := f.DiscoveryClient()

View File

@ -73,8 +73,7 @@ type ApplyOptions struct {
OpenApiPatch bool OpenApiPatch bool
PruneWhitelist []string PruneWhitelist []string
Out io.Writer genericclioptions.IOStreams
ErrOut io.Writer
} }
const ( const (
@ -113,7 +112,7 @@ var (
warningNoLastAppliedConfigAnnotation = "Warning: %[1]s apply should be used on resource created by either %[1]s create --save-config or %[1]s apply\n" warningNoLastAppliedConfigAnnotation = "Warning: %[1]s apply should be used on resource created by either %[1]s create --save-config or %[1]s apply\n"
) )
func NewApplyOptions(out, errout io.Writer) *ApplyOptions { func NewApplyOptions(ioStreams genericclioptions.IOStreams) *ApplyOptions {
return &ApplyOptions{ return &ApplyOptions{
RecordFlags: genericclioptions.NewRecordFlags(), RecordFlags: genericclioptions.NewRecordFlags(),
DeleteFlags: NewDeleteFlags("that contains the configuration to apply"), DeleteFlags: NewDeleteFlags("that contains the configuration to apply"),
@ -124,13 +123,12 @@ func NewApplyOptions(out, errout io.Writer) *ApplyOptions {
Recorder: genericclioptions.NoopRecorder{}, Recorder: genericclioptions.NoopRecorder{},
Out: out, IOStreams: ioStreams,
ErrOut: errout,
} }
} }
func NewCmdApply(baseName string, f cmdutil.Factory, out, errOut io.Writer) *cobra.Command { func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewApplyOptions(out, errOut) o := NewApplyOptions(ioStreams)
// Store baseName for use in printing warnings / messages involving the base command name. // Store baseName for use in printing warnings / messages involving the base command name.
// This is useful for downstream command that wrap this one. // This is useful for downstream command that wrap this one.
@ -167,9 +165,9 @@ func NewCmdApply(baseName string, f cmdutil.Factory, out, errOut io.Writer) *cob
cmdutil.AddIncludeUninitializedFlag(cmd) cmdutil.AddIncludeUninitializedFlag(cmd)
// apply subcommands // apply subcommands
cmd.AddCommand(NewCmdApplyViewLastApplied(f, out, errOut)) cmd.AddCommand(NewCmdApplyViewLastApplied(f, ioStreams))
cmd.AddCommand(NewCmdApplySetLastApplied(f, out, errOut)) cmd.AddCommand(NewCmdApplySetLastApplied(f, ioStreams))
cmd.AddCommand(NewCmdApplyEditLastApplied(f, out, errOut)) cmd.AddCommand(NewCmdApplyEditLastApplied(f, ioStreams))
return cmd return cmd
} }

View File

@ -17,14 +17,13 @@ limitations under the License.
package cmd package cmd
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor" "k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
var ( var (
@ -57,8 +56,8 @@ var (
kubectl apply edit-last-applied -f deploy.yaml -o json`) kubectl apply edit-last-applied -f deploy.yaml -o json`)
) )
func NewCmdApplyEditLastApplied(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command { func NewCmdApplyEditLastApplied(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := editor.NewEditOptions(editor.ApplyEditMode, out, errOut) o := editor.NewEditOptions(editor.ApplyEditMode, ioStreams)
validArgs := cmdutil.ValidArgList(f) validArgs := cmdutil.ValidArgList(f)

View File

@ -35,6 +35,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor" "k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
@ -55,8 +56,7 @@ type SetLastAppliedOptions struct {
PatchBufferList []PatchBuffer PatchBufferList []PatchBuffer
Factory cmdutil.Factory Factory cmdutil.Factory
Out io.Writer genericclioptions.IOStreams
ErrOut io.Writer
} }
type PatchBuffer struct { type PatchBuffer struct {
@ -82,15 +82,14 @@ var (
`)) `))
) )
func NewSetLastAppliedOptions(out, errout io.Writer) *SetLastAppliedOptions { func NewSetLastAppliedOptions(ioStreams genericclioptions.IOStreams) *SetLastAppliedOptions {
return &SetLastAppliedOptions{ return &SetLastAppliedOptions{
Out: out, IOStreams: ioStreams,
ErrOut: errout,
} }
} }
func NewCmdApplySetLastApplied(f cmdutil.Factory, out, errout io.Writer) *cobra.Command { func NewCmdApplySetLastApplied(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := NewSetLastAppliedOptions(out, errout) options := NewSetLastAppliedOptions(ioStreams)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "set-last-applied -f FILENAME", Use: "set-last-applied -f FILENAME",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,

View File

@ -51,6 +51,7 @@ import (
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi" "k8s.io/kubernetes/pkg/kubectl/cmd/util/openapi"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
) )
@ -70,13 +71,10 @@ var (
) )
func TestApplyExtraArgsFail(t *testing.T) { func TestApplyExtraArgsFail(t *testing.T) {
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup() defer f.Cleanup()
c := NewCmdApply("kubectl", f, buf, errBuf) c := NewCmdApply("kubectl", f, genericclioptions.NewTestIOStreamsDiscard())
if validateApplyArgs(c, []string{"rc"}) == nil { if validateApplyArgs(c, []string{"rc"}) == nil {
t.Fatalf("unexpected non-error") t.Fatalf("unexpected non-error")
} }
@ -298,10 +296,9 @@ func TestRunApplyPrintsValidObjectList(t *testing.T) {
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameCM) cmd.Flags().Set("filename", filenameCM)
cmd.Flags().Set("output", "json") cmd.Flags().Set("output", "json")
cmd.Flags().Set("dry-run", "true") cmd.Flags().Set("dry-run", "true")
@ -426,7 +423,6 @@ func TestRunApplyViewLastApplied(t *testing.T) {
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
cmdutil.BehaviorOnFatal(func(str string, code int) { cmdutil.BehaviorOnFatal(func(str string, code int) {
if str != test.expectedErr { if str != test.expectedErr {
@ -434,7 +430,8 @@ func TestRunApplyViewLastApplied(t *testing.T) {
} }
}) })
cmd := NewCmdApplyViewLastApplied(tf, buf, errBuf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdApplyViewLastApplied(tf, ioStreams)
if test.filePath != "" { if test.filePath != "" {
cmd.Flags().Set("filename", test.filePath) cmd.Flags().Set("filename", test.filePath)
} }
@ -479,10 +476,9 @@ func TestApplyObjectWithoutAnnotation(t *testing.T) {
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameRC) cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -527,10 +523,9 @@ func TestApplyObject(t *testing.T) {
} }
tf.OpenAPISchemaFunc = fn tf.OpenAPISchemaFunc = fn
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameRC) cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -592,10 +587,9 @@ func TestApplyObjectOutput(t *testing.T) {
} }
tf.OpenAPISchemaFunc = fn tf.OpenAPISchemaFunc = fn
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameRC) cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "yaml") cmd.Flags().Set("output", "yaml")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -654,10 +648,9 @@ func TestApplyRetry(t *testing.T) {
} }
tf.OpenAPISchemaFunc = fn tf.OpenAPISchemaFunc = fn
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameRC) cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -704,10 +697,9 @@ func TestApplyNonExistObject(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameRC) cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -759,10 +751,8 @@ func TestApplyEmptyPatch(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
// 1. apply non exist object // 1. apply non exist object
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
errBuf := bytes.NewBuffer([]byte{}) cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC) cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -776,10 +766,8 @@ func TestApplyEmptyPatch(t *testing.T) {
} }
// 2. test apply already exist object, will not send empty patch request // 2. test apply already exist object, will not send empty patch request
buf = bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ = genericclioptions.NewTestIOStreams()
errBuf = bytes.NewBuffer([]byte{}) cmd = NewCmdApply("kubectl", tf, ioStreams)
cmd = NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC) cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -835,10 +823,9 @@ func testApplyMultipleObjects(t *testing.T, asList bool) {
} }
tf.OpenAPISchemaFunc = fn tf.OpenAPISchemaFunc = fn
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
if asList { if asList {
cmd.Flags().Set("filename", filenameRCSVC) cmd.Flags().Set("filename", filenameRCSVC)
} else { } else {
@ -936,10 +923,9 @@ func TestApplyNULLPreservation(t *testing.T) {
} }
tf.OpenAPISchemaFunc = fn tf.OpenAPISchemaFunc = fn
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameDeployObjClientside) cmd.Flags().Set("filename", filenameDeployObjClientside)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
@ -1003,10 +989,9 @@ func TestUnstructuredApply(t *testing.T) {
} }
tf.OpenAPISchemaFunc = fn tf.OpenAPISchemaFunc = fn
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameWidgetClientside) cmd.Flags().Set("filename", filenameWidgetClientside)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -1097,10 +1082,9 @@ func TestUnstructuredIdempotentApply(t *testing.T) {
} }
tf.OpenAPISchemaFunc = fn tf.OpenAPISchemaFunc = fn
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdApply("kubectl", tf, buf, errBuf) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd.Flags().Set("filename", filenameWidgetClientside) cmd.Flags().Set("filename", filenameWidgetClientside)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -1203,7 +1187,6 @@ func TestRunApplySetLastApplied(t *testing.T) {
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf, errBuf := bytes.NewBuffer([]byte{}), bytes.NewBuffer([]byte{})
cmdutil.BehaviorOnFatal(func(str string, code int) { cmdutil.BehaviorOnFatal(func(str string, code int) {
if str != test.expectedErr { if str != test.expectedErr {
@ -1211,7 +1194,8 @@ func TestRunApplySetLastApplied(t *testing.T) {
} }
}) })
cmd := NewCmdApplySetLastApplied(tf, buf, errBuf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdApplySetLastApplied(tf, ioStreams)
cmd.Flags().Set("filename", test.filePath) cmd.Flags().Set("filename", test.filePath)
cmd.Flags().Set("output", test.output) cmd.Flags().Set("output", test.output)
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -1382,10 +1366,8 @@ func TestForceApply(t *testing.T) {
tf.ClientConfigVal = &restclient.Config{} tf.ClientConfigVal = &restclient.Config{}
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
errBuf := bytes.NewBuffer([]byte{}) cmd := NewCmdApply("kubectl", tf, ioStreams)
cmd := NewCmdApply("kubectl", tf, buf, errBuf)
cmd.Flags().Set("filename", filenameRC) cmd.Flags().Set("filename", filenameRC)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Flags().Set("force", "true") cmd.Flags().Set("force", "true")

View File

@ -20,13 +20,13 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io"
"github.com/ghodss/yaml" "github.com/ghodss/yaml"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -38,8 +38,8 @@ type ViewLastAppliedOptions struct {
OutputFormat string OutputFormat string
All bool All bool
Factory cmdutil.Factory Factory cmdutil.Factory
Out io.Writer
ErrOut io.Writer genericclioptions.IOStreams
} }
var ( var (
@ -57,16 +57,16 @@ var (
kubectl apply view-last-applied -f deploy.yaml -o json`)) kubectl apply view-last-applied -f deploy.yaml -o json`))
) )
func NewViewLastAppliedOptions(out, err io.Writer) *ViewLastAppliedOptions { func NewViewLastAppliedOptions(ioStreams genericclioptions.IOStreams) *ViewLastAppliedOptions {
return &ViewLastAppliedOptions{ return &ViewLastAppliedOptions{
Out: out,
ErrOut: err,
OutputFormat: "yaml", OutputFormat: "yaml",
IOStreams: ioStreams,
} }
} }
func NewCmdApplyViewLastApplied(f cmdutil.Factory, out, err io.Writer) *cobra.Command { func NewCmdApplyViewLastApplied(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := NewViewLastAppliedOptions(out, err) options := NewViewLastAppliedOptions(ioStreams)
validArgs := cmdutil.ValidArgList(f) validArgs := cmdutil.ValidArgList(f)
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -34,6 +34,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
const ( const (
@ -246,11 +247,13 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
// From this point and forward we get warnings on flags that contain "_" separators // From this point and forward we get warnings on flags that contain "_" separators
cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc) cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)
ioStreams := genericclioptions.IOStreams{In: in, Out: out, ErrOut: err}
groups := templates.CommandGroups{ groups := templates.CommandGroups{
{ {
Message: "Basic Commands (Beginner):", Message: "Basic Commands (Beginner):",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
create.NewCmdCreate(f, out, err), create.NewCmdCreate(f, ioStreams),
NewCmdExposeService(f, out), NewCmdExposeService(f, out),
NewCmdRun(f, in, out, err), NewCmdRun(f, in, out, err),
set.NewCmdSet(f, in, out, err), set.NewCmdSet(f, in, out, err),
@ -262,7 +265,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
Commands: []*cobra.Command{ Commands: []*cobra.Command{
resource.NewCmdGet(f, out, err), resource.NewCmdGet(f, out, err),
NewCmdExplain(f, out, err), NewCmdExplain(f, out, err),
NewCmdEdit(f, out, err), NewCmdEdit(f, ioStreams),
NewCmdDelete(f, out, err), NewCmdDelete(f, out, err),
}, },
}, },
@ -303,7 +306,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
{ {
Message: "Advanced Commands:", Message: "Advanced Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
NewCmdApply("kubectl", f, out, err), NewCmdApply("kubectl", f, ioStreams),
NewCmdPatch(f, out), NewCmdPatch(f, out),
NewCmdReplace(f, out, err), NewCmdReplace(f, out, err),
NewCmdConvert(f, out), NewCmdConvert(f, out),
@ -313,7 +316,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
Message: "Settings Commands:", Message: "Settings Commands:",
Commands: []*cobra.Command{ Commands: []*cobra.Command{
NewCmdLabel(f, out, err), NewCmdLabel(f, out, err),
NewCmdAnnotate(f, out), NewCmdAnnotate(f, ioStreams),
NewCmdCompletion(out, ""), NewCmdCompletion(out, ""),
}, },
}, },
@ -347,7 +350,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
cmds.AddCommand(NewCmdPlugin(f, in, out, err)) cmds.AddCommand(NewCmdPlugin(f, in, out, err))
cmds.AddCommand(NewCmdVersion(f, out)) cmds.AddCommand(NewCmdVersion(f, out))
cmds.AddCommand(NewCmdApiVersions(f, out)) cmds.AddCommand(NewCmdApiVersions(f, out))
cmds.AddCommand(NewCmdApiResources(f, out)) cmds.AddCommand(NewCmdApiResources(f, ioStreams))
cmds.AddCommand(NewCmdOptions(out)) cmds.AddCommand(NewCmdOptions(out))
return cmds return cmds

View File

@ -77,6 +77,7 @@ go_test(
"//pkg/kubectl:go_default_library", "//pkg/kubectl:go_default_library",
"//pkg/kubectl/cmd/testing:go_default_library", "//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library", "//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library",
"//pkg/kubectl/scheme:go_default_library", "//pkg/kubectl/scheme:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/k8s.io/api/batch/v1:go_default_library", "//vendor/k8s.io/api/batch/v1:go_default_library",

View File

@ -50,11 +50,11 @@ type CreateOptions struct {
Selector string Selector string
EditBeforeCreate bool EditBeforeCreate bool
Raw string Raw string
Out io.Writer
ErrOut io.Writer
Recorder genericclioptions.Recorder Recorder genericclioptions.Recorder
PrintObj func(obj kruntime.Object) error PrintObj func(obj kruntime.Object) error
genericclioptions.IOStreams
} }
var ( var (
@ -74,20 +74,19 @@ var (
kubectl create -f docker-registry.yaml --edit -o json`)) kubectl create -f docker-registry.yaml --edit -o json`))
) )
func NewCreateOptions(out, errOut io.Writer) *CreateOptions { func NewCreateOptions(ioStreams genericclioptions.IOStreams) *CreateOptions {
return &CreateOptions{ return &CreateOptions{
PrintFlags: NewPrintFlags("created"), PrintFlags: NewPrintFlags("created"),
RecordFlags: genericclioptions.NewRecordFlags(), RecordFlags: genericclioptions.NewRecordFlags(),
Recorder: genericclioptions.NoopRecorder{}, Recorder: genericclioptions.NoopRecorder{},
Out: out, IOStreams: ioStreams,
ErrOut: errOut,
} }
} }
func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command { func NewCmdCreate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewCreateOptions(out, errOut) o := NewCreateOptions(ioStreams)
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "create -f FILENAME", Use: "create -f FILENAME",
@ -97,7 +96,7 @@ func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
Example: createExample, Example: createExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) { if cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
defaultRunFunc := cmdutil.DefaultSubCommandRun(errOut) defaultRunFunc := cmdutil.DefaultSubCommandRun(ioStreams.ErrOut)
defaultRunFunc(cmd, args) defaultRunFunc(cmd, args)
return return
} }
@ -125,20 +124,20 @@ func NewCmdCreate(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
o.PrintFlags.AddFlags(cmd) o.PrintFlags.AddFlags(cmd)
// create subcommands // create subcommands
cmd.AddCommand(NewCmdCreateNamespace(f, out)) cmd.AddCommand(NewCmdCreateNamespace(f, ioStreams))
cmd.AddCommand(NewCmdCreateQuota(f, out)) cmd.AddCommand(NewCmdCreateQuota(f, ioStreams))
cmd.AddCommand(NewCmdCreateSecret(f, out, errOut)) cmd.AddCommand(NewCmdCreateSecret(f, ioStreams))
cmd.AddCommand(NewCmdCreateConfigMap(f, out)) cmd.AddCommand(NewCmdCreateConfigMap(f, ioStreams))
cmd.AddCommand(NewCmdCreateServiceAccount(f, out)) cmd.AddCommand(NewCmdCreateServiceAccount(f, ioStreams))
cmd.AddCommand(NewCmdCreateService(f, out, errOut)) cmd.AddCommand(NewCmdCreateService(f, ioStreams))
cmd.AddCommand(NewCmdCreateDeployment(f, out, errOut)) cmd.AddCommand(NewCmdCreateDeployment(f, ioStreams))
cmd.AddCommand(NewCmdCreateClusterRole(f, out)) cmd.AddCommand(NewCmdCreateClusterRole(f, ioStreams))
cmd.AddCommand(NewCmdCreateClusterRoleBinding(f, out)) cmd.AddCommand(NewCmdCreateClusterRoleBinding(f, ioStreams))
cmd.AddCommand(NewCmdCreateRole(f, out)) cmd.AddCommand(NewCmdCreateRole(f, ioStreams))
cmd.AddCommand(NewCmdCreateRoleBinding(f, out)) cmd.AddCommand(NewCmdCreateRoleBinding(f, ioStreams))
cmd.AddCommand(NewCmdCreatePodDisruptionBudget(f, out)) cmd.AddCommand(NewCmdCreatePodDisruptionBudget(f, ioStreams))
cmd.AddCommand(NewCmdCreatePriorityClass(f, out)) cmd.AddCommand(NewCmdCreatePriorityClass(f, ioStreams))
cmd.AddCommand(NewCmdCreateJob(f, out)) cmd.AddCommand(NewCmdCreateJob(f, ioStreams))
return cmd return cmd
} }
@ -207,7 +206,7 @@ func (o *CreateOptions) RunCreate(f cmdutil.Factory, cmd *cobra.Command) error {
} }
if o.EditBeforeCreate { if o.EditBeforeCreate {
return RunEditOnCreate(f, o.RecordFlags, o.Out, o.ErrOut, cmd, &o.FilenameOptions) return RunEditOnCreate(f, o.RecordFlags, o.IOStreams, cmd, &o.FilenameOptions)
} }
schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate")) schema, err := f.Validator(cmdutil.GetFlagBool(cmd, "validate"))
if err != nil { if err != nil {
@ -292,8 +291,8 @@ func (o *CreateOptions) raw(f cmdutil.Factory) error {
return nil return nil
} }
func RunEditOnCreate(f cmdutil.Factory, recordFlags *genericclioptions.RecordFlags, out, errOut io.Writer, cmd *cobra.Command, options *resource.FilenameOptions) error { func RunEditOnCreate(f cmdutil.Factory, recordFlags *genericclioptions.RecordFlags, ioStreams genericclioptions.IOStreams, cmd *cobra.Command, options *resource.FilenameOptions) error {
editOptions := editor.NewEditOptions(editor.EditBeforeCreateMode, out, errOut) editOptions := editor.NewEditOptions(editor.EditBeforeCreateMode, ioStreams)
editOptions.FilenameOptions = *options editOptions.FilenameOptions = *options
editOptions.ValidateOptions = cmdutil.ValidateOptions{ editOptions.ValidateOptions = cmdutil.ValidateOptions{
EnableValidation: cmdutil.GetFlagBool(cmd, "validate"), EnableValidation: cmdutil.GetFlagBool(cmd, "validate"),
@ -341,8 +340,14 @@ type CreateSubcommandOptions struct {
PrintObj func(obj kruntime.Object) error PrintObj func(obj kruntime.Object) error
CmdOut io.Writer genericclioptions.IOStreams
CmdErr io.Writer }
func NewCreateSubcommandOptions(ioStreams genericclioptions.IOStreams) *CreateSubcommandOptions {
return &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
IOStreams: ioStreams,
}
} }
func (o *CreateSubcommandOptions) Complete(cmd *cobra.Command, args []string, generator kubectl.StructuredGenerator) error { func (o *CreateSubcommandOptions) Complete(cmd *cobra.Command, args []string, generator kubectl.StructuredGenerator) error {
@ -365,7 +370,7 @@ func (o *CreateSubcommandOptions) Complete(cmd *cobra.Command, args []string, ge
} }
o.PrintObj = func(obj kruntime.Object) error { o.PrintObj = func(obj kruntime.Object) error {
return printer.PrintObj(obj, o.CmdOut) return printer.PrintObj(obj, o.Out)
} }
return nil return nil

View File

@ -18,7 +18,6 @@ package create
import ( import (
"fmt" "fmt"
"io"
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -26,6 +25,7 @@ import (
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -59,12 +59,9 @@ type CreateClusterRoleOptions struct {
} }
// ClusterRole is a command to ease creating ClusterRoles. // ClusterRole is a command to ease creating ClusterRoles.
func NewCmdCreateClusterRole(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateClusterRole(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
c := &CreateClusterRoleOptions{ c := &CreateClusterRoleOptions{
CreateRoleOptions: &CreateRoleOptions{ CreateRoleOptions: NewCreateRoleOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
Out: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename] [--dry-run]", Use: "clusterrole NAME --verb=verb --resource=resource.group [--resource-name=resourcename] [--dry-run]",

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"testing" "testing"
rbac "k8s.io/api/rbac/v1" rbac "k8s.io/api/rbac/v1"
@ -29,6 +28,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" 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/scheme"
) )
@ -133,8 +133,8 @@ func TestCreateClusterRole(t *testing.T) {
} }
for name, test := range tests { for name, test := range tests {
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateClusterRole(tf, buf) cmd := NewCmdCreateClusterRole(tf, ioStreams)
cmd.Flags().Set("dry-run", "true") cmd.Flags().Set("dry-run", "true")
cmd.Flags().Set("output", "yaml") cmd.Flags().Set("output", "yaml")
cmd.Flags().Set("verb", test.verbs) cmd.Flags().Set("verb", test.verbs)

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -41,12 +40,9 @@ type ClusterRoleBindingOpts struct {
} }
// ClusterRoleBinding is a command to ease creating ClusterRoleBindings. // ClusterRoleBinding is a command to ease creating ClusterRoleBindings.
func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateClusterRoleBinding(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ClusterRoleBindingOpts{ options := &ClusterRoleBindingOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -32,6 +32,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
func TestCreateClusterRoleBinding(t *testing.T) { func TestCreateClusterRoleBinding(t *testing.T) {
@ -111,8 +112,8 @@ func TestCreateClusterRoleBinding(t *testing.T) {
} }
expectedOutput := "clusterrolebinding.rbac.authorization.k8s.io/" + expectBinding.Name + "\n" expectedOutput := "clusterrolebinding.rbac.authorization.k8s.io/" + expectBinding.Name + "\n"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateClusterRoleBinding(tf, buf) cmd := NewCmdCreateClusterRoleBinding(tf, ioStreams)
cmd.Flags().Set("clusterrole", "fake-clusterrole") cmd.Flags().Set("clusterrole", "fake-clusterrole")
cmd.Flags().Set("user", "fake-user") cmd.Flags().Set("user", "fake-user")
cmd.Flags().Set("group", "fake-group") cmd.Flags().Set("group", "fake-group")

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -62,12 +61,9 @@ type ConfigMapOpts struct {
} }
// ConfigMap is a command to ease creating ConfigMaps. // ConfigMap is a command to ease creating ConfigMaps.
func NewCmdCreateConfigMap(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateConfigMap(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ConfigMapOpts{ options := &ConfigMapOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -29,6 +29,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" 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/scheme"
) )
@ -55,8 +56,8 @@ func TestCreateConfigMap(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateConfigMap(tf, buf) cmd := NewCmdCreateConfigMap(tf, ioStreams)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{configMap.Name}) cmd.Run(cmd, []string{configMap.Name})
expectedOutput := "configmap/" + configMap.Name + "\n" expectedOutput := "configmap/" + configMap.Name + "\n"

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -43,13 +42,9 @@ type DeploymentOpts struct {
// NewCmdCreateDeployment is a macro command to create a new deployment. // NewCmdCreateDeployment is a macro command to create a new deployment.
// This command is better known to users as `kubectl create deployment`. // This command is better known to users as `kubectl create deployment`.
// Note that this command overlaps significantly with the `kubectl run` command. // Note that this command overlaps significantly with the `kubectl run` command.
func NewCmdCreateDeployment(f cmdutil.Factory, cmdOut, cmdErr io.Writer) *cobra.Command { func NewCmdCreateDeployment(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &DeploymentOpts{ options := &DeploymentOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
CmdErr: cmdErr,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -131,12 +126,12 @@ func (o *DeploymentOpts) Complete(f cmdutil.Factory, cmd *cobra.Command, args []
if len(generatorName) == 0 { if len(generatorName) == 0 {
generatorName = cmdutil.DeploymentBasicAppsV1GeneratorName generatorName = cmdutil.DeploymentBasicAppsV1GeneratorName
generatorNameTemp, err := cmdutil.FallbackGeneratorNameIfNecessary(generatorName, clientset.Discovery(), o.CreateSubcommandOptions.CmdErr) generatorNameTemp, err := cmdutil.FallbackGeneratorNameIfNecessary(generatorName, clientset.Discovery(), o.CreateSubcommandOptions.ErrOut)
if err != nil { if err != nil {
return err return err
} }
if generatorNameTemp != generatorName { if generatorNameTemp != generatorName {
cmdutil.Warning(o.CreateSubcommandOptions.CmdErr, generatorName, generatorNameTemp) cmdutil.Warning(o.CreateSubcommandOptions.ErrOut, generatorName, generatorNameTemp)
} else { } else {
generatorName = generatorNameTemp generatorName = generatorNameTemp
} }

View File

@ -30,6 +30,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
func Test_generatorFromName(t *testing.T) { func Test_generatorFromName(t *testing.T) {
@ -104,9 +105,9 @@ func TestCreateDeployment(t *testing.T) {
} }
tf.ClientConfigVal = &restclient.Config{} tf.ClientConfigVal = &restclient.Config{}
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdCreateDeployment(tf, buf, buf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateDeployment(tf, ioStreams)
cmd.Flags().Set("dry-run", "true") cmd.Flags().Set("dry-run", "true")
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Flags().Set("image", "hollywood/jonny.depp:v2") cmd.Flags().Set("image", "hollywood/jonny.depp:v2")
@ -136,16 +137,14 @@ func TestCreateDeploymentNoImage(t *testing.T) {
tf.ClientConfigVal = &restclient.Config{} tf.ClientConfigVal = &restclient.Config{}
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams := genericclioptions.NewTestIOStreamsDiscard()
errBuff := bytes.NewBuffer([]byte{}) cmd := NewCmdCreateDeployment(tf, ioStreams)
cmd := NewCmdCreateDeployment(tf, buf, errBuff)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
options := &DeploymentOpts{ options := &DeploymentOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"), PrintFlags: NewPrintFlags("created"),
CmdOut: buf,
CmdErr: errBuff,
DryRun: true, DryRun: true,
IOStreams: ioStreams,
}, },
} }

View File

@ -18,7 +18,6 @@ package create
import ( import (
"fmt" "fmt"
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -29,6 +28,7 @@ import (
clientbatchv1 "k8s.io/client-go/kubernetes/typed/batch/v1" clientbatchv1 "k8s.io/client-go/kubernetes/typed/batch/v1"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/resource" "k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -53,30 +53,36 @@ type CreateJobOptions struct {
Namespace string Namespace string
OutputFormat string OutputFormat string
Client clientbatchv1.BatchV1Interface Client clientbatchv1.BatchV1Interface
Out io.Writer
DryRun bool DryRun bool
Builder *resource.Builder Builder *resource.Builder
Cmd *cobra.Command Cmd *cobra.Command
genericclioptions.IOStreams
}
func NewCreateJobOptions(ioStreams genericclioptions.IOStreams) *CreateJobOptions {
return &CreateJobOptions{
PrintFlags: NewPrintFlags("created"),
IOStreams: ioStreams,
}
} }
// NewCmdCreateJob is a command to ease creating Jobs from CronJobs. // NewCmdCreateJob is a command to ease creating Jobs from CronJobs.
func NewCmdCreateJob(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateJob(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
c := &CreateJobOptions{ o := NewCreateJobOptions(ioStreams)
PrintFlags: NewPrintFlags("created"),
Out: cmdOut,
}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "job NAME [--from=CRONJOB]", Use: "job NAME [--from=CRONJOB]",
Short: jobLong, Short: jobLong,
Long: jobLong, Long: jobLong,
Example: jobExample, Example: jobExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(c.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(c.RunCreateJob()) cmdutil.CheckErr(o.RunCreateJob())
}, },
} }
c.PrintFlags.AddFlags(cmd) o.PrintFlags.AddFlags(cmd)
cmdutil.AddApplyAnnotationFlags(cmd) cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddValidateFlags(cmd) cmdutil.AddValidateFlags(cmd)
@ -86,14 +92,14 @@ func NewCmdCreateJob(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
return cmd return cmd
} }
func (c *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) (err error) { func (o *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) (err error) {
if len(args) == 0 { if len(args) == 0 {
return cmdutil.UsageErrorf(cmd, "NAME is required") return cmdutil.UsageErrorf(cmd, "NAME is required")
} }
c.Name = args[0] o.Name = args[0]
c.From = cmdutil.GetFlagString(cmd, "from") o.From = cmdutil.GetFlagString(cmd, "from")
c.Namespace, _, err = f.DefaultNamespace() o.Namespace, _, err = f.DefaultNamespace()
if err != nil { if err != nil {
return err return err
} }
@ -102,32 +108,32 @@ func (c *CreateJobOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
if err != nil { if err != nil {
return err return err
} }
c.Client = clientset.BatchV1() o.Client = clientset.BatchV1()
c.Builder = f.NewBuilder() o.Builder = f.NewBuilder()
c.DryRun = cmdutil.GetDryRunFlag(cmd) o.DryRun = cmdutil.GetDryRunFlag(cmd)
c.Cmd = cmd o.Cmd = cmd
c.OutputFormat = cmdutil.GetFlagString(cmd, "output") o.OutputFormat = cmdutil.GetFlagString(cmd, "output")
if c.DryRun { if o.DryRun {
c.PrintFlags.Complete("%s (dry run)") o.PrintFlags.Complete("%s (dry run)")
} }
printer, err := c.PrintFlags.ToPrinter() printer, err := o.PrintFlags.ToPrinter()
if err != nil { if err != nil {
return err return err
} }
c.PrintObj = func(obj runtime.Object) error { o.PrintObj = func(obj runtime.Object) error {
return printer.PrintObj(obj, c.Out) return printer.PrintObj(obj, o.Out)
} }
return nil return nil
} }
func (c *CreateJobOptions) RunCreateJob() error { func (o *CreateJobOptions) RunCreateJob() error {
infos, err := c.Builder. infos, err := o.Builder.
Unstructured(). Unstructured().
NamespaceParam(c.Namespace).DefaultNamespace(). NamespaceParam(o.Namespace).DefaultNamespace().
ResourceTypeOrNameArgs(false, c.From). ResourceTypeOrNameArgs(false, o.From).
Flatten(). Flatten().
Latest(). Latest().
Do(). Do().
@ -143,10 +149,10 @@ func (c *CreateJobOptions) RunCreateJob() error {
return fmt.Errorf("from must be an existing cronjob") return fmt.Errorf("from must be an existing cronjob")
} }
return c.createJob(cronJob) return o.createJob(cronJob)
} }
func (c *CreateJobOptions) createJob(cronJob *batchv1beta1.CronJob) error { func (o *CreateJobOptions) createJob(cronJob *batchv1beta1.CronJob) error {
annotations := make(map[string]string) annotations := make(map[string]string)
annotations["cronjob.kubernetes.io/instantiate"] = "manual" annotations["cronjob.kubernetes.io/instantiate"] = "manual"
for k, v := range cronJob.Spec.JobTemplate.Annotations { for k, v := range cronJob.Spec.JobTemplate.Annotations {
@ -154,21 +160,21 @@ func (c *CreateJobOptions) createJob(cronJob *batchv1beta1.CronJob) error {
} }
job := &batchv1.Job{ job := &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: c.Name, Name: o.Name,
Namespace: c.Namespace, Namespace: o.Namespace,
Annotations: annotations, Annotations: annotations,
Labels: cronJob.Spec.JobTemplate.Labels, Labels: cronJob.Spec.JobTemplate.Labels,
}, },
Spec: cronJob.Spec.JobTemplate.Spec, Spec: cronJob.Spec.JobTemplate.Spec,
} }
if !c.DryRun { if !o.DryRun {
var err error var err error
job, err = c.Client.Jobs(c.Namespace).Create(job) job, err = o.Client.Jobs(o.Namespace).Create(job)
if err != nil { if err != nil {
return fmt.Errorf("failed to create job: %v", err) return fmt.Errorf("failed to create job: %v", err)
} }
} }
return c.PrintObj(job) return o.PrintObj(job)
} }

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"testing" "testing"
batchv1 "k8s.io/api/batch/v1" batchv1 "k8s.io/api/batch/v1"
@ -28,6 +27,7 @@ import (
fake "k8s.io/client-go/kubernetes/fake" fake "k8s.io/client-go/kubernetes/fake"
clienttesting "k8s.io/client-go/testing" clienttesting "k8s.io/client-go/testing"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
func TestCreateJobFromCronJob(t *testing.T) { func TestCreateJobFromCronJob(t *testing.T) {
@ -86,14 +86,13 @@ func TestCreateJobFromCronJob(t *testing.T) {
printFlags := NewPrintFlags("created") printFlags := NewPrintFlags("created")
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmdOptions := &CreateJobOptions{ cmdOptions := &CreateJobOptions{
PrintFlags: printFlags, PrintFlags: printFlags,
Name: testJobName, Name: testJobName,
Namespace: testNamespaceName, Namespace: testNamespaceName,
Client: clientset.BatchV1(), Client: clientset.BatchV1(),
Out: buf, Cmd: NewCmdCreateJob(f, ioStreams),
Cmd: NewCmdCreateJob(f, buf),
PrintObj: func(obj runtime.Object) error { PrintObj: func(obj runtime.Object) error {
p, err := printFlags.ToPrinter() p, err := printFlags.ToPrinter()
if err != nil { if err != nil {
@ -102,6 +101,7 @@ func TestCreateJobFromCronJob(t *testing.T) {
return p.PrintObj(obj, buf) return p.PrintObj(obj, buf)
}, },
IOStreams: ioStreams,
} }
err := cmdOptions.createJob(cronJob) err := cmdOptions.createJob(cronJob)

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -41,12 +40,9 @@ type NamespaceOpts struct {
} }
// NewCmdCreateNamespace is a macro command to create a new namespace // NewCmdCreateNamespace is a macro command to create a new namespace
func NewCmdCreateNamespace(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateNamespace(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &NamespaceOpts{ options := &NamespaceOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"net/http" "net/http"
"testing" "testing"
@ -26,6 +25,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" 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/scheme"
) )
@ -51,8 +51,8 @@ func TestCreateNamespace(t *testing.T) {
} }
}), }),
} }
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateNamespace(tf, buf) cmd := NewCmdCreateNamespace(tf, ioStreams)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{namespaceObject.Name}) cmd.Run(cmd, []string{namespaceObject.Name})
expectedOutput := "namespace/" + namespaceObject.Name + "\n" expectedOutput := "namespace/" + namespaceObject.Name + "\n"

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -46,12 +45,9 @@ type PodDisruptionBudgetOpts struct {
} }
// NewCmdCreatePodDisruptionBudget is a macro command to create a new pod disruption budget. // NewCmdCreatePodDisruptionBudget is a macro command to create a new pod disruption budget.
func NewCmdCreatePodDisruptionBudget(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreatePodDisruptionBudget(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &PodDisruptionBudgetOpts{ options := &PodDisruptionBudgetOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -27,6 +27,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
func TestCreatePdb(t *testing.T) { func TestCreatePdb(t *testing.T) {
@ -48,11 +49,11 @@ func TestCreatePdb(t *testing.T) {
} }
tf.ClientConfigVal = &restclient.Config{} tf.ClientConfigVal = &restclient.Config{}
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
outputFormat := "name" outputFormat := "name"
cmd := NewCmdCreatePodDisruptionBudget(tf, buf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreatePodDisruptionBudget(tf, ioStreams)
cmd.Flags().Set("min-available", "1") cmd.Flags().Set("min-available", "1")
cmd.Flags().Set("selector", "app=rails") cmd.Flags().Set("selector", "app=rails")
cmd.Flags().Set("dry-run", "true") cmd.Flags().Set("dry-run", "true")
@ -64,8 +65,8 @@ func TestCreatePdb(t *testing.T) {
options := &PodDisruptionBudgetOpts{ options := &PodDisruptionBudgetOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: printFlags, PrintFlags: printFlags,
CmdOut: buf,
Name: pdbName, Name: pdbName,
IOStreams: ioStreams,
}, },
} }
err := options.Complete(cmd, []string{pdbName}) err := options.Complete(cmd, []string{pdbName})

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -44,12 +43,9 @@ type PriorityClassOpts struct {
} }
// NewCmdCreatePriorityClass is a macro command to create a new priorityClass. // NewCmdCreatePriorityClass is a macro command to create a new priorityClass.
func NewCmdCreatePriorityClass(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreatePriorityClass(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &PriorityClassOpts{ options := &PriorityClassOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -27,6 +27,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
func TestCreatePriorityClass(t *testing.T) { func TestCreatePriorityClass(t *testing.T) {
@ -47,11 +48,11 @@ func TestCreatePriorityClass(t *testing.T) {
}), }),
} }
tf.ClientConfigVal = &restclient.Config{} tf.ClientConfigVal = &restclient.Config{}
buf := bytes.NewBuffer([]byte{})
outputFormat := "name" outputFormat := "name"
cmd := NewCmdCreatePriorityClass(tf, buf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreatePriorityClass(tf, ioStreams)
cmd.Flags().Set("value", "1000") cmd.Flags().Set("value", "1000")
cmd.Flags().Set("global-default", "true") cmd.Flags().Set("global-default", "true")
cmd.Flags().Set("description", "my priority") cmd.Flags().Set("description", "my priority")
@ -64,8 +65,8 @@ func TestCreatePriorityClass(t *testing.T) {
options := &PriorityClassOpts{ options := &PriorityClassOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: printFlags, PrintFlags: printFlags,
CmdOut: buf,
Name: pcName, Name: pcName,
IOStreams: ioStreams,
}, },
} }
err := options.Complete(cmd, []string{pcName}) err := options.Complete(cmd, []string{pcName})

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -44,12 +43,9 @@ type QuotaOpts struct {
} }
// NewCmdCreateQuota is a macro command to create a new quota // NewCmdCreateQuota is a macro command to create a new quota
func NewCmdCreateQuota(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateQuota(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &QuotaOpts{ options := &QuotaOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"net/http" "net/http"
"testing" "testing"
@ -26,6 +25,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" 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/scheme"
) )
@ -75,8 +75,8 @@ func TestCreateQuota(t *testing.T) {
}, },
} }
for name, test := range tests { for name, test := range tests {
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateQuota(tf, buf) cmd := NewCmdCreateQuota(tf, ioStreams)
cmd.Flags().Parse(test.flags) cmd.Flags().Parse(test.flags)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{resourceQuotaObject.Name}) cmd.Run(cmd, []string{resourceQuotaObject.Name})

View File

@ -18,7 +18,6 @@ package create
import ( import (
"fmt" "fmt"
"io"
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -31,6 +30,7 @@ import (
clientgorbacv1 "k8s.io/client-go/kubernetes/typed/rbac/v1" clientgorbacv1 "k8s.io/client-go/kubernetes/typed/rbac/v1"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -112,17 +112,23 @@ type CreateRoleOptions struct {
Namespace string Namespace string
Client clientgorbacv1.RbacV1Interface Client clientgorbacv1.RbacV1Interface
Mapper meta.RESTMapper Mapper meta.RESTMapper
Out io.Writer
PrintObj func(obj runtime.Object) error PrintObj func(obj runtime.Object) error
genericclioptions.IOStreams
}
func NewCreateRoleOptions(ioStreams genericclioptions.IOStreams) *CreateRoleOptions {
return &CreateRoleOptions{
PrintFlags: NewPrintFlags("created"),
IOStreams: ioStreams,
}
} }
// Role is a command to ease creating Roles. // Role is a command to ease creating Roles.
func NewCmdCreateRole(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateRole(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
c := &CreateRoleOptions{ o := NewCreateRoleOptions(ioStreams)
PrintFlags: NewPrintFlags("created"),
Out: cmdOut,
}
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run]", Use: "role NAME --verb=verb --resource=resource.group/subresource [--resource-name=resourcename] [--dry-run]",
DisableFlagsInUseLine: true, DisableFlagsInUseLine: true,
@ -130,34 +136,34 @@ func NewCmdCreateRole(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
Long: roleLong, Long: roleLong,
Example: roleExample, Example: roleExample,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(c.Complete(f, cmd, args)) cmdutil.CheckErr(o.Complete(f, cmd, args))
cmdutil.CheckErr(c.Validate()) cmdutil.CheckErr(o.Validate())
cmdutil.CheckErr(c.RunCreateRole()) cmdutil.CheckErr(o.RunCreateRole())
}, },
} }
c.PrintFlags.AddFlags(cmd) o.PrintFlags.AddFlags(cmd)
cmdutil.AddApplyAnnotationFlags(cmd) cmdutil.AddApplyAnnotationFlags(cmd)
cmdutil.AddValidateFlags(cmd) cmdutil.AddValidateFlags(cmd)
cmdutil.AddDryRunFlag(cmd) cmdutil.AddDryRunFlag(cmd)
cmd.Flags().StringSliceVar(&c.Verbs, "verb", c.Verbs, "Verb that applies to the resources contained in the rule") cmd.Flags().StringSliceVar(&o.Verbs, "verb", o.Verbs, "Verb that applies to the resources contained in the rule")
cmd.Flags().StringSlice("resource", []string{}, "Resource that the rule applies to") cmd.Flags().StringSlice("resource", []string{}, "Resource that the rule applies to")
cmd.Flags().StringArrayVar(&c.ResourceNames, "resource-name", c.ResourceNames, "Resource in the white list that the rule applies to, repeat this flag for multiple items") cmd.Flags().StringArrayVar(&o.ResourceNames, "resource-name", o.ResourceNames, "Resource in the white list that the rule applies to, repeat this flag for multiple items")
return cmd return cmd
} }
func (c *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error { func (o *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
name, err := NameFromCommandArgs(cmd, args) name, err := NameFromCommandArgs(cmd, args)
if err != nil { if err != nil {
return err return err
} }
c.Name = name o.Name = name
// Remove duplicate verbs. // Remove duplicate verbs.
verbs := []string{} verbs := []string{}
for _, v := range c.Verbs { for _, v := range o.Verbs {
// VerbAll respresents all kinds of verbs. // VerbAll respresents all kinds of verbs.
if v == "*" { if v == "*" {
verbs = []string{"*"} verbs = []string{"*"}
@ -167,7 +173,7 @@ func (c *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
verbs = append(verbs, v) verbs = append(verbs, v)
} }
} }
c.Verbs = verbs o.Verbs = verbs
// Support resource.group pattern. If no API Group specified, use "" as core API Group. // Support resource.group pattern. If no API Group specified, use "" as core API Group.
// e.g. --resource=pods,deployments.extensions // e.g. --resource=pods,deployments.extensions
@ -186,36 +192,36 @@ func (c *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
} }
resource.Resource = parts[0] resource.Resource = parts[0]
c.Resources = append(c.Resources, *resource) o.Resources = append(o.Resources, *resource)
} }
// Remove duplicate resource names. // Remove duplicate resource names.
resourceNames := []string{} resourceNames := []string{}
for _, n := range c.ResourceNames { for _, n := range o.ResourceNames {
if !arrayContains(resourceNames, n) { if !arrayContains(resourceNames, n) {
resourceNames = append(resourceNames, n) resourceNames = append(resourceNames, n)
} }
} }
c.ResourceNames = resourceNames o.ResourceNames = resourceNames
// Complete other options for Run. // Complete other options for Run.
c.Mapper, _ = f.Object() o.Mapper, _ = f.Object()
c.DryRun = cmdutil.GetDryRunFlag(cmd) o.DryRun = cmdutil.GetDryRunFlag(cmd)
c.OutputFormat = cmdutil.GetFlagString(cmd, "output") o.OutputFormat = cmdutil.GetFlagString(cmd, "output")
if c.DryRun { if o.DryRun {
c.PrintFlags.Complete("%s (dry run)") o.PrintFlags.Complete("%s (dry run)")
} }
printer, err := c.PrintFlags.ToPrinter() printer, err := o.PrintFlags.ToPrinter()
if err != nil { if err != nil {
return err return err
} }
c.PrintObj = func(obj runtime.Object) error { o.PrintObj = func(obj runtime.Object) error {
return printer.PrintObj(obj, c.Out) return printer.PrintObj(obj, o.Out)
} }
c.Namespace, _, err = f.DefaultNamespace() o.Namespace, _, err = f.DefaultNamespace()
if err != nil { if err != nil {
return err return err
} }
@ -224,48 +230,48 @@ func (c *CreateRoleOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args
if err != nil { if err != nil {
return err return err
} }
c.Client = clientset.RbacV1() o.Client = clientset.RbacV1()
return nil return nil
} }
func (c *CreateRoleOptions) Validate() error { func (o *CreateRoleOptions) Validate() error {
if c.Name == "" { if o.Name == "" {
return fmt.Errorf("name must be specified") return fmt.Errorf("name must be specified")
} }
// validate verbs. // validate verbs.
if len(c.Verbs) == 0 { if len(o.Verbs) == 0 {
return fmt.Errorf("at least one verb must be specified") return fmt.Errorf("at least one verb must be specified")
} }
for _, v := range c.Verbs { for _, v := range o.Verbs {
if !arrayContains(validResourceVerbs, v) { if !arrayContains(validResourceVerbs, v) {
return fmt.Errorf("invalid verb: '%s'", v) return fmt.Errorf("invalid verb: '%s'", v)
} }
} }
// validate resources. // validate resources.
if len(c.Resources) == 0 { if len(o.Resources) == 0 {
return fmt.Errorf("at least one resource must be specified") return fmt.Errorf("at least one resource must be specified")
} }
return c.validateResource() return o.validateResource()
} }
func (c *CreateRoleOptions) validateResource() error { func (o *CreateRoleOptions) validateResource() error {
for _, r := range c.Resources { for _, r := range o.Resources {
if len(r.Resource) == 0 { if len(r.Resource) == 0 {
return fmt.Errorf("resource must be specified if apiGroup/subresource specified") return fmt.Errorf("resource must be specified if apiGroup/subresource specified")
} }
resource := schema.GroupVersionResource{Resource: r.Resource, Group: r.Group} resource := schema.GroupVersionResource{Resource: r.Resource, Group: r.Group}
groupVersionResource, err := c.Mapper.ResourceFor(schema.GroupVersionResource{Resource: r.Resource, Group: r.Group}) groupVersionResource, err := o.Mapper.ResourceFor(schema.GroupVersionResource{Resource: r.Resource, Group: r.Group})
if err == nil { if err == nil {
resource = groupVersionResource resource = groupVersionResource
} }
for _, v := range c.Verbs { for _, v := range o.Verbs {
if groupResources, ok := specialVerbs[v]; ok { if groupResources, ok := specialVerbs[v]; ok {
match := false match := false
for _, extra := range groupResources { for _, extra := range groupResources {
@ -288,24 +294,24 @@ func (c *CreateRoleOptions) validateResource() error {
return nil return nil
} }
func (c *CreateRoleOptions) RunCreateRole() error { func (o *CreateRoleOptions) RunCreateRole() error {
role := &rbacv1.Role{} role := &rbacv1.Role{}
role.Name = c.Name role.Name = o.Name
rules, err := generateResourcePolicyRules(c.Mapper, c.Verbs, c.Resources, c.ResourceNames, []string{}) rules, err := generateResourcePolicyRules(o.Mapper, o.Verbs, o.Resources, o.ResourceNames, []string{})
if err != nil { if err != nil {
return err return err
} }
role.Rules = rules role.Rules = rules
// Create role. // Create role.
if !c.DryRun { if !o.DryRun {
role, err = c.Client.Roles(c.Namespace).Create(role) role, err = o.Client.Roles(o.Namespace).Create(role)
if err != nil { if err != nil {
return err return err
} }
} }
return c.PrintObj(role) return o.PrintObj(role)
} }
func arrayContains(s []string, e string) bool { func arrayContains(s []string, e string) bool {

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"reflect" "reflect"
"testing" "testing"
@ -29,6 +28,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
func TestCreateRole(t *testing.T) { func TestCreateRole(t *testing.T) {
@ -129,8 +129,8 @@ func TestCreateRole(t *testing.T) {
for name, test := range tests { for name, test := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateRole(tf, buf) cmd := NewCmdCreateRole(tf, ioStreams)
cmd.Flags().Set("dry-run", "true") cmd.Flags().Set("dry-run", "true")
cmd.Flags().Set("output", "yaml") cmd.Flags().Set("output", "yaml")
cmd.Flags().Set("verb", test.verbs) cmd.Flags().Set("verb", test.verbs)
@ -360,8 +360,7 @@ func TestComplete(t *testing.T) {
tf.Client = &fake.RESTClient{} tf.Client = &fake.RESTClient{}
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{}) cmd := NewCmdCreateRole(tf, genericclioptions.NewTestIOStreamsDiscard())
cmd := NewCmdCreateRole(tf, buf)
cmd.Flags().Set("resource", "pods,deployments.extensions") cmd.Flags().Set("resource", "pods,deployments.extensions")
tests := map[string]struct { tests := map[string]struct {

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -41,12 +40,9 @@ type RoleBindingOpts struct {
} }
// RoleBinding is a command to ease creating RoleBindings. // RoleBinding is a command to ease creating RoleBindings.
func NewCmdCreateRoleBinding(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateRoleBinding(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &RoleBindingOpts{ options := &RoleBindingOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -32,6 +32,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
) )
var groupVersion = schema.GroupVersion{Group: "rbac.authorization.k8s.io", Version: "v1"} var groupVersion = schema.GroupVersion{Group: "rbac.authorization.k8s.io", Version: "v1"}
@ -112,8 +113,7 @@ func TestCreateRoleBinding(t *testing.T) {
}, },
} }
buf := bytes.NewBuffer([]byte{}) cmd := NewCmdCreateRoleBinding(tf, genericclioptions.NewTestIOStreamsDiscard())
cmd := NewCmdCreateRoleBinding(tf, buf)
cmd.Flags().Set("role", "fake-role") cmd.Flags().Set("role", "fake-role")
cmd.Flags().Set("user", "fake-user") cmd.Flags().Set("user", "fake-user")
cmd.Flags().Set("group", "fake-group") cmd.Flags().Set("group", "fake-group")

View File

@ -17,27 +17,26 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
// NewCmdCreateSecret groups subcommands to create various types of secrets // NewCmdCreateSecret groups subcommands to create various types of secrets
func NewCmdCreateSecret(f cmdutil.Factory, cmdOut, errOut io.Writer) *cobra.Command { func NewCmdCreateSecret(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "secret", Use: "secret",
Short: i18n.T("Create a secret using specified subcommand"), Short: i18n.T("Create a secret using specified subcommand"),
Long: "Create a secret using specified subcommand.", Long: "Create a secret using specified subcommand.",
Run: cmdutil.DefaultSubCommandRun(errOut), Run: cmdutil.DefaultSubCommandRun(ioStreams.ErrOut),
} }
cmd.AddCommand(NewCmdCreateSecretDockerRegistry(f, cmdOut)) cmd.AddCommand(NewCmdCreateSecretDockerRegistry(f, ioStreams))
cmd.AddCommand(NewCmdCreateSecretTLS(f, cmdOut)) cmd.AddCommand(NewCmdCreateSecretTLS(f, ioStreams))
cmd.AddCommand(NewCmdCreateSecretGeneric(f, cmdOut)) cmd.AddCommand(NewCmdCreateSecretGeneric(f, ioStreams))
return cmd return cmd
} }
@ -78,12 +77,9 @@ type SecretGenericOpts struct {
} }
// NewCmdCreateSecretGeneric is a command to create generic secrets from files, directories, or literal values // NewCmdCreateSecretGeneric is a command to create generic secrets from files, directories, or literal values
func NewCmdCreateSecretGeneric(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateSecretGeneric(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &SecretGenericOpts{ options := &SecretGenericOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -166,12 +162,9 @@ type SecretDockerRegistryOpts struct {
} }
// NewCmdCreateSecretDockerRegistry is a macro command for creating secrets to work with Docker registries // NewCmdCreateSecretDockerRegistry is a macro command for creating secrets to work with Docker registries
func NewCmdCreateSecretDockerRegistry(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateSecretDockerRegistry(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &SecretDockerRegistryOpts{ options := &SecretDockerRegistryOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -260,12 +253,9 @@ type SecretTLSOpts struct {
} }
// NewCmdCreateSecretTLS is a macro command for creating secrets to work with Docker registries // NewCmdCreateSecretTLS is a macro command for creating secrets to work with Docker registries
func NewCmdCreateSecretTLS(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateSecretTLS(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &SecretTLSOpts{ options := &SecretTLSOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"net/http" "net/http"
"testing" "testing"
@ -26,6 +25,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" 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/scheme"
) )
@ -57,8 +57,8 @@ func TestCreateSecretGeneric(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateSecretGeneric(tf, buf) cmd := NewCmdCreateSecretGeneric(tf, ioStreams)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Flags().Set("from-literal", "password=includes,comma") cmd.Flags().Set("from-literal", "password=includes,comma")
cmd.Flags().Set("from-literal", "username=test_user") cmd.Flags().Set("from-literal", "username=test_user")
@ -90,8 +90,8 @@ func TestCreateSecretDockerRegistry(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateSecretDockerRegistry(tf, buf) cmd := NewCmdCreateSecretDockerRegistry(tf, ioStreams)
cmd.Flags().Set("docker-username", "test-user") cmd.Flags().Set("docker-username", "test-user")
cmd.Flags().Set("docker-password", "test-pass") cmd.Flags().Set("docker-password", "test-pass")
cmd.Flags().Set("docker-email", "test-email") cmd.Flags().Set("docker-email", "test-email")

View File

@ -17,30 +17,29 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
// NewCmdCreateService is a macro command to create a new service // NewCmdCreateService is a macro command to create a new service
func NewCmdCreateService(f cmdutil.Factory, cmdOut, errOut io.Writer) *cobra.Command { func NewCmdCreateService(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{ cmd := &cobra.Command{
Use: "service", Use: "service",
Aliases: []string{"svc"}, Aliases: []string{"svc"},
Short: i18n.T("Create a service using specified subcommand."), Short: i18n.T("Create a service using specified subcommand."),
Long: "Create a service using specified subcommand.", Long: "Create a service using specified subcommand.",
Run: cmdutil.DefaultSubCommandRun(errOut), Run: cmdutil.DefaultSubCommandRun(ioStreams.ErrOut),
} }
cmd.AddCommand(NewCmdCreateServiceClusterIP(f, cmdOut)) cmd.AddCommand(NewCmdCreateServiceClusterIP(f, ioStreams))
cmd.AddCommand(NewCmdCreateServiceNodePort(f, cmdOut)) cmd.AddCommand(NewCmdCreateServiceNodePort(f, ioStreams))
cmd.AddCommand(NewCmdCreateServiceLoadBalancer(f, cmdOut)) cmd.AddCommand(NewCmdCreateServiceLoadBalancer(f, ioStreams))
cmd.AddCommand(NewCmdCreateServiceExternalName(f, cmdOut)) cmd.AddCommand(NewCmdCreateServiceExternalName(f, ioStreams))
return cmd return cmd
} }
@ -66,12 +65,9 @@ type ServiceClusterIPOpts struct {
} }
// NewCmdCreateServiceClusterIP is a command to create a ClusterIP service // NewCmdCreateServiceClusterIP is a command to create a ClusterIP service
func NewCmdCreateServiceClusterIP(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateServiceClusterIP(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ServiceClusterIPOpts{ options := &ServiceClusterIPOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -141,12 +137,9 @@ type ServiceNodePortOpts struct {
} }
// NewCmdCreateServiceNodePort is a macro command for creating a NodePort service // NewCmdCreateServiceNodePort is a macro command for creating a NodePort service
func NewCmdCreateServiceNodePort(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateServiceNodePort(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ServiceNodePortOpts{ options := &ServiceNodePortOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -213,12 +206,9 @@ type ServiceLoadBalancerOpts struct {
} }
// NewCmdCreateServiceLoadBalancer is a macro command for creating a LoadBalancer service // NewCmdCreateServiceLoadBalancer is a macro command for creating a LoadBalancer service
func NewCmdCreateServiceLoadBalancer(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateServiceLoadBalancer(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ServiceLoadBalancerOpts{ options := &ServiceLoadBalancerOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{
@ -287,12 +277,9 @@ type ServiceExternalNameOpts struct {
} }
// NewCmdCreateServiceExternalName is a macro command for creating an ExternalName service // NewCmdCreateServiceExternalName is a macro command for creating an ExternalName service
func NewCmdCreateServiceExternalName(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateServiceExternalName(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ServiceExternalNameOpts{ options := &ServiceExternalNameOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"net/http" "net/http"
"testing" "testing"
@ -26,6 +25,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" 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/scheme"
) )
@ -52,8 +52,8 @@ func TestCreateService(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateServiceClusterIP(tf, buf) cmd := NewCmdCreateServiceClusterIP(tf, ioStreams)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Flags().Set("tcp", "8080:8000") cmd.Flags().Set("tcp", "8080:8000")
cmd.Run(cmd, []string{service.Name}) cmd.Run(cmd, []string{service.Name})
@ -86,8 +86,8 @@ func TestCreateServiceNodePort(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateServiceNodePort(tf, buf) cmd := NewCmdCreateServiceNodePort(tf, ioStreams)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Flags().Set("tcp", "30000:8000") cmd.Flags().Set("tcp", "30000:8000")
cmd.Run(cmd, []string{service.Name}) cmd.Run(cmd, []string{service.Name})
@ -120,8 +120,8 @@ func TestCreateServiceExternalName(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateServiceExternalName(tf, buf) cmd := NewCmdCreateServiceExternalName(tf, ioStreams)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Flags().Set("external-name", "name") cmd.Flags().Set("external-name", "name")
cmd.Run(cmd, []string{service.Name}) cmd.Run(cmd, []string{service.Name})

View File

@ -17,13 +17,12 @@ limitations under the License.
package create package create
import ( import (
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl" "k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -41,12 +40,9 @@ type ServiceAccountOpts struct {
} }
// NewCmdCreateServiceAccount is a macro command to create a new service account // NewCmdCreateServiceAccount is a macro command to create a new service account
func NewCmdCreateServiceAccount(f cmdutil.Factory, cmdOut io.Writer) *cobra.Command { func NewCmdCreateServiceAccount(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
options := &ServiceAccountOpts{ options := &ServiceAccountOpts{
CreateSubcommandOptions: &CreateSubcommandOptions{ CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
} }
cmd := &cobra.Command{ cmd := &cobra.Command{

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"net/http" "net/http"
"testing" "testing"
@ -26,6 +25,7 @@ import (
"k8s.io/client-go/rest/fake" "k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" 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/scheme"
) )
@ -52,8 +52,8 @@ func TestCreateServiceAccount(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateServiceAccount(tf, buf) cmd := NewCmdCreateServiceAccount(tf, ioStreams)
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{serviceAccountObject.Name}) cmd.Run(cmd, []string{serviceAccountObject.Name})
expectedOutput := "serviceaccount/" + serviceAccountObject.Name + "\n" expectedOutput := "serviceaccount/" + serviceAccountObject.Name + "\n"

View File

@ -17,7 +17,6 @@ limitations under the License.
package create package create
import ( import (
"bytes"
"net/http" "net/http"
"testing" "testing"
@ -30,18 +29,17 @@ import (
api "k8s.io/kubernetes/pkg/apis/core" api "k8s.io/kubernetes/pkg/apis/core"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/scheme" "k8s.io/kubernetes/pkg/kubectl/scheme"
) )
func TestExtraArgsFail(t *testing.T) { func TestExtraArgsFail(t *testing.T) {
initTestErrorHandler(t) initTestErrorHandler(t)
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
f := cmdtesting.NewTestFactory() f := cmdtesting.NewTestFactory()
defer f.Cleanup() defer f.Cleanup()
c := NewCmdCreate(f, buf, errBuf) c := NewCmdCreate(f, genericclioptions.NewTestIOStreamsDiscard())
options := CreateOptions{} options := CreateOptions{}
if options.ValidateArgs(c, []string{"rc"}) == nil { if options.ValidateArgs(c, []string{"rc"}) == nil {
t.Errorf("unexpected non-error") t.Errorf("unexpected non-error")
@ -72,10 +70,9 @@ func TestCreateObject(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdCreate(tf, buf, errBuf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreate(tf, ioStreams)
cmd.Flags().Set("filename", "../../../../examples/guestbook/legacy/redis-master-controller.yaml") cmd.Flags().Set("filename", "../../../../examples/guestbook/legacy/redis-master-controller.yaml")
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
@ -111,10 +108,9 @@ func TestCreateMultipleObject(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdCreate(tf, buf, errBuf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreate(tf, ioStreams)
cmd.Flags().Set("filename", "../../../../examples/guestbook/legacy/redis-master-controller.yaml") cmd.Flags().Set("filename", "../../../../examples/guestbook/legacy/redis-master-controller.yaml")
cmd.Flags().Set("filename", "../../../../examples/guestbook/frontend-service.yaml") cmd.Flags().Set("filename", "../../../../examples/guestbook/frontend-service.yaml")
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
@ -150,10 +146,9 @@ func TestCreateDirectory(t *testing.T) {
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
errBuf := bytes.NewBuffer([]byte{})
cmd := NewCmdCreate(tf, buf, errBuf) ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreate(tf, ioStreams)
cmd.Flags().Set("filename", "../../../../examples/guestbook/legacy") cmd.Flags().Set("filename", "../../../../examples/guestbook/legacy")
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})

View File

@ -18,7 +18,6 @@ package cmd
import ( import (
"fmt" "fmt"
"io"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -26,6 +25,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/cmd/templates" "k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/cmd/util/editor" "k8s.io/kubernetes/pkg/kubectl/cmd/util/editor"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n" "k8s.io/kubernetes/pkg/kubectl/util/i18n"
) )
@ -68,8 +68,8 @@ var (
kubectl edit deployment/mydeployment -o yaml --save-config`)) kubectl edit deployment/mydeployment -o yaml --save-config`))
) )
func NewCmdEdit(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command { func NewCmdEdit(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := editor.NewEditOptions(editor.NormalEditMode, out, errOut) o := editor.NewEditOptions(editor.NormalEditMode, ioStreams)
o.ValidateOptions = cmdutil.ValidateOptions{EnableValidation: true} o.ValidateOptions = cmdutil.ValidateOptions{EnableValidation: true}
validArgs := cmdutil.ValidArgList(f) validArgs := cmdutil.ValidArgList(f)

View File

@ -39,6 +39,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/cmd/create" "k8s.io/kubernetes/pkg/kubectl/cmd/create"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing" cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" 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/resource"
) )
@ -229,18 +230,17 @@ func TestEdit(t *testing.T) {
} }
tf.ClientConfigVal = defaultClientConfig() tf.ClientConfigVal = defaultClientConfig()
tf.CommandVal = "edit test cmd invocation" tf.CommandVal = "edit test cmd invocation"
buf := bytes.NewBuffer([]byte{}) ioStreams, _, buf, errBuf := genericclioptions.NewTestIOStreams()
errBuf := bytes.NewBuffer([]byte{})
var cmd *cobra.Command var cmd *cobra.Command
switch testcase.Mode { switch testcase.Mode {
case "edit": case "edit":
cmd = NewCmdEdit(tf, buf, errBuf) cmd = NewCmdEdit(tf, ioStreams)
case "create": case "create":
cmd = create.NewCmdCreate(tf, buf, errBuf) cmd = create.NewCmdCreate(tf, ioStreams)
cmd.Flags().Set("edit", "true") cmd.Flags().Set("edit", "true")
case "edit-last-applied": case "edit-last-applied":
cmd = NewCmdApplyEditLastApplied(tf, buf, errBuf) cmd = NewCmdApplyEditLastApplied(tf, ioStreams)
default: default:
t.Fatalf("%s: unexpected mode %s", name, testcase.Mode) t.Fatalf("%s: unexpected mode %s", name, testcase.Mode)
} }

View File

@ -72,8 +72,7 @@ type EditOptions struct {
ApplyAnnotation bool ApplyAnnotation bool
ChangeCause string ChangeCause string
Out io.Writer genericclioptions.IOStreams
ErrOut io.Writer
Recorder genericclioptions.Recorder Recorder genericclioptions.Recorder
f cmdutil.Factory f cmdutil.Factory
@ -81,7 +80,7 @@ type EditOptions struct {
updatedResultGetter func(data []byte) *resource.Result updatedResultGetter func(data []byte) *resource.Result
} }
func NewEditOptions(editMode EditMode, out, errOut io.Writer) *EditOptions { func NewEditOptions(editMode EditMode, ioStreams genericclioptions.IOStreams) *EditOptions {
return &EditOptions{ return &EditOptions{
RecordFlags: genericclioptions.NewRecordFlags(), RecordFlags: genericclioptions.NewRecordFlags(),
@ -92,8 +91,7 @@ func NewEditOptions(editMode EditMode, out, errOut io.Writer) *EditOptions {
Recorder: genericclioptions.NoopRecorder{}, Recorder: genericclioptions.NoopRecorder{},
Out: out, IOStreams: ioStreams,
ErrOut: errOut,
} }
} }

View File

@ -4,6 +4,7 @@ go_library(
name = "go_default_library", name = "go_default_library",
srcs = [ srcs = [
"doc.go", "doc.go",
"io_options.go",
"record_flags.go", "record_flags.go",
], ],
importpath = "k8s.io/kubernetes/pkg/kubectl/genericclioptions", importpath = "k8s.io/kubernetes/pkg/kubectl/genericclioptions",

View File

@ -0,0 +1,57 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package genericclioptions
import (
"bytes"
"io"
"io/ioutil"
)
// IOStreams provides the standard names for iostreams. This is useful for embedding and for unit testing.
// Inconsistent and different names make it hard to read and review code
type IOStreams struct {
// In think, os.Stdin
In io.Reader
// Out think, os.Stdout
Out io.Writer
// ErrOut think, os.Stderr
ErrOut io.Writer
}
// NewTestIOStreams returns a valid IOStreams and in, out, errout buffers for unit tests
func NewTestIOStreams() (IOStreams, *bytes.Buffer, *bytes.Buffer, *bytes.Buffer) {
in := &bytes.Buffer{}
out := &bytes.Buffer{}
errOut := &bytes.Buffer{}
return IOStreams{
In: in,
Out: out,
ErrOut: errOut,
}, in, out, errOut
}
// NewTestIOStreamsDiscard returns a valid IOStreams that just discards
func NewTestIOStreamsDiscard() IOStreams {
in := &bytes.Buffer{}
return IOStreams{
In: in,
Out: ioutil.Discard,
ErrOut: ioutil.Discard,
}
}