feat: include preview versions as fallback (#674)
* feat: include preview versions as fallback * feat: cleanup code * fix: review findings * fix: review findings * fix: linter warning * fix: applied review comments
This commit is contained in:
parent
f0168cfed9
commit
bb472001de
2 changed files with 281 additions and 48 deletions
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -743,6 +744,33 @@ func (r *clusterResource) Create(ctx context.Context, req resource.CreateRequest
|
|||
tflog.Info(ctx, "SKE cluster created")
|
||||
}
|
||||
|
||||
func sortK8sVersions(versions []ske.KubernetesVersion) {
|
||||
sort.Slice(versions, func(i, j int) bool {
|
||||
v1, v2 := (versions)[i].Version, (versions)[j].Version
|
||||
if v1 == nil {
|
||||
return false
|
||||
}
|
||||
if v2 == nil {
|
||||
return true
|
||||
}
|
||||
|
||||
// we have to make copies of the input strings to add prefixes,
|
||||
// otherwise we would be changing the passed elements
|
||||
t1, t2 := *v1, *v2
|
||||
|
||||
if !strings.HasPrefix(t1, "v") {
|
||||
t1 = "v" + t1
|
||||
}
|
||||
if !strings.HasPrefix(t2, "v") {
|
||||
t2 = "v" + t2
|
||||
}
|
||||
return semver.Compare(t1, t2) > 0
|
||||
})
|
||||
}
|
||||
|
||||
// loadAvailableVersions loads the available k8s and machine versions from the API.
|
||||
// The k8s versions are sorted descending order, i.e. the latest versions (including previews)
|
||||
// are listed first
|
||||
func (r *clusterResource) loadAvailableVersions(ctx context.Context) ([]ske.KubernetesVersion, []ske.MachineImage, error) {
|
||||
c := r.skeClient
|
||||
res, err := c.ListProviderOptions(ctx).Execute()
|
||||
|
|
@ -793,7 +821,7 @@ func (r *clusterResource) createOrUpdateCluster(ctx context.Context, diags *diag
|
|||
// cluster vars
|
||||
projectId := model.ProjectId.ValueString()
|
||||
name := model.Name.ValueString()
|
||||
kubernetes, hasDeprecatedVersion, err := toKubernetesPayload(model, availableKubernetesVersions, currentKubernetesVersion)
|
||||
kubernetes, hasDeprecatedVersion, err := toKubernetesPayload(model, availableKubernetesVersions, currentKubernetesVersion, diags)
|
||||
if err != nil {
|
||||
core.LogAndAddError(ctx, diags, "Error creating/updating cluster", fmt.Sprintf("Creating cluster config API payload: %v", err))
|
||||
return
|
||||
|
|
@ -1813,7 +1841,7 @@ func mapExtensions(ctx context.Context, cl *ske.Cluster, m *Model) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func toKubernetesPayload(m *Model, availableVersions []ske.KubernetesVersion, currentKubernetesVersion *string) (kubernetesPayload *ske.Kubernetes, hasDeprecatedVersion bool, err error) {
|
||||
func toKubernetesPayload(m *Model, availableVersions []ske.KubernetesVersion, currentKubernetesVersion *string, diags *diag.Diagnostics) (kubernetesPayload *ske.Kubernetes, hasDeprecatedVersion bool, err error) {
|
||||
providedVersionMin := m.KubernetesVersionMin.ValueStringPointer()
|
||||
|
||||
if !m.KubernetesVersion.IsNull() {
|
||||
|
|
@ -1823,7 +1851,7 @@ func toKubernetesPayload(m *Model, availableVersions []ske.KubernetesVersion, cu
|
|||
providedVersionMin = conversion.StringValueToPointer(m.KubernetesVersion)
|
||||
}
|
||||
|
||||
versionUsed, hasDeprecatedVersion, err := latestMatchingKubernetesVersion(availableVersions, providedVersionMin, currentKubernetesVersion)
|
||||
versionUsed, hasDeprecatedVersion, err := latestMatchingKubernetesVersion(availableVersions, providedVersionMin, currentKubernetesVersion, diags)
|
||||
if err != nil {
|
||||
return nil, false, fmt.Errorf("getting latest matching kubernetes version: %w", err)
|
||||
}
|
||||
|
|
@ -1835,9 +1863,7 @@ func toKubernetesPayload(m *Model, availableVersions []ske.KubernetesVersion, cu
|
|||
return k, hasDeprecatedVersion, nil
|
||||
}
|
||||
|
||||
func latestMatchingKubernetesVersion(availableVersions []ske.KubernetesVersion, kubernetesVersionMin, currentKubernetesVersion *string) (version *string, deprecated bool, err error) {
|
||||
deprecated = false
|
||||
|
||||
func latestMatchingKubernetesVersion(availableVersions []ske.KubernetesVersion, kubernetesVersionMin, currentKubernetesVersion *string, diags *diag.Diagnostics) (version *string, deprecated bool, err error) {
|
||||
if availableVersions == nil {
|
||||
return nil, false, fmt.Errorf("nil available kubernetes versions")
|
||||
}
|
||||
|
|
@ -1865,58 +1891,113 @@ func latestMatchingKubernetesVersion(availableVersions []ske.KubernetesVersion,
|
|||
}
|
||||
}
|
||||
|
||||
var fullVersion bool
|
||||
versionExp := validate.FullVersionRegex
|
||||
versionRegex := regexp.MustCompile(versionExp)
|
||||
if versionRegex.MatchString(*kubernetesVersionMin) {
|
||||
fullVersion = true
|
||||
}
|
||||
versionRegex := regexp.MustCompile(validate.FullVersionRegex)
|
||||
fullVersion := versionRegex.MatchString(*kubernetesVersionMin)
|
||||
|
||||
providedVersionPrefixed := "v" + *kubernetesVersionMin
|
||||
|
||||
if !semver.IsValid(providedVersionPrefixed) {
|
||||
return nil, false, fmt.Errorf("provided version is invalid")
|
||||
}
|
||||
|
||||
var versionUsed *string
|
||||
var state *string
|
||||
var availableVersionsArray []string
|
||||
// Get the higher available version that matches the major, minor and patch version provided by the user
|
||||
for _, v := range availableVersions {
|
||||
if v.State == nil || v.Version == nil {
|
||||
continue
|
||||
}
|
||||
availableVersionsArray = append(availableVersionsArray, *v.Version)
|
||||
vPreffixed := "v" + *v.Version
|
||||
|
||||
if fullVersion {
|
||||
// [MAJOR].[MINOR].[PATCH] version provided, match available version
|
||||
if semver.Compare(vPreffixed, providedVersionPrefixed) == 0 {
|
||||
versionUsed = v.Version
|
||||
state = v.State
|
||||
break
|
||||
}
|
||||
} else {
|
||||
// [MAJOR].[MINOR] version provided, get the latest non-preview patch version
|
||||
if semver.MajorMinor(vPreffixed) == semver.MajorMinor(providedVersionPrefixed) &&
|
||||
(semver.Compare(vPreffixed, providedVersionPrefixed) == 1 || semver.Compare(vPreffixed, providedVersionPrefixed) == 0) &&
|
||||
(v.State != nil && *v.State != VersionStatePreview) {
|
||||
versionUsed = v.Version
|
||||
state = v.State
|
||||
}
|
||||
}
|
||||
var (
|
||||
selectedVersion *ske.KubernetesVersion
|
||||
availableVersionsArray []string
|
||||
)
|
||||
if fullVersion {
|
||||
availableVersionsArray, selectedVersion = selectFullVersion(availableVersions, providedVersionPrefixed)
|
||||
} else {
|
||||
availableVersionsArray, selectedVersion = selectMatchingVersion(availableVersions, providedVersionPrefixed)
|
||||
}
|
||||
|
||||
if versionUsed != nil {
|
||||
deprecated = strings.EqualFold(*state, VersionStateDeprecated)
|
||||
deprecated = isDeprecated(selectedVersion)
|
||||
|
||||
if isPreview(selectedVersion) {
|
||||
diags.AddWarning("preview version selected", fmt.Sprintf("only the preview version %q matched the selection criteria", *selectedVersion.Version))
|
||||
}
|
||||
|
||||
// Throwing error if we could not match the version with the available versions
|
||||
if versionUsed == nil {
|
||||
if selectedVersion == nil {
|
||||
return nil, false, fmt.Errorf("provided version is not one of the available kubernetes versions, available versions are: %s", strings.Join(availableVersionsArray, ","))
|
||||
}
|
||||
|
||||
return versionUsed, deprecated, nil
|
||||
return selectedVersion.Version, deprecated, nil
|
||||
}
|
||||
|
||||
func selectFullVersion(availableVersions []ske.KubernetesVersion, kubernetesVersionMin string) (availableVersionsArray []string, selectedVersion *ske.KubernetesVersion) {
|
||||
for _, versionCandidate := range availableVersions {
|
||||
if versionCandidate.State == nil || versionCandidate.Version == nil {
|
||||
continue
|
||||
}
|
||||
availableVersionsArray = append(availableVersionsArray, *versionCandidate.Version)
|
||||
vPrefixed := "v" + *versionCandidate.Version
|
||||
|
||||
// [MAJOR].[MINOR].[PATCH] version provided, match available version
|
||||
if semver.Compare(vPrefixed, kubernetesVersionMin) == 0 {
|
||||
selectedVersion = &versionCandidate
|
||||
break
|
||||
}
|
||||
}
|
||||
return availableVersionsArray, selectedVersion
|
||||
}
|
||||
|
||||
func selectMatchingVersion(availableVersions []ske.KubernetesVersion, kubernetesVersionMin string) (availableVersionsArray []string, selectedVersion *ske.KubernetesVersion) {
|
||||
sortK8sVersions(availableVersions)
|
||||
for _, candidateVersion := range availableVersions {
|
||||
if candidateVersion.State == nil || candidateVersion.Version == nil {
|
||||
continue
|
||||
}
|
||||
availableVersionsArray = append(availableVersionsArray, *candidateVersion.Version)
|
||||
vPreffixed := "v" + *candidateVersion.Version
|
||||
|
||||
// [MAJOR].[MINOR] version provided, get the latest non-preview patch version
|
||||
if semver.MajorMinor(vPreffixed) == semver.MajorMinor(kubernetesVersionMin) &&
|
||||
(semver.Compare(vPreffixed, kubernetesVersionMin) >= 0) &&
|
||||
(candidateVersion.State != nil) {
|
||||
// take the current version as a candidate, if we have no other version inspected before
|
||||
// OR the previously found version was a preview version
|
||||
if selectedVersion == nil || (isSupported(&candidateVersion) && isPreview(selectedVersion)) {
|
||||
selectedVersion = &candidateVersion
|
||||
}
|
||||
// all other cases are ignored
|
||||
}
|
||||
}
|
||||
return availableVersionsArray, selectedVersion
|
||||
}
|
||||
|
||||
func isDeprecated(v *ske.KubernetesVersion) bool {
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if v.State == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return *v.State == VersionStateDeprecated
|
||||
}
|
||||
|
||||
func isPreview(v *ske.KubernetesVersion) bool {
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if v.State == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return *v.State == VersionStatePreview
|
||||
}
|
||||
|
||||
func isSupported(v *ske.KubernetesVersion) bool {
|
||||
if v == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if v.State == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return *v.State == VersionStateSupported
|
||||
}
|
||||
|
||||
func getLatestSupportedKubernetesVersion(versions []ske.KubernetesVersion) (*string, error) {
|
||||
|
|
|
|||
|
|
@ -3,11 +3,13 @@ package ske
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/hashicorp/terraform-plugin-framework/attr"
|
||||
"github.com/hashicorp/terraform-plugin-framework/diag"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types"
|
||||
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
|
||||
"github.com/stackitcloud/stackit-sdk-go/core/utils"
|
||||
|
|
@ -709,6 +711,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
currentKubernetesVersion *string
|
||||
expectedVersionUsed *string
|
||||
expectedHasDeprecatedVersion bool
|
||||
expectedWarning bool
|
||||
isValid bool
|
||||
}{
|
||||
{
|
||||
|
|
@ -735,6 +738,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
utils.Ptr("1.20.1"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -761,6 +765,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
utils.Ptr("1.20.0"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -787,6 +792,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
utils.Ptr("1.20.2"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -813,6 +819,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
utils.Ptr("1.20.1"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -831,6 +838,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
utils.Ptr("1.20.0"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -849,6 +857,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
utils.Ptr("1.19.0"),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -868,6 +877,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
utils.Ptr("1.20.0"),
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
},
|
||||
{
|
||||
"nil_provided_version_get_latest",
|
||||
|
|
@ -885,6 +895,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
utils.Ptr("1.20.0"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -903,6 +914,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
utils.Ptr("1.19.0"),
|
||||
utils.Ptr("1.19.0"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -921,6 +933,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
utils.Ptr("1.20.0"),
|
||||
utils.Ptr("1.20.0"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -943,6 +956,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
utils.Ptr("1.20.0"),
|
||||
utils.Ptr("1.20.0"),
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -961,6 +975,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
utils.Ptr("1.20.0"),
|
||||
utils.Ptr("1.20.0"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -979,6 +994,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
utils.Ptr("1.19.0"),
|
||||
utils.Ptr("1.20.0"),
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
},
|
||||
{
|
||||
|
|
@ -998,6 +1014,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"no_matching_available_versions_patch",
|
||||
|
|
@ -1020,6 +1037,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"no_matching_available_versions_patch_2",
|
||||
|
|
@ -1042,6 +1060,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"no_matching_available_versions_patch_current",
|
||||
|
|
@ -1064,6 +1083,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"no_matching_available_versions_patch_2_current",
|
||||
|
|
@ -1086,6 +1106,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"no_available_version",
|
||||
|
|
@ -1095,6 +1116,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"nil_available_version",
|
||||
|
|
@ -1104,6 +1126,7 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
"empty_provided_version",
|
||||
|
|
@ -1122,11 +1145,45 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
nil,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
},
|
||||
{
|
||||
description: "minimum_version_without_patch_version_results_in_latest_supported_version,even_if_preview_is_available",
|
||||
availableVersions: []ske.KubernetesVersion{
|
||||
{Version: utils.Ptr("1.20.0"), State: utils.Ptr(VersionStateSupported)},
|
||||
{Version: utils.Ptr("1.20.1"), State: utils.Ptr(VersionStateSupported)},
|
||||
{Version: utils.Ptr("1.20.2"), State: utils.Ptr(VersionStateSupported)},
|
||||
{Version: utils.Ptr("1.20.3"), State: utils.Ptr(VersionStateSupported)},
|
||||
{Version: utils.Ptr("1.20.4"), State: utils.Ptr(VersionStatePreview)},
|
||||
},
|
||||
kubernetesVersionMin: utils.Ptr("1.20"),
|
||||
currentKubernetesVersion: nil,
|
||||
expectedVersionUsed: utils.Ptr("1.20.3"),
|
||||
expectedHasDeprecatedVersion: false,
|
||||
expectedWarning: false,
|
||||
isValid: true,
|
||||
},
|
||||
{
|
||||
description: "use_preview_when_no_supported_release_is_available",
|
||||
availableVersions: []ske.KubernetesVersion{
|
||||
{Version: utils.Ptr("1.19.5"), State: utils.Ptr(VersionStateSupported)},
|
||||
{Version: utils.Ptr("1.19.6"), State: utils.Ptr(VersionStateSupported)},
|
||||
{Version: utils.Ptr("1.19.7"), State: utils.Ptr(VersionStateSupported)},
|
||||
{Version: utils.Ptr("1.20.0"), State: utils.Ptr(VersionStateDeprecated)},
|
||||
{Version: utils.Ptr("1.20.1"), State: utils.Ptr(VersionStatePreview)},
|
||||
},
|
||||
kubernetesVersionMin: utils.Ptr("1.20"),
|
||||
currentKubernetesVersion: nil,
|
||||
expectedVersionUsed: utils.Ptr("1.20.1"),
|
||||
expectedHasDeprecatedVersion: false,
|
||||
expectedWarning: true,
|
||||
isValid: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.description, func(t *testing.T) {
|
||||
versionUsed, hasDeprecatedVersion, err := latestMatchingKubernetesVersion(tt.availableVersions, tt.kubernetesVersionMin, tt.currentKubernetesVersion)
|
||||
var diags diag.Diagnostics
|
||||
versionUsed, hasDeprecatedVersion, err := latestMatchingKubernetesVersion(tt.availableVersions, tt.kubernetesVersionMin, tt.currentKubernetesVersion, &diags)
|
||||
if !tt.isValid && err == nil {
|
||||
t.Fatalf("Should have failed")
|
||||
}
|
||||
|
|
@ -1141,6 +1198,9 @@ func TestLatestMatchingKubernetesVersion(t *testing.T) {
|
|||
t.Fatalf("hasDeprecatedVersion flag is wrong: expecting %t, got %t", tt.expectedHasDeprecatedVersion, hasDeprecatedVersion)
|
||||
}
|
||||
}
|
||||
if hasWarnings := len(diags.Warnings()) > 0; tt.expectedWarning != hasWarnings {
|
||||
t.Fatalf("Emitted warnings do not match. Expected %t but got %t", tt.expectedWarning, hasWarnings)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -2368,9 +2428,9 @@ func TestMaintenanceWindow(t *testing.T) {
|
|||
"enable_machine_image_version_updates": basetypes.NewBoolValue(false),
|
||||
}
|
||||
|
||||
val, diag := basetypes.NewObjectValue(attributeTypes, attributeValues)
|
||||
if diag.HasError() {
|
||||
t.Fatalf("cannot create object value: %v", diag)
|
||||
val, diags := basetypes.NewObjectValue(attributeTypes, attributeValues)
|
||||
if diags.HasError() {
|
||||
t.Fatalf("cannot create object value: %v", diags)
|
||||
}
|
||||
model := Model{
|
||||
Maintenance: val,
|
||||
|
|
@ -2400,3 +2460,95 @@ func TestMaintenanceWindow(t *testing.T) {
|
|||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSortK8sVersion(t *testing.T) {
|
||||
testcases := []struct {
|
||||
description string
|
||||
versions []ske.KubernetesVersion
|
||||
wantSorted []ske.KubernetesVersion
|
||||
}{
|
||||
{
|
||||
description: "slice with well formed elements",
|
||||
versions: []ske.KubernetesVersion{
|
||||
{Version: utils.Ptr("v1.2.3")},
|
||||
{Version: utils.Ptr("v1.1.10")},
|
||||
{Version: utils.Ptr("v1.2.1")},
|
||||
{Version: utils.Ptr("v1.2.0")},
|
||||
{Version: utils.Ptr("v1.1")},
|
||||
{Version: utils.Ptr("v1.2.2")},
|
||||
},
|
||||
wantSorted: []ske.KubernetesVersion{
|
||||
{Version: utils.Ptr("v1.2.3")},
|
||||
{Version: utils.Ptr("v1.2.2")},
|
||||
{Version: utils.Ptr("v1.2.1")},
|
||||
{Version: utils.Ptr("v1.2.0")},
|
||||
{Version: utils.Ptr("v1.1.10")},
|
||||
{Version: utils.Ptr("v1.1")},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "slice with undefined elements",
|
||||
versions: []ske.KubernetesVersion{
|
||||
{Version: utils.Ptr("v1.2.3")},
|
||||
{Version: utils.Ptr("v1.1.10")},
|
||||
{},
|
||||
{Version: utils.Ptr("v1.2.0")},
|
||||
{Version: utils.Ptr("v1.1")},
|
||||
{Version: utils.Ptr("v1.2.2")},
|
||||
},
|
||||
wantSorted: []ske.KubernetesVersion{
|
||||
{Version: utils.Ptr("v1.2.3")},
|
||||
{Version: utils.Ptr("v1.2.2")},
|
||||
{Version: utils.Ptr("v1.2.0")},
|
||||
{Version: utils.Ptr("v1.1.10")},
|
||||
{Version: utils.Ptr("v1.1")},
|
||||
{Version: nil},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "slice without prefix and minor version change",
|
||||
versions: []ske.KubernetesVersion{
|
||||
{Version: utils.Ptr("1.20.0")},
|
||||
{Version: utils.Ptr("1.19.0")},
|
||||
{Version: utils.Ptr("1.20.1")},
|
||||
{Version: utils.Ptr("1.20.2")},
|
||||
},
|
||||
wantSorted: []ske.KubernetesVersion{
|
||||
{Version: utils.Ptr("1.20.2")},
|
||||
{Version: utils.Ptr("1.20.1")},
|
||||
{Version: utils.Ptr("1.20.0")},
|
||||
{Version: utils.Ptr("1.19.0")},
|
||||
},
|
||||
},
|
||||
{
|
||||
description: "empty slice",
|
||||
},
|
||||
}
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.description, func(t *testing.T) {
|
||||
sortK8sVersions(tc.versions)
|
||||
|
||||
joinK8sVersions := func(in []ske.KubernetesVersion, sep string) string {
|
||||
var builder strings.Builder
|
||||
for i, l := 0, len(in); i < l; i++ {
|
||||
if i > 0 {
|
||||
builder.WriteString(sep)
|
||||
}
|
||||
if v := in[i].Version; v != nil {
|
||||
builder.WriteString(*v)
|
||||
} else {
|
||||
builder.WriteString("undef")
|
||||
}
|
||||
}
|
||||
return builder.String()
|
||||
}
|
||||
|
||||
expected := joinK8sVersions(tc.wantSorted, ", ")
|
||||
actual := joinK8sVersions(tc.versions, ", ")
|
||||
|
||||
if expected != actual {
|
||||
t.Errorf("wrong sort order. wanted %s but got %s", expected, actual)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue