Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(k8s): integrate public_ip_disabled field #2157

Merged
merged 3 commits into from
Oct 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading