Skip to content

Commit d970243

Browse files
committed
feat(k8s): version: add major_minor_only attribute for auto-upgrade
1 parent ff08324 commit d970243

File tree

7 files changed

+1025
-44
lines changed

7 files changed

+1025
-44
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ require (
3333
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.35.0.20251017125838-3eb0f2adaa94
3434
github.com/stretchr/testify v1.11.1
3535
golang.org/x/crypto v0.43.0
36+
golang.org/x/mod v0.29.0
3637
golang.org/x/sync v0.17.0
3738
gopkg.in/dnaeon/go-vcr.v3 v3.2.0
3839
gopkg.in/dnaeon/go-vcr.v4 v4.0.5
@@ -162,7 +163,6 @@ require (
162163
go.opentelemetry.io/otel/metric v1.38.0 // indirect
163164
go.opentelemetry.io/otel/trace v1.38.0 // indirect
164165
golang.org/x/exp v0.0.0-20251009144603-d2f985daa21b // indirect
165-
golang.org/x/mod v0.29.0 // indirect
166166
golang.org/x/net v0.46.0 // indirect
167167
golang.org/x/sys v0.37.0 // indirect
168168
golang.org/x/term v0.36.0 // indirect

internal/services/k8s/cluster_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ func TestAccCluster_AutoUpgrade(t *testing.T) {
341341
),
342342
Steps: []resource.TestStep{
343343
{
344-
Config: testAccCheckK8SClusterAutoUpgrade(false, "any", 0, previousK8SVersion),
344+
Config: testAccCheckK8SClusterAutoUpgrade(false, "any", 0, fmt.Sprintf("%q", previousK8SVersion)),
345345
Check: resource.ComposeTestCheckFunc(
346346
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.auto_upgrade"),
347347
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "version", previousK8SVersion),
@@ -351,7 +351,7 @@ func TestAccCluster_AutoUpgrade(t *testing.T) {
351351
),
352352
},
353353
{
354-
Config: testAccCheckK8SClusterAutoUpgrade(true, "any", 0, previousK8SVersionMinor),
354+
Config: testAccCheckK8SClusterAutoUpgrade(true, "any", 0, fmt.Sprintf("%q", previousK8SVersionMinor)),
355355
Check: resource.ComposeTestCheckFunc(
356356
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.auto_upgrade"),
357357
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "version", previousK8SVersionMinor),
@@ -361,7 +361,7 @@ func TestAccCluster_AutoUpgrade(t *testing.T) {
361361
),
362362
},
363363
{
364-
Config: testAccCheckK8SClusterAutoUpgrade(true, "any", 0, latestK8SVersionMinor),
364+
Config: testAccCheckK8SClusterAutoUpgrade(true, "any", 0, fmt.Sprintf("%q", latestK8SVersionMinor)),
365365
Check: resource.ComposeTestCheckFunc(
366366
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.auto_upgrade"),
367367
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "version", latestK8SVersionMinor),
@@ -371,7 +371,7 @@ func TestAccCluster_AutoUpgrade(t *testing.T) {
371371
),
372372
},
373373
{
374-
Config: testAccCheckK8SClusterAutoUpgrade(false, "any", 0, latestK8SVersion),
374+
Config: testAccCheckK8SClusterAutoUpgrade(false, "any", 0, fmt.Sprintf("%q", latestK8SVersion)),
375375
Check: resource.ComposeTestCheckFunc(
376376
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.auto_upgrade"),
377377
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "version", latestK8SVersion),
@@ -381,7 +381,7 @@ func TestAccCluster_AutoUpgrade(t *testing.T) {
381381
),
382382
},
383383
{
384-
Config: testAccCheckK8SClusterAutoUpgrade(true, "tuesday", 3, latestK8SVersionMinor),
384+
Config: testAccCheckK8SClusterAutoUpgrade(true, "tuesday", 3, fmt.Sprintf("%q", latestK8SVersionMinor)),
385385
Check: resource.ComposeTestCheckFunc(
386386
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.auto_upgrade"),
387387
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "version", latestK8SVersionMinor),
@@ -391,7 +391,7 @@ func TestAccCluster_AutoUpgrade(t *testing.T) {
391391
),
392392
},
393393
{
394-
Config: testAccCheckK8SClusterAutoUpgrade(true, "any", 0, latestK8SVersionMinor),
394+
Config: testAccCheckK8SClusterAutoUpgrade(true, "any", 0, fmt.Sprintf("%q", latestK8SVersionMinor)),
395395
Check: resource.ComposeTestCheckFunc(
396396
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.auto_upgrade"),
397397
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "version", latestK8SVersionMinor),
@@ -789,7 +789,7 @@ resource "scaleway_vpc_private_network" "auto_upgrade" {
789789
790790
resource "scaleway_k8s_cluster" "auto_upgrade" {
791791
cni = "calico"
792-
version = "%s"
792+
version = %s
793793
name = "test-auto-upgrade"
794794
auto_upgrade {
795795
enable = %t

internal/services/k8s/k8s_version_data_source.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"errors"
66
"fmt"
7+
"strings"
78

89
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
910
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
@@ -19,7 +20,12 @@ func DataSourceVersion() *schema.Resource {
1920
"name": {
2021
Type: schema.TypeString,
2122
Required: true,
22-
Description: "Name of the Kubernetes version",
23+
Description: "Name of the Kubernetes version in the form x.y.z",
24+
},
25+
"major_minor_only": {
26+
Type: schema.TypeString,
27+
Computed: true,
28+
Description: "The name of the version in the form x.y (ignoring patch version)",
2329
},
2430
"available_cnis": {
2531
Type: schema.TypeList,
@@ -88,12 +94,27 @@ func DataSourceK8SVersionRead(ctx context.Context, d *schema.ResourceData, m any
8894
version = res
8995
}
9096

97+
majorMinor, err := VersionNameWithoutPatch(version.Name)
98+
if err != nil {
99+
return diag.FromErr(err)
100+
}
101+
91102
d.SetId(fmt.Sprintf("%s/%s", region, version.Name))
92103
_ = d.Set("name", version.Name)
104+
_ = d.Set("major_minor_only", majorMinor)
93105
_ = d.Set("available_cnis", version.AvailableCnis)
94106
_ = d.Set("available_container_runtimes", version.AvailableContainerRuntimes)
95107
_ = d.Set("available_feature_gates", version.AvailableFeatureGates)
96108
_ = d.Set("region", region)
97109

98110
return nil
99111
}
112+
113+
func VersionNameWithoutPatch(version string) (string, error) {
114+
versionSplit := strings.Split(version, ".")
115+
if len(versionSplit) != 3 {
116+
return "", fmt.Errorf("version name must contain 3 parts, got %q", version)
117+
}
118+
119+
return strings.Join(versionSplit[:2], "."), nil
120+
}

internal/services/k8s/k8s_version_data_source_test.go

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,35 @@ import (
66

77
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
88
"github.com/hashicorp/terraform-plugin-testing/terraform"
9-
"github.com/scaleway/scaleway-sdk-go/api/k8s/v1"
9+
k8sSDK "github.com/scaleway/scaleway-sdk-go/api/k8s/v1"
1010
"github.com/scaleway/terraform-provider-scaleway/v2/internal/acctest"
1111
"github.com/scaleway/terraform-provider-scaleway/v2/internal/locality/regional"
12+
"github.com/scaleway/terraform-provider-scaleway/v2/internal/services/k8s"
13+
"github.com/stretchr/testify/assert"
14+
"github.com/stretchr/testify/require"
1215
)
1316

1417
func TestAccDataSourceVersion_Basic(t *testing.T) {
1518
tt := acctest.NewTestTools(t)
1619
defer tt.Cleanup()
1720

21+
version := "1.32.2"
22+
versionWithoutPatch := "1.32"
23+
1824
resource.ParallelTest(t, resource.TestCase{
1925
ProtoV6ProviderFactories: tt.ProviderFactories,
2026
CheckDestroy: testAccCheckK8SClusterDestroy(tt),
2127
Steps: []resource.TestStep{
2228
{
23-
Config: `
29+
Config: fmt.Sprintf(`
2430
data "scaleway_k8s_version" "by_name" {
25-
name = "1.32.2"
31+
name = %q
2632
}
27-
`,
33+
`, version),
2834
Check: resource.ComposeTestCheckFunc(
2935
testAccCheckK8SVersionExists(tt, "data.scaleway_k8s_version.by_name"),
30-
resource.TestCheckResourceAttrSet("data.scaleway_k8s_version.by_name", "name"),
36+
resource.TestCheckResourceAttr("data.scaleway_k8s_version.by_name", "name", version),
37+
resource.TestCheckResourceAttr("data.scaleway_k8s_version.by_name", "major_minor_only", versionWithoutPatch),
3138
resource.TestCheckResourceAttr("data.scaleway_k8s_version.by_name", "available_cnis.#", "4"),
3239
resource.TestCheckResourceAttr("data.scaleway_k8s_version.by_name", "available_cnis.0", "cilium"),
3340
resource.TestCheckResourceAttr("data.scaleway_k8s_version.by_name", "available_cnis.1", "calico"),
@@ -75,6 +82,42 @@ func TestAccDataSourceVersion_Latest(t *testing.T) {
7582
})
7683
}
7784

85+
func TestAccDataSourceVersion_WithAutoUpgrade(t *testing.T) {
86+
tt := acctest.NewTestTools(t)
87+
defer tt.Cleanup()
88+
89+
latestK8SVersion := testAccK8SClusterGetLatestK8SVersion(tt)
90+
91+
latestK8SVersionWithoutPatch, err := k8s.VersionNameWithoutPatch(latestK8SVersion)
92+
if err != nil {
93+
t.Fatal(err)
94+
}
95+
96+
resource.ParallelTest(t, resource.TestCase{
97+
ProtoV6ProviderFactories: tt.ProviderFactories,
98+
CheckDestroy: testAccCheckK8SClusterDestroy(tt),
99+
Steps: []resource.TestStep{
100+
{
101+
Config: `
102+
data "scaleway_k8s_version" "latest" {
103+
name = "latest"
104+
}
105+
` + testAccCheckK8SClusterAutoUpgrade(true, "any", 0, "data.scaleway_k8s_version.latest.major_minor_only"),
106+
Check: resource.ComposeTestCheckFunc(
107+
testAccCheckK8SVersionExists(tt, "data.scaleway_k8s_version.latest"),
108+
testAccCheckK8SClusterExists(tt, "scaleway_k8s_cluster.auto_upgrade"),
109+
resource.TestCheckResourceAttr("data.scaleway_k8s_version.latest", "name", latestK8SVersion),
110+
resource.TestCheckResourceAttr("data.scaleway_k8s_version.latest", "major_minor_only", latestK8SVersionWithoutPatch),
111+
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "version", latestK8SVersionWithoutPatch),
112+
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "auto_upgrade.0.enable", "true"),
113+
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "auto_upgrade.0.maintenance_window_day", "any"),
114+
resource.TestCheckResourceAttr("scaleway_k8s_cluster.auto_upgrade", "auto_upgrade.0.maintenance_window_start_hour", "0"),
115+
),
116+
},
117+
},
118+
})
119+
}
120+
78121
func testAccCheckK8SVersionExists(tt *acctest.TestTools, n string) resource.TestCheckFunc {
79122
return func(s *terraform.State) error {
80123
rs, ok := s.RootModule().Resources[n]
@@ -88,9 +131,9 @@ func testAccCheckK8SVersionExists(tt *acctest.TestTools, n string) resource.Test
88131
return err
89132
}
90133

91-
k8sAPI := k8s.NewAPI(tt.Meta.ScwClient())
134+
k8sAPI := k8sSDK.NewAPI(tt.Meta.ScwClient())
92135

93-
_, err = k8sAPI.GetVersion(&k8s.GetVersionRequest{
136+
_, err = k8sAPI.GetVersion(&k8sSDK.GetVersionRequest{
94137
Region: region,
95138
VersionName: name,
96139
})
@@ -101,3 +144,35 @@ func testAccCheckK8SVersionExists(tt *acctest.TestTools, n string) resource.Test
101144
return nil
102145
}
103146
}
147+
148+
func TestVersionNameWithoutPatch(t *testing.T) {
149+
tt := acctest.NewTestTools(t)
150+
defer tt.Cleanup()
151+
152+
t.Run("ok-without-prefix", func(t *testing.T) {
153+
version := "1.32.3"
154+
expected := "1.32"
155+
actual, err := k8s.VersionNameWithoutPatch(version)
156+
require.NoError(t, err)
157+
assert.Equal(t, expected, actual)
158+
})
159+
t.Run("ok-with-prefix", func(t *testing.T) {
160+
version := "v2.57.9"
161+
expected := "v2.57"
162+
actual, err := k8s.VersionNameWithoutPatch(version)
163+
require.NoError(t, err)
164+
assert.Equal(t, expected, actual)
165+
})
166+
t.Run("errors", func(t *testing.T) {
167+
versionsToTest := []string{
168+
"1.32.3.4",
169+
"1.32",
170+
"",
171+
}
172+
for _, version := range versionsToTest {
173+
expectedError := "version name must contain 3 parts"
174+
_, err := k8s.VersionNameWithoutPatch(version)
175+
assert.ErrorContains(t, err, expectedError)
176+
}
177+
})
178+
}

0 commit comments

Comments
 (0)