From 114272486dd81a3804c33fa8a574b9c455c93ef1 Mon Sep 17 00:00:00 2001 From: Patryk Matuszak <305846+pmtk@users.noreply.github.com> Date: Thu, 22 Jun 2023 15:20:00 +0200 Subject: [PATCH] simple list of blocked upgrades --- pkg/admin/prerun/upgrade_blocking.go | 59 +++++++++++++++++ pkg/admin/prerun/upgrade_blocking_test.go | 77 +++++++++++++++++++++++ pkg/admin/prerun/version.go | 2 +- 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 pkg/admin/prerun/upgrade_blocking.go create mode 100644 pkg/admin/prerun/upgrade_blocking_test.go diff --git a/pkg/admin/prerun/upgrade_blocking.go b/pkg/admin/prerun/upgrade_blocking.go new file mode 100644 index 0000000000..696b4cee88 --- /dev/null +++ b/pkg/admin/prerun/upgrade_blocking.go @@ -0,0 +1,59 @@ +package prerun + +import ( + "encoding/json" + "errors" + "fmt" + "io/fs" + + embedded "github.com/openshift/microshift/assets" + "k8s.io/klog/v2" +) + +func IsUpgradeBlocked(execVersion versionMetadata, dataVersion versionMetadata) (bool, error) { + buf, err := getBlockedUpgradesAsset() + if err != nil { + if errors.Is(err, fs.ErrNotExist) { + return false, nil + } + return false, fmt.Errorf("failed to load embedded blocked upgrades asset: %w", err) + } + + m, err := unmarshalBlockedUpgrades(buf) + if err != nil { + return false, err + } + + return isBlocked(m, execVersion.String(), dataVersion.String()), nil +} + +func getBlockedUpgradesAsset() ([]byte, error) { + return embedded.Asset("release/upgrade-blocks.json") +} + +func unmarshalBlockedUpgrades(data []byte) (map[string][]string, error) { + var blockedEdges map[string][]string + err := json.Unmarshal(data, &blockedEdges) + if err != nil { + return nil, fmt.Errorf("failed to unmarshal %q: %w", string(data), err) + } + return blockedEdges, nil +} + +func isBlocked(blockedUpgrades map[string][]string, execVersion, dataVersion string) bool { + klog.InfoS("Checking if upgrade is allowed", "existing-data-version", dataVersion, "new-binary-version", execVersion, "blocked-upgrades", blockedUpgrades) + + for targetVersion, fromVersions := range blockedUpgrades { + if targetVersion == execVersion { + for _, from := range fromVersions { + if from == dataVersion { + klog.ErrorS(nil, "Detected an attempt of unsupported upgrade", "existing-data-version", dataVersion, "new-binary-version", execVersion) + return true + } + } + } + } + + klog.InfoS("Upgrade is allowed", "existing-data-version", dataVersion, "new-binary-version", execVersion) + return false +} diff --git a/pkg/admin/prerun/upgrade_blocking_test.go b/pkg/admin/prerun/upgrade_blocking_test.go new file mode 100644 index 0000000000..e9a0ced5b9 --- /dev/null +++ b/pkg/admin/prerun/upgrade_blocking_test.go @@ -0,0 +1,77 @@ +package prerun + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_UnmarshalBlockedUpgrades(t *testing.T) { + testData := []struct { + input string + expectedOutput map[string][]string + }{ + { + input: `{"4.14.10": ["4.14.5", "4.14.4"]}`, + expectedOutput: map[string][]string{"4.14.10": {"4.14.5", "4.14.4"}}, + }, + { + input: `{}`, + expectedOutput: make(map[string][]string), + }, + } + + for _, td := range testData { + result, err := unmarshalBlockedUpgrades([]byte(td.input)) + assert.NoError(t, err) + assert.Equal(t, td.expectedOutput, result) + } +} + +func Test_IsBlocked(t *testing.T) { + edges := map[string][]string{ + "4.14.10": {"4.14.5", "4.14.6"}, + "4.15.5": {"4.15.2"}, + } + + testData := []struct { + dataVersion string + execVersion string + expectedResult bool + }{ + { + dataVersion: "4.14.4", + execVersion: "4.14.10", + expectedResult: false, + }, + { + dataVersion: "4.14.5", + execVersion: "4.14.10", + expectedResult: true, + }, + { + dataVersion: "4.14.6", + execVersion: "4.14.10", + expectedResult: true, + }, + { + dataVersion: "4.14.7", + execVersion: "4.14.10", + expectedResult: false, + }, + { + dataVersion: "4.14.7", + execVersion: "4.15.0", + expectedResult: false, + }, + { + dataVersion: "4.15.2", + execVersion: "4.15.5", + expectedResult: true, + }, + } + + for _, td := range testData { + assert.Equal(t, td.expectedResult, isBlocked(edges, td.execVersion, td.dataVersion)) + } +} diff --git a/pkg/admin/prerun/version.go b/pkg/admin/prerun/version.go index 7b9dffdf1a..bc14dae3cb 100644 --- a/pkg/admin/prerun/version.go +++ b/pkg/admin/prerun/version.go @@ -133,5 +133,5 @@ func checkVersionDiff(execVer, dataVer versionMetadata) (bool, error) { } } - return false, nil + return IsUpgradeBlocked(execVer, dataVer) }