Unverified Commit d2b2c330 authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #63244 from soltysh/finish_printflags

Automatic merge from submit-queue (batch tested with PRs 60890, 63244, 60741, 63254). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Finish wiring PrintFlags **What this PR does / why we need it**: This is rebased version of #63055, I don't want to wait for @juanvallejo to return and to unblock myself, and him for next week. I've rebased his PR and will push it forward. /assign @deads2k since you "broke" us 😉 **Release note**: ```release-note NONE ```
parents bbcd21e0 f432ebe2
......@@ -273,9 +273,9 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
{
Message: "Deploy Commands:",
Commands: []*cobra.Command{
rollout.NewCmdRollout(f, out, err),
NewCmdRollingUpdate(f, out),
NewCmdScale(f, out, err),
rollout.NewCmdRollout(f, ioStreams),
NewCmdRollingUpdate(f, ioStreams),
NewCmdScale(f, ioStreams),
NewCmdAutoscale(f, ioStreams),
},
},
......@@ -288,7 +288,7 @@ func NewKubectlCommand(f cmdutil.Factory, in io.Reader, out, err io.Writer) *cob
NewCmdCordon(f, ioStreams),
NewCmdUncordon(f, ioStreams),
NewCmdDrain(f, ioStreams),
NewCmdTaint(f, out),
NewCmdTaint(f, ioStreams),
},
},
{
......
......@@ -17,10 +17,10 @@ limitations under the License.
package cmd
import (
"bytes"
"testing"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
)
func TestValidateArgs(t *testing.T) {
......@@ -74,8 +74,7 @@ func TestValidateArgs(t *testing.T) {
},
}
for _, test := range tests {
out := &bytes.Buffer{}
cmd := NewCmdRollingUpdate(f, out)
cmd := NewCmdRollingUpdate(f, genericclioptions.NewTestIOStreamsDiscard())
if test.flags != nil {
for key, val := range test.flags {
......
......@@ -24,8 +24,10 @@ go_library(
"//pkg/kubectl/cmd/set:go_default_library",
"//pkg/kubectl/cmd/templates:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library",
"//pkg/kubectl/resource:go_default_library",
"//pkg/kubectl/util/i18n:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/util/interrupt:go_default_library",
"//vendor/github.com/renstrom/dedent:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
......@@ -59,6 +61,7 @@ go_test(
"//pkg/api/legacyscheme:go_default_library",
"//pkg/apis/extensions:go_default_library",
"//pkg/kubectl/cmd/testing:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
......
......@@ -17,12 +17,12 @@ limitations under the License.
package rollout
import (
"io"
"github.com/renstrom/dedent"
"github.com/spf13/cobra"
"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,22 +46,21 @@ var (
`)
)
func NewCmdRollout(f cmdutil.Factory, out, errOut io.Writer) *cobra.Command {
func NewCmdRollout(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
cmd := &cobra.Command{
Use: "rollout SUBCOMMAND",
DisableFlagsInUseLine: true,
Short: i18n.T("Manage the rollout of a resource"),
Long: rollout_long,
Example: rollout_example,
Run: cmdutil.DefaultSubCommandRun(errOut),
Run: cmdutil.DefaultSubCommandRun(streams.Out),
}
// subcommands
cmd.AddCommand(NewCmdRolloutHistory(f, out))
cmd.AddCommand(NewCmdRolloutPause(f, out))
cmd.AddCommand(NewCmdRolloutResume(f, out))
cmd.AddCommand(NewCmdRolloutUndo(f, out))
cmd.AddCommand(NewCmdRolloutStatus(f, out))
cmd.AddCommand(NewCmdRolloutHistory(f, streams.Out))
cmd.AddCommand(NewCmdRolloutPause(f, streams))
cmd.AddCommand(NewCmdRolloutResume(f, streams))
cmd.AddCommand(NewCmdRolloutUndo(f, streams.Out))
cmd.AddCommand(NewCmdRolloutStatus(f, streams))
return cmd
}
......@@ -18,7 +18,6 @@ package rollout
import (
"fmt"
"io"
"github.com/spf13/cobra"
......@@ -30,20 +29,24 @@ import (
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
"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"
"k8s.io/kubernetes/pkg/printers"
)
// PauseConfig 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 PauseConfig struct {
resource.FilenameOptions
PrintFlags *printers.PrintFlags
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
Pauser func(info *resource.Info) ([]byte, error)
Mapper meta.RESTMapper
Infos []*resource.Info
Out io.Writer
genericclioptions.IOStreams
}
var (
......@@ -61,8 +64,11 @@ var (
kubectl rollout pause deployment/nginx`)
)
func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &PauseConfig{}
func NewCmdRolloutPause(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := &PauseConfig{
PrintFlags: printers.NewPrintFlags("paused"),
IOStreams: streams,
}
validArgs := []string{"deployment"}
argAliases := kubectl.ResourceAliases(validArgs)
......@@ -75,11 +81,11 @@ func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
Example: pause_example,
Run: func(cmd *cobra.Command, args []string) {
allErrs := []error{}
err := options.CompletePause(f, cmd, out, args)
err := o.CompletePause(f, cmd, args)
if err != nil {
allErrs = append(allErrs, err)
}
err = options.RunPause()
err = o.RunPause()
if err != nil {
allErrs = append(allErrs, err)
}
......@@ -90,11 +96,11 @@ func NewCmdRolloutPause(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
return cmd
}
func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string) error {
func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
}
......@@ -102,7 +108,6 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i
o.Mapper = f.RESTMapper()
o.Pauser = f.Pauser
o.Out = out
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
......@@ -123,6 +128,16 @@ func (o *PauseConfig) CompletePause(f cmdutil.Factory, cmd *cobra.Command, out i
return err
}
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return nil, err
}
return printer.PrintObj, nil
}
o.Infos, err = r.Infos()
if err != nil {
return err
......@@ -140,7 +155,12 @@ func (o PauseConfig) RunPause() error {
}
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "already paused")
printer, err := o.ToPrinter("already paused")
if err != nil {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
continue
}
......@@ -151,7 +171,12 @@ func (o PauseConfig) RunPause() error {
}
info.Refresh(obj, true)
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "paused")
printer, err := o.ToPrinter("paused")
if err != nil {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
}
return utilerrors.NewAggregate(allErrs)
......
......@@ -31,6 +31,7 @@ import (
"k8s.io/kubernetes/pkg/api/legacyscheme"
extensions "k8s.io/kubernetes/pkg/apis/extensions"
cmdtesting "k8s.io/kubernetes/pkg/kubectl/cmd/testing"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
)
var rolloutPauseGroupVersionEncoder = schema.GroupVersion{Group: "extensions", Version: "v1beta1"}
......@@ -62,11 +63,11 @@ func TestRolloutPause(t *testing.T) {
}
tf.Namespace = "test"
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdRolloutPause(tf, buf)
streams, _, buf, _ := genericclioptions.NewTestIOStreams()
cmd := NewCmdRolloutPause(tf, streams)
cmd.Run(cmd, []string{deploymentName})
expectedOutput := "deployment.apps \"" + deploymentName + "\" paused\n"
expectedOutput := "deployment.extensions/" + deploymentName + " paused\n"
if buf.String() != expectedOutput {
t.Errorf("expected output: %s, but got: %s", expectedOutput, buf.String())
}
......
......@@ -18,7 +18,6 @@ package rollout
import (
"fmt"
"io"
"github.com/spf13/cobra"
......@@ -30,20 +29,24 @@ import (
"k8s.io/kubernetes/pkg/kubectl/cmd/set"
"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"
"k8s.io/kubernetes/pkg/printers"
)
// ResumeConfig 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 ResumeConfig struct {
resource.FilenameOptions
PrintFlags *printers.PrintFlags
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
Resumer func(object *resource.Info) ([]byte, error)
Mapper meta.RESTMapper
Infos []*resource.Info
Out io.Writer
genericclioptions.IOStreams
}
var (
......@@ -59,8 +62,11 @@ var (
kubectl rollout resume deployment/nginx`)
)
func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &ResumeConfig{}
func NewCmdRolloutResume(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := &ResumeConfig{
PrintFlags: printers.NewPrintFlags("resumed"),
IOStreams: streams,
}
validArgs := []string{"deployment"}
argAliases := kubectl.ResourceAliases(validArgs)
......@@ -73,11 +79,11 @@ func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
Example: resume_example,
Run: func(cmd *cobra.Command, args []string) {
allErrs := []error{}
err := options.CompleteResume(f, cmd, out, args)
err := o.CompleteResume(f, cmd, args)
if err != nil {
allErrs = append(allErrs, err)
}
err = options.RunResume()
err = o.RunResume()
if err != nil {
allErrs = append(allErrs, err)
}
......@@ -88,11 +94,11 @@ func NewCmdRolloutResume(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
return cmd
}
func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string) error {
func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames) {
return cmdutil.UsageErrorf(cmd, "%s", cmd.Use)
}
......@@ -100,13 +106,22 @@ func (o *ResumeConfig) CompleteResume(f cmdutil.Factory, cmd *cobra.Command, out
o.Mapper = f.RESTMapper()
o.Resumer = f.Resumer
o.Out = out
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
if err != nil {
return err
}
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return nil, err
}
return printer.PrintObj, nil
}
r := f.NewBuilder().
Internal(legacyscheme.Scheme).
NamespaceParam(cmdNamespace).DefaultNamespace().
......@@ -145,8 +160,12 @@ func (o ResumeConfig) RunResume() error {
}
if string(patch.Patch) == "{}" || len(patch.Patch) == 0 {
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "already resumed")
continue
printer, err := o.ToPrinter("already resumed")
if err != nil {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
}
obj, err := resource.NewHelper(info.Client, info.Mapping).Patch(info.Namespace, info.Name, types.StrategicMergePatchType, patch.Patch)
......@@ -156,7 +175,12 @@ func (o ResumeConfig) RunResume() error {
}
info.Refresh(obj, true)
cmdutil.PrintSuccess(false, o.Out, info.Object, false, "resumed")
printer, err := o.ToPrinter("resumed")
if err != nil {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
}
return utilerrors.NewAggregate(allErrs)
......
......@@ -18,7 +18,6 @@ package rollout
import (
"fmt"
"io"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/watch"
......@@ -26,6 +25,7 @@ import (
"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"
"k8s.io/kubernetes/pkg/util/interrupt"
......@@ -49,8 +49,32 @@ var (
kubectl rollout status deployment/nginx`)
)
func NewCmdRolloutStatus(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &resource.FilenameOptions{}
type RolloutStatusOptions struct {
FilenameOptions *resource.FilenameOptions
genericclioptions.IOStreams
Namespace string
EnforceNamespace bool
BuilderArgs []string
Watch bool
Revision int64
StatusViewer func(*meta.RESTMapping) (kubectl.StatusViewer, error)
Builder *resource.Builder
}
func NewRolloutStatusOptions(streams genericclioptions.IOStreams) *RolloutStatusOptions {
return &RolloutStatusOptions{
FilenameOptions: &resource.FilenameOptions{},
IOStreams: streams,
Watch: true,
}
}
func NewCmdRolloutStatus(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
o := NewRolloutStatusOptions(streams)
validArgs := []string{"deployment", "daemonset", "statefulset"}
argAliases := kubectl.ResourceAliases(validArgs)
......@@ -62,38 +86,52 @@ func NewCmdRolloutStatus(f cmdutil.Factory, out io.Writer) *cobra.Command {
Long: status_long,
Example: status_example,
Run: func(cmd *cobra.Command, args []string) {
cmdutil.CheckErr(RunStatus(f, cmd, out, args, options))
cmdutil.CheckErr(o.Complete(f, args))
cmdutil.CheckErr(o.Validate(cmd, args))
cmdutil.CheckErr(o.Run())
},
ValidArgs: validArgs,
ArgAliases: argAliases,
}
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, options, usage)
cmd.Flags().BoolP("watch", "w", true, "Watch the status of the rollout until it's done.")
cmd.Flags().Int64("revision", 0, "Pin to a specific revision for showing its status. Defaults to 0 (last revision).")
cmdutil.AddFilenameOptionFlags(cmd, o.FilenameOptions, usage)
cmd.Flags().BoolVarP(&o.Watch, "watch", "w", o.Watch, "Watch the status of the rollout until it's done.")
cmd.Flags().Int64Var(&o.Revision, "revision", o.Revision, "Pin to a specific revision for showing its status. Defaults to 0 (last revision).")
return cmd
}
func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []string, options *resource.FilenameOptions) error {
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(options.Filenames) {
return cmdutil.UsageErrorf(cmd, "Required resource not specified.")
}
func (o *RolloutStatusOptions) Complete(f cmdutil.Factory, args []string) error {
o.Builder = f.NewBuilder()
cmdNamespace, enforceNamespace, err := f.DefaultNamespace()
var err error
o.Namespace, o.EnforceNamespace, err = f.DefaultNamespace()
if err != nil {
return err
}
r := f.NewBuilder().
o.BuilderArgs = args
o.StatusViewer = f.StatusViewer
return nil
}
func (o *RolloutStatusOptions) Validate(cmd *cobra.Command, args []string) error {
if len(args) == 0 && cmdutil.IsFilenameSliceEmpty(o.FilenameOptions.Filenames) {
return cmdutil.UsageErrorf(cmd, "Required resource not specified.")
}
return nil
}
func (o *RolloutStatusOptions) Run() error {
r := o.Builder.
Internal(legacyscheme.Scheme).
NamespaceParam(cmdNamespace).DefaultNamespace().
FilenameParam(enforceNamespace, options).
ResourceTypeOrNameArgs(true, args...).
NamespaceParam(o.Namespace).DefaultNamespace().
FilenameParam(o.EnforceNamespace, o.FilenameOptions).
ResourceTypeOrNameArgs(true, o.BuilderArgs...).
SingleResourceType().
Latest().
Do()
err = r.Err()
err := r.Err()
if err != nil {
return err
}
......@@ -117,12 +155,12 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
return err
}
statusViewer, err := f.StatusViewer(mapping)
statusViewer, err := o.StatusViewer(mapping)
if err != nil {
return err
}
revision := cmdutil.GetFlagInt64(cmd, "revision")
revision := o.Revision
if revision < 0 {
return fmt.Errorf("revision must be a positive integer: %v", revision)
}
......@@ -132,12 +170,12 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
if err != nil {
return err
}
fmt.Fprintf(out, "%s", status)
fmt.Fprintf(o.Out, "%s", status)
if done {
return nil
}
shouldWatch := cmdutil.GetFlagBool(cmd, "watch")
shouldWatch := o.Watch
if !shouldWatch {
return nil
}
......@@ -157,7 +195,7 @@ func RunStatus(f cmdutil.Factory, cmd *cobra.Command, out io.Writer, args []stri
if err != nil {
return false, err
}
fmt.Fprintf(out, "%s", status)
fmt.Fprintf(o.Out, "%s", status)
// Quit waiting if the rollout is done
if done {
return true, nil
......
......@@ -27,6 +27,7 @@ import (
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/resource"
"k8s.io/kubernetes/pkg/kubectl/util/i18n"
"k8s.io/kubernetes/pkg/printers"
"github.com/spf13/cobra"
)
......@@ -36,6 +37,9 @@ import (
type UndoOptions struct {
resource.FilenameOptions
PrintFlags *printers.PrintFlags
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
Rollbackers []kubectl.Rollbacker
Mapper meta.RESTMapper
Infos []*resource.Info
......@@ -61,7 +65,9 @@ var (
)
func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &UndoOptions{}
o := &UndoOptions{
PrintFlags: printers.NewPrintFlags(""),
}
validArgs := []string{"deployment", "daemonset", "statefulset"}
argAliases := kubectl.ResourceAliases(validArgs)
......@@ -74,11 +80,11 @@ func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
Example: undo_example,
Run: func(cmd *cobra.Command, args []string) {
allErrs := []error{}
err := options.CompleteUndo(f, cmd, out, args)
err := o.CompleteUndo(f, cmd, out, args)
if err != nil {
allErrs = append(allErrs, err)
}
err = options.RunUndo()
err = o.RunUndo()
if err != nil {
allErrs = append(allErrs, err)
}
......@@ -90,7 +96,7 @@ func NewCmdRolloutUndo(f cmdutil.Factory, out io.Writer) *cobra.Command {
cmd.Flags().Int64("to-revision", 0, "The revision to rollback to. Default to 0 (last revision).")
usage := "identifying the resource to get from a server."
cmdutil.AddFilenameOptionFlags(cmd, &options.FilenameOptions, usage)
cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
cmdutil.AddDryRunFlag(cmd)
return cmd
}
......@@ -110,6 +116,19 @@ func (o *UndoOptions) CompleteUndo(f cmdutil.Factory, cmd *cobra.Command, out io
return err
}
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
if o.DryRun {
o.PrintFlags.Complete("%s (dry run)")
}
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return nil, err
}
return printer.PrintObj, nil
}
r := f.NewBuilder().
Internal(legacyscheme.Scheme).
NamespaceParam(cmdNamespace).DefaultNamespace().
......@@ -147,7 +166,12 @@ func (o *UndoOptions) RunUndo() error {
allErrs = append(allErrs, cmdutil.AddSourceToErr("undoing", info.Source, err))
continue
}
cmdutil.PrintSuccess(false, o.Out, info.Object, false, result)
printer, err := o.ToPrinter(result)
if err != nil {
allErrs = append(allErrs, err)
continue
}
printer.PrintObj(info.AsVersioned(legacyscheme.Scheme), o.Out)
}
return utilerrors.NewAggregate(allErrs)
}
......@@ -18,7 +18,6 @@ package cmd
import (
"fmt"
"io"
"strings"
"encoding/json"
......@@ -26,6 +25,7 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/strategicpatch"
......@@ -34,13 +34,18 @@ import (
"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"
"k8s.io/kubernetes/pkg/printers"
taintutils "k8s.io/kubernetes/pkg/util/taints"
)
// TaintOptions have the data required to perform the taint operation
type TaintOptions struct {
PrintFlags *printers.PrintFlags
ToPrinter func(string) (printers.ResourcePrinterFunc, error)
resources []string
taintsToAdd []v1.Taint
taintsToRemove []v1.Taint
......@@ -48,9 +53,10 @@ type TaintOptions struct {
selector string
overwrite bool
all bool
f cmdutil.Factory
out io.Writer
cmd *cobra.Command
ClientForMapping func(*meta.RESTMapping) (resource.RESTClient, error)
genericclioptions.IOStreams
}
var (
......@@ -79,8 +85,11 @@ var (
kubectl taint node -l myLabel=X dedicated=foo:PreferNoSchedule`))
)
func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
options := &TaintOptions{}
func NewCmdTaint(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
options := &TaintOptions{
PrintFlags: printers.NewPrintFlags("tainted"),
IOStreams: streams,
}
validArgs := []string{"node"}
argAliases := kubectl.ResourceAliases(validArgs)
......@@ -92,7 +101,7 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
Long: fmt.Sprintf(taintLong, validation.DNS1123SubdomainMaxLength, validation.LabelValueMaxLength),
Example: taintExample,
Run: func(cmd *cobra.Command, args []string) {
if err := options.Complete(f, out, cmd, args); err != nil {
if err := options.Complete(f, cmd, args); err != nil {
cmdutil.CheckErr(err)
}
if err := options.Validate(); err != nil {
......@@ -105,9 +114,10 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
ValidArgs: validArgs,
ArgAliases: argAliases,
}
cmdutil.AddValidateFlags(cmd)
cmdutil.AddPrinterFlags(cmd)
options.PrintFlags.AddFlags(cmd)
cmdutil.AddValidateFlags(cmd)
cmd.Flags().StringVarP(&options.selector, "selector", "l", options.selector, "Selector (label query) to filter on, supports '=', '==', and '!='.(e.g. -l key1=value1,key2=value2)")
cmd.Flags().BoolVar(&options.overwrite, "overwrite", options.overwrite, "If true, allow taints to be overwritten, otherwise reject taint updates that overwrite existing taints.")
cmd.Flags().BoolVar(&options.all, "all", options.all, "Select all nodes in the cluster")
......@@ -115,7 +125,7 @@ func NewCmdTaint(f cmdutil.Factory, out io.Writer) *cobra.Command {
}
// Complete adapts from the command line args and factory to the data required.
func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Command, args []string) (err error) {
func (o *TaintOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) (err error) {
namespace, _, err := f.DefaultNamespace()
if err != nil {
return err
......@@ -140,6 +150,16 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Com
}
}
o.ToPrinter = func(operation string) (printers.ResourcePrinterFunc, error) {
o.PrintFlags.NamePrintFlags.Operation = operation
printer, err := o.PrintFlags.ToPrinter()
if err != nil {
return nil, err
}
return printer.PrintObj, nil
}
if len(o.resources) < 1 {
return fmt.Errorf("one or more resources must be specified as <resource> <name>")
}
......@@ -166,9 +186,8 @@ func (o *TaintOptions) Complete(f cmdutil.Factory, out io.Writer, cmd *cobra.Com
o.builder = o.builder.LabelSelectorParam(o.selector).
Flatten().
Latest()
o.f = f
o.out = out
o.cmd = cmd
o.ClientForMapping = f.ClientForMapping
return nil
}
......@@ -258,7 +277,7 @@ func (o TaintOptions) RunTaint() error {
}
mapping := info.ResourceMapping()
client, err := o.f.ClientForMapping(mapping)
client, err := o.ClientForMapping(mapping)
if err != nil {
return err
}
......@@ -274,13 +293,11 @@ func (o TaintOptions) RunTaint() error {
return err
}
outputFormat := cmdutil.GetFlagString(o.cmd, "output")
if outputFormat != "" {
return cmdutil.PrintObject(o.cmd, outputObj, o.out)
printer, err := o.ToPrinter(operation)
if err != nil {
return err
}
cmdutil.PrintSuccess(false, o.out, info.Object, false, operation)
return nil
return printer.PrintObj(outputObj, o.Out)
})
}
......
......@@ -17,7 +17,6 @@ limitations under the License.
package cmd
import (
"bytes"
"io/ioutil"
"net/http"
"reflect"
......@@ -32,6 +31,7 @@ import (
"k8s.io/kubernetes/pkg/api/legacyscheme"
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"
)
......@@ -302,8 +302,7 @@ func TestTaint(t *testing.T) {
}
tf.ClientConfigVal = defaultClientConfig()
buf := bytes.NewBuffer([]byte{})
cmd := NewCmdTaint(tf, buf)
cmd := NewCmdTaint(tf, genericclioptions.NewTestIOStreamsDiscard())
saw_fatal := false
func() {
......
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