From 72afd143c42056aa377b691d4b2a8d4fcca9cda1 Mon Sep 17 00:00:00 2001 From: Justin Santa Barbara Date: Sun, 26 Feb 2017 00:41:39 -0500 Subject: [PATCH] kubectl drain: make code reusable DrainOptions requires a few fields to be set, and the expectation is that these are set as part of construction of the object. If they are set, then the drain code can be reused in other kubernetes projects. This does not create a contract that DrainOptions should fulfill going forwards, any more than any of the other types that happen to be exposed are part of the contract. Instead, this merely makes use outside the package possible. --- pkg/kubectl/cmd/drain.go | 42 +++++++++++++++++------------------ pkg/kubectl/cmd/drain_test.go | 2 +- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/pkg/kubectl/cmd/drain.go b/pkg/kubectl/cmd/drain.go index 05c3d38c09f..c44c0d58691 100644 --- a/pkg/kubectl/cmd/drain.go +++ b/pkg/kubectl/cmd/drain.go @@ -49,7 +49,7 @@ import ( type DrainOptions struct { client *internalclientset.Clientset restClient *restclient.RESTClient - factory cmdutil.Factory + Factory cmdutil.Factory Force bool GracePeriodSeconds int IgnoreDaemonsets bool @@ -58,8 +58,8 @@ type DrainOptions struct { DeleteLocalData bool mapper meta.RESTMapper nodeInfo *resource.Info - out io.Writer - errOut io.Writer + Out io.Writer + ErrOut io.Writer typer runtime.ObjectTyper } @@ -96,7 +96,7 @@ var ( ) func NewCmdCordon(f cmdutil.Factory, out io.Writer) *cobra.Command { - options := &DrainOptions{factory: f, out: out} + options := &DrainOptions{Factory: f, Out: out} cmd := &cobra.Command{ Use: "cordon NODE", @@ -121,7 +121,7 @@ var ( ) func NewCmdUncordon(f cmdutil.Factory, out io.Writer) *cobra.Command { - options := &DrainOptions{factory: f, out: out} + options := &DrainOptions{Factory: f, Out: out} cmd := &cobra.Command{ Use: "uncordon NODE", @@ -170,7 +170,7 @@ var ( ) func NewCmdDrain(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command { - options := &DrainOptions{factory: f, out: out, errOut: errOut, backOff: clockwork.NewRealClock()} + options := &DrainOptions{Factory: f, Out: out, ErrOut: errOut, backOff: clockwork.NewRealClock()} cmd := &cobra.Command{ Use: "drain NODE", @@ -198,23 +198,23 @@ func (o *DrainOptions) SetupDrain(cmd *cobra.Command, args []string) error { return cmdutil.UsageError(cmd, fmt.Sprintf("USAGE: %s [flags]", cmd.Use)) } - if o.client, err = o.factory.ClientSet(); err != nil { + if o.client, err = o.Factory.ClientSet(); err != nil { return err } - o.restClient, err = o.factory.RESTClient() + o.restClient, err = o.Factory.RESTClient() if err != nil { return err } - o.mapper, o.typer = o.factory.Object() + o.mapper, o.typer = o.Factory.Object() - cmdNamespace, _, err := o.factory.DefaultNamespace() + cmdNamespace, _, err := o.Factory.DefaultNamespace() if err != nil { return err } - r := o.factory.NewBuilder(). + r := o.Factory.NewBuilder(). NamespaceParam(cmdNamespace).DefaultNamespace(). ResourceNames("node", args[0]). Do() @@ -240,7 +240,7 @@ func (o *DrainOptions) RunDrain() error { err := o.deleteOrEvictPodsSimple() if err == nil { - cmdutil.PrintSuccess(o.mapper, false, o.out, "node", o.nodeInfo.Name, false, "drained") + cmdutil.PrintSuccess(o.mapper, false, o.Out, "node", o.nodeInfo.Name, false, "drained") } return err } @@ -257,9 +257,9 @@ func (o *DrainOptions) deleteOrEvictPodsSimple() error { if newErr != nil { return newErr } - fmt.Fprintf(o.errOut, "There are pending pods when an error occurred: %v\n", err) + fmt.Fprintf(o.ErrOut, "There are pending pods when an error occurred: %v\n", err) for _, pendingPod := range pendingPods { - fmt.Fprintf(o.errOut, "%s/%s\n", "pod", pendingPod.Name) + fmt.Fprintf(o.ErrOut, "%s/%s\n", "pod", pendingPod.Name) } } return err @@ -288,7 +288,7 @@ func (o *DrainOptions) getPodCreator(pod api.Pod) (*api.SerializedReference, err } // Now verify that the specified creator actually exists. sr := &api.SerializedReference{} - if err := runtime.DecodeInto(o.factory.Decoder(true), []byte(creatorRef), sr); err != nil { + if err := runtime.DecodeInto(o.Factory.Decoder(true), []byte(creatorRef), sr); err != nil { return nil, err } // We assume the only reason for an error is because the controller is @@ -413,7 +413,7 @@ func (o *DrainOptions) getPodsForDeletion() (pods []api.Pod, err error) { return []api.Pod{}, errors.New(fs.Message()) } if len(ws) > 0 { - fmt.Fprintf(o.errOut, "WARNING: %s\n", ws.Message()) + fmt.Fprintf(o.ErrOut, "WARNING: %s\n", ws.Message()) } return pods, nil } @@ -551,7 +551,7 @@ func (o *DrainOptions) waitForDelete(pods []api.Pod, interval, timeout time.Dura for i, pod := range pods { p, err := getPodFn(pod.Namespace, pod.Name) if apierrors.IsNotFound(err) || (p != nil && p.ObjectMeta.UID != pod.ObjectMeta.UID) { - cmdutil.PrintSuccess(o.mapper, false, o.out, "pod", pod.Name, false, verbStr) + cmdutil.PrintSuccess(o.mapper, false, o.Out, "pod", pod.Name, false, verbStr) continue } else if err != nil { return false, err @@ -603,7 +603,7 @@ func SupportEviction(clientset *internalclientset.Clientset) (string, error) { // RunCordonOrUncordon runs either Cordon or Uncordon. The desired value for // "Unschedulable" is passed as the first arg. func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { - cmdNamespace, _, err := o.factory.DefaultNamespace() + cmdNamespace, _, err := o.Factory.DefaultNamespace() if err != nil { return err } @@ -611,7 +611,7 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { if o.nodeInfo.Mapping.GroupVersionKind.Kind == "Node" { unsched := reflect.ValueOf(o.nodeInfo.Object).Elem().FieldByName("Spec").FieldByName("Unschedulable") if unsched.Bool() == desired { - cmdutil.PrintSuccess(o.mapper, false, o.out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, false, already(desired)) + cmdutil.PrintSuccess(o.mapper, false, o.Out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, false, already(desired)) } else { helper := resource.NewHelper(o.restClient, o.nodeInfo.Mapping) unsched.SetBool(desired) @@ -633,10 +633,10 @@ func (o *DrainOptions) RunCordonOrUncordon(desired bool) error { if err != nil { return err } - cmdutil.PrintSuccess(o.mapper, false, o.out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, false, changed(desired)) + cmdutil.PrintSuccess(o.mapper, false, o.Out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, false, changed(desired)) } } else { - cmdutil.PrintSuccess(o.mapper, false, o.out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, false, "skipped") + cmdutil.PrintSuccess(o.mapper, false, o.Out, o.nodeInfo.Mapping.Resource, o.nodeInfo.Name, false, "skipped") } return nil diff --git a/pkg/kubectl/cmd/drain_test.go b/pkg/kubectl/cmd/drain_test.go index 8bbc503aab7..70489a03e5d 100644 --- a/pkg/kubectl/cmd/drain_test.go +++ b/pkg/kubectl/cmd/drain_test.go @@ -682,7 +682,7 @@ func TestDeletePods(t *testing.T) { f, _, _, _ := cmdtesting.NewAPIFactory() o := DrainOptions{} o.mapper, _ = f.Object() - o.out = os.Stdout + o.Out = os.Stdout _, pods := createPods(false) pendingPods, err := o.waitForDelete(pods, test.interval, test.timeout, false, test.getPodFn)