update delete, replace, run cmds

parent a62a157c
...@@ -305,7 +305,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob ...@@ -305,7 +305,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
Commands: []*cobra.Command{ Commands: []*cobra.Command{
NewCmdApply("kubectl", f, out, err), NewCmdApply("kubectl", f, out, err),
NewCmdPatch(f, out), NewCmdPatch(f, out),
NewCmdReplace(f, out), NewCmdReplace(f, out, err),
NewCmdConvert(f, out), NewCmdConvert(f, out),
}, },
}, },
......
...@@ -151,192 +151,6 @@ func stringBody(body string) io.ReadCloser { ...@@ -151,192 +151,6 @@ func stringBody(body string) io.ReadCloser {
return ioutil.NopCloser(bytes.NewReader([]byte(body))) return ioutil.NopCloser(bytes.NewReader([]byte(body)))
} }
func Example_printMultiContainersReplicationControllerWithWide() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: nil,
}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
ctrl := &api.ReplicationController{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Labels: map[string]string{"foo": "bar"},
CreationTimestamp: metav1.Time{Time: time.Now().AddDate(-10, 0, 0)},
},
Spec: api.ReplicationControllerSpec{
Replicas: 1,
Selector: map[string]string{"foo": "bar"},
Template: &api.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"foo": "bar"},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "foo",
Image: "someimage",
},
{
Name: "foo2",
Image: "someimage2",
},
},
},
},
},
Status: api.ReplicationControllerStatus{
Replicas: 1,
},
}
cmd.Flags().Set("output", "wide")
err := cmdutil.PrintObject(cmd, ctrl, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
// Output:
// NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
// foo 1 1 0 10y foo,foo2 someimage,someimage2 foo=bar
}
func Example_printReplicationController() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: nil,
}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
ctrl := &api.ReplicationController{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Labels: map[string]string{"foo": "bar"},
CreationTimestamp: metav1.Time{Time: time.Now().AddDate(-10, 0, 0)},
},
Spec: api.ReplicationControllerSpec{
Replicas: 1,
Selector: map[string]string{"foo": "bar"},
Template: &api.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"foo": "bar"},
},
Spec: api.PodSpec{
Containers: []api.Container{
{
Name: "foo",
Image: "someimage",
},
{
Name: "foo2",
Image: "someimage",
},
},
},
},
},
Status: api.ReplicationControllerStatus{
Replicas: 1,
},
}
err := cmdutil.PrintObject(cmd, ctrl, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
// Output:
// NAME DESIRED CURRENT READY AGE
// foo 1 1 0 10y
}
func Example_printPodWithWideFormat() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: nil,
}
nodeName := "kubernetes-node-abcd"
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
pod := &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test1",
CreationTimestamp: metav1.Time{Time: time.Now().AddDate(-10, 0, 0)},
},
Spec: api.PodSpec{
Containers: make([]api.Container, 2),
NodeName: nodeName,
},
Status: api.PodStatus{
Phase: "podPhase",
ContainerStatuses: []api.ContainerStatus{
{Ready: true, RestartCount: 3, State: api.ContainerState{Running: &api.ContainerStateRunning{}}},
{RestartCount: 3},
},
PodIP: "10.1.1.3",
},
}
cmd.Flags().Set("output", "wide")
err := cmdutil.PrintObject(cmd, pod, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
// Output:
// NAME READY STATUS RESTARTS AGE IP NODE
// test1 1/2 podPhase 6 10y 10.1.1.3 kubernetes-node-abcd
}
func Example_printPodWithShowLabels() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: nil,
}
nodeName := "kubernetes-node-abcd"
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
pod := &api.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: "test1",
CreationTimestamp: metav1.Time{Time: time.Now().AddDate(-10, 0, 0)},
Labels: map[string]string{
"l1": "key",
"l2": "value",
},
},
Spec: api.PodSpec{
Containers: make([]api.Container, 2),
NodeName: nodeName,
},
Status: api.PodStatus{
Phase: "podPhase",
ContainerStatuses: []api.ContainerStatus{
{Ready: true, RestartCount: 3, State: api.ContainerState{Running: &api.ContainerStateRunning{}}},
{RestartCount: 3},
},
},
}
cmd.Flags().Set("show-labels", "true")
err := cmdutil.PrintObject(cmd, pod, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
// Output:
// NAME READY STATUS RESTARTS AGE LABELS
// test1 1/2 podPhase 6 10y l1=key,l2=value
}
func newAllPhasePodList() *api.PodList { func newAllPhasePodList() *api.PodList {
nodeName := "kubernetes-node-abcd" nodeName := "kubernetes-node-abcd"
return &api.PodList{ return &api.PodList{
...@@ -429,37 +243,6 @@ func newAllPhasePodList() *api.PodList { ...@@ -429,37 +243,6 @@ func newAllPhasePodList() *api.PodList {
} }
} }
func Example_printPodShowTerminated() {
tf := cmdtesting.NewTestFactory()
defer tf.Cleanup()
ns := legacyscheme.Codecs
tf.Client = &fake.RESTClient{
NegotiatedSerializer: ns,
Client: nil,
}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
podList := newAllPhasePodList()
printer, err := cmdutil.PrinterForOptions(cmdutil.ExtractCmdPrintOptions(cmd, false))
if err != nil {
fmt.Printf("Unexpected printer get error: %v\n", err)
}
for _, pod := range []runtime.Object{podList} {
err := printer.PrintObj(pod, os.Stdout)
if err != nil {
fmt.Printf("Unexpected error: %v", err)
}
}
// Output:
// NAME READY STATUS RESTARTS AGE
// test1 1/2 Pending 6 10y
// test2 1/2 Running 6 10y
// test3 1/2 Succeeded 6 10y
// test4 1/2 Failed 6 10y
// test5 1/2 Unknown 6 10y
}
func Example_printServiceWithLabels() { func Example_printServiceWithLabels() {
tf := cmdtesting.NewTestFactory() tf := cmdtesting.NewTestFactory()
defer tf.Cleanup() defer tf.Cleanup()
......
...@@ -98,6 +98,8 @@ type DeleteOptions struct { ...@@ -98,6 +98,8 @@ type DeleteOptions struct {
ForceDeletion bool ForceDeletion bool
WaitForDeletion bool WaitForDeletion bool
Reaper func(mapping *meta.RESTMapping) (kubectl.Reaper, error)
GracePeriod int GracePeriod int
Timeout time.Duration Timeout time.Duration
...@@ -107,21 +109,23 @@ type DeleteOptions struct { ...@@ -107,21 +109,23 @@ type DeleteOptions struct {
Mapper meta.RESTMapper Mapper meta.RESTMapper
Result *resource.Result Result *resource.Result
f cmdutil.Factory
Out io.Writer Out io.Writer
ErrOut io.Writer ErrOut io.Writer
} }
func NewDeleteOptions() *DeleteOptions { func NewDeleteOptions(out, errout io.Writer) *DeleteOptions {
return &DeleteOptions{ return &DeleteOptions{
Cascade: true, Cascade: true,
GracePeriod: -1, GracePeriod: -1,
Include3rdParty: true, Include3rdParty: true,
Out: out,
ErrOut: errout,
} }
} }
func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command { func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
options := NewDeleteOptions() options := NewDeleteOptions(out, errOut)
validArgs := cmdutil.ValidArgList(f) validArgs := cmdutil.ValidArgList(f)
cmd := &cobra.Command{ cmd := &cobra.Command{
...@@ -146,6 +150,7 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command { ...@@ -146,6 +150,7 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
ValidArgs: validArgs, ValidArgs: validArgs,
ArgAliases: kubectl.ResourceAliases(validArgs), ArgAliases: kubectl.ResourceAliases(validArgs),
} }
usage := "containing the resource to delete." usage := "containing the resource to delete."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage) cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, not including uninitialized ones.") cmd.Flags().StringVarP(&options.Selector, "selector", "l", options.Selector, "Selector (label query) to filter on, not including uninitialized ones.")
...@@ -156,7 +161,11 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command { ...@@ -156,7 +161,11 @@ func NewCmdDelete(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
cmd.Flags().BoolVar(&options.DeleteNow, "now", options.DeleteNow, "If true, resources are signaled for immediate shutdown (same as --grace-period=1).") cmd.Flags().BoolVar(&options.DeleteNow, "now", options.DeleteNow, "If true, resources are signaled for immediate shutdown (same as --grace-period=1).")
cmd.Flags().BoolVar(&options.ForceDeletion, "force", options.ForceDeletion, "Only used when grace-period=0. If true, immediately remove resources from API and bypass graceful deletion. Note that immediate deletion of some resources may result in inconsistency or data loss and requires confirmation.") cmd.Flags().BoolVar(&options.ForceDeletion, "force", options.ForceDeletion, "Only used when grace-period=0. If true, immediately remove resources from API and bypass graceful deletion. Note that immediate deletion of some resources may result in inconsistency or data loss and requires confirmation.")
cmd.Flags().DurationVar(&options.Timeout, "timeout", options.Timeout, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object") cmd.Flags().DurationVar(&options.Timeout, "timeout", options.Timeout, "The length of time to wait before giving up on a delete, zero means determine a timeout from the size of the object")
// we do not need to wire PrintFlags through this command,
// as it does not deal with runtime.Objects, and only accepts the "name" output format
cmdutil.AddOutputVarFlagsForMutation(cmd, &options.Output) cmdutil.AddOutputVarFlagsForMutation(cmd, &options.Output)
cmdutil.AddInclude3rdPartyVarFlags(cmd, &options.Include3rdParty) cmdutil.AddInclude3rdPartyVarFlags(cmd, &options.Include3rdParty)
cmdutil.AddIncludeUninitializedFlag(cmd) cmdutil.AddIncludeUninitializedFlag(cmd)
return cmd return cmd
...@@ -168,6 +177,8 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args ...@@ -168,6 +177,8 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
return err return err
} }
o.Reaper = f.Reaper
includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false) includeUninitialized := cmdutil.ShouldIncludeUninitialized(cmd, false)
r := f.NewBuilder(). r := f.NewBuilder().
Unstructured(). Unstructured().
...@@ -187,7 +198,6 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args ...@@ -187,7 +198,6 @@ func (o *DeleteOptions) Complete(f cmdutil.Factory, out, errOut io.Writer, args
o.Result = r o.Result = r
o.Mapper = r.Mapper().RESTMapper o.Mapper = r.Mapper().RESTMapper
o.f = f
// Set up writer // Set up writer
o.Out = out o.Out = out
o.ErrOut = errOut o.ErrOut = errOut
...@@ -233,17 +243,20 @@ func (o *DeleteOptions) Validate(cmd *cobra.Command) error { ...@@ -233,17 +243,20 @@ func (o *DeleteOptions) Validate(cmd *cobra.Command) error {
} }
func (o *DeleteOptions) RunDelete() error { func (o *DeleteOptions) RunDelete() error {
shortOutput := o.Output == "name"
// By default use a reaper to delete all related resources. // By default use a reaper to delete all related resources.
if o.Cascade { if o.Cascade {
return ReapResult(o.Result, o.f, o.Out, true, o.IgnoreNotFound, o.Timeout, o.GracePeriod, o.WaitForDeletion, shortOutput, false) // TODO(juanvallejo): although o.Result can be accessed from the options
// it is also passed here so that callers of this method outside of the "delete"
// command do not have to tack it to the "delete" options as well.
// Find a cleaner way to approach this.
return o.ReapResult(o.Result, true, false)
} }
return DeleteResult(o.Result, o.Out, o.IgnoreNotFound, o.GracePeriod, shortOutput) return o.DeleteResult(o.Result)
} }
func ReapResult(r *resource.Result, f cmdutil.Factory, out io.Writer, isDefaultDelete, ignoreNotFound bool, timeout time.Duration, gracePeriod int, waitForDeletion, shortOutput bool, quiet bool) error { func (o *DeleteOptions) ReapResult(r *resource.Result, isDefaultDelete, quiet bool) error {
found := 0 found := 0
if ignoreNotFound { if o.IgnoreNotFound {
r = r.IgnoreErrors(errors.IsNotFound) r = r.IgnoreErrors(errors.IsNotFound)
} }
err := r.Visit(func(info *resource.Info, err error) error { err := r.Visit(func(info *resource.Info, err error) error {
...@@ -251,29 +264,29 @@ func ReapResult(r *resource.Result, f cmdutil.Factory, out io.Writer, isDefaultD ...@@ -251,29 +264,29 @@ func ReapResult(r *resource.Result, f cmdutil.Factory, out io.Writer, isDefaultD
return err return err
} }
found++ found++
reaper, err := f.Reaper(info.Mapping) reaper, err := o.Reaper(info.Mapping)
if err != nil { if err != nil {
// If there is no reaper for this resources and the user didn't explicitly ask for stop. // If there is no reaper for this resources and the user didn't explicitly ask for stop.
if kubectl.IsNoSuchReaperError(err) && isDefaultDelete { if kubectl.IsNoSuchReaperError(err) && isDefaultDelete {
// No client side reaper found. Let the server do cascading deletion. // No client side reaper found. Let the server do cascading deletion.
return cascadingDeleteResource(info, out, shortOutput, gracePeriod) return o.cascadingDeleteResource(info)
} }
return cmdutil.AddSourceToErr("reaping", info.Source, err) return cmdutil.AddSourceToErr("reaping", info.Source, err)
} }
var options *metav1.DeleteOptions var options *metav1.DeleteOptions
if gracePeriod >= 0 { if o.GracePeriod >= 0 {
options = metav1.NewDeleteOptions(int64(gracePeriod)) options = metav1.NewDeleteOptions(int64(o.GracePeriod))
} }
if err := reaper.Stop(info.Namespace, info.Name, timeout, options); err != nil { if err := reaper.Stop(info.Namespace, info.Name, o.Timeout, options); err != nil {
return cmdutil.AddSourceToErr("stopping", info.Source, err) return cmdutil.AddSourceToErr("stopping", info.Source, err)
} }
if waitForDeletion { if o.WaitForDeletion {
if err := waitForObjectDeletion(info, timeout); err != nil { if err := waitForObjectDeletion(info, o.Timeout); err != nil {
return cmdutil.AddSourceToErr("stopping", info.Source, err) return cmdutil.AddSourceToErr("stopping", info.Source, err)
} }
} }
if !quiet { if !quiet {
printDeletion(info, out, shortOutput, gracePeriod) o.PrintObj(info)
} }
return nil return nil
}) })
...@@ -281,14 +294,14 @@ func ReapResult(r *resource.Result, f cmdutil.Factory, out io.Writer, isDefaultD ...@@ -281,14 +294,14 @@ func ReapResult(r *resource.Result, f cmdutil.Factory, out io.Writer, isDefaultD
return err return err
} }
if found == 0 { if found == 0 {
fmt.Fprintf(out, "No resources found\n") fmt.Fprintf(o.Out, "No resources found\n")
} }
return nil return nil
} }
func DeleteResult(r *resource.Result, out io.Writer, ignoreNotFound bool, gracePeriod int, shortOutput bool) error { func (o *DeleteOptions) DeleteResult(r *resource.Result) error {
found := 0 found := 0
if ignoreNotFound { if o.IgnoreNotFound {
r = r.IgnoreErrors(errors.IsNotFound) r = r.IgnoreErrors(errors.IsNotFound)
} }
err := r.Visit(func(info *resource.Info, err error) error { err := r.Visit(func(info *resource.Info, err error) error {
...@@ -300,38 +313,38 @@ func DeleteResult(r *resource.Result, out io.Writer, ignoreNotFound bool, graceP ...@@ -300,38 +313,38 @@ func DeleteResult(r *resource.Result, out io.Writer, ignoreNotFound bool, graceP
// if we're here, it means that cascade=false (not the default), so we should orphan as requested // if we're here, it means that cascade=false (not the default), so we should orphan as requested
orphan := true orphan := true
options := &metav1.DeleteOptions{} options := &metav1.DeleteOptions{}
if gracePeriod >= 0 { if o.GracePeriod >= 0 {
options = metav1.NewDeleteOptions(int64(gracePeriod)) options = metav1.NewDeleteOptions(int64(o.GracePeriod))
} }
options.OrphanDependents = &orphan options.OrphanDependents = &orphan
return deleteResource(info, out, shortOutput, options, gracePeriod) return o.deleteResource(info, options)
}) })
if err != nil { if err != nil {
return err return err
} }
if found == 0 { if found == 0 {
fmt.Fprintf(out, "No resources found\n") fmt.Fprintf(o.Out, "No resources found\n")
} }
return nil return nil
} }
func cascadingDeleteResource(info *resource.Info, out io.Writer, shortOutput bool, gracePeriod int) error { func (o *DeleteOptions) cascadingDeleteResource(info *resource.Info) error {
falseVar := false falseVar := false
deleteOptions := &metav1.DeleteOptions{OrphanDependents: &falseVar} return o.deleteResource(info, &metav1.DeleteOptions{OrphanDependents: &falseVar})
return deleteResource(info, out, shortOutput, deleteOptions, gracePeriod)
} }
func deleteResource(info *resource.Info, out io.Writer, shortOutput bool, deleteOptions *metav1.DeleteOptions, gracePeriod int) error { func (o *DeleteOptions) deleteResource(info *resource.Info, deleteOptions *metav1.DeleteOptions) error {
if err := resource.NewHelper(info.Client, info.Mapping).DeleteWithOptions(info.Namespace, info.Name, deleteOptions); err != nil { if err := resource.NewHelper(info.Client, info.Mapping).DeleteWithOptions(info.Namespace, info.Name, deleteOptions); err != nil {
return cmdutil.AddSourceToErr("deleting", info.Source, err) return cmdutil.AddSourceToErr("deleting", info.Source, err)
} }
printDeletion(info, out, shortOutput, gracePeriod) o.PrintObj(info)
return nil return nil
} }
// deletion printing is special because they don't have an object to print. This logic mirrors PrintSuccess // deletion printing is special because we do not have an object to print.
func printDeletion(info *resource.Info, out io.Writer, shortOutput bool, gracePeriod int) { // This mirrors name printer behavior
func (o *DeleteOptions) PrintObj(info *resource.Info) {
operation := "deleted" operation := "deleted"
groupKind := info.Mapping.GroupVersionKind groupKind := info.Mapping.GroupVersionKind
kindString := fmt.Sprintf("%s.%s", strings.ToLower(groupKind.Kind), groupKind.Group) kindString := fmt.Sprintf("%s.%s", strings.ToLower(groupKind.Kind), groupKind.Group)
...@@ -339,18 +352,18 @@ func printDeletion(info *resource.Info, out io.Writer, shortOutput bool, gracePe ...@@ -339,18 +352,18 @@ func printDeletion(info *resource.Info, out io.Writer, shortOutput bool, gracePe
kindString = strings.ToLower(groupKind.Kind) kindString = strings.ToLower(groupKind.Kind)
} }
if gracePeriod == 0 { if o.GracePeriod == 0 {
operation = "force deleted" operation = "force deleted"
} }
if shortOutput { if o.Output == "name" {
// -o name: prints resource/name // -o name: prints resource/name
fmt.Fprintf(out, "%s/%s\n", kindString, info.Name) fmt.Fprintf(o.Out, "%s/%s\n", kindString, info.Name)
return return
} }
// understandable output by default // understandable output by default
fmt.Fprintf(out, "%s \"%s\" %s\n", kindString, info.Name, operation) fmt.Fprintf(o.Out, "%s \"%s\" %s\n", kindString, info.Name, operation)
} }
// objectDeletionWaitInterval is the interval to wait between checks for deletion. // objectDeletionWaitInterval is the interval to wait between checks for deletion.
......
...@@ -65,7 +65,7 @@ func TestReplaceObject(t *testing.T) { ...@@ -65,7 +65,7 @@ func TestReplaceObject(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
cmd := NewCmdReplace(tf, buf) cmd := NewCmdReplace(tf, buf, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml") cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml")
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
cmd.Run(cmd, []string{}) cmd.Run(cmd, []string{})
...@@ -136,7 +136,7 @@ func TestReplaceMultipleObject(t *testing.T) { ...@@ -136,7 +136,7 @@ func TestReplaceMultipleObject(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
cmd := NewCmdReplace(tf, buf) cmd := NewCmdReplace(tf, buf, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml") cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml")
cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml") cmd.Flags().Set("filename", "../../../examples/guestbook/frontend-service.yaml")
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
...@@ -194,7 +194,7 @@ func TestReplaceDirectory(t *testing.T) { ...@@ -194,7 +194,7 @@ func TestReplaceDirectory(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
cmd := NewCmdReplace(tf, buf) cmd := NewCmdReplace(tf, buf, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/legacy") cmd.Flags().Set("filename", "../../../examples/guestbook/legacy")
cmd.Flags().Set("namespace", "test") cmd.Flags().Set("namespace", "test")
cmd.Flags().Set("output", "name") cmd.Flags().Set("output", "name")
...@@ -241,7 +241,7 @@ func TestForceReplaceObjectNotFound(t *testing.T) { ...@@ -241,7 +241,7 @@ func TestForceReplaceObjectNotFound(t *testing.T) {
tf.Namespace = "test" tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{}) buf := bytes.NewBuffer([]byte{})
cmd := NewCmdReplace(tf, buf) cmd := NewCmdReplace(tf, buf, buf)
cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml") cmd.Flags().Set("filename", "../../../examples/guestbook/legacy/redis-master-controller.yaml")
cmd.Flags().Set("force", "true") cmd.Flags().Set("force", "true")
cmd.Flags().Set("cascade", "false") cmd.Flags().Set("cascade", "false")
......
...@@ -188,12 +188,28 @@ func TestRunArgsFollowDashRules(t *testing.T) { ...@@ -188,12 +188,28 @@ func TestRunArgsFollowDashRules(t *testing.T) {
}, nil }, nil
}), }),
} }
tf.Namespace = "test" tf.Namespace = "test"
tf.ClientConfigVal = &restclient.Config{} tf.ClientConfigVal = &restclient.Config{}
cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr) cmd := NewCmdRun(tf, os.Stdin, os.Stdout, os.Stderr)
cmd.Flags().Set("image", "nginx") cmd.Flags().Set("image", "nginx")
cmd.Flags().Set("generator", "run/v1") cmd.Flags().Set("generator", "run/v1")
err := RunRun(tf, os.Stdin, os.Stdout, os.Stderr, cmd, test.args, test.argsLenAtDash)
opts := &RunOpts{
DeleteOptions: NewDeleteOptions(os.Stdout, os.Stderr),
In: os.Stdin,
Out: os.Stdout,
ErrOut: os.Stderr,
Image: "nginx",
Generator: "run/v1",
ArgsLenAtDash: test.argsLenAtDash,
}
err := opts.Run(tf, cmd, test.args)
if test.expectError && err == nil { if test.expectError && err == nil {
t.Errorf("unexpected non-error (%s)", test.name) t.Errorf("unexpected non-error (%s)", test.name)
} }
...@@ -335,6 +351,18 @@ func TestGenerateService(t *testing.T) { ...@@ -335,6 +351,18 @@ func TestGenerateService(t *testing.T) {
} }
}), }),
} }
buff := &bytes.Buffer{}
opts := &RunOpts{
DeleteOptions: NewDeleteOptions(os.Stdout, os.Stderr),
Out: buff,
ErrOut: buff,
Port: test.port,
Record: false,
}
cmd := &cobra.Command{} cmd := &cobra.Command{}
cmd.Flags().Bool(cmdutil.ApplyAnnotationsFlag, false, "") cmd.Flags().Bool(cmdutil.ApplyAnnotationsFlag, false, "")
cmd.Flags().Bool("record", false, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.") cmd.Flags().Bool("record", false, "Record current kubectl command in the resource annotation. If set to false, do not record the command. If set to true, record the command. If not set, default to updating the existing annotation value only if one already exists.")
...@@ -343,7 +371,7 @@ func TestGenerateService(t *testing.T) { ...@@ -343,7 +371,7 @@ func TestGenerateService(t *testing.T) {
addRunFlags(cmd) addRunFlags(cmd)
if !test.expectPOST { if !test.expectPOST {
cmd.Flags().Set("dry-run", "true") opts.DryRun = true
} }
if len(test.port) > 0 { if len(test.port) > 0 {
...@@ -351,8 +379,7 @@ func TestGenerateService(t *testing.T) { ...@@ -351,8 +379,7 @@ func TestGenerateService(t *testing.T) {
test.params["port"] = test.port test.params["port"] = test.port
} }
buff := &bytes.Buffer{} _, err := opts.generateService(tf, cmd, test.serviceGenerator, test.params, "namespace")
_, err := generateService(tf, cmd, test.args, test.serviceGenerator, test.params, "namespace", buff)
if test.expectErr { if test.expectErr {
if err == nil { if err == nil {
t.Error("unexpected non-error") t.Error("unexpected non-error")
...@@ -473,7 +500,12 @@ func TestRunValidations(t *testing.T) { ...@@ -473,7 +500,12 @@ func TestRunValidations(t *testing.T) {
for flagName, flagValue := range test.flags { for flagName, flagValue := range test.flags {
cmd.Flags().Set(flagName, flagValue) cmd.Flags().Set(flagName, flagValue)
} }
err := RunRun(tf, inBuf, outBuf, errBuf, cmd, test.args, cmd.ArgsLenAtDash()) cmd.Run(cmd, test.args)
var err error
if errBuf.Len() > 0 {
err = fmt.Errorf("%v", errBuf.String())
}
if err != nil && len(test.expectedErr) > 0 { if err != nil && len(test.expectedErr) > 0 {
if !strings.Contains(err.Error(), test.expectedErr) { if !strings.Contains(err.Error(), test.expectedErr) {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment