rollout_history.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. Copyright 2016 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package rollout
  14. import (
  15. "fmt"
  16. "github.com/spf13/cobra"
  17. "k8s.io/cli-runtime/pkg/genericclioptions"
  18. "k8s.io/cli-runtime/pkg/printers"
  19. "k8s.io/cli-runtime/pkg/resource"
  20. cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
  21. "k8s.io/kubernetes/pkg/kubectl/polymorphichelpers"
  22. "k8s.io/kubernetes/pkg/kubectl/scheme"
  23. "k8s.io/kubernetes/pkg/kubectl/util/i18n"
  24. "k8s.io/kubernetes/pkg/kubectl/util/templates"
  25. )
  26. var (
  27. historyLong = templates.LongDesc(`
  28. View previous rollout revisions and configurations.`)
  29. historyExample = templates.Examples(`
  30. # View the rollout history of a deployment
  31. kubectl rollout history deployment/abc
  32. # View the details of daemonset revision 3
  33. kubectl rollout history daemonset/abc --revision=3`)
  34. )
  35. // RolloutHistoryOptions holds the options for 'rollout history' sub command
  36. type RolloutHistoryOptions struct {
  37. PrintFlags *genericclioptions.PrintFlags
  38. ToPrinter func(string) (printers.ResourcePrinter, error)
  39. Revision int64
  40. Builder func() *resource.Builder
  41. Resources []string
  42. Namespace string
  43. EnforceNamespace bool
  44. HistoryViewer polymorphichelpers.HistoryViewerFunc
  45. RESTClientGetter genericclioptions.RESTClientGetter
  46. resource.FilenameOptions
  47. genericclioptions.IOStreams
  48. }
  49. // NewRolloutHistoryOptions returns an initialized RolloutHistoryOptions instance
  50. func NewRolloutHistoryOptions(streams genericclioptions.IOStreams) *RolloutHistoryOptions {
  51. return &RolloutHistoryOptions{
  52. PrintFlags: genericclioptions.NewPrintFlags("").WithTypeSetter(scheme.Scheme),
  53. IOStreams: streams,
  54. }
  55. }
  56. // NewCmdRolloutHistory returns a Command instance for RolloutHistory sub command
  57. func NewCmdRolloutHistory(f cmdutil.Factory, streams genericclioptions.IOStreams) *cobra.Command {
  58. o := NewRolloutHistoryOptions(streams)
  59. validArgs := []string{"deployment", "daemonset", "statefulset"}
  60. cmd := &cobra.Command{
  61. Use: "history (TYPE NAME | TYPE/NAME) [flags]",
  62. DisableFlagsInUseLine: true,
  63. Short: i18n.T("View rollout history"),
  64. Long: historyLong,
  65. Example: historyExample,
  66. Run: func(cmd *cobra.Command, args []string) {
  67. cmdutil.CheckErr(o.Complete(f, cmd, args))
  68. cmdutil.CheckErr(o.Validate())
  69. cmdutil.CheckErr(o.Run())
  70. },
  71. ValidArgs: validArgs,
  72. }
  73. cmd.Flags().Int64Var(&o.Revision, "revision", o.Revision, "See the details, including podTemplate of the revision specified")
  74. usage := "identifying the resource to get from a server."
  75. cmdutil.AddFilenameOptionFlags(cmd, &o.FilenameOptions, usage)
  76. o.PrintFlags.AddFlags(cmd)
  77. return cmd
  78. }
  79. // Complete completes al the required options
  80. func (o *RolloutHistoryOptions) Complete(f cmdutil.Factory, cmd *cobra.Command, args []string) error {
  81. o.Resources = args
  82. var err error
  83. if o.Namespace, o.EnforceNamespace, err = f.ToRawKubeConfigLoader().Namespace(); err != nil {
  84. return err
  85. }
  86. o.ToPrinter = func(operation string) (printers.ResourcePrinter, error) {
  87. o.PrintFlags.NamePrintFlags.Operation = operation
  88. return o.PrintFlags.ToPrinter()
  89. }
  90. o.HistoryViewer = polymorphichelpers.HistoryViewerFn
  91. o.RESTClientGetter = f
  92. o.Builder = f.NewBuilder
  93. return nil
  94. }
  95. // Validate makes sure all the provided values for command-line options are valid
  96. func (o *RolloutHistoryOptions) Validate() error {
  97. if len(o.Resources) == 0 && cmdutil.IsFilenameSliceEmpty(o.Filenames, o.Kustomize) {
  98. return fmt.Errorf("required resource not specified")
  99. }
  100. if o.Revision < 0 {
  101. return fmt.Errorf("revision must be a positive integer: %v", o.Revision)
  102. }
  103. return nil
  104. }
  105. // Run performs the execution of 'rollout history' sub command
  106. func (o *RolloutHistoryOptions) Run() error {
  107. r := o.Builder().
  108. WithScheme(scheme.Scheme, scheme.Scheme.PrioritizedVersionsAllGroups()...).
  109. NamespaceParam(o.Namespace).DefaultNamespace().
  110. FilenameParam(o.EnforceNamespace, &o.FilenameOptions).
  111. ResourceTypeOrNameArgs(true, o.Resources...).
  112. ContinueOnError().
  113. Latest().
  114. Flatten().
  115. Do()
  116. if err := r.Err(); err != nil {
  117. return err
  118. }
  119. return r.Visit(func(info *resource.Info, err error) error {
  120. if err != nil {
  121. return err
  122. }
  123. mapping := info.ResourceMapping()
  124. historyViewer, err := o.HistoryViewer(o.RESTClientGetter, mapping)
  125. if err != nil {
  126. return err
  127. }
  128. historyInfo, err := historyViewer.ViewHistory(info.Namespace, info.Name, o.Revision)
  129. if err != nil {
  130. return err
  131. }
  132. withRevision := ""
  133. if o.Revision > 0 {
  134. withRevision = fmt.Sprintf("with revision #%d", o.Revision)
  135. }
  136. printer, err := o.ToPrinter(fmt.Sprintf("%s\n%s", withRevision, historyInfo))
  137. if err != nil {
  138. return err
  139. }
  140. return printer.PrintObj(info.Object, o.Out)
  141. })
  142. }