diff --git a/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional-cv.yaml b/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional-cv.yaml new file mode 100644 index 0000000000..63d51bef0e --- /dev/null +++ b/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional-cv.yaml @@ -0,0 +1,430 @@ +apiVersion: v1 +items: +- apiVersion: config.openshift.io/v1 + kind: ClusterVersion + metadata: + creationTimestamp: "2024-02-07T15:59:55Z" + generation: 3 + name: version + resourceVersion: "33786" + uid: 16ac3a1e-7f9a-414c-83a4-d67f415835a5 + spec: + channel: candidate-4.14 + clusterID: 4acee7ef-728d-43bd-ab41-401873c444ea + desiredUpdate: + image: quay.io/openshift-release-dev/ocp-release@sha256:05ba8e63f8a76e568afe87f182334504a01d47342b6ad5b4c3ff83a2463018bd + version: 4.14.1 + upstream: https://api.integration.openshift.com/api/upgrades_info/graph + status: + availableUpdates: + - channels: + - candidate-4.14 + - candidate-4.15 + image: quay.io/openshift-release-dev/ocp-release@sha256:36783a8b066c96dd6258e818ce51b5a763438adbf56221ea5c4b62ae4f345886 + url: https://access.redhat.com/errata/RHSA-2024:0642 + version: 4.14.11 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:03cc63c0c48b2416889e9ee53f2efc2c940323c15f08384b439c00de8e66e8aa + url: https://access.redhat.com/errata/RHSA-2024:0290 + version: 4.14.10 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:f5eaf0248779a0478cfd83f055d56dc7d755937800a68ad55f6047c503977c44 + url: https://access.redhat.com/errata/RHSA-2024:0204 + version: 4.14.9 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:073a4e46289be25e2a05f5264c8f1d697410db66b960c9ceeddebd1c61e58717 + url: https://access.redhat.com/errata/RHSA-2024:0050 + version: 4.14.8 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:a346fc0c84644e64c726013a98bef0f75e58f246fce1faa83fb6bbbc6d4050aa + url: https://access.redhat.com/errata/RHSA-2023:7831 + version: 4.14.7 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:e5128c3b0ab225e0abf9344dae504e08b82dda4885bbd047e2dbc13cc3d9879b + url: https://access.redhat.com/errata/RHSA-2023:7682 + version: 4.14.6 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:0ec9d715c717b2a592d07dd83860013613529fae69bc9eecb4b2d4ace679f6f3 + url: https://access.redhat.com/errata/RHSA-2023:7599 + version: 4.14.5 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:e6e1d90b492d50438034e6edb46bdafa6c86ae3b80ef3328685912d89681fdee + url: https://access.redhat.com/errata/RHSA-2023:7470 + version: 4.14.4 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55 + url: https://access.redhat.com/errata/RHSA-2023:7315 + version: 4.14.3 + - channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:45a396b169974dcbd8aae481c647bf55bcf9f0f8f6222483d407d7cec450928d + url: https://access.redhat.com/errata/RHSA-2023:6837 + version: 4.14.2 + capabilities: + enabledCapabilities: + - Build + - CSISnapshot + - Console + - DeploymentConfig + - ImageRegistry + - Insights + - MachineAPI + - NodeTuning + - Storage + - baremetal + - marketplace + - openshift-samples + knownCapabilities: + - Build + - CSISnapshot + - Console + - DeploymentConfig + - ImageRegistry + - Insights + - MachineAPI + - NodeTuning + - Storage + - baremetal + - marketplace + - openshift-samples + conditionalUpdates: + - conditions: + - lastTransitionTime: "2024-02-07T16:31:06Z" + message: The update is recommended, because none of the conditional update + risks apply to this cluster. + reason: AsExpected + status: "True" + type: Recommended + release: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:f5eaf0248779a0478cfd83f055d56dc7d755937800a68ad55f6047c503977c44 + url: https://access.redhat.com/errata/RHSA-2024:0204 + version: 4.14.9 + risks: + - matchingRules: + - promql: + promql: | + ( + group(cluster_operator_conditions{name="aro"}) + or + 0 * group(cluster_operator_conditions) + ) + type: PromQL + message: Adding a new worker node will fail for clusters running on ARO. + name: AROBrokenDNSMasq + url: https://issues.redhat.com/browse/MCO-958 + - conditions: + - lastTransitionTime: "2024-02-07T16:31:06Z" + message: The update is recommended, because none of the conditional update + risks apply to this cluster. + reason: AsExpected + status: "True" + type: Recommended + release: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:073a4e46289be25e2a05f5264c8f1d697410db66b960c9ceeddebd1c61e58717 + url: https://access.redhat.com/errata/RHSA-2024:0050 + version: 4.14.8 + risks: + - matchingRules: + - promql: + promql: | + ( + group(cluster_operator_conditions{name="aro"}) + or + 0 * group(cluster_operator_conditions) + ) + type: PromQL + message: Adding a new worker node will fail for clusters running on ARO. + name: AROBrokenDNSMasq + url: https://issues.redhat.com/browse/MCO-958 + - conditions: + - lastTransitionTime: "2024-02-07T16:31:06Z" + message: The update is recommended, because none of the conditional update + risks apply to this cluster. + reason: AsExpected + status: "True" + type: Recommended + release: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:a346fc0c84644e64c726013a98bef0f75e58f246fce1faa83fb6bbbc6d4050aa + url: https://access.redhat.com/errata/RHSA-2023:7831 + version: 4.14.7 + risks: + - matchingRules: + - promql: + promql: | + ( + group(cluster_operator_conditions{name="aro"}) + or + 0 * group(cluster_operator_conditions) + ) + type: PromQL + message: Adding a new worker node will fail for clusters running on ARO. + name: AROBrokenDNSMasq + url: https://issues.redhat.com/browse/MCO-958 + - conditions: + - lastTransitionTime: "2024-02-07T16:31:06Z" + message: The update is recommended, because none of the conditional update + risks apply to this cluster. + reason: AsExpected + status: "True" + type: Recommended + release: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:e5128c3b0ab225e0abf9344dae504e08b82dda4885bbd047e2dbc13cc3d9879b + url: https://access.redhat.com/errata/RHSA-2023:7682 + version: 4.14.6 + risks: + - matchingRules: + - promql: + promql: | + ( + group(cluster_operator_conditions{name="aro"}) + or + 0 * group(cluster_operator_conditions) + ) + type: PromQL + message: Adding a new worker node will fail for clusters running on ARO. + name: AROBrokenDNSMasq + url: https://issues.redhat.com/browse/MCO-958 + - conditions: + - lastTransitionTime: "2024-02-07T16:31:06Z" + message: The update is recommended, because none of the conditional update + risks apply to this cluster. + reason: AsExpected + status: "True" + type: Recommended + release: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:0ec9d715c717b2a592d07dd83860013613529fae69bc9eecb4b2d4ace679f6f3 + url: https://access.redhat.com/errata/RHSA-2023:7599 + version: 4.14.5 + risks: + - matchingRules: + - promql: + promql: | + ( + group(cluster_operator_conditions{name="aro"}) + or + 0 * group(cluster_operator_conditions) + ) + type: PromQL + message: Adding a new worker node will fail for clusters running on ARO. + name: AROBrokenDNSMasq + url: https://issues.redhat.com/browse/MCO-958 + - conditions: + - lastTransitionTime: "2024-02-07T16:31:06Z" + message: The update is recommended, because none of the conditional update + risks apply to this cluster. + reason: AsExpected + status: "True" + type: Recommended + release: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:e6e1d90b492d50438034e6edb46bdafa6c86ae3b80ef3328685912d89681fdee + url: https://access.redhat.com/errata/RHSA-2023:7470 + version: 4.14.4 + risks: + - matchingRules: + - promql: + promql: | + ( + group(cluster_operator_conditions{name="aro"}) + or + 0 * group(cluster_operator_conditions) + ) + type: PromQL + message: Adding a new worker node will fail for clusters running on ARO. + name: AROBrokenDNSMasq + url: https://issues.redhat.com/browse/MCO-958 + - conditions: + - lastTransitionTime: "2024-02-07T16:31:06Z" + message: The update is recommended, because none of the conditional update + risks apply to this cluster. + reason: AsExpected + status: "True" + type: Recommended + release: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55 + url: https://access.redhat.com/errata/RHSA-2023:7315 + version: 4.14.3 + risks: + - matchingRules: + - promql: + promql: | + ( + group(cluster_operator_conditions{name="aro"}) + or + 0 * group(cluster_operator_conditions) + ) + type: PromQL + message: Adding a new worker node will fail for clusters running on ARO + name: AROBrokenDNSMasq + url: https://issues.redhat.com/browse/MCO-958 + - conditions: + - lastTransitionTime: "2024-02-07T16:31:06Z" + message: The update is recommended, because none of the conditional update + risks apply to this cluster. + reason: AsExpected + status: "True" + type: Recommended + release: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:45a396b169974dcbd8aae481c647bf55bcf9f0f8f6222483d407d7cec450928d + url: https://access.redhat.com/errata/RHSA-2023:6837 + version: 4.14.2 + risks: + - matchingRules: + - promql: + promql: | + ( + group(cluster_operator_conditions{name="aro"}) + or + 0 * group(cluster_operator_conditions) + ) + type: PromQL + message: Adding a new worker node will fail for clusters running on ARO + name: AROBrokenDNSMasq + url: https://issues.redhat.com/browse/MCO-958 + conditions: + - lastTransitionTime: "2024-02-07T15:59:57Z" + status: "True" + type: RetrievedUpdates + - lastTransitionTime: "2024-02-07T15:59:57Z" + message: Capabilities match configured spec + reason: AsExpected + status: "False" + type: ImplicitlyEnabledCapabilities + - lastTransitionTime: "2024-02-07T15:59:57Z" + message: Payload loaded version="4.14.1" image="quay.io/openshift-release-dev/ocp-release@sha256:05ba8e63f8a76e568afe87f182334504a01d47342b6ad5b4c3ff83a2463018bd" + architecture="amd64" + reason: PayloadLoaded + status: "True" + type: ReleaseAccepted + - lastTransitionTime: "2024-02-07T16:17:57Z" + message: Done applying 4.14.0 + status: "True" + type: Available + - lastTransitionTime: "2024-02-07T16:17:57Z" + status: "False" + type: Failing + - lastTransitionTime: "2024-02-07T16:31:03Z" + message: 'Working towards 4.14.1: 139 of 859 done (16% complete), waiting on + kube-scheduler' + reason: ClusterOperatorUpdating + status: "True" + type: Progressing + desired: + channels: + - candidate-4.14 + - candidate-4.15 + - eus-4.14 + - fast-4.14 + - stable-4.14 + image: quay.io/openshift-release-dev/ocp-release@sha256:05ba8e63f8a76e568afe87f182334504a01d47342b6ad5b4c3ff83a2463018bd + url: https://access.redhat.com/errata/RHBA-2023:6153 + version: 4.14.1 + history: + - completionTime: null + image: quay.io/openshift-release-dev/ocp-release@sha256:05ba8e63f8a76e568afe87f182334504a01d47342b6ad5b4c3ff83a2463018bd + startedTime: "2024-02-07T16:31:03Z" + state: Partial + verified: true + version: 4.14.1 + - completionTime: "2024-02-07T16:17:57Z" + image: registry.build05.ci.openshift.org/ci-ln-lyxhrwb/release@sha256:e2c70fca183e380c6121a1c847806f11e839482123277235a8579db472b9ccf2 + startedTime: "2024-02-07T15:59:57Z" + state: Completed + verified: false + version: 4.14.0 + observedGeneration: 3 + versionHash: I3skQa0FyxU= +kind: List +metadata: + resourceVersion: "" diff --git a/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional.include-not-recommended-output b/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional.include-not-recommended-output new file mode 100644 index 0000000000..6a5b365877 --- /dev/null +++ b/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional.include-not-recommended-output @@ -0,0 +1,20 @@ +info: An upgrade is in progress. Working towards 4.14.1: 139 of 859 done (16% complete), waiting on kube-scheduler + +Upstream: https://api.integration.openshift.com/api/upgrades_info/graph +Channel: candidate-4.14 (available channels: candidate-4.14, candidate-4.15, eus-4.14, fast-4.14, stable-4.14) + +Recommended updates: + + VERSION IMAGE + 4.14.11 quay.io/openshift-release-dev/ocp-release@sha256:36783a8b066c96dd6258e818ce51b5a763438adbf56221ea5c4b62ae4f345886 + 4.14.10 quay.io/openshift-release-dev/ocp-release@sha256:03cc63c0c48b2416889e9ee53f2efc2c940323c15f08384b439c00de8e66e8aa + 4.14.9 quay.io/openshift-release-dev/ocp-release@sha256:f5eaf0248779a0478cfd83f055d56dc7d755937800a68ad55f6047c503977c44 + 4.14.8 quay.io/openshift-release-dev/ocp-release@sha256:073a4e46289be25e2a05f5264c8f1d697410db66b960c9ceeddebd1c61e58717 + 4.14.7 quay.io/openshift-release-dev/ocp-release@sha256:a346fc0c84644e64c726013a98bef0f75e58f246fce1faa83fb6bbbc6d4050aa + 4.14.6 quay.io/openshift-release-dev/ocp-release@sha256:e5128c3b0ab225e0abf9344dae504e08b82dda4885bbd047e2dbc13cc3d9879b + 4.14.5 quay.io/openshift-release-dev/ocp-release@sha256:0ec9d715c717b2a592d07dd83860013613529fae69bc9eecb4b2d4ace679f6f3 + 4.14.4 quay.io/openshift-release-dev/ocp-release@sha256:e6e1d90b492d50438034e6edb46bdafa6c86ae3b80ef3328685912d89681fdee + 4.14.3 quay.io/openshift-release-dev/ocp-release@sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55 + 4.14.2 quay.io/openshift-release-dev/ocp-release@sha256:45a396b169974dcbd8aae481c647bf55bcf9f0f8f6222483d407d7cec450928d + +No updates which are not recommended based on your cluster configuration are available. diff --git a/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional.output b/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional.output new file mode 100644 index 0000000000..8f410944a2 --- /dev/null +++ b/pkg/cli/admin/upgrade/recommend/examples/4.14.1-both-available-and-conditional.output @@ -0,0 +1,18 @@ +info: An upgrade is in progress. Working towards 4.14.1: 139 of 859 done (16% complete), waiting on kube-scheduler + +Upstream: https://api.integration.openshift.com/api/upgrades_info/graph +Channel: candidate-4.14 (available channels: candidate-4.14, candidate-4.15, eus-4.14, fast-4.14, stable-4.14) + +Recommended updates: + + VERSION IMAGE + 4.14.11 quay.io/openshift-release-dev/ocp-release@sha256:36783a8b066c96dd6258e818ce51b5a763438adbf56221ea5c4b62ae4f345886 + 4.14.10 quay.io/openshift-release-dev/ocp-release@sha256:03cc63c0c48b2416889e9ee53f2efc2c940323c15f08384b439c00de8e66e8aa + 4.14.9 quay.io/openshift-release-dev/ocp-release@sha256:f5eaf0248779a0478cfd83f055d56dc7d755937800a68ad55f6047c503977c44 + 4.14.8 quay.io/openshift-release-dev/ocp-release@sha256:073a4e46289be25e2a05f5264c8f1d697410db66b960c9ceeddebd1c61e58717 + 4.14.7 quay.io/openshift-release-dev/ocp-release@sha256:a346fc0c84644e64c726013a98bef0f75e58f246fce1faa83fb6bbbc6d4050aa + 4.14.6 quay.io/openshift-release-dev/ocp-release@sha256:e5128c3b0ab225e0abf9344dae504e08b82dda4885bbd047e2dbc13cc3d9879b + 4.14.5 quay.io/openshift-release-dev/ocp-release@sha256:0ec9d715c717b2a592d07dd83860013613529fae69bc9eecb4b2d4ace679f6f3 + 4.14.4 quay.io/openshift-release-dev/ocp-release@sha256:e6e1d90b492d50438034e6edb46bdafa6c86ae3b80ef3328685912d89681fdee + 4.14.3 quay.io/openshift-release-dev/ocp-release@sha256:e73ab4b33a9c3ff00c9f800a38d69853ca0c4dfa5a88e3df331f66df8f18ec55 + 4.14.2 quay.io/openshift-release-dev/ocp-release@sha256:45a396b169974dcbd8aae481c647bf55bcf9f0f8f6222483d407d7cec450928d diff --git a/pkg/cli/admin/upgrade/recommend/examples/README.md b/pkg/cli/admin/upgrade/recommend/examples/README.md new file mode 100644 index 0000000000..e13f6fa8d3 --- /dev/null +++ b/pkg/cli/admin/upgrade/recommend/examples/README.md @@ -0,0 +1,20 @@ +# Examples for `oc adm upgrade recommend` + +Each example consists of inputs and outputs, matched by a common substring: + +* `TESTCASE-cv.yaml` (input): ClusterVersion object (created by `oc get clusterversion version -o yaml`) (FIXME or list?) +* `TESTCASE.output` (output): expected output of `oc adm upgrade recommend`. +* `TESTCASE.include-not-recommended-output` (output): expected output of `oc adm upgrade recommend --include-not-recommended`. + +The `TestExamples` test in [`examples_test.go`](../examples_test.go) file above validates all examples. +When the testcase is executed with a non-empty `UPDATE` environmental variable, it will update the `TESTCASE.out` fixture: + +```console +$ UPDATE=yes go test -v ./pkg/cli/admin/upgrade/recommend/... +``` + +You can also pass the inputs to the `oc adm upgrade recommend` directly: + +```console +$ oc adm upgrade recommend --mock-clusterversion=4.14.1-both-available-and-conditional-cv.yaml +``` diff --git a/pkg/cli/admin/upgrade/recommend/examples_test.go b/pkg/cli/admin/upgrade/recommend/examples_test.go new file mode 100644 index 0000000000..7aea0273d6 --- /dev/null +++ b/pkg/cli/admin/upgrade/recommend/examples_test.go @@ -0,0 +1,89 @@ +package recommend + +import ( + "bytes" + "context" + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func compareWithFixture(t *testing.T, actualOut []byte, cvPath string, outputSuffix string) { + t.Helper() + expectedOutPath := strings.Replace(cvPath, "-cv.yaml", outputSuffix, 1) + + if update := os.Getenv("UPDATE"); update != "" { + if err := os.WriteFile(expectedOutPath, actualOut, 0644); err != nil { + t.Fatalf("Error when writing output fixture: %v", err) + } + return + } + + expectedOut, err := os.ReadFile(expectedOutPath) + if err != nil { + if !os.IsNotExist(err) { + t.Fatalf("Error when reading output fixture: %v", err) + } else { + t.Fatalf("Output file %s does not exist. You may rerun this test with UPDATE=true to create output file with the following actual output:\n%s", expectedOutPath, actualOut) + } + } + + if diff := cmp.Diff(string(expectedOut), string(actualOut)); diff != "" { + t.Errorf("Output differs from expected (%s):\n%s", filepath.Base(expectedOutPath), diff) + } +} + +func TestExamples(t *testing.T) { + cvs, err := filepath.Glob("examples/*-cv.yaml") + if err != nil { + t.Fatalf("Error when listing examples: %v", err) + } + + variants := []struct { + name string + includeNotRecommended bool + outputSuffix string + }{ + { + name: "normal output", + includeNotRecommended: false, + outputSuffix: ".output", + }, + { + name: "include not recommended output", + includeNotRecommended: true, + outputSuffix: ".include-not-recommended-output", + }, + } + + for _, cv := range cvs { + cv := cv + for _, variant := range variants { + variant := variant + t.Run(fmt.Sprintf("%s-%s", cv, variant.name), func(t *testing.T) { + t.Parallel() + opts := &options{ + mockData: mockData{cvPath: cv}, + IncludeNotRecommended: variant.includeNotRecommended, + } + if err := opts.Complete(nil, nil, nil); err != nil { + t.Fatalf("Error when completing options: %v", err) + } + + var stdout, stderr bytes.Buffer + opts.Out = &stdout + opts.ErrOut = &stderr + + if err := opts.Run(context.Background()); err != nil { + t.Fatalf("Error when running: %v", err) + } + + compareWithFixture(t, stdout.Bytes(), cv, variant.outputSuffix) + }) + } + } +} diff --git a/pkg/cli/admin/upgrade/recommend/mockresources.go b/pkg/cli/admin/upgrade/recommend/mockresources.go new file mode 100644 index 0000000000..a96f35e62b --- /dev/null +++ b/pkg/cli/admin/upgrade/recommend/mockresources.go @@ -0,0 +1,69 @@ +package recommend + +import ( + "fmt" + "os" + + configv1 "github.com/openshift/api/config/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" +) + +type mockData struct { + cvPath string + clusterVersion *configv1.ClusterVersion +} + +func asResourceList[T any](objects *corev1.List, decoder runtime.Decoder) ([]T, error) { + var outputItems []T + for i, item := range objects.Items { + obj, err := runtime.Decode(decoder, item.Raw) + if err != nil { + return nil, err + } + typedObj, ok := any(obj).(*T) + if !ok { + return nil, fmt.Errorf("unexpected object type %T in List content at index %d", obj, i) + } + outputItems = append(outputItems, *typedObj) + } + return outputItems, nil +} + +func (o *mockData) load() error { + scheme := runtime.NewScheme() + codecs := serializer.NewCodecFactory(scheme) + if err := configv1.Install(scheme); err != nil { + return err + } + if err := corev1.AddToScheme(scheme); err != nil { + return err + } + decoder := codecs.UniversalDecoder(configv1.GroupVersion, corev1.SchemeGroupVersion) + + cvBytes, err := os.ReadFile(o.cvPath) + if err != nil { + return err + } + cvObj, err := runtime.Decode(decoder, cvBytes) + if err != nil { + return err + } + switch cvObj := cvObj.(type) { + case *configv1.ClusterVersion: + o.clusterVersion = cvObj + case *configv1.ClusterVersionList: + o.clusterVersion = &cvObj.Items[0] + case *corev1.List: + cvs, err := asResourceList[configv1.ClusterVersion](cvObj, decoder) + if err != nil { + return fmt.Errorf("error while parsing file %s: %w", o.cvPath, err) + } + o.clusterVersion = &cvs[0] + default: + return fmt.Errorf("unexpected object type %T in --mock-clusterversion=%s content", cvObj, o.cvPath) + } + + return nil +} diff --git a/pkg/cli/admin/upgrade/recommend/recommend.go b/pkg/cli/admin/upgrade/recommend/recommend.go index 2c95242c69..0f611bbc22 100644 --- a/pkg/cli/admin/upgrade/recommend/recommend.go +++ b/pkg/cli/admin/upgrade/recommend/recommend.go @@ -53,12 +53,17 @@ func New(f kcmdutil.Factory, streams genericiooptions.IOStreams) *cobra.Command flags := cmd.Flags() flags.BoolVar(&o.IncludeNotRecommended, "include-not-recommended", o.IncludeNotRecommended, "Display additional updates which are not recommended based on your cluster configuration.") + // TODO: We can remove this flag once the idea about `oc adm upgrade recommend` stabilizes and the command + // is promoted out of the OC_ENABLE_CMD_UPGRADE_RECOMMEND feature gate + flags.StringVar(&o.mockData.cvPath, "mock-clusterversion", "", "Path to a YAML ClusterVersion object to use for testing (will be removed later).") + return cmd } type options struct { genericiooptions.IOStreams + mockData mockData IncludeNotRecommended bool Client configv1client.Interface @@ -67,25 +72,37 @@ type options struct { func (o *options) Complete(f kcmdutil.Factory, cmd *cobra.Command, args []string) error { kcmdutil.RequireNoArguments(cmd, args) - cfg, err := f.ToRESTConfig() - if err != nil { - return err - } - client, err := configv1client.NewForConfig(cfg) - if err != nil { - return err + if o.mockData.cvPath == "" { + cfg, err := f.ToRESTConfig() + if err != nil { + return err + } + client, err := configv1client.NewForConfig(cfg) + if err != nil { + return err + } + o.Client = client + } else { + err := o.mockData.load() + if err != nil { + return err + } } - o.Client = client + return nil } func (o *options) Run(ctx context.Context) error { - cv, err := o.Client.ConfigV1().ClusterVersions().Get(ctx, "version", metav1.GetOptions{}) - if err != nil { - if apierrors.IsNotFound(err) { - return fmt.Errorf("No cluster version information available - you must be connected to an OpenShift version 4 server to fetch the current version") + var cv *configv1.ClusterVersion + if cv = o.mockData.clusterVersion; cv == nil { + var err error + cv, err = o.Client.ConfigV1().ClusterVersions().Get(ctx, "version", metav1.GetOptions{}) + if err != nil { + if apierrors.IsNotFound(err) { + return fmt.Errorf("No cluster version information available - you must be connected to an OpenShift version 4 server to fetch the current version") + } + return err } - return err } if c := findClusterOperatorStatusCondition(cv.Status.Conditions, clusterStatusFailing); c != nil {