provide standard iostream struct for commands

pull/8/head
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 (
"bytes"
"fmt"
"io"
jsonpatch "github.com/evanphx/json-patch"
"github.com/golang/glog"
@ -60,8 +59,7 @@ type AnnotateOptions struct {
removeAnnotations []string
Recorder genericclioptions.Recorder
// Common share fields
out io.Writer
genericclioptions.IOStreams
}
var (
@ -99,17 +97,17 @@ var (
kubectl annotate pods foo description-`))
)
func NewAnnotateOptions(out io.Writer) *AnnotateOptions {
func NewAnnotateOptions(ioStreams genericclioptions.IOStreams) *AnnotateOptions {
return &AnnotateOptions{
out: out,
RecordFlags: genericclioptions.NewRecordFlags(),
Recorder: genericclioptions.NoopRecorder{},
Recorder: genericclioptions.NoopRecorder{},
IOStreams: ioStreams,
}
}
func NewCmdAnnotate(f cmdutil.Factory, out io.Writer) *cobra.Command {
o := NewAnnotateOptions(out)
func NewCmdAnnotate(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewAnnotateOptions(ioStreams)
validArgs := cmdutil.ValidArgList(f)
cmd := &cobra.Command{
@ -283,9 +281,9 @@ func (o AnnotateOptions) RunAnnotate(f cmdutil.Factory, cmd *cobra.Command) erro
}
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
})
}

View File

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

View File

@ -29,6 +29,7 @@ import (
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/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
// referencing the cmd.Flags()
type ApiResourcesOptions struct {
out io.Writer
Output string
APIGroup string
Namespaced bool
NoHeaders bool
genericclioptions.IOStreams
}
// groupResource contains the APIGroup and APIResource
@ -67,10 +68,14 @@ type groupResource struct {
APIResource metav1.APIResource
}
func NewCmdApiResources(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &ApiResourcesOptions{
out: out,
func NewAPIResourceOptions(ioStreams genericclioptions.IOStreams) *ApiResourcesOptions {
return &ApiResourcesOptions{
IOStreams: ioStreams,
}
}
func NewCmdApiResources(f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewAPIResourceOptions(ioStreams)
cmd := &cobra.Command{
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",
Example: apiresources_example,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(options.Complete(cmd))
cmdutil.CheckErr(options.Validate(cmd))
cmdutil.CheckErr(options.RunApiResources(cmd, f))
cmdutil.CheckErr(o.Complete(cmd))
cmdutil.CheckErr(o.Validate(cmd))
cmdutil.CheckErr(o.RunApiResources(cmd, f))
},
}
cmdutil.AddOutputFlags(cmd)
cmdutil.AddNoHeadersFlags(cmd)
cmd.Flags().StringVar(&options.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().StringVar(&o.APIGroup, "api-group", "", "The API group to use when talking to the server.")
cmd.Flags().BoolVar(&o.Namespaced, "namespaced", true, "Namespaced indicates if a resource is namespaced or not.")
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 {
w := printers.GetNewTabWriter(o.out)
w := printers.GetNewTabWriter(o.Out)
defer w.Flush()
discoveryclient, err := f.DiscoveryClient()

View File

@ -73,8 +73,7 @@ type ApplyOptions struct {
OpenApiPatch bool
PruneWhitelist []string
Out io.Writer
ErrOut io.Writer
genericclioptions.IOStreams
}
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"
)
func NewApplyOptions(out, errout io.Writer) *ApplyOptions {
func NewApplyOptions(ioStreams genericclioptions.IOStreams) *ApplyOptions {
return &ApplyOptions{
RecordFlags: genericclioptions.NewRecordFlags(),
DeleteFlags: NewDeleteFlags("that contains the configuration to apply"),
@ -124,13 +123,12 @@ func NewApplyOptions(out, errout io.Writer) *ApplyOptions {
Recorder: genericclioptions.NoopRecorder{},
Out: out,
ErrOut: errout,
IOStreams: ioStreams,
}
}
func NewCmdApply(baseName string, f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
o := NewApplyOptions(out, errOut)
func NewCmdApply(baseName string, f cmdutil.Factory, ioStreams genericclioptions.IOStreams) *cobra.Command {
o := NewApplyOptions(ioStreams)
// Store baseName for use in printing warnings / messages involving the base command name.
// 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)
// apply subcommands
cmd.AddCommand(NewCmdApplyViewLastApplied(f, out, errOut))
cmd.AddCommand(NewCmdApplySetLastApplied(f, out, errOut))
cmd.AddCommand(NewCmdApplyEditLastApplied(f, out, errOut))
cmd.AddCommand(NewCmdApplyViewLastApplied(f, ioStreams))
cmd.AddCommand(NewCmdApplySetLastApplied(f, ioStreams))
cmd.AddCommand(NewCmdApplyEditLastApplied(f, ioStreams))
return cmd
}

View File

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

View File

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

View File

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

View File

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

View File

@ -34,6 +34,7 @@ import (
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
)
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
cmds.SetGlobalNormalizationFunc(flag.WarnWordSepNormalizeFunc)
ioStreams := genericclioptions.IOStreams{In: in, Out: out, ErrOut: err}
groups := templates.CommandGroups{
{
Message: "Basic Commands (Beginner):",
Commands: []*cobra.Command{
create.NewCmdCreate(f, out, err),
create.NewCmdCreate(f, ioStreams),
NewCmdExposeService(f, out),
NewCmdRun(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{
resource.NewCmdGet(f, out, err),
NewCmdExplain(f, out, err),
NewCmdEdit(f, out, err),
NewCmdEdit(f, ioStreams),
NewCmdDelete(f, out, err),
},
},
@ -303,7 +306,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
{
Message: "Advanced Commands:",
Commands: []*cobra.Command{
NewCmdApply("kubectl", f, out, err),
NewCmdApply("kubectl", f, ioStreams),
NewCmdPatch(f, out),
NewCmdReplace(f, out, err),
NewCmdConvert(f, out),
@ -313,7 +316,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
Message: "Settings Commands:",
Commands: []*cobra.Command{
NewCmdLabel(f, out, err),
NewCmdAnnotate(f, out),
NewCmdAnnotate(f, ioStreams),
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(NewCmdVersion(f, out))
cmds.AddCommand(NewCmdApiVersions(f, out))
cmds.AddCommand(NewCmdApiResources(f, out))
cmds.AddCommand(NewCmdApiResources(f, ioStreams))
cmds.AddCommand(NewCmdOptions(out))
return cmds

View File

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

View File

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

View File

@ -18,7 +18,6 @@ package create
import (
"fmt"
"io"
"strings"
"github.com/spf13/cobra"
@ -26,6 +25,7 @@ import (
rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -59,12 +59,9 @@ type CreateClusterRoleOptions struct {
}
// 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{
CreateRoleOptions: &CreateRoleOptions{
PrintFlags: NewPrintFlags("created"),
Out: cmdOut,
},
CreateRoleOptions: NewCreateRoleOptions(ioStreams),
}
cmd := &cobra.Command{
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
import (
"bytes"
"testing"
rbac "k8s.io/api/rbac/v1"
@ -29,6 +28,7 @@ import (
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/scheme"
)
@ -133,8 +133,8 @@ func TestCreateClusterRole(t *testing.T) {
}
for name, test := range tests {
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdCreateClusterRole(tf, buf)
ioStreams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdCreateClusterRole(tf, ioStreams)
cmd.Flags().Set("dry-run", "true")
cmd.Flags().Set("output", "yaml")
cmd.Flags().Set("verb", test.verbs)

View File

@ -17,13 +17,12 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -41,12 +40,9 @@ type ClusterRoleBindingOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

@ -17,13 +17,12 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -62,12 +61,9 @@ type ConfigMapOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

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

View File

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

View File

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

View File

@ -17,13 +17,12 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -41,12 +40,9 @@ type NamespaceOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

@ -17,13 +17,12 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -46,12 +45,9 @@ type PodDisruptionBudgetOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

@ -17,13 +17,12 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -44,12 +43,9 @@ type PriorityClassOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

@ -17,13 +17,12 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -44,12 +43,9 @@ type QuotaOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

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

View File

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

View File

@ -17,13 +17,12 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -41,12 +40,9 @@ type RoleBindingOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

@ -32,6 +32,7 @@ import (
"k8s.io/client-go/rest/fake"
"k8s.io/kubernetes/pkg/api/legacyscheme"
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"}
@ -112,8 +113,7 @@ func TestCreateRoleBinding(t *testing.T) {
},
}
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdCreateRoleBinding(tf, buf)
cmd := NewCmdCreateRoleBinding(tf, genericclioptions.NewTestIOStreamsDiscard())
cmd.Flags().Set("role", "fake-role")
cmd.Flags().Set("user", "fake-user")
cmd.Flags().Set("group", "fake-group")

View File

@ -17,27 +17,26 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
// 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{
Use: "secret",
Short: i18n.T("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(NewCmdCreateSecretTLS(f, cmdOut))
cmd.AddCommand(NewCmdCreateSecretGeneric(f, cmdOut))
cmd.AddCommand(NewCmdCreateSecretDockerRegistry(f, ioStreams))
cmd.AddCommand(NewCmdCreateSecretTLS(f, ioStreams))
cmd.AddCommand(NewCmdCreateSecretGeneric(f, ioStreams))
return cmd
}
@ -78,12 +77,9 @@ type SecretGenericOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{
@ -166,12 +162,9 @@ type SecretDockerRegistryOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{
@ -260,12 +253,9 @@ type SecretTLSOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

@ -17,30 +17,29 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
// 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{
Use: "service",
Aliases: []string{"svc"},
Short: i18n.T("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(NewCmdCreateServiceNodePort(f, cmdOut))
cmd.AddCommand(NewCmdCreateServiceLoadBalancer(f, cmdOut))
cmd.AddCommand(NewCmdCreateServiceExternalName(f, cmdOut))
cmd.AddCommand(NewCmdCreateServiceClusterIP(f, ioStreams))
cmd.AddCommand(NewCmdCreateServiceNodePort(f, ioStreams))
cmd.AddCommand(NewCmdCreateServiceLoadBalancer(f, ioStreams))
cmd.AddCommand(NewCmdCreateServiceExternalName(f, ioStreams))
return cmd
}
@ -66,12 +65,9 @@ type ServiceClusterIPOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{
@ -141,12 +137,9 @@ type ServiceNodePortOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{
@ -213,12 +206,9 @@ type ServiceLoadBalancerOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{
@ -287,12 +277,9 @@ type ServiceExternalNameOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

@ -17,13 +17,12 @@ limitations under the License.
package create
import (
"io"
"github.com/spf13/cobra"
"k8s.io/kubernetes/pkg/kubectl"
"k8s.io/kubernetes/pkg/kubectl/cmd/templates"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
)
@ -41,12 +40,9 @@ type ServiceAccountOpts struct {
}
// 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{
CreateSubcommandOptions: &CreateSubcommandOptions{
PrintFlags: NewPrintFlags("created"),
CmdOut: cmdOut,
},
CreateSubcommandOptions: NewCreateSubcommandOptions(ioStreams),
}
cmd := &cobra.Command{

View File

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

View File

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

View File

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

View File

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

View File

@ -72,8 +72,7 @@ type EditOptions struct {
ApplyAnnotation bool
ChangeCause string
Out io.Writer
ErrOut io.Writer
genericclioptions.IOStreams
Recorder genericclioptions.Recorder
f cmdutil.Factory
@ -81,7 +80,7 @@ type EditOptions struct {
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{
RecordFlags: genericclioptions.NewRecordFlags(),
@ -92,8 +91,7 @@ func NewEditOptions(editMode EditMode, out, errOut io.Writer) *EditOptions {
Recorder: genericclioptions.NoopRecorder{},
Out: out,
ErrOut: errOut,
IOStreams: ioStreams,
}
}

View File

@ -4,6 +4,7 @@ go_library(
name = "go_default_library",
srcs = [
"doc.go",
"io_options.go",
"record_flags.go",
],
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,
}
}