Add '-o name' to mutations

This commit is contained in:
Janet Kuo
2015-07-01 15:47:43 -07:00
parent a171d2e4fb
commit 0e42d0699a
27 changed files with 241 additions and 56 deletions

View File

@@ -51,7 +51,9 @@ func NewCmdCreate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
Example: create_example,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(ValidateArgs(cmd, args))
cmdutil.CheckErr(RunCreate(f, out, filenames))
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
cmdutil.CheckErr(RunCreate(f, out, filenames, shortOutput))
},
}
@@ -59,6 +61,7 @@ func NewCmdCreate(f *cmdutil.Factory, out io.Writer) *cobra.Command {
kubectl.AddJsonFilenameFlag(cmd, &filenames, usage)
cmd.MarkFlagRequired("filename")
cmdutil.AddOutputFlagsForMutation(cmd)
return cmd
}
@@ -69,7 +72,7 @@ func ValidateArgs(cmd *cobra.Command, args []string) error {
return nil
}
func RunCreate(f *cmdutil.Factory, out io.Writer, filenames util.StringList) error {
func RunCreate(f *cmdutil.Factory, out io.Writer, filenames util.StringList, shortOutput bool) error {
schema, err := f.Validator()
if err != nil {
return err
@@ -105,8 +108,10 @@ func RunCreate(f *cmdutil.Factory, out io.Writer, filenames util.StringList) err
}
count++
info.Refresh(obj, true)
printObjectSpecificMessage(info.Object, out)
fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name)
if !shortOutput {
printObjectSpecificMessage(info.Object, out)
}
cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "created")
return nil
})
if err != nil {

View File

@@ -59,10 +59,11 @@ func TestCreateObject(t *testing.T) {
cmd := NewCmdCreate(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
if buf.String() != "replicationcontrollers/redis-master-controller\n" {
if buf.String() != "replicationcontroller/redis-master-controller\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -92,10 +93,11 @@ func TestCreateMultipleObject(t *testing.T) {
cmd := NewCmdCreate(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// Names should come from the REST response, NOT the files
if buf.String() != "replicationcontrollers/rc1\nservices/baz\n" {
if buf.String() != "replicationcontroller/rc1\nservice/baz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -125,9 +127,10 @@ func TestCreateDirectory(t *testing.T) {
cmd := NewCmdCreate(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/name\nservices/baz\nreplicationcontrollers/name\nservices/baz\nreplicationcontrollers/name\nservices/baz\n" {
if buf.String() != "replicationcontroller/name\nservice/baz\nreplicationcontroller/name\nservice/baz\nreplicationcontroller/name\nservice/baz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}

View File

@@ -25,6 +25,7 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/errors"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
cmdutil "github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/cmd/util"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl/resource"
@@ -66,7 +67,9 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {
Long: delete_long,
Example: delete_example,
Run: func(cmd *cobra.Command, args []string) {
err := RunDelete(f, out, cmd, args, filenames)
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
err := RunDelete(f, out, cmd, args, filenames, shortOutput)
cmdutil.CheckErr(err)
},
}
@@ -78,10 +81,11 @@ func NewCmdDelete(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().Bool("cascade", true, "If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.")
cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object")
cmdutil.AddOutputFlagsForMutation(cmd)
return cmd
}
func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList, shortOutput bool) error {
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
return err
@@ -117,12 +121,12 @@ func RunDelete(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []str
// By default use a reaper to delete all related resources.
if cmdutil.GetFlagBool(cmd, "cascade") {
return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period"))
return ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period"), shortOutput, mapper)
}
return DeleteResult(r, out, ignoreNotFound)
return DeleteResult(r, out, ignoreNotFound, shortOutput, mapper)
}
func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefaultDelete, ignoreNotFound bool, timeout time.Duration, gracePeriod int) error {
func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefaultDelete, ignoreNotFound bool, timeout time.Duration, gracePeriod int, shortOutput bool, mapper meta.RESTMapper) error {
found := 0
if ignoreNotFound {
r = r.IgnoreErrors(errors.IsNotFound)
@@ -133,7 +137,7 @@ func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefault
if err != nil {
// If there is no reaper for this resources and the user didn't explicitly ask for stop.
if kubectl.IsNoSuchReaperError(err) && isDefaultDelete {
return deleteResource(info, out)
return deleteResource(info, out, shortOutput, mapper)
}
return cmdutil.AddSourceToErr("reaping", info.Source, err)
}
@@ -144,7 +148,7 @@ func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefault
if _, err := reaper.Stop(info.Namespace, info.Name, timeout, options); err != nil {
return cmdutil.AddSourceToErr("stopping", info.Source, err)
}
fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name)
cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "deleted")
return nil
})
if err != nil {
@@ -156,14 +160,14 @@ func ReapResult(r *resource.Result, f *cmdutil.Factory, out io.Writer, isDefault
return nil
}
func DeleteResult(r *resource.Result, out io.Writer, ignoreNotFound bool) error {
func DeleteResult(r *resource.Result, out io.Writer, ignoreNotFound bool, shortOutput bool, mapper meta.RESTMapper) error {
found := 0
if ignoreNotFound {
r = r.IgnoreErrors(errors.IsNotFound)
}
err := r.Visit(func(info *resource.Info) error {
found++
return deleteResource(info, out)
return deleteResource(info, out, shortOutput, mapper)
})
if err != nil {
return err
@@ -174,10 +178,10 @@ func DeleteResult(r *resource.Result, out io.Writer, ignoreNotFound bool) error
return nil
}
func deleteResource(info *resource.Info, out io.Writer) error {
func deleteResource(info *resource.Info, out io.Writer, shortOutput bool, mapper meta.RESTMapper) error {
if err := resource.NewHelper(info.Client, info.Mapping).Delete(info.Namespace, info.Name); err != nil {
return cmdutil.AddSourceToErr("deleting", info.Source, err)
}
fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name)
cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "deleted")
return nil
}

View File

@@ -53,9 +53,10 @@ func TestDeleteObjectByTuple(t *testing.T) {
cmd := NewCmdDelete(f, buf)
cmd.Flags().Set("namespace", "test")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{"replicationcontrollers/redis-master-controller"})
if buf.String() != "replicationcontrollers/redis-master-controller\n" {
if buf.String() != "replicationcontroller/redis-master-controller\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -84,9 +85,10 @@ func TestDeleteNamedObject(t *testing.T) {
cmd := NewCmdDelete(f, buf)
cmd.Flags().Set("namespace", "test")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{"replicationcontrollers", "redis-master-controller"})
if buf.String() != "replicationcontrollers/redis-master-controller\n" {
if buf.String() != "replicationcontroller/redis-master-controller\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -114,10 +116,11 @@ func TestDeleteObject(t *testing.T) {
cmd := NewCmdDelete(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
if buf.String() != "replicationcontrollers/redis-master\n" {
if buf.String() != "replicationcontroller/redis-master\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -143,8 +146,9 @@ func TestDeleteObjectNotFound(t *testing.T) {
cmd := NewCmdDelete(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
filenames := cmd.Flags().Lookup("filename").Value.(*util.StringList)
err := RunDelete(f, buf, cmd, []string{}, *filenames)
err := RunDelete(f, buf, cmd, []string{}, *filenames, true)
if err == nil || !errors.IsNotFound(err) {
t.Errorf("unexpected error: expected NotFound, got %v", err)
}
@@ -172,6 +176,7 @@ func TestDeleteObjectIgnoreNotFound(t *testing.T) {
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("ignore-not-found", "true")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "" {
@@ -214,7 +219,7 @@ func TestDeleteAllNotFound(t *testing.T) {
// Make sure we can explicitly choose to fail on NotFound errors, even with --all
cmd.Flags().Set("ignore-not-found", "false")
err := RunDelete(f, buf, cmd, []string{"services"}, nil)
err := RunDelete(f, buf, cmd, []string{"services"}, nil, true)
if err == nil || !errors.IsNotFound(err) {
t.Errorf("unexpected error: expected NotFound, got %v", err)
}
@@ -252,9 +257,10 @@ func TestDeleteAllIgnoreNotFound(t *testing.T) {
cmd := NewCmdDelete(f, buf)
cmd.Flags().Set("all", "true")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{"services"})
if buf.String() != "services/baz\n" {
if buf.String() != "service/baz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -285,9 +291,10 @@ func TestDeleteMultipleObject(t *testing.T) {
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/redis-master\nservices/frontend\n" {
if buf.String() != "replicationcontroller/redis-master\nservice/frontend\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -318,14 +325,15 @@ func TestDeleteMultipleObjectContinueOnMissing(t *testing.T) {
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
filenames := cmd.Flags().Lookup("filename").Value.(*util.StringList)
t.Logf("filenames: %v\n", filenames)
err := RunDelete(f, buf, cmd, []string{}, *filenames)
err := RunDelete(f, buf, cmd, []string{}, *filenames, true)
if err == nil || !errors.IsNotFound(err) {
t.Errorf("unexpected error: expected NotFound, got %v", err)
}
if buf.String() != "services/frontend\n" {
if buf.String() != "service/frontend\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -355,9 +363,10 @@ func TestDeleteDirectory(t *testing.T) {
cmd := NewCmdDelete(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/frontend\nservices/frontend\nreplicationcontrollers/redis-master\nservices/redis-master\nreplicationcontrollers/redis-slave\nservices/redis-slave\n" {
if buf.String() != "replicationcontroller/frontend\nservice/frontend\nreplicationcontroller/redis-master\nservice/redis-master\nreplicationcontroller/redis-slave\nservice/redis-slave\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -397,9 +406,10 @@ func TestDeleteMultipleSelector(t *testing.T) {
cmd := NewCmdDelete(f, buf)
cmd.Flags().Set("selector", "a=b")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{"pods,services"})
if buf.String() != "pods/foo\npods/bar\nservices/baz\n" {
if buf.String() != "pod/foo\npod/bar\nservice/baz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}

View File

@@ -17,7 +17,6 @@ limitations under the License.
package cmd
import (
"fmt"
"io"
"github.com/spf13/cobra"
@@ -43,16 +42,19 @@ func NewCmdPatch(f *cmdutil.Factory, out io.Writer) *cobra.Command {
Long: patch_long,
Example: patch_example,
Run: func(cmd *cobra.Command, args []string) {
err := RunPatch(f, out, cmd, args)
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
err := RunPatch(f, out, cmd, args, shortOutput)
cmdutil.CheckCustomErr("Patch failed", err)
},
}
cmd.Flags().StringP("patch", "p", "", "The patch to be applied to the resource JSON file.")
cmd.MarkFlagRequired("patch")
cmdutil.AddOutputFlagsForMutation(cmd)
return cmd
}
func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error {
cmdNamespace, _, err := f.DefaultNamespace()
if err != nil {
return err
@@ -94,6 +96,6 @@ func RunPatch(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
if err != nil {
return err
}
fmt.Fprintf(out, "%s\n", name)
cmdutil.PrintSuccess(mapper, shortOutput, out, "", name, "patched")
return nil
}

View File

@@ -47,6 +47,7 @@ func TestPatchObject(t *testing.T) {
cmd := NewCmdPatch(f, buf)
cmd.Flags().Set("namespace", "test")
cmd.Flags().Set("patch", `{"spec":{"type":"NodePort"}}`)
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{"services/frontend"})
// uses the name from the file, not the response

View File

@@ -56,7 +56,9 @@ func NewCmdReplace(f *cmdutil.Factory, out io.Writer) *cobra.Command {
Long: replace_long,
Example: replace_example,
Run: func(cmd *cobra.Command, args []string) {
err := RunReplace(f, out, cmd, args, filenames)
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
err := RunReplace(f, out, cmd, args, filenames, shortOutput)
cmdutil.CheckCustomErr("Replace failed", err)
},
}
@@ -67,10 +69,11 @@ func NewCmdReplace(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().Bool("cascade", false, "Only relevant during a force replace. If true, cascade the deletion of the resources managed by this resource (e.g. Pods created by a ReplicationController). Default true.")
cmd.Flags().Int("grace-period", -1, "Only relevant during a force replace. Period of time in seconds given to the old resource to terminate gracefully. Ignored if negative.")
cmd.Flags().Duration("timeout", 0, "Only relevant during a force replace. The length of time to wait before giving up on a delete of the old resource, zero means determine a timeout from the size of the object")
cmdutil.AddOutputFlagsForMutation(cmd)
return cmd
}
func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList, shortOutput bool) error {
if len(os.Args) > 1 && os.Args[1] == "update" {
printDeprecationWarning("replace", "update")
}
@@ -90,7 +93,7 @@ func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
}
if force {
return forceReplace(f, out, cmd, args, filenames)
return forceReplace(f, out, cmd, args, filenames, shortOutput)
}
mapper, typer := f.Object()
@@ -117,12 +120,12 @@ func RunReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []st
}
info.Refresh(obj, true)
printObjectSpecificMessage(obj, out)
fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name)
cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "replaced")
return nil
})
}
func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList) error {
func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, filenames util.StringList, shortOutput bool) error {
schema, err := f.Validator()
if err != nil {
return err
@@ -166,9 +169,9 @@ func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
// By default use a reaper to delete all related resources.
if cmdutil.GetFlagBool(cmd, "cascade") {
glog.Warningf("\"cascade\" is set, kubectl will delete and re-create all resources managed by this resource (e.g. Pods created by a ReplicationController). Consider using \"kubectl rolling-update\" if you want to update a ReplicationController together with its Pods.")
err = ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period"))
err = ReapResult(r, f, out, cmdutil.GetFlagBool(cmd, "cascade"), ignoreNotFound, cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period"), shortOutput, mapper)
} else {
err = DeleteResult(r, out, ignoreNotFound)
err = DeleteResult(r, out, ignoreNotFound, shortOutput, mapper)
}
if err != nil {
return err
@@ -199,7 +202,7 @@ func forceReplace(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []
count++
info.Refresh(obj, true)
printObjectSpecificMessage(obj, out)
fmt.Fprintf(out, "%s/%s\n", info.Mapping.Resource, info.Name)
cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "replaced")
return nil
})
if err != nil {

View File

@@ -49,19 +49,21 @@ func TestReplaceObject(t *testing.T) {
cmd := NewCmdReplace(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
// uses the name from the file, not the response
if buf.String() != "replicationcontrollers/rc1\n" {
if buf.String() != "replicationcontroller/rc1\n" {
t.Errorf("unexpected output: %s", buf.String())
}
buf.Reset()
cmd.Flags().Set("force", "true")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/redis-master\nreplicationcontrollers/rc1\n" {
if buf.String() != "replicationcontroller/redis-master\nreplicationcontroller/rc1\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -95,18 +97,20 @@ func TestReplaceMultipleObject(t *testing.T) {
cmd := NewCmdReplace(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/rc1\nservices/baz\n" {
if buf.String() != "replicationcontroller/rc1\nservice/baz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
buf.Reset()
cmd.Flags().Set("force", "true")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/redis-master\nservices/frontend\nreplicationcontrollers/rc1\nservices/baz\n" {
if buf.String() != "replicationcontroller/redis-master\nservice/frontend\nreplicationcontroller/rc1\nservice/baz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -140,9 +144,10 @@ func TestReplaceDirectory(t *testing.T) {
cmd := NewCmdReplace(f, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook")
cmd.Flags().Set("namespace", "test")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/rc1\nservices/baz\nreplicationcontrollers/rc1\nservices/baz\nreplicationcontrollers/rc1\nservices/baz\n" {
if buf.String() != "replicationcontroller/rc1\nservice/baz\nreplicationcontroller/rc1\nservice/baz\nreplicationcontroller/rc1\nservice/baz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
@@ -151,8 +156,8 @@ func TestReplaceDirectory(t *testing.T) {
cmd.Flags().Set("cascade", "false")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/frontend\nservices/frontend\nreplicationcontrollers/redis-master\nservices/redis-master\nreplicationcontrollers/redis-slave\nservices/redis-slave\n"+
"replicationcontrollers/rc1\nservices/baz\nreplicationcontrollers/rc1\nservices/baz\nreplicationcontrollers/rc1\nservices/baz\n" {
if buf.String() != "replicationcontroller/frontend\nservice/frontend\nreplicationcontroller/redis-master\nservice/redis-master\nreplicationcontroller/redis-slave\nservice/redis-slave\n"+
"replicationcontroller/rc1\nservice/baz\nreplicationcontroller/rc1\nservice/baz\nreplicationcontroller/rc1\nservice/baz\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}
@@ -183,9 +188,10 @@ func TestForceReplaceObjectNotFound(t *testing.T) {
cmd.Flags().Set("filename", "../../../examples/guestbook/redis-master-controller.yaml")
cmd.Flags().Set("force", "true")
cmd.Flags().Set("cascade", "false")
cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{})
if buf.String() != "replicationcontrollers/rc1\n" {
if buf.String() != "replicationcontroller/rc1\n" {
t.Errorf("unexpected output: %s", buf.String())
}
}

View File

@@ -52,7 +52,9 @@ func NewCmdScale(f *cmdutil.Factory, out io.Writer) *cobra.Command {
Long: scale_long,
Example: scale_example,
Run: func(cmd *cobra.Command, args []string) {
err := RunScale(f, out, cmd, args)
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
err := RunScale(f, out, cmd, args, shortOutput)
cmdutil.CheckErr(err)
},
}
@@ -60,11 +62,12 @@ func NewCmdScale(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().Int("current-replicas", -1, "Precondition for current size. Requires that the current size of the replication controller match this value in order to scale.")
cmd.Flags().Int("replicas", -1, "The new desired number of replicas. Required.")
cmd.MarkFlagRequired("replicas")
cmdutil.AddOutputFlagsForMutation(cmd)
return cmd
}
// RunScale executes the scaling
func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) error {
func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string, shortOutput bool) error {
if len(os.Args) > 1 && os.Args[1] == "resize" {
printDeprecationWarning("scale", "resize")
}
@@ -117,6 +120,6 @@ func RunScale(f *cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []stri
if err := scaler.Scale(info.Namespace, info.Name, uint(count), precondition, retry, waitForReplicas); err != nil {
return err
}
fmt.Fprint(out, "scaled\n")
cmdutil.PrintSuccess(mapper, shortOutput, out, info.Mapping.Resource, info.Name, "scaled")
return nil
}

View File

@@ -54,7 +54,9 @@ func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command {
Long: stop_long,
Example: stop_example,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(RunStop(f, cmd, args, flags.Filenames, out))
cmdutil.CheckErr(cmdutil.ValidateOutputArgs(cmd))
shortOutput := cmdutil.GetFlagString(cmd, "output") == "name"
cmdutil.CheckErr(RunStop(f, cmd, args, flags.Filenames, out, shortOutput))
},
}
usage := "Filename, directory, or URL to file of resource(s) to be stopped."
@@ -64,10 +66,11 @@ func NewCmdStop(f *cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().Bool("ignore-not-found", false, "Treat \"resource not found\" as a successful stop.")
cmd.Flags().Int("grace-period", -1, "Period of time in seconds given to the resource to terminate gracefully. Ignored if negative.")
cmd.Flags().Duration("timeout", 0, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object")
cmdutil.AddOutputFlagsForMutation(cmd)
return cmd
}
func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames util.StringList, out io.Writer) error {
func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames util.StringList, out io.Writer, shortOutput bool) error {
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
return err
@@ -85,5 +88,5 @@ func RunStop(f *cmdutil.Factory, cmd *cobra.Command, args []string, filenames ut
if r.Err() != nil {
return r.Err()
}
return ReapResult(r, f, out, false, cmdutil.GetFlagBool(cmd, "ignore-not-found"), cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period"))
return ReapResult(r, f, out, false, cmdutil.GetFlagBool(cmd, "ignore-not-found"), cmdutil.GetFlagDuration(cmd, "timeout"), cmdutil.GetFlagInt(cmd, "grace-period"), shortOutput, mapper)
}

View File

@@ -17,6 +17,10 @@ limitations under the License.
package util
import (
"fmt"
"io"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/meta"
"github.com/GoogleCloudPlatform/kubernetes/pkg/kubectl"
"github.com/spf13/cobra"
@@ -30,6 +34,40 @@ func AddPrinterFlags(cmd *cobra.Command) {
cmd.Flags().StringP("template", "t", "", "Template string or path to template file to use when -o=template or -o=templatefile. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview]")
}
// AddOutputFlagsForMutation adds output related flags to a command. Used by mutations only.
func AddOutputFlagsForMutation(cmd *cobra.Command) {
cmd.Flags().StringP("output", "o", "", "Output mode. Use \"-o name\" for shorter output (resource/name).")
}
// PrintSuccess prints message after finishing mutating operations
func PrintSuccess(mapper meta.RESTMapper, shortOutput bool, out io.Writer, resource string, name string, operation string) {
resource, _ = mapper.ResourceSingularizer(resource)
if shortOutput {
// -o name: prints resource/name
if len(resource) > 0 {
fmt.Fprintf(out, "%s/%s\n", resource, name)
} else {
fmt.Fprintf(out, "%s\n", name)
}
} else {
// understandable output by default
if len(resource) > 0 {
fmt.Fprintf(out, "%s \"%s\" %s\n", resource, name, operation)
} else {
fmt.Fprintf(out, "\"%s\" %s\n", name, operation)
}
}
}
// ValidateOutputArgs validates -o flag args for mutations
func ValidateOutputArgs(cmd *cobra.Command) error {
outputMode := GetFlagString(cmd, "output")
if outputMode != "" && outputMode != "name" {
return UsageError(cmd, "Unexpected -o output mode: %v. We only support '-o name'.", outputMode)
}
return nil
}
// OutputVersion returns the preferred output version for generic content (JSON, YAML, or templates)
func OutputVersion(cmd *cobra.Command, defaultVersion string) string {
outputVersion := GetFlagString(cmd, "output-version")