...

Source file src/k8s.io/kubectl/pkg/cmd/rollout/rollout_history.go

Documentation: k8s.io/kubectl/pkg/cmd/rollout

     1  /*
     2  Copyright 2016 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package rollout
    18  
    19  import (
    20  	"fmt"
    21  	"sort"
    22  
    23  	"github.com/spf13/cobra"
    24  
    25  	"k8s.io/cli-runtime/pkg/genericclioptions"
    26  	"k8s.io/cli-runtime/pkg/genericiooptions"
    27  	"k8s.io/cli-runtime/pkg/printers"
    28  	"k8s.io/cli-runtime/pkg/resource"
    29  	cmdutil "k8s.io/kubectl/pkg/cmd/util"
    30  	"k8s.io/kubectl/pkg/polymorphichelpers"
    31  	"k8s.io/kubectl/pkg/scheme"
    32  	"k8s.io/kubectl/pkg/util/completion"
    33  	"k8s.io/kubectl/pkg/util/i18n"
    34  	"k8s.io/kubectl/pkg/util/templates"
    35  )
    36  
    37  var (
    38  	historyLong = templates.LongDesc(i18n.T(`
    39  		View previous rollout revisions and configurations.`))
    40  
    41  	historyExample = templates.Examples(`
    42  		# View the rollout history of a deployment
    43  		kubectl rollout history deployment/abc
    44  
    45  		# View the details of daemonset revision 3
    46  		kubectl rollout history daemonset/abc --revision=3`)
    47  )
    48  
    49  // RolloutHistoryOptions holds the options for 'rollout history' sub command
    50  type RolloutHistoryOptions struct {
    51  	PrintFlags *genericclioptions.PrintFlags
    52  	ToPrinter  func(string) (printers.ResourcePrinter, error)
    53  
    54  	Revision int64
    55  
    56  	Builder          func() *resource.Builder
    57  	Resources        []string
    58  	Namespace        string
    59  	EnforceNamespace bool
    60  	LabelSelector    string
    61  
    62  	HistoryViewer    polymorphichelpers.HistoryViewerFunc
    63  	RESTClientGetter genericclioptions.RESTClientGetter
    64  
    65  	resource.FilenameOptions
    66  	genericiooptions.IOStreams
    67  }
    68  
    69  // NewRolloutHistoryOptions returns an initialized RolloutHistoryOptions instance
    70  func NewRolloutHistoryOptions(streams genericiooptions.IOStreams) *RolloutHistoryOptions {
    71  	return &RolloutHistoryOptions{
    72  		PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme),
    73  		IOStreams:  streams,
    74  	}
    75  }
    76  
    77  // NewCmdRolloutHistory returns a Command instance for RolloutHistory sub command
    78  func NewCmdRolloutHistory(f cmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command {
    79  	o := NewRolloutHistoryOptions(streams)
    80  
    81  	validArgs := []string{"deployment", "daemonset", "statefulset"}
    82  
    83  	cmd := &cobra.Command{
    84  		Use:                   "history (TYPE NAME | TYPE/NAME) [flags]",
    85  		DisableFlagsInUseLine: true,
    86  		Short:                 i18n.T("View rollout history"),
    87  		Long:                  historyLong,
    88  		Example:               historyExample,
    89  		ValidArgsFunction:     completion.SpecifiedResourceTypeAndNameCompletionFunc(f, validArgs),
    90  		Run: func(cmd *cobra.Command, args []string) {
    91  			cmdutil.CheckErr(o.Complete(f, cmd, args))
    92  			cmdutil.CheckErr(o.Validate())
    93  			cmdutil.CheckErr(o.Run())
    94  		},
    95  	}
    96  
    97  	cmd.Flags().Int64Var(&o.Revision, "revision", o.Revision, "See the details, including podTemplate of the revision specified")
    98  	cmdutil.AddLabelSelectorFlagVar(cmd, &o.LabelSelector)
    99  
   100  	usage := "identifying the resource to get from a server."
   101  	cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
   102  
   103  	o.PrintFlags.AddFlags(cmd)
   104  
   105  	return cmd
   106  }
   107  
   108  // Complete completes al the required options
   109  func (o *RolloutHistoryOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
   110  	o.Resources = args
   111  
   112  	var err error
   113  	if o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace(); err != nil {
   114  		return err
   115  	}
   116  
   117  	o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
   118  		o.PrintFlags.NamePrintFlags.Operation = operation
   119  		return o.PrintFlags.ToPrinter()
   120  	}
   121  
   122  	o.HistoryViewer = polymorphichelpers.HistoryViewerFn
   123  	o.RESTClientGetter = f
   124  	o.Builder = f.NewBuilder
   125  
   126  	return nil
   127  }
   128  
   129  // Validate makes sure all the provided values for command-line options are valid
   130  func (o *RolloutHistoryOptions) Validate() error {
   131  	if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
   132  		return fmt.Errorf("required resource not specified")
   133  	}
   134  	if o.Revision < 0 {
   135  		return fmt.Errorf("revision must be a positive integer: %v", o.Revision)
   136  	}
   137  
   138  	return nil
   139  }
   140  
   141  // Run performs the execution of 'rollout history' sub command
   142  func (o *RolloutHistoryOptions) Run() error {
   143  
   144  	r := o.Builder().
   145  		WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
   146  		NamespaceParam(o.Namespace).DefaultNamespace().
   147  		FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
   148  		LabelSelectorParam(o.LabelSelector).
   149  		ResourceTypeOrNameArgs(true, o.Resources...).
   150  		ContinueOnError().
   151  		Latest().
   152  		Flatten().
   153  		Do()
   154  	if err := r.Err(); err != nil {
   155  		return err
   156  	}
   157  
   158  	if o.PrintFlags.OutputFlagSpecified() {
   159  		printer, err := o.PrintFlags.ToPrinter()
   160  		if err != nil {
   161  			return err
   162  		}
   163  
   164  		return r.Visit(func(info *resource.Info, err error) error {
   165  			if err != nil {
   166  				return err
   167  			}
   168  
   169  			mapping := info.ResourceMapping()
   170  			historyViewer, err := o.HistoryViewer(o.RESTClientGetter, mapping)
   171  			if err != nil {
   172  				return err
   173  			}
   174  			historyInfo, err := historyViewer.GetHistory(info.Namespace, info.Name)
   175  			if err != nil {
   176  				return err
   177  			}
   178  
   179  			if o.Revision > 0 {
   180  				printer.PrintObj(historyInfo[o.Revision], o.Out)
   181  			} else {
   182  				sortedKeys := make([]int64, 0, len(historyInfo))
   183  				for k := range historyInfo {
   184  					sortedKeys = append(sortedKeys, k)
   185  				}
   186  				sort.Slice(sortedKeys, func(i, j int) bool { return sortedKeys[i] < sortedKeys[j] })
   187  				for _, k := range sortedKeys {
   188  					printer.PrintObj(historyInfo[k], o.Out)
   189  				}
   190  			}
   191  
   192  			return nil
   193  		})
   194  	}
   195  
   196  	return r.Visit(func(info *resource.Info, err error) error {
   197  		if err != nil {
   198  			return err
   199  		}
   200  
   201  		mapping := info.ResourceMapping()
   202  		historyViewer, err := o.HistoryViewer(o.RESTClientGetter, mapping)
   203  		if err != nil {
   204  			return err
   205  		}
   206  		historyInfo, err := historyViewer.ViewHistory(info.Namespace, info.Name, o.Revision)
   207  		if err != nil {
   208  			return err
   209  		}
   210  
   211  		withRevision := ""
   212  		if o.Revision > 0 {
   213  			withRevision = fmt.Sprintf("with revision #%d", o.Revision)
   214  		}
   215  
   216  		printer, err := o.ToPrinter(fmt.Sprintf("%s\n%s", withRevision, historyInfo))
   217  		if err != nil {
   218  			return err
   219  		}
   220  
   221  		return printer.PrintObj(info.Object, o.Out)
   222  	})
   223  }
   224  

View as plain text