Skip to content

Commit

Permalink
feat(k8s): integrate public_ip_disabled field (#2157)
Browse files Browse the repository at this point in the history
* feat(k8s): integrate `public_ip_disabled` field to the provider

* doc(k8s): integrate `public_ip_disabled` field

* test(k8s): add test for `public_ip_disabled` field
  • Loading branch information
Mia-Cross authored Oct 16, 2023
1 parent c74497f commit 618ebe7
Show file tree
Hide file tree
Showing 4 changed files with 7,563 additions and 11 deletions.
5 changes: 4 additions & 1 deletion docs/resources/k8s_pool.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ The following arguments are supported:

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

- `wait_for_pool_ready` - (Default to `false`) Whether to wait for the pool to be ready.
- `wait_for_pool_ready` - (Defaults to `false`) Whether to wait for the pool to be ready.

- `public_ip_disabled` - (Defaults to `false`) Defines if the public IP should be removed from Nodes. To use this feature, your Cluster must have an attached [Private Network](vpc_private_network.md) set up with a [Public Gateway](vpc_public_gateway.md).
~> **Important:** Updates to this field will recreate a new resource.

## Attributes Reference

Expand Down
29 changes: 19 additions & 10 deletions scaleway/resource_k8s_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,13 @@ func resourceScalewayK8SPool() *schema.Resource {
ForceNew: true,
Description: "The size of the system volume of the nodes in gigabyte",
},
"public_ip_disabled": {
Type: schema.TypeBool,
Optional: true,
Default: false,
ForceNew: true,
Description: "Defines if the public IP should be removed from the nodes.",
},
"zone": zoneSchema(),
"region": regionSchema(),
// Computed elements
Expand Down Expand Up @@ -227,16 +234,17 @@ func resourceScalewayK8SPoolCreate(ctx context.Context, d *schema.ResourceData,
// Create pool
////
req := &k8s.CreatePoolRequest{
Region: region,
ClusterID: expandID(d.Get("cluster_id")),
Name: expandOrGenerateString(d.Get("name"), "pool"),
NodeType: d.Get("node_type").(string),
Autoscaling: d.Get("autoscaling").(bool),
Autohealing: d.Get("autohealing").(bool),
Size: uint32(d.Get("size").(int)),
Tags: expandStrings(d.Get("tags")),
Zone: scw.Zone(d.Get("zone").(string)),
KubeletArgs: expandKubeletArgs(d.Get("kubelet_args")),
Region: region,
ClusterID: expandID(d.Get("cluster_id")),
Name: expandOrGenerateString(d.Get("name"), "pool"),
NodeType: d.Get("node_type").(string),
Autoscaling: d.Get("autoscaling").(bool),
Autohealing: d.Get("autohealing").(bool),
Size: uint32(d.Get("size").(int)),
Tags: expandStrings(d.Get("tags")),
Zone: scw.Zone(d.Get("zone").(string)),
KubeletArgs: expandKubeletArgs(d.Get("kubelet_args")),
PublicIPDisabled: d.Get("public_ip_disabled").(bool),
}

if v, ok := d.GetOk("region"); ok {
Expand Down Expand Up @@ -379,6 +387,7 @@ func resourceScalewayK8SPoolRead(ctx context.Context, d *schema.ResourceData, me
_ = d.Set("kubelet_args", flattenKubeletArgs(pool.KubeletArgs))
_ = d.Set("zone", pool.Zone)
_ = d.Set("upgrade_policy", poolUpgradePolicyFlatten(pool))
_ = d.Set("public_ip_disabled", pool.PublicIPDisabled)

if pool.PlacementGroupID != nil {
_ = d.Set("placement_group_id", newZonedID(pool.Zone, *pool.PlacementGroupID).String())
Expand Down
156 changes: 156 additions & 0 deletions scaleway/resource_k8s_pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,104 @@ func TestAccScalewayK8SCluster_PoolPrivateNetwork(t *testing.T) {
})
}

func TestAccScalewayK8SCluster_PoolPublicIPDisabled(t *testing.T) {
tt := NewTestTools(t)
defer tt.Cleanup()

latestK8SVersion := testAccScalewayK8SClusterGetLatestK8SVersion(tt)

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
ProviderFactories: tt.ProviderFactories,
CheckDestroy: testAccCheckScalewayK8SClusterDestroy(tt),
Steps: []resource.TestStep{
{
Config: fmt.Sprintf(`
resource "scaleway_vpc_private_network" "public_ip" {
name = "k8s-private-network"
}
resource "scaleway_k8s_cluster" "public_ip" {
name = "private-network-cluster"
version = "%s"
cni = "cilium"
private_network_id = scaleway_vpc_private_network.public_ip.id
tags = [ "terraform-test", "scaleway_k8s_cluster", "public_ip" ]
delete_additional_resources = true
depends_on = [scaleway_vpc_private_network.public_ip]
}
resource "scaleway_k8s_pool" "public_ip" {
cluster_id = scaleway_k8s_cluster.public_ip.id
name = "pool"
node_type = "gp1_xs"
size = 1
autoscaling = false
autohealing = true
wait_for_pool_ready = true
}`, latestK8SVersion),
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayK8SClusterExists(tt, "scaleway_k8s_cluster.public_ip"),
testAccCheckScalewayVPCPrivateNetworkExists(tt, "scaleway_vpc_private_network.public_ip"),
testAccCheckScalewayK8SPoolExists(tt, "scaleway_k8s_pool.public_ip"),
resource.TestCheckResourceAttr("scaleway_k8s_pool.public_ip", "public_ip_disabled", "false"),
testAccCheckScalewayK8SPoolPublicIP(tt, "scaleway_k8s_cluster.public_ip", "scaleway_k8s_pool.public_ip", false),
),
},
{
Config: fmt.Sprintf(`
resource "scaleway_vpc_private_network" "public_ip" {
name = "private-network-for-public-ip"
}
resource "scaleway_vpc_public_gateway" "public_ip" {
name = "public-gateway-for-public-ip"
type = "VPC-GW-S"
}
resource "scaleway_vpc_public_gateway_dhcp" "public_ip" {
subnet = "192.168.0.0/22"
push_default_route = true
}
resource "scaleway_vpc_gateway_network" "public_ip" {
gateway_id = scaleway_vpc_public_gateway.public_ip.id
private_network_id = scaleway_vpc_private_network.public_ip.id
dhcp_id = scaleway_vpc_public_gateway_dhcp.public_ip.id
}
resource "scaleway_k8s_cluster" "public_ip" {
name = "cluster-for-public-ip"
version = "%s"
cni = "cilium"
private_network_id = scaleway_vpc_private_network.public_ip.id
tags = [ "terraform-test", "scaleway_k8s_cluster", "public_ip" ]
delete_additional_resources = true
depends_on = [
scaleway_vpc_private_network.public_ip,
scaleway_vpc_gateway_network.public_ip,
]
}
resource "scaleway_k8s_pool" "public_ip" {
cluster_id = scaleway_k8s_cluster.public_ip.id
name = "pool"
node_type = "gp1_xs"
size = 1
autoscaling = false
autohealing = true
wait_for_pool_ready = true
public_ip_disabled = true
}`, latestK8SVersion),
Check: resource.ComposeTestCheckFunc(
testAccCheckScalewayK8SClusterExists(tt, "scaleway_k8s_cluster.public_ip"),
testAccCheckScalewayVPCPrivateNetworkExists(tt, "scaleway_vpc_private_network.public_ip"),
testAccCheckScalewayK8SPoolExists(tt, "scaleway_k8s_pool.public_ip"),
resource.TestCheckResourceAttr("scaleway_k8s_pool.public_ip", "public_ip_disabled", "true"),
testAccCheckScalewayK8SPoolPublicIP(tt, "scaleway_k8s_cluster.public_ip", "scaleway_k8s_pool.public_ip", true),
),
},
},
})
}

func testAccCheckScalewayK8SPoolServersAreInPrivateNetwork(tt *TestTools, clusterTFName, poolTFName, pnTFName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[clusterTFName]
Expand Down Expand Up @@ -489,6 +587,64 @@ func testAccCheckScalewayK8SPoolServersAreInPrivateNetwork(tt *TestTools, cluste
}
}

func testAccCheckScalewayK8SPoolPublicIP(tt *TestTools, clusterTFName, poolTFName string, disabled bool) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[clusterTFName]
if !ok {
return fmt.Errorf("resource not found: %s", clusterTFName)
}
k8sAPI, region, clusterID, err := k8sAPIWithRegionAndID(tt.Meta, rs.Primary.ID)
if err != nil {
return err
}

rs, ok = s.RootModule().Resources[poolTFName]
if !ok {
return fmt.Errorf("resource not found: %s", poolTFName)
}
_, _, poolID, err := k8sAPIWithRegionAndID(tt.Meta, rs.Primary.ID)
if err != nil {
return err
}

nodes, err := k8sAPI.ListNodes(&k8s.ListNodesRequest{
Region: region,
PoolID: &poolID,
ClusterID: clusterID,
})
if err != nil {
return err
}

instanceAPI := instance.NewAPI(tt.Meta.scwClient)

for _, node := range nodes.Nodes {
providerIDSplit := strings.SplitN(node.ProviderID, "/", 5)
// node.ProviderID is of the form scaleway://instance/<zone>/<id>
if len(providerIDSplit) < 5 {
return fmt.Errorf("unexpected format for ProviderID in node %s", node.ID)
}

server, err := instanceAPI.GetServer(&instance.GetServerRequest{
Zone: scw.Zone(providerIDSplit[3]),
ServerID: providerIDSplit[4],
})
if err != nil {
return err
}

if disabled == true && server.Server.PublicIPs != nil && len(server.Server.PublicIPs) > 0 {
return fmt.Errorf("found node with public IP when none was expected")
}
if disabled == false && (server.Server.PublicIPs == nil || len(server.Server.PublicIPs) == 0) {
return fmt.Errorf("found node with no public IP when one was expected")
}
}

return nil
}
}

func testAccCheckScalewayK8SPoolDestroy(tt *TestTools, n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
Expand Down
Loading

0 comments on commit 618ebe7

Please sign in to comment.