Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package pluto for openSUSE:Factory checked 
in at 2023-02-23 16:28:51
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/pluto (Old)
 and      /work/SRC/openSUSE:Factory/.pluto.new.1706 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "pluto"

Thu Feb 23 16:28:51 2023 rev:26 rq:1067396 version:5.15.1

Changes:
--------
--- /work/SRC/openSUSE:Factory/pluto/pluto.changes      2023-02-21 
15:36:57.980605714 +0100
+++ /work/SRC/openSUSE:Factory/.pluto.new.1706/pluto.changes    2023-02-23 
16:53:04.341019635 +0100
@@ -1,0 +2,18 @@
+Thu Feb 23 10:39:17 UTC 2023 - ka...@b1-systems.de
+
+- Update to version 5.15.1:
+  * add: set replacement-available-in to existing version. (#457)
+
+-------------------------------------------------------------------
+Thu Feb 23 10:37:21 UTC 2023 - ka...@b1-systems.de
+
+- Update to version 5.15.0:
+  * Add a `detect-all-in-cluster` command to run both `detect-helm` and 
`detect-api-resources` (#455)
+
+-------------------------------------------------------------------
+Wed Feb 22 17:26:16 UTC 2023 - ka...@b1-systems.de
+
+- Update to version 5.14.0:
+  * add replacement-available-in (#452)
+
+-------------------------------------------------------------------

Old:
----
  pluto-5.13.4.tar.gz

New:
----
  pluto-5.15.1.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ pluto.spec ++++++
--- /var/tmp/diff_new_pack.ofmFj9/_old  2023-02-23 16:53:04.893022836 +0100
+++ /var/tmp/diff_new_pack.ofmFj9/_new  2023-02-23 16:53:04.913022952 +0100
@@ -19,7 +19,7 @@
 %define __arch_install_post export NO_BRP_STRIP_DEBUG=true
 
 Name:           pluto
-Version:        5.13.4
+Version:        5.15.1
 Release:        0
 Summary:        A cli tool to help discover deprecated apiVersions in 
Kubernetes
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.ofmFj9/_old  2023-02-23 16:53:04.957023207 +0100
+++ /var/tmp/diff_new_pack.ofmFj9/_new  2023-02-23 16:53:04.965023253 +0100
@@ -3,7 +3,7 @@
     <param name="url">https://github.com/FairwindsOps/pluto</param>
     <param name="scm">git</param>
     <param name="exclude">.git</param>
-    <param name="revision">v5.13.4</param>
+    <param name="revision">v5.15.1</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="changesgenerate">enable</param>
     <param name="versionrewrite-pattern">v(.*)</param>
@@ -16,7 +16,7 @@
     <param name="compression">gz</param>
   </service>
   <service name="go_modules" mode="disabled">
-    <param name="archive">pluto-5.13.4.tar.gz</param>
+    <param name="archive">pluto-5.15.1.tar.gz</param>
   </service>
 </services>
 

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.ofmFj9/_old  2023-02-23 16:53:04.985023370 +0100
+++ /var/tmp/diff_new_pack.ofmFj9/_new  2023-02-23 16:53:04.993023416 +0100
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param name="url">https://github.com/FairwindsOps/pluto</param>
-              <param 
name="changesrevision">87f16b12344ffa38690a3c252fa3d1a23664c10b</param></service></servicedata>
+              <param 
name="changesrevision">cf69d915f3bcb2c54c55b2b7a5c0a6bbce7f78c8</param></service></servicedata>
 (No newline at EOF)
 

++++++ pluto-5.13.4.tar.gz -> pluto-5.15.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/cmd/root.go new/pluto-5.15.1/cmd/root.go
--- old/pluto-5.13.4/cmd/root.go        2023-02-20 18:46:37.000000000 +0100
+++ new/pluto-5.15.1/cmd/root.go        2023-02-22 22:11:39.000000000 +0100
@@ -48,23 +48,24 @@
 )
 
 var (
-       version                string
-       versionCommit          string
-       versionFileData        []byte
-       additionalVersionsFile string
-       directory              string
-       outputFormat           string
-       ignoreDeprecations     bool
-       ignoreRemovals         bool
-       namespace              string
-       apiInstance            *api.Instance
-       targetVersions         map[string]string
-       customColumns          []string
-       componentsFromUser     []string
-       onlyShowRemoved        bool
-       kubeContext            string
-       noHeaders              bool
-       exitCode               int
+       version                       string
+       versionCommit                 string
+       versionFileData               []byte
+       additionalVersionsFile        string
+       directory                     string
+       outputFormat                  string
+       ignoreDeprecations            bool
+       ignoreRemovals                bool
+       ignoreUnavailableReplacements bool
+       namespace                     string
+       apiInstance                   *api.Instance
+       targetVersions                map[string]string
+       customColumns                 []string
+       componentsFromUser            []string
+       onlyShowRemoved               bool
+       kubeContext                   string
+       noHeaders                     bool
+       exitCode                      int
 )
 
 const (
@@ -84,6 +85,7 @@
 func init() {
        rootCmd.PersistentFlags().BoolVar(&ignoreDeprecations, 
"ignore-deprecations", false, "Ignore the default behavior to exit 2 if 
deprecated apiVersions are found.")
        rootCmd.PersistentFlags().BoolVar(&ignoreRemovals, "ignore-removals", 
false, "Ignore the default behavior to exit 3 if removed apiVersions are 
found.")
+       rootCmd.PersistentFlags().BoolVar(&ignoreUnavailableReplacements, 
"ignore-unavailable-replacements", false, "Ignore the default behavior to exit 
4 if deprecated but unavailable apiVersions are found.")
        rootCmd.PersistentFlags().BoolVarP(&onlyShowRemoved, 
"only-show-removed", "r", false, "Only display the apiVersions that have been 
removed in the target version.")
        rootCmd.PersistentFlags().BoolVarP(&noHeaders, "no-headers", "H", 
false, "When using the default or custom-column output format, don't print 
headers (default print headers).")
        rootCmd.PersistentFlags().StringVarP(&additionalVersionsFile, 
"additional-versions", "f", "", "Additional deprecated versions file to add to 
the list. Cannot contain any existing versions")
@@ -103,6 +105,10 @@
        detectApiResourceCmd.PersistentFlags().StringVarP(&namespace, 
"namespace", "n", "", "Only detect resources in a specific namespace.")
        detectApiResourceCmd.PersistentFlags().StringVar(&kubeContext, 
"kube-context", "", "The kube context to use. If blank, defaults to current 
context.")
 
+       rootCmd.AddCommand(detectAllInClusterCmd)
+       detectAllInClusterCmd.PersistentFlags().StringVarP(&namespace, 
"namespace", "n", "", "Only detect resources in a specific namespace.")
+       detectAllInClusterCmd.PersistentFlags().StringVar(&kubeContext, 
"kube-context", "", "The kube context to use. If blank, defaults to current 
context.")
+
        rootCmd.AddCommand(listVersionsCmd)
        rootCmd.AddCommand(detectCmd)
 
@@ -268,15 +274,16 @@
 
                // this apiInstance will be used by all detection methods
                apiInstance = &api.Instance{
-                       TargetVersions:     targetVersions,
-                       OutputFormat:       outputFormat,
-                       CustomColumns:      customColumns,
-                       IgnoreDeprecations: ignoreDeprecations,
-                       IgnoreRemovals:     ignoreRemovals,
-                       OnlyShowRemoved:    onlyShowRemoved,
-                       NoHeaders:          noHeaders,
-                       DeprecatedVersions: deprecatedVersionList,
-                       Components:         componentList,
+                       TargetVersions:                targetVersions,
+                       OutputFormat:                  outputFormat,
+                       CustomColumns:                 customColumns,
+                       IgnoreDeprecations:            ignoreDeprecations,
+                       IgnoreRemovals:                ignoreRemovals,
+                       IgnoreUnavailableReplacements: 
ignoreUnavailableReplacements,
+                       OnlyShowRemoved:               onlyShowRemoved,
+                       NoHeaders:                     noHeaders,
+                       DeprecatedVersions:            deprecatedVersionList,
+                       Components:                    componentList,
                }
 
                return nil
@@ -309,24 +316,19 @@
        Short: "detect-helm",
        Long:  `Detect Kubernetes apiVersions in a helm release (in cluster)`,
        Run: func(cmd *cobra.Command, args []string) {
-               h, err := helm.NewHelm(namespace, kubeContext, apiInstance)
+               err := detectHelm()
                if err != nil {
-                       fmt.Printf("error getting helm configuration: %s\n", 
err.Error())
-                       os.Exit(1)
-               }
-               err = h.FindVersions()
-               if err != nil {
-                       fmt.Println("Error running helm-detect:", err)
+                       fmt.Println(err)
                        os.Exit(1)
                }
                err = apiInstance.DisplayOutput()
                if err != nil {
-                       fmt.Println("Error Parsing Output:", err)
+                       fmt.Printf("Error Parsing Output: %v\n", err)
                        os.Exit(1)
                }
-               retCode := apiInstance.GetReturnCode()
-               klog.V(5).Infof("retCode: %d", retCode)
-               os.Exit(retCode)
+               exitCode := apiInstance.GetReturnCode()
+               klog.V(5).Infof("retCode: %d", exitCode)
+               os.Exit(exitCode)
        },
 }
 
@@ -335,23 +337,48 @@
        Short: "detect-api-resources",
        Long:  `Detect Kubernetes apiVersions from an active cluster (using 
last-applied-configuration annotation)`,
        Run: func(cmd *cobra.Command, args []string) {
-               disCl, err := discoveryapi.NewDiscoveryClient(namespace, 
kubeContext, apiInstance)
+               err := detectAPIResources()
+               if err != nil {
+                       fmt.Println(err)
+                       os.Exit(1)
+               }
+               err = apiInstance.DisplayOutput()
+               if err != nil {
+                       fmt.Printf("Error Parsing Output: %v\n", err)
+                       os.Exit(1)
+               }
+               exitCode := apiInstance.GetReturnCode()
+               klog.V(5).Infof("retCode: %d", exitCode)
+               os.Exit(exitCode)
+       },
+}
+
+var detectAllInClusterCmd = &cobra.Command{
+       Use:   "detect-all-in-cluster",
+       Short: "run all in-cluster detections",
+       Long:  `Detect Kubernetes apiVersions from an active cluster using all 
available methods (Helm releases, using the last-applied-configuration 
annotation)`,
+       Run: func(cmd *cobra.Command, args []string) {
+               err := detectHelm()
                if err != nil {
-                       fmt.Println("Error creating Discovery REST Client: ", 
err)
+                       fmt.Println(err)
                        os.Exit(1)
                }
-               err = disCl.GetApiResources()
+               klog.V(5).Infof("after running detect-helm, exit-code is %d, 
and there are %d output items", apiInstance.GetReturnCode(), 
len(apiInstance.Outputs))
+               err = detectAPIResources()
                if err != nil {
-                       fmt.Println("Error getting API resources using 
discovery client:", err)
+                       fmt.Println(err)
                        os.Exit(1)
                }
+               klog.V(5).Infof("after running detect-api-resources, exit-code 
is %d, and there are %d output items", apiInstance.GetReturnCode(), 
len(apiInstance.Outputs))
+
                err = apiInstance.DisplayOutput()
                if err != nil {
-                       fmt.Println("Error Parsing Output:", err)
+                       fmt.Printf("Error Parsing Output: %v\n", err)
                        os.Exit(1)
                }
-               exitCode = apiInstance.GetReturnCode()
+               exitCode := apiInstance.GetReturnCode()
                klog.V(5).Infof("retCode: %d", exitCode)
+               os.Exit(exitCode)
        },
 }
 
@@ -438,3 +465,27 @@
                os.Exit(1)
        }
 }
+
+func detectHelm() error {
+       h, err := helm.NewHelm(namespace, kubeContext, apiInstance)
+       if err != nil {
+               return fmt.Errorf("error getting helm configuration: %v", err)
+       }
+       err = h.FindVersions()
+       if err != nil {
+               return fmt.Errorf("Error running helm-detect: %v", err)
+       }
+       return nil
+}
+
+func detectAPIResources() error {
+       disCl, err := discoveryapi.NewDiscoveryClient(namespace, kubeContext, 
apiInstance)
+       if err != nil {
+               return fmt.Errorf("Error creating Discovery REST Client: %v", 
err)
+       }
+       err = disCl.GetApiResources()
+       if err != nil {
+               return fmt.Errorf("Error getting API resources using discovery 
client: %v", err)
+       }
+       return nil
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/docs/quickstart.md 
new/pluto-5.15.1/docs/quickstart.md
--- old/pluto-5.13.4/docs/quickstart.md 2023-02-20 18:46:37.000000000 +0100
+++ new/pluto-5.15.1/docs/quickstart.md 2023-02-22 22:11:39.000000000 +0100
@@ -61,3 +61,15 @@
 ```
 
 This indicates that the PodSecurityPolicy  was deployed with apps/v1beta1 
which is deprecated in 1.21
+
+### helm and API resources (in-cluster)
+
+```
+$ pluto detect-all-in-cluster -o wide 2>/dev/null
+NAME              NAMESPACE   KIND                VERSION                     
REPLACEMENT            DEPRECATED   DEPRECATED IN   REMOVED   REMOVED IN  
+testing/viahelm   viahelm     Ingress             networking.k8s.io/v1beta1   
networking.k8s.io/v1   true         v1.19.0         true      v1.22.0     
+webapp            default     Ingress             networking.k8s.io/v1beta1   
networking.k8s.io/v1   true         v1.19.0         true      v1.22.0     
+eks.privileged    <UNKNOWN>   PodSecurityPolicy   policy/v1beta1               
                      true         v1.21.0         false     v1.25.0     
+```
+
+This combines all available in-cluster detections, showing results from Helm 
releases and API resources.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/e2e/tests/01_helm-detect-3.yaml 
new/pluto-5.15.1/e2e/tests/01_helm-detect-3.yaml
--- old/pluto-5.13.4/e2e/tests/01_helm-detect-3.yaml    2023-02-20 
18:46:37.000000000 +0100
+++ new/pluto-5.15.1/e2e/tests/01_helm-detect-3.yaml    2023-02-22 
22:11:39.000000000 +0100
@@ -57,7 +57,7 @@
   - script: pluto detect-helm  -ojson --target-versions k8s=v1.16.0
     assertions:
     - result.code ShouldEqual 3
-    - result.systemout ShouldEqual 
{"items":[{"name":"test/test-helm3chart-v1beta1","namespace":"default","api":{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","component":"k8s"},"deprecated":true,"removed":true},{"name":"test/test-helm3chart-v1beta1","namespace":"demo2","api":{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","component":"k8s"},"deprecated":true,"removed":true}],"target-versions":{"cert-manager":"v1.5.3","istio":"v1.11.0","k8s":"v1.16.0"}}
+    - result.systemout ShouldEqual 
{"items":[{"name":"test/test-helm3chart-v1beta1","namespace":"default","api":{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","replacement-available-in":"v1.9.0","component":"k8s"},"deprecated":true,"removed":true,"replacementAvailable":true},{"name":"test/test-helm3chart-v1beta1","namespace":"demo2","api":{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","replacement-available-in":"v1.9.0","component":"k8s"},"deprecated":true,"removed":true,"replacementAvailable":true}],"target-versions":{"cert-manager":"v1.5.3","istio":"v1.11.0","k8s":"v1.16.0"}}
 
 - name: helm detect --kube-context=doesnotexist
   steps:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/pkg/api/columns.go 
new/pluto-5.15.1/pkg/api/columns.go
--- old/pluto-5.13.4/pkg/api/columns.go 2023-02-20 18:46:37.000000000 +0100
+++ new/pluto-5.15.1/pkg/api/columns.go 2023-02-22 22:11:39.000000000 +0100
@@ -24,7 +24,7 @@
 
 type columnList map[int]column
 
-//PossibleColumnNames is the list of implmented columns
+// PossibleColumnNames is the list of implmented columns
 var PossibleColumnNames = []string{
        "NAME",
        "FILEPATH",
@@ -37,6 +37,8 @@
        "REMOVED",
        "REMOVED IN",
        "COMPONENT",
+       "REPL AVAIL",
+       "REPL AVAIL IN",
 }
 
 var possibleColumns = []column{
@@ -129,6 +131,22 @@
 func (c component) header() string              { return "COMPONENT" }
 func (c component) value(output *Output) string { return 
output.APIVersion.Component }
 
+// replacementAvailable is the output for the boolean ReplacementAvailable
+type replacementAvailable struct{}
+
+func (ra replacementAvailable) header() string { return "REPL AVAIL" }
+func (ra replacementAvailable) value(output *Output) string {
+       return fmt.Sprintf("%t", output.ReplacementAvailable)
+}
+
+// replacementAvailableIn is the string value of when an output was 
ReplacementAvailableIn
+type replacementAvailableIn struct{}
+
+func (rai replacementAvailableIn) header() string { return "REPL AVAIL IN" }
+func (rai replacementAvailableIn) value(output *Output) string {
+       return output.APIVersion.ReplacementAvailableIn
+}
+
 // normalColumns returns the list of columns for -onormal
 func (instance *Instance) normalColumns() columnList {
        columnList := columnList{
@@ -138,6 +156,7 @@
                3: new(replacement),
                4: new(removed),
                5: new(deprecated),
+               6: new(replacementAvailable),
        }
        return columnList
 }
@@ -145,15 +164,17 @@
 // wideColumns returns the list of columns for -owide
 func (instance *Instance) wideColumns() columnList {
        columnList := columnList{
-               0: new(name),
-               1: new(namespace),
-               2: new(kind),
-               3: new(version),
-               4: new(replacement),
-               5: new(deprecated),
-               6: new(deprecatedIn),
-               7: new(removed),
-               8: new(removedIn),
+               0:  new(name),
+               1:  new(namespace),
+               2:  new(kind),
+               3:  new(version),
+               4:  new(replacement),
+               5:  new(deprecated),
+               6:  new(deprecatedIn),
+               7:  new(removed),
+               8:  new(removedIn),
+               9:  new(replacementAvailable),
+               10: new(replacementAvailableIn),
        }
        return columnList
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/pkg/api/output.go 
new/pluto-5.15.1/pkg/api/output.go
--- old/pluto-5.13.4/pkg/api/output.go  2023-02-20 18:46:37.000000000 +0100
+++ new/pluto-5.15.1/pkg/api/output.go  2023-02-22 22:11:39.000000000 +0100
@@ -45,22 +45,25 @@
        Deprecated bool `json:"deprecated" yaml:"deprecated"`
        // Removed is a boolean indicating whether or not the version has been 
removed
        Removed bool `json:"removed" yaml:"removed"`
+       // ReplacementAvailable is a boolean indicating whether or not the 
replacement is available
+       ReplacementAvailable bool `json:"replacementAvailable" 
yaml:"replacementAvailable"`
        // CustomColumns is a list of column headers to be displayed with 
-ocustom or -omarkdown
        CustomColumns []string `json:"-" yaml:"-"`
 }
 
 // Instance is an instance of the API. This holds configuration for a "run" of 
Pluto
 type Instance struct {
-       Outputs            []*Output         `json:"items,omitempty" 
yaml:"items,omitempty"`
-       IgnoreDeprecations bool              `json:"-" yaml:"-"`
-       IgnoreRemovals     bool              `json:"-" yaml:"-"`
-       OnlyShowRemoved    bool              `json:"-" yaml:"-"`
-       NoHeaders          bool              `json:"-" yaml:"-"`
-       OutputFormat       string            `json:"-" yaml:"-"`
-       TargetVersions     map[string]string `json:"target-versions,omitempty" 
yaml:"target-versions,omitempty"`
-       DeprecatedVersions []Version         `json:"-" yaml:"-"`
-       CustomColumns      []string          `json:"-" yaml:"-"`
-       Components         []string          `json:"-" yaml:"-"`
+       Outputs                       []*Output         `json:"items,omitempty" 
yaml:"items,omitempty"`
+       IgnoreDeprecations            bool              `json:"-" yaml:"-"`
+       IgnoreRemovals                bool              `json:"-" yaml:"-"`
+       IgnoreUnavailableReplacements bool              `json:"-" yaml:"-"`
+       OnlyShowRemoved               bool              `json:"-" yaml:"-"`
+       NoHeaders                     bool              `json:"-" yaml:"-"`
+       OutputFormat                  string            `json:"-" yaml:"-"`
+       TargetVersions                map[string]string 
`json:"target-versions,omitempty" yaml:"target-versions,omitempty"`
+       DeprecatedVersions            []Version         `json:"-" yaml:"-"`
+       CustomColumns                 []string          `json:"-" yaml:"-"`
+       Components                    []string          `json:"-" yaml:"-"`
 }
 
 // DisplayOutput prints the output based on desired variables
@@ -155,6 +158,7 @@
        for _, output := range instance.Outputs {
                output.Deprecated = 
output.APIVersion.isDeprecatedIn(instance.TargetVersions)
                output.Removed = 
output.APIVersion.isRemovedIn(instance.TargetVersions)
+               output.ReplacementAvailable = 
output.APIVersion.isReplacementAvailableIn(instance.TargetVersions)
                switch instance.OnlyShowRemoved {
                case false:
                        if output.Deprecated || output.Removed {
@@ -298,23 +302,34 @@
 // takes a boolean to ignore any errors.
 // exit 2 - version deprecated
 // exit 3 - version removed
+// exit 4 - replacement is unavailable in target version
 func (instance *Instance) GetReturnCode() int {
        returnCode := 0
        var deprecations int
        var removals int
+       var unavailableReplacements int
        for _, output := range instance.Outputs {
                if output.APIVersion.isRemovedIn(instance.TargetVersions) {
                        removals = removals + 1
                }
                if output.APIVersion.isDeprecatedIn(instance.TargetVersions) {
-                       deprecations = deprecations + 1
+                       if 
output.APIVersion.isReplacementAvailableIn(instance.TargetVersions) || 
!instance.IgnoreUnavailableReplacements {
+                               deprecations = deprecations + 1
+                       }
+               }
+               if 
!output.APIVersion.isReplacementAvailableIn(instance.TargetVersions) {
+                       unavailableReplacements = unavailableReplacements + 1
                }
        }
+
        if deprecations > 0 && !instance.IgnoreDeprecations {
                returnCode = 2
        }
        if removals > 0 && !instance.IgnoreRemovals {
                returnCode = 3
        }
+       if unavailableReplacements > 0 && 
!instance.IgnoreUnavailableReplacements {
+               returnCode = 4
+       }
        return returnCode
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/pkg/api/output_test.go 
new/pluto-5.15.1/pkg/api/output_test.go
--- old/pluto-5.13.4/pkg/api/output_test.go     2023-02-20 18:46:37.000000000 
+0100
+++ new/pluto-5.15.1/pkg/api/output_test.go     2023-02-22 22:11:39.000000000 
+0100
@@ -39,35 +39,38 @@
        Namespace: "pluto-namespace",
        FilePath:  "path-to-file",
        APIVersion: &Version{
-               Name:           "extensions/v1beta1",
-               Kind:           "Deployment",
-               DeprecatedIn:   "v1.9.0",
-               RemovedIn:      "v1.16.0",
-               ReplacementAPI: "apps/v1",
-               Component:      "foo",
+               Name:                   "extensions/v1beta1",
+               Kind:                   "Deployment",
+               DeprecatedIn:           "v1.9.0",
+               RemovedIn:              "v1.16.0",
+               ReplacementAPI:         "apps/v1",
+               ReplacementAvailableIn: "v1.10.0",
+               Component:              "foo",
        },
 }
 var testOutput2 = &Output{
        Name: "some name two",
        APIVersion: &Version{
-               Name:           "extensions/v1beta1",
-               Kind:           "Deployment",
-               DeprecatedIn:   "v1.9.0",
-               RemovedIn:      "v1.16.0",
-               ReplacementAPI: "apps/v1",
-               Component:      "foo",
+               Name:                   "extensions/v1beta1",
+               Kind:                   "Deployment",
+               DeprecatedIn:           "v1.9.0",
+               RemovedIn:              "v1.16.0",
+               ReplacementAPI:         "apps/v1",
+               ReplacementAvailableIn: "v1.10.0",
+               Component:              "foo",
        },
 }
 
 var testOutputNoOutput = &Output{
        Name: "not a deprecated object",
        APIVersion: &Version{
-               Name:           "apps/v1",
-               Kind:           "Deployment",
-               DeprecatedIn:   "",
-               RemovedIn:      "",
-               ReplacementAPI: "",
-               Component:      "foo",
+               Name:                   "apps/v1",
+               Kind:                   "Deployment",
+               DeprecatedIn:           "",
+               RemovedIn:              "",
+               ReplacementAPI:         "",
+               ReplacementAvailableIn: "",
+               Component:              "foo",
        },
 }
 
@@ -103,10 +106,10 @@
        _ = instance.DisplayOutput()
 
        // Output:
-       // NAME-------------------- KIND-------- VERSION------------- 
REPLACEMENT-- REMOVED-- DEPRECATED--
-       // some name one----------- Deployment-- extensions/v1beta1-- 
apps/v1------ true----- true--------
-       // some name two----------- Deployment-- extensions/v1beta1-- 
apps/v1------ true----- true--------
-       // deprecated not removed-- Deployment-- apps/v1------------- 
none--------- false---- true--------
+       // NAME-------------------- KIND-------- VERSION------------- 
REPLACEMENT-- REMOVED-- DEPRECATED-- REPL AVAIL--
+       // some name one----------- Deployment-- extensions/v1beta1-- 
apps/v1------ true----- true-------- true--------
+       // some name two----------- Deployment-- extensions/v1beta1-- 
apps/v1------ true----- true-------- true--------
+       // deprecated not removed-- Deployment-- apps/v1------------- 
none--------- false---- true-------- true--------
 }
 
 func ExampleInstance_DisplayOutput_onlyShowRemoved() {
@@ -126,9 +129,9 @@
        _ = instance.DisplayOutput()
 
        // Output:
-       // NAME----------- KIND-------- VERSION------------- REPLACEMENT-- 
REMOVED-- DEPRECATED--
-       // some name one-- Deployment-- extensions/v1beta1-- apps/v1------ 
true----- true--------
-       // some name two-- Deployment-- extensions/v1beta1-- apps/v1------ 
true----- true--------
+       // NAME----------- KIND-------- VERSION------------- REPLACEMENT-- 
REMOVED-- DEPRECATED-- REPL AVAIL--
+       // some name one-- Deployment-- extensions/v1beta1-- apps/v1------ 
true----- true-------- true--------
+       // some name two-- Deployment-- extensions/v1beta1-- apps/v1------ 
true----- true-------- true--------
 }
 
 func ExampleInstance_DisplayOutput_wide() {
@@ -146,9 +149,9 @@
        _ = instance.DisplayOutput()
 
        // Output:
-       // NAME----------- NAMESPACE-------- KIND-------- VERSION------------- 
REPLACEMENT-- DEPRECATED-- DEPRECATED IN-- REMOVED-- REMOVED IN--
-       // some name one-- pluto-namespace-- Deployment-- extensions/v1beta1-- 
apps/v1------ true-------- v1.9.0--------- true----- v1.16.0-----
-       // some name two-- <UNKNOWN>-------- Deployment-- extensions/v1beta1-- 
apps/v1------ true-------- v1.9.0--------- true----- v1.16.0-----
+       // NAME----------- NAMESPACE-------- KIND-------- VERSION------------- 
REPLACEMENT-- DEPRECATED-- DEPRECATED IN-- REMOVED-- REMOVED IN-- REPL AVAIL-- 
REPL AVAIL IN--
+       // some name one-- pluto-namespace-- Deployment-- extensions/v1beta1-- 
apps/v1------ true-------- v1.9.0--------- true----- v1.16.0----- true-------- 
v1.10.0--------
+       // some name two-- <UNKNOWN>-------- Deployment-- extensions/v1beta1-- 
apps/v1------ true-------- v1.9.0--------- true----- v1.16.0----- true-------- 
v1.10.0--------
 }
 
 func ExampleInstance_DisplayOutput_custom() {
@@ -187,10 +190,10 @@
        _ = instance.DisplayOutput()
 
        // Output:
-       // |     NAME      |    NAMESPACE    |    KIND    |      VERSION       
| REPLACEMENT | DEPRECATED | DEPRECATED IN | REMOVED | REMOVED IN |
-       // 
|---------------|-----------------|------------|--------------------|-------------|------------|---------------|---------|------------|
-       // | some name one | pluto-namespace | Deployment | extensions/v1beta1 
| apps/v1     | true       | v1.9.0        | true    | v1.16.0    |
-       // | some name two | <UNKNOWN>       | Deployment | extensions/v1beta1 
| apps/v1     | true       | v1.9.0        | true    | v1.16.0    |
+       // |     NAME      |    NAMESPACE    |    KIND    |      VERSION       
| REPLACEMENT | DEPRECATED | DEPRECATED IN | REMOVED | REMOVED IN | REPL AVAIL 
| REPL AVAIL IN |
+       // 
|---------------|-----------------|------------|--------------------|-------------|------------|---------------|---------|------------|------------|---------------|
+       // | some name one | pluto-namespace | Deployment | extensions/v1beta1 
| apps/v1     | true       | v1.9.0        | true    | v1.16.0    | true       
| v1.10.0       |
+       // | some name two | <UNKNOWN>       | Deployment | extensions/v1beta1 
| apps/v1     | true       | v1.9.0        | true    | v1.16.0    | true       
| v1.10.0       |
 }
 
 func ExampleInstance_DisplayOutput_markdown_customcolumns() {
@@ -230,7 +233,7 @@
        _ = instance.DisplayOutput()
 
        // Output:
-       // {"items":[{"name":"some name 
one","filePath":"path-to-file","namespace":"pluto-namespace","api":{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","component":"foo"},"deprecated":true,"removed":true},{"name":"some
 name 
two","api":{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","component":"foo"},"deprecated":true,"removed":true}],"target-versions":{"foo":"v1.16.0"}}
+       // {"items":[{"name":"some name 
one","filePath":"path-to-file","namespace":"pluto-namespace","api":{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","replacement-available-in":"v1.10.0","component":"foo"},"deprecated":true,"removed":true,"replacementAvailable":true},{"name":"some
 name 
two","api":{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","replacement-available-in":"v1.10.0","component":"foo"},"deprecated":true,"removed":true,"replacementAvailable":true}],"target-versions":{"foo":"v1.16.0"}}
 }
 
 func ExampleInstance_DisplayOutput_yaml() {
@@ -258,9 +261,11 @@
        //         deprecated-in: v1.9.0
        //         removed-in: v1.16.0
        //         replacement-api: apps/v1
+       //         replacement-available-in: v1.10.0
        //         component: foo
        //       deprecated: true
        //       removed: true
+       //       replacementAvailable: true
        //     - name: some name two
        //       api:
        //         version: extensions/v1beta1
@@ -268,9 +273,11 @@
        //         deprecated-in: v1.9.0
        //         removed-in: v1.16.0
        //         replacement-api: apps/v1
+       //         replacement-available-in: v1.10.0
        //         component: foo
        //       deprecated: true
        //       removed: true
+       //       replacementAvailable: true
        // target-versions:
        //     foo: v1.16.0
 }
@@ -290,9 +297,9 @@
        _ = instance.DisplayOutput()
 
        // Output:
-       // NAME,NAMESPACE,KIND,VERSION,REPLACEMENT,DEPRECATED,DEPRECATED 
IN,REMOVED,REMOVED IN
-       // some name 
one,pluto-namespace,Deployment,extensions/v1beta1,apps/v1,true,v1.9.0,true,v1.16.0
-       // some name 
two,<UNKNOWN>,Deployment,extensions/v1beta1,apps/v1,true,v1.9.0,true,v1.16.0
+       // NAME,NAMESPACE,KIND,VERSION,REPLACEMENT,DEPRECATED,DEPRECATED 
IN,REMOVED,REMOVED IN,REPL AVAIL,REPL AVAIL IN
+       // some name 
one,pluto-namespace,Deployment,extensions/v1beta1,apps/v1,true,v1.9.0,true,v1.16.0,true,v1.10.0
+       // some name 
two,<UNKNOWN>,Deployment,extensions/v1beta1,apps/v1,true,v1.9.0,true,v1.16.0,true,v1.10.0
 }
 
 func ExampleInstance_DisplayOutput_csv_customcolumns() {
@@ -332,8 +339,8 @@
        _ = instance.DisplayOutput()
 
        // Output:
-       // some name 
one,pluto-namespace,Deployment,extensions/v1beta1,apps/v1,true,v1.9.0,true,v1.16.0
-       // some name 
two,<UNKNOWN>,Deployment,extensions/v1beta1,apps/v1,true,v1.9.0,true,v1.16.0
+       // some name 
one,pluto-namespace,Deployment,extensions/v1beta1,apps/v1,true,v1.9.0,true,v1.16.0,true,v1.10.0
+       // some name 
two,<UNKNOWN>,Deployment,extensions/v1beta1,apps/v1,true,v1.9.0,true,v1.16.0,true,v1.10.0
 }
 
 func ExampleInstance_DisplayOutput_noOutput() {
@@ -368,9 +375,10 @@
 func TestGetReturnCode(t *testing.T) {
 
        type args struct {
-               outputs            []*Output
-               ignoreDeprecations bool
-               ignoreRemovals     bool
+               outputs                      []*Output
+               ignoreDeprecations           bool
+               ignoreRemovals               bool
+               ignoreReplacementUnavailable bool
        }
        tests := []struct {
                name string
@@ -380,13 +388,15 @@
                {
                        name: "empty return zero",
                        args: args{
-                               outputs:            []*Output{},
-                               ignoreDeprecations: false,
+                               outputs:                      []*Output{},
+                               ignoreDeprecations:           false,
+                               ignoreRemovals:               false,
+                               ignoreReplacementUnavailable: false,
                        },
                        want: 0,
                },
                {
-                       name: "version is deprecated return one",
+                       name: "version is deprecated return two",
                        args: args{
                                outputs: []*Output{
                                        {
@@ -397,8 +407,9 @@
                                                },
                                        },
                                },
-                               ignoreDeprecations: false,
-                               ignoreRemovals:     false,
+                               ignoreDeprecations:           false,
+                               ignoreRemovals:               false,
+                               ignoreReplacementUnavailable: false,
                        },
                        want: 2,
                },
@@ -414,8 +425,9 @@
                                                },
                                        },
                                },
-                               ignoreDeprecations: true,
-                               ignoreRemovals:     false,
+                               ignoreDeprecations:           true,
+                               ignoreRemovals:               false,
+                               ignoreReplacementUnavailable: false,
                        },
                        want: 0,
                },
@@ -431,10 +443,67 @@
                                                },
                                        },
                                },
+                               ignoreDeprecations:           false,
+                               ignoreRemovals:               false,
+                               ignoreReplacementUnavailable: false,
+                       },
+                       want: 3,
+               },
+               {
+                       name: "version is removed and replacement is 
unavailable",
+                       args: args{
+                               outputs: []*Output{
+                                       {
+                                               APIVersion: &Version{
+                                                       DeprecatedIn:           
"v1.16.0",
+                                                       RemovedIn:              
"v1.16.0",
+                                                       ReplacementAvailableIn: 
"v1.17.0",
+                                                       Component:              
"foo",
+                                               },
+                                       },
+                               },
+                               ignoreDeprecations:           false,
+                               ignoreRemovals:               false,
+                               ignoreReplacementUnavailable: true,
+                       },
+                       want: 3,
+               },
+               {
+                       name: "version is deprecated and replacement is 
unavailable",
+                       args: args{
+                               outputs: []*Output{
+                                       {
+                                               APIVersion: &Version{
+                                                       DeprecatedIn:           
"v1.16.0",
+                                                       RemovedIn:              
"v1.20.0",
+                                                       ReplacementAvailableIn: 
"v1.17.0",
+                                                       Component:              
"foo",
+                                               },
+                                       },
+                               },
                                ignoreDeprecations: false,
                                ignoreRemovals:     false,
                        },
-                       want: 3,
+                       want: 4,
+               },
+               {
+                       name: "version is deprecated and replacement is 
unavailable but ignored",
+                       args: args{
+                               outputs: []*Output{
+                                       {
+                                               APIVersion: &Version{
+                                                       DeprecatedIn:           
"v1.16.0",
+                                                       RemovedIn:              
"v1.20.0",
+                                                       ReplacementAvailableIn: 
"v1.17.0",
+                                                       Component:              
"foo",
+                                               },
+                                       },
+                               },
+                               ignoreDeprecations:           false,
+                               ignoreRemovals:               false,
+                               ignoreReplacementUnavailable: true,
+                       },
+                       want: 0,
                },
        }
        for _, tt := range tests {
@@ -443,9 +512,10 @@
                                TargetVersions: map[string]string{
                                        "foo": "v1.16.0",
                                },
-                               IgnoreDeprecations: tt.args.ignoreDeprecations,
-                               IgnoreRemovals:     tt.args.ignoreRemovals,
-                               Outputs:            tt.args.outputs,
+                               IgnoreDeprecations:            
tt.args.ignoreDeprecations,
+                               IgnoreRemovals:                
tt.args.ignoreRemovals,
+                               IgnoreUnavailableReplacements: 
tt.args.ignoreReplacementUnavailable,
+                               Outputs:                       tt.args.outputs,
                        }
                        got := instance.GetReturnCode()
                        assert.Equal(t, tt.want, got)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/pkg/api/versions.go 
new/pluto-5.15.1/pkg/api/versions.go
--- old/pluto-5.13.4/pkg/api/versions.go        2023-02-20 18:46:37.000000000 
+0100
+++ new/pluto-5.15.1/pkg/api/versions.go        2023-02-22 22:11:39.000000000 
+0100
@@ -70,6 +70,8 @@
        RemovedIn string `json:"removed-in" yaml:"removed-in"`
        // ReplacementAPI is the apiVersion that replaces the deprecated one
        ReplacementAPI string `json:"replacement-api" yaml:"replacement-api"`
+       // ReplacementAvailableIn is the version in which the replacement api 
is available
+       ReplacementAvailableIn string `json:"replacement-available-in" 
yaml:"replacement-available-in"`
        // Component is the component associated with this version
        Component string `json:"component" yaml:"component"`
 }
@@ -240,6 +242,30 @@
        return comparison >= 0
 }
 
+// isReplacementAvailableIn returns true if the replacement api is available 
in the applicable targetVersion
+// Will return false if the targetVersion passed is not a valid semver string
+func (v *Version) isReplacementAvailableIn(targetVersions map[string]string) 
bool {
+       for component, targetVersion := range targetVersions {
+               if !semver.IsValid(targetVersion) {
+                       klog.V(3).Infof("targetVersion %s for %s is not valid 
semVer", targetVersion, component)
+                       return false
+               }
+       }
+
+       if v.ReplacementAvailableIn == "" {
+               return true
+       }
+
+       targetVersion, ok := targetVersions[v.Component]
+       if !ok {
+               klog.V(3).Infof("targetVersion missing for component %s", 
v.Component)
+               return false
+       }
+
+       comparison := semver.Compare(targetVersion, v.ReplacementAvailableIn)
+       return comparison >= 0
+}
+
 // PrintVersionList prints out the list of versions
 // in a specific format
 func (instance *Instance) PrintVersionList(outputFormat string) error {
@@ -282,7 +308,7 @@
        w.Init(os.Stdout, 0, 15, 2, padChar, 0)
 
        if !instance.NoHeaders {
-               fmt.Fprintln(w, "KIND\t NAME\t DEPRECATED IN\t REMOVED IN\t 
REPLACEMENT\t COMPONENT\t")
+               fmt.Fprintln(w, "KIND\t NAME\t DEPRECATED IN\t REMOVED IN\t 
REPLACEMENT\t REPL AVAIL IN\t COMPONENT\t")
        }
 
        for _, version := range instance.DeprecatedVersions {
@@ -300,7 +326,12 @@
                        replacementAPI = "n/a"
                }
 
-               _, _ = fmt.Fprintf(w, "%s\t %s\t %s\t %s\t %s\t %s\t\n", 
version.Kind, version.Name, deprecatedIn, removedIn, replacementAPI, 
version.Component)
+               replacementAvailableIn := version.ReplacementAvailableIn
+               if replacementAvailableIn == "" {
+                       replacementAvailableIn = "n/a"
+               }
+
+               _, _ = fmt.Fprintf(w, "%s\t %s\t %s\t %s\t %s\t %s\t %s\t\n", 
version.Kind, version.Name, deprecatedIn, removedIn, replacementAPI, 
replacementAvailableIn, version.Component)
        }
        err := w.Flush()
        if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/pkg/api/versions_test.go 
new/pluto-5.15.1/pkg/api/versions_test.go
--- old/pluto-5.13.4/pkg/api/versions_test.go   2023-02-20 18:46:37.000000000 
+0100
+++ new/pluto-5.15.1/pkg/api/versions_test.go   2023-02-22 22:11:39.000000000 
+0100
@@ -55,6 +55,7 @@
   deprecated-in: v1.9.0
   removed-in: v1.16.0
   replacement-api: apps/v1
+  replacement-available-in: v1.10.0
   component: k8s
 target-versions:
   k8s: v1.16.0
@@ -62,12 +63,13 @@
   cert-manager: v0.15.1`
 
 var testVersionDeployment = Version{
-       Name:           "extensions/v1beta1",
-       Kind:           "Deployment",
-       DeprecatedIn:   "v1.9.0",
-       RemovedIn:      "v1.16.0",
-       ReplacementAPI: "apps/v1",
-       Component:      "k8s",
+       Name:                   "extensions/v1beta1",
+       Kind:                   "Deployment",
+       DeprecatedIn:           "v1.9.0",
+       RemovedIn:              "v1.16.0",
+       ReplacementAPI:         "apps/v1",
+       ReplacementAvailableIn: "v1.10.0",
+       Component:              "k8s",
 }
 
 func Test_jsonToStub(t *testing.T) {
@@ -425,34 +427,91 @@
        }
 }
 
+func TestVersion_isReplacementAvailableIn(t *testing.T) {
+       tests := []struct {
+               name                   string
+               targetVersions         map[string]string
+               component              string
+               want                   bool
+               replacementAvailableIn string
+       }{
+               {
+                       name:                   "not available yet 1.15.0",
+                       targetVersions:         map[string]string{"foo": 
"v1.15.0"},
+                       component:              "foo",
+                       replacementAvailableIn: "v1.16.0",
+                       want:                   false,
+               },
+               {
+                       name:                   "equal values",
+                       targetVersions:         map[string]string{"foo": 
"v1.16.0"},
+                       component:              "foo",
+                       replacementAvailableIn: "v1.16.0",
+                       want:                   true,
+               },
+               {
+                       name:                   "greater than",
+                       targetVersions:         map[string]string{"foo": 
"v1.17.0"},
+                       component:              "foo",
+                       replacementAvailableIn: "v1.16.0",
+                       want:                   true,
+               },
+               {
+                       name:                   "bad semVer",
+                       targetVersions:         map[string]string{"foo": "foo"},
+                       replacementAvailableIn: "v1.16.0",
+                       want:                   false,
+               },
+               {
+                       name:                   "blank replacementAvailableIn - 
is available",
+                       targetVersions:         map[string]string{"foo": 
"v1.16.0"},
+                       component:              "foo",
+                       replacementAvailableIn: "",
+                       want:                   true,
+               },
+               {
+                       name:                   "targetVersions not included 
for component",
+                       targetVersions:         map[string]string{"one": 
"v1.16.0"},
+                       component:              "two",
+                       replacementAvailableIn: "v1.16.0",
+                       want:                   false,
+               },
+       }
+       for _, tt := range tests {
+               removedVersion := &Version{ReplacementAvailableIn: 
tt.replacementAvailableIn, Component: tt.component}
+               got := 
removedVersion.isReplacementAvailableIn(tt.targetVersions)
+               assert.Equal(t, tt.want, got, "test failed: "+tt.name)
+       }
+}
+
 func ExampleInstance_printVersionsTabular() {
        instance := Instance{
                DeprecatedVersions: []Version{
                        testVersionDeployment,
-                       {Kind: "testkind", Name: "testname", DeprecatedIn: "", 
RemovedIn: "", Component: "custom"},
+                       {Kind: "testkind", Name: "testname", DeprecatedIn: "", 
RemovedIn: "", ReplacementAvailableIn: "", Component: "custom"},
                },
        }
        _ = instance.printVersionsTabular()
 
        // Output:
-       // KIND-------- NAME---------------- DEPRECATED IN-- REMOVED IN-- 
REPLACEMENT-- COMPONENT--
-       // Deployment-- extensions/v1beta1-- v1.9.0--------- v1.16.0----- 
apps/v1------ k8s--------
-       // testkind---- testname------------ n/a------------ n/a--------- 
n/a---------- custom-----
+       // KIND-------- NAME---------------- DEPRECATED IN-- REMOVED IN-- 
REPLACEMENT-- REPL AVAIL IN-- COMPONENT--
+       // Deployment-- extensions/v1beta1-- v1.9.0--------- v1.16.0----- 
apps/v1------ v1.10.0-------- k8s--------
+       // testkind---- testname------------ n/a------------ n/a--------- 
n/a---------- n/a------------ custom-----
 }
 
 func ExampleInstance_printVersionsTabular_noHeaders() {
        instance := Instance{
                DeprecatedVersions: []Version{
                        testVersionDeployment,
-                       {Kind: "testkind", Name: "testname", DeprecatedIn: "", 
RemovedIn: "", Component: "custom"},
+                       {Kind: "testkind", Name: "testname", DeprecatedIn: "", 
RemovedIn: "", ReplacementAvailableIn: "", Component: "custom"},
                },
                NoHeaders: true,
        }
        _ = instance.printVersionsTabular()
 
        // Output:
-       // Deployment-- extensions/v1beta1-- v1.9.0-- v1.16.0-- apps/v1-- 
k8s-----
-       // testkind---- testname------------ n/a----- n/a------ n/a------ 
custom--
+       // Deployment-- extensions/v1beta1-- v1.9.0-- v1.16.0-- apps/v1-- 
v1.10.0-- k8s-----
+       // testkind---- testname------------ n/a----- n/a------ n/a------ 
n/a------ custom--
 }
 
 func ExampleInstance_PrintVersionList_json() {
@@ -462,7 +521,7 @@
        _ = instance.PrintVersionList("json")
 
        // Output:
-       // 
{"deprecated-versions":[{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","component":"k8s"}]}
+       // 
{"deprecated-versions":[{"version":"extensions/v1beta1","kind":"Deployment","deprecated-in":"v1.9.0","removed-in":"v1.16.0","replacement-api":"apps/v1","replacement-available-in":"v1.10.0","component":"k8s"}]}
 }
 
 func ExampleInstance_PrintVersionList_yaml() {
@@ -478,6 +537,7 @@
        //       deprecated-in: v1.9.0
        //       removed-in: v1.16.0
        //       replacement-api: apps/v1
+       //       replacement-available-in: v1.10.0
        //       component: k8s
 }
 
@@ -488,8 +548,8 @@
        _ = instance.PrintVersionList("normal")
 
        // Output:
-       // KIND-------- NAME---------------- DEPRECATED IN-- REMOVED IN-- 
REPLACEMENT-- COMPONENT--
-       // Deployment-- extensions/v1beta1-- v1.9.0--------- v1.16.0----- 
apps/v1------ k8s--------
+       // KIND-------- NAME---------------- DEPRECATED IN-- REMOVED IN-- 
REPLACEMENT-- REPL AVAIL IN-- COMPONENT--
+       // Deployment-- extensions/v1beta1-- v1.9.0--------- v1.16.0----- 
apps/v1------ v1.10.0-------- k8s--------
 }
 
 func ExampleInstance_PrintVersionList_wide() {
@@ -499,8 +559,8 @@
        _ = instance.PrintVersionList("wide")
 
        // Output:
-       // KIND-------- NAME---------------- DEPRECATED IN-- REMOVED IN-- 
REPLACEMENT-- COMPONENT--
-       // Deployment-- extensions/v1beta1-- v1.9.0--------- v1.16.0----- 
apps/v1------ k8s--------
+       // KIND-------- NAME---------------- DEPRECATED IN-- REMOVED IN-- 
REPLACEMENT-- REPL AVAIL IN-- COMPONENT--
+       // Deployment-- extensions/v1beta1-- v1.9.0--------- v1.16.0----- 
apps/v1------ v1.10.0-------- k8s--------
 }
 
 func ExampleInstance_PrintVersionList_badformat() {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/pluto-5.13.4/versions.yaml 
new/pluto-5.15.1/versions.yaml
--- old/pluto-5.13.4/versions.yaml      2023-02-20 18:46:37.000000000 +0100
+++ new/pluto-5.15.1/versions.yaml      2023-02-22 22:11:39.000000000 +0100
@@ -4,72 +4,84 @@
     deprecated-in: v1.9.0
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: apps/v1beta2
     kind: Deployment
     deprecated-in: v1.9.0
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: apps/v1beta1
     kind: Deployment
     deprecated-in: v1.9.0
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: apps/v1beta1
     kind: StatefulSet
     deprecated-in: v1.9.0
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: apps/v1beta2
     kind: StatefulSet
     deprecated-in: v1.9.0
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: extensions/v1beta1
     kind: NetworkPolicy
     deprecated-in: v1.9.0
     removed-in: v1.16.0
     replacement-api: networking.k8s.io/v1
+    replacement-available-in: v1.8.0
     component: k8s
   - version: extensions/v1beta1
     kind: Ingress
     deprecated-in: v1.14.0
     removed-in: v1.22.0
     replacement-api: networking.k8s.io/v1
+    replacement-available-in: v1.19.0
     component: k8s
   - version: networking.k8s.io/v1beta1
     kind: Ingress
     deprecated-in: v1.19.0
     removed-in: v1.22.0
     replacement-api: networking.k8s.io/v1
+    replacement-available-in: v1.19.0
     component: k8s
   - version: networking.k8s.io/v1beta1
     kind: IngressClass
     deprecated-in: v1.19.0
     removed-in: v1.22.0
     replacement-api: networking.k8s.io/v1
+    replacement-available-in: v1.19.0
     component: k8s
   - version: apps/v1beta2
     kind: DaemonSet
     deprecated-in: v1.9.0
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: extensions/v1beta1
     kind: DaemonSet
     deprecated-in: v1.9.0
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: extensions/v1beta1
     kind: PodSecurityPolicy
     deprecated-in: v1.10.0
     removed-in: v1.16.0
     replacement-api: policy/v1beta1
+    replacement-available-in: v1.10.0
     component: k8s
   - version: policy/v1beta1
     kind: PodSecurityPolicy
@@ -82,24 +94,28 @@
     deprecated-in: ""
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: apps/v1beta1
     kind: ReplicaSet
     deprecated-in: ""
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: apps/v1beta2
     kind: ReplicaSet
     deprecated-in: ""
     removed-in: v1.16.0
     replacement-api: apps/v1
+    replacement-available-in: v1.9.0
     component: k8s
   - version: scheduling.k8s.io/v1beta1
     kind: PriorityClass
     deprecated-in: v1.14.0
     removed-in: v1.22.0
     replacement-api: scheduling.k8s.io/v1
+    replacement-available-in: v1.14.0
     component: k8s
   - version: scheduling.k8s.io/v1alpha1
     kind: PriorityClass
@@ -112,30 +128,35 @@
     deprecated-in: v1.16.0
     removed-in: v1.22.0
     replacement-api: apiextensions.k8s.io/v1
+    replacement-available-in: v1.16.0
     component: k8s
   - version: admissionregistration.k8s.io/v1beta1
     kind: MutatingWebhookConfiguration
     deprecated-in: v1.16.0
     removed-in: v1.22.0
     replacement-api: admissionregistration.k8s.io/v1
+    replacement-available-in: v1.16.0
     component: k8s
   - version: admissionregistration.k8s.io/v1beta1
     kind: ValidatingWebhookConfiguration
     deprecated-in: v1.16.0
     removed-in: v1.22.0
     replacement-api: admissionregistration.k8s.io/v1
+    replacement-available-in: v1.16.0
     component: k8s
   - version: rbac.authorization.k8s.io/v1alpha1
     kind: ClusterRoleBinding
     deprecated-in: v1.17.0
     removed-in: v1.22.0
     replacement-api: rbac.authorization.k8s.io/v1
+    replacement-available-in: v1.8.0
     component: k8s
   - version: rbac.authorization.k8s.io/v1alpha1
     kind: ClusterRole
     deprecated-in: v1.17.0
     removed-in: v1.22.0
     replacement-api: rbac.authorization.k8s.io/v1
+    replacement-available-in: v1.8.0
     component: k8s
   - version: rbac.authorization.k8s.io/v1alpha1
     kind: ClusterRoleBindingList
@@ -154,12 +175,14 @@
     deprecated-in: v1.17.0
     removed-in: v1.22.0
     replacement-api: rbac.authorization.k8s.io/v1
+    replacement-available-in: v1.8.0
     component: k8s
   - version: rbac.authorization.k8s.io/v1alpha1
     kind: RoleBinding
     deprecated-in: v1.17.0
     removed-in: v1.22.0
     replacement-api: rbac.authorization.k8s.io/v1
+    replacement-available-in: v1.8.0
     component: k8s
   - version: rbac.authorization.k8s.io/v1alpha1
     kind: RoleList
@@ -221,11 +244,19 @@
     removed-in: v1.22.0
     replacement-api: rbac.authorization.k8s.io/v1
     component: k8s
+  - version: node.k8s.io/v1beta1
+    kind: RuntimeClass
+    deprecated-in: v1.22.0
+    removed-in: v1.25.0
+    replacement-api: node.k8s.io/v1
+    replacement-available-in: v1.20.0
+    component: k8s
   - version: policy/v1beta1
     kind: PodDisruptionBudget
     deprecated-in: v1.21.0
     removed-in: v1.25.0
     replacement-api: policy/v1
+    replacement-available-in: v1.21.0
     component: k8s
   - version: policy/v1beta1
     kind: PodDisruptionBudgetList
@@ -238,6 +269,7 @@
     deprecated-in: v1.22.0
     removed-in: v1.25.0
     replacement-api: autoscaling/v2
+    replacement-available-in: v1.23.0
     component: k8s
   - version: autoscaling/v2beta1
     kind: HorizontalPodAutoscalerList
@@ -260,6 +292,7 @@
   - version: batch/v1beta1
     kind: CronJob
     replacement-api: batch/v1
+    replacement-available-in: v1.21.0
     deprecated-in: v1.21.0
     removed-in: v1.25.0
     component: k8s
@@ -274,40 +307,47 @@
     deprecated-in: v1.17.0
     removed-in: v1.22.0
     replacement-api: storage.k8s.io/v1
+    replacement-available-in: v1.17.0
     component: k8s
   - version: storage.k8s.io/v1beta1
     kind: CSIDriver
     deprecated-in: v1.19.0
     removed-in: v1.22.0
     replacement-api: storage.k8s.io/v1
+    replacement-available-in: v1.19.0
     component: k8s
   - version: storage.k8s.io/v1beta1
     kind: CSIStorageCapacity
     deprecated-in: v1.24.0
     removed-in: v1.27.0
     replacement-api: storage.k8s.io/v1
+    replacement-available-in: v1.24.0
     component: k8s
   - version: storage.k8s.io/v1beta1
     kind: StorageClass
     deprecated-in: v1.6.0
     removed-in: v1.22.0
     replacement-api: storage.k8s.io/v1
+    replacement-available-in: v1.6.0
     component: k8s
   - version: storage.k8s.io/v1beta1
     kind: VolumeAttachment
     deprecated-in: v1.13.0
     removed-in: v1.22.0
     replacement-api: storage.k8s.io/v1
+    replacement-available-in: v1.13.0
     component: k8s
   - version: apiregistration.k8s.io/v1beta1
     kind: APIService
     removed-in: v1.22.0
     deprecated-in: v1.10.0
     replacement-api: apiregistration.k8s.io/v1
+    replacement-available-in: v1.10.0
     component: k8s
   - version: authentication.k8s.io/v1beta1
     kind: TokenReview
     replacement-api: authentication.k8s.io/v1
+    replacement-available-in: v1.6.0
     deprecated-in: v1.6.0
     removed-in: v1.22.0
     component: k8s
@@ -316,22 +356,26 @@
     deprecated-in: v1.19.0
     removed-in: v1.22.0
     replacement-api: certificates.k8s.io/v1
+    replacement-available-in: v1.19.0
     component: k8s
   - version: coordination.k8s.io/v1beta1
     kind: Lease
     replacement-api: coordination.k8s.io/v1
+    replacement-available-in: v1.14.0
     deprecated-in: v1.14.0
     removed-in: v1.22.0
     component: k8s
   - version: events.k8s.io/v1beta1
     kind: Event
     replacement-api: events.k8s.io/v1
+    replacement-available-in: v1.19.0
     deprecated-in: v1.19.0
     removed-in: v1.25.0
     component: k8s
   - version: discovery.k8s.io/v1beta1
     kind: EndpointSlice
     replacement-api: discovery.k8s.io/v1
+    replacement-available-in: v1.21.0
     deprecated-in: v1.21.0
     removed-in: v1.25.0
     component: k8s

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/pluto/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.pluto.new.1706/vendor.tar.gz differ: char 5, line 1

Reply via email to