Skip to content

Commit 5d5c129

Browse files
authored
feat(k8s): private network integration in kapsule (#1865)
1 parent 8fb9eeb commit 5d5c129

File tree

9 files changed

+1134
-1298
lines changed

9 files changed

+1134
-1298
lines changed

docs/data-sources/k8s_cluster.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,8 @@ In addition to all above arguments, the following attributes are exported:
100100

101101
- `admission_plugins` - The list of [admission plugins](https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/) enabled on the cluster.
102102

103+
- `private_network_id` - The ID of the private network of the cluster.
104+
103105
- `region` - The [region](../guides/regions_and_zones.md#regions) in which the cluster is.
104106

105107
- `organization_id` - The ID of the organization the cluster is associated with.

docs/resources/k8s_cluster.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,11 @@ If you prefer keeping it, you should instead set it as `false`.
281281

282282
- `required_claim` - (Optional) Multiple key=value pairs that describes a required claim in the ID Token
283283

284+
- `private_network_id` - (Optional) The ID of the private network of the cluster.
285+
286+
~> **Important:** This field can only be set at cluster creation and cannot be updated later.
287+
Changes to this field will cause the cluster to be destroyed then recreated.
288+
284289
- `default_pool` - (Deprecated) See below.
285290

286291
- `region` - (Defaults to [provider](../index.md#arguments-reference) `region`) The [region](../guides/regions_and_zones.md#regions) in which the cluster should be created.

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ require (
1414
github.com/hashicorp/terraform-plugin-log v0.8.0
1515
github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1
1616
github.com/robfig/cron/v3 v3.0.1
17-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15
17+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15.0.20230330162401-14ed2c90a334
1818
github.com/stretchr/testify v1.8.2
1919
golang.org/x/exp v0.0.0-20230118134722-a68e582fa157
2020
)

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,8 +237,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:
237237
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
238238
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
239239
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
240-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15 h1:Y7xOFbD+3jaPw+VN7lkakNJ/pa+ZSQVFp1ONtJaBxns=
241-
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
240+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15.0.20230330162401-14ed2c90a334 h1:inIaZ6yJnpAbkfxzSaOelPFyEfhFoXZ3srp+kEPhG6o=
241+
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.15.0.20230330162401-14ed2c90a334/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg=
242242
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
243243
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
244244
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=

scaleway/resource_k8s_cluster.go

Lines changed: 43 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"time"
88

99
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
1213
"github.com/scaleway/scaleway-sdk-go/api/k8s/v1"
@@ -157,6 +158,15 @@ func resourceScalewayK8SCluster() *schema.Resource {
157158
Required: true,
158159
Description: "Delete additional resources like block volumes and loadbalancers on cluster deletion",
159160
},
161+
"private_network_id": {
162+
Type: schema.TypeString,
163+
Optional: true,
164+
Computed: true,
165+
ForceNew: true,
166+
Description: "The ID of the cluster's private network",
167+
ValidateFunc: validationUUIDorUUIDWithLocality(),
168+
DiffSuppressFunc: diffSuppressFuncLocality,
169+
},
160170
"region": regionSchema(),
161171
"organization_id": organizationIDSchema(),
162172
"project_id": projectIDSchema(),
@@ -222,18 +232,21 @@ func resourceScalewayK8SCluster() *schema.Resource {
222232
Description: "The status of the cluster",
223233
},
224234
},
225-
CustomizeDiff: func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
226-
autoUpgradeEnable, okAutoUpgradeEnable := diff.GetOkExists("auto_upgrade.0.enable")
235+
CustomizeDiff: customdiff.All(
236+
func(ctx context.Context, diff *schema.ResourceDiff, i interface{}) error {
237+
autoUpgradeEnable, okAutoUpgradeEnable := diff.GetOkExists("auto_upgrade.0.enable")
227238

228-
version := diff.Get("version").(string)
229-
versionIsOnlyMinor := len(strings.Split(version, ".")) == 2
239+
version := diff.Get("version").(string)
240+
versionIsOnlyMinor := len(strings.Split(version, ".")) == 2
230241

231-
if okAutoUpgradeEnable && versionIsOnlyMinor != autoUpgradeEnable.(bool) {
232-
return fmt.Errorf("minor version x.y must be used with auto upgrade enabled")
233-
}
242+
if okAutoUpgradeEnable && versionIsOnlyMinor != autoUpgradeEnable.(bool) {
243+
return fmt.Errorf("minor version x.y must be used with auto upgrade enabled")
244+
}
234245

235-
return nil
236-
},
246+
return nil
247+
},
248+
customizeDiffLocalityCheck("private_network_id"),
249+
),
237250
}
238251
}
239252

@@ -271,6 +284,8 @@ func resourceScalewayK8SClusterCreate(ctx context.Context, d *schema.ResourceDat
271284
ApiserverCertSans: expandStrings(d.Get("apiserver_cert_sans")),
272285
}
273286

287+
// Autoscaler configuration
288+
274289
autoscalerReq := &k8s.CreateClusterRequestAutoscalerConfig{}
275290

276291
if scaleDownDisabled, ok := d.GetOk("autoscaler_config.0.disable_scale_down"); ok {
@@ -315,6 +330,8 @@ func resourceScalewayK8SClusterCreate(ctx context.Context, d *schema.ResourceDat
315330

316331
req.AutoscalerConfig = autoscalerReq
317332

333+
// OpenIDConnect configuration
334+
318335
createClusterRequestOpenIDConnectConfig := &k8s.CreateClusterRequestOpenIDConnectConfig{}
319336

320337
if issuerURL, ok := d.GetOk("open_id_connect_config.0.issuer_url"); ok {
@@ -349,6 +366,8 @@ func resourceScalewayK8SClusterCreate(ctx context.Context, d *schema.ResourceDat
349366
createClusterRequestOpenIDConnectConfig.RequiredClaim = scw.StringsPtr(expandStrings(requiredClaim))
350367
}
351368

369+
// Auto-upgrade configuration
370+
352371
autoUpgradeEnable, okAutoUpgradeEnable := d.GetOkExists("auto_upgrade.0.enable")
353372
autoUpgradeStartHour, okAutoUpgradeStartHour := d.GetOkExists("auto_upgrade.0.maintenance_window_start_hour")
354373
autoUpgradeDay, okAutoUpgradeDay := d.GetOk("auto_upgrade.0.maintenance_window_day")
@@ -375,6 +394,8 @@ func resourceScalewayK8SClusterCreate(ctx context.Context, d *schema.ResourceDat
375394
}
376395
}
377396

397+
// K8S Version
398+
378399
version := d.Get("version").(string)
379400
versionIsOnlyMinor := len(strings.Split(version, ".")) == 2
380401

@@ -391,6 +412,14 @@ func resourceScalewayK8SClusterCreate(ctx context.Context, d *schema.ResourceDat
391412

392413
req.Version = version
393414

415+
// Private network configuration
416+
417+
if pnID, ok := d.GetOk("private_network_id"); ok {
418+
req.PrivateNetworkID = scw.StringPtr(expandZonedID(pnID.(string)).ID)
419+
}
420+
421+
// Cluster creation
422+
394423
res, err := k8sAPI.CreateCluster(req, scw.WithContext(ctx))
395424
if err != nil {
396425
return diag.FromErr(err)
@@ -462,6 +491,11 @@ func resourceScalewayK8SClusterRead(ctx context.Context, d *schema.ResourceData,
462491
_ = d.Set("open_id_connect_config", clusterOpenIDConnectConfigFlatten(cluster))
463492
_ = d.Set("auto_upgrade", clusterAutoUpgradeFlatten(cluster))
464493

494+
// private_network
495+
if cluster.PrivateNetworkID != nil {
496+
_ = d.Set("private_network_id", cluster.PrivateNetworkID)
497+
}
498+
465499
////
466500
// Read kubeconfig
467501
////

scaleway/resource_k8s_cluster_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,31 @@ func TestAccScalewayK8SCluster_AutoUpgrade(t *testing.T) {
384384
})
385385
}
386386

387+
func TestAccScalewayK8SCluster_PrivateNetwork(t *testing.T) {
388+
tt := NewTestTools(t)
389+
defer tt.Cleanup()
390+
391+
latestK8SVersion := testAccScalewayK8SClusterGetLatestK8SVersion(tt)
392+
393+
resource.ParallelTest(t, resource.TestCase{
394+
PreCheck: func() {
395+
testAccPreCheck(t)
396+
},
397+
ProviderFactories: tt.ProviderFactories,
398+
CheckDestroy: testAccCheckScalewayK8SClusterDestroy(tt),
399+
Steps: []resource.TestStep{
400+
{
401+
Config: testAccCheckScalewayK8SClusterConfigPrivateNetwork(latestK8SVersion),
402+
Check: resource.ComposeTestCheckFunc(
403+
testAccCheckScalewayK8SClusterExists(tt, "scaleway_k8s_cluster.private_network"),
404+
testAccCheckScalewayVPCPrivateNetworkExists(tt, "scaleway_vpc_private_network.private_network"),
405+
resource.TestCheckResourceAttrPair("scaleway_k8s_cluster.private_network", "private_network_id", "scaleway_vpc_private_network.private_network", "id"),
406+
),
407+
},
408+
},
409+
})
410+
}
411+
387412
func TestAccScalewayK8SCluster_Multicloud(t *testing.T) {
388413
tt := NewTestTools(t)
389414
defer tt.Cleanup()
@@ -574,6 +599,22 @@ resource "scaleway_k8s_cluster" "auto_upgrade" {
574599
}`, version, enable, hour, day)
575600
}
576601

602+
func testAccCheckScalewayK8SClusterConfigPrivateNetwork(version string) string {
603+
return fmt.Sprintf(`
604+
resource "scaleway_vpc_private_network" "private_network" {
605+
name = "k8s-private-network"
606+
}
607+
resource "scaleway_k8s_cluster" "private_network" {
608+
cni = "calico"
609+
version = "%s"
610+
name = "k8s-private-network-cluster"
611+
private_network_id = scaleway_vpc_private_network.private_network.id
612+
tags = [ "terraform-test", "scaleway_k8s_cluster", "private_network" ]
613+
delete_additional_resources = true
614+
depends_on = [scaleway_vpc_private_network.private_network]
615+
}`, version)
616+
}
617+
577618
func testAccCheckScalewayK8SClusterMulticloud(version string) string {
578619
return fmt.Sprintf(`
579620
resource "scaleway_k8s_cluster" "multicloud" {

scaleway/resource_k8s_pool_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -302,16 +302,18 @@ func TestAccScalewayK8SCluster_PoolSize(t *testing.T) {
302302
tt := NewTestTools(t)
303303
defer tt.Cleanup()
304304

305+
latestK8SVersionMinor := testAccScalewayK8SClusterGetLatestK8SVersionMinor(tt)
306+
305307
resource.ParallelTest(t, resource.TestCase{
306308
PreCheck: func() { testAccPreCheck(t) },
307309
ProviderFactories: tt.ProviderFactories,
308310
CheckDestroy: testAccCheckScalewayK8SClusterDestroy(tt),
309311
Steps: []resource.TestStep{
310312
{
311-
Config: `
313+
Config: fmt.Sprintf(`
312314
resource "scaleway_k8s_cluster" "cluster" {
313315
name = "cluster"
314-
version = "1.23"
316+
version = "%s"
315317
cni = "cilium"
316318
delete_additional_resources = true
317319
auto_upgrade {
@@ -329,13 +331,13 @@ func TestAccScalewayK8SCluster_PoolSize(t *testing.T) {
329331
autoscaling = false
330332
autohealing = true
331333
wait_for_pool_ready = true
332-
}`,
334+
}`, latestK8SVersionMinor),
333335
},
334336
{
335-
Config: `
337+
Config: fmt.Sprintf(`
336338
resource "scaleway_k8s_cluster" "cluster" {
337339
name = "cluster"
338-
version = "1.23"
340+
version = "%s"
339341
cni = "cilium"
340342
auto_upgrade {
341343
enable = true
@@ -353,7 +355,7 @@ func TestAccScalewayK8SCluster_PoolSize(t *testing.T) {
353355
autoscaling = false
354356
autohealing = true
355357
wait_for_pool_ready = true
356-
}`,
358+
}`, latestK8SVersionMinor),
357359
PlanOnly: true,
358360
ExpectNonEmptyPlan: true,
359361
},

0 commit comments

Comments
 (0)