Skip to content

Commit ee832b2

Browse files
authored
feat(flexibleip): add support for IPv6 (#2104)
* feat(flexibleip): add support for IPv6 * fix * update test * gofumpt
1 parent 9aea92a commit ee832b2

5 files changed

+567
-86
lines changed

docs/resources/flexible_ip.md

+19-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ resource "scaleway_flexible_ip" "main" {
2626
}
2727
```
2828

29+
### With IPv6
30+
31+
```hcl
32+
resource "scaleway_flexible_ip" "main" {
33+
is_ipv6 = "true"
34+
}
35+
```
36+
2937
### With baremetal server
3038

3139
```hcl
@@ -62,9 +70,10 @@ resource "scaleway_flexible_ip" "main" {
6270

6371
The following arguments are supported:
6472

65-
- `description`: (Optional) A description of the flexible IP.
66-
- `tags`: (Optional) A list of tags to apply to the flexible IP.
73+
- `description` - (Optional) A description of the flexible IP.
74+
- `tags` - (Optional) A list of tags to apply to the flexible IP.
6775
- `reverse` - (Optional) The reverse domain associated with this flexible IP.
76+
- `is_ipv6` - (Optional) Defines whether the flexible IP has an IPv6 address.
6877

6978
## Attributes Reference
7079

@@ -74,11 +83,14 @@ In addition to all arguments above, the following attributes are exported:
7483

7584
~> **Important:** Flexible IPs' IDs are [zoned](../guides/regions_and_zones.md#resource-ids), which means they are of the form `{zone}/{id}`, e.g. `fr-par-1/11111111-1111-1111-1111-111111111111`
7685

77-
- `ip_address` - The IPv4 address of the Flexible IP
78-
- `zone` - The zone of the Flexible IP
79-
- `organization_id` - The organization of the Flexible IP
80-
- `project_id` - The project of the Flexible IP
81-
- `server_id` - The ID of the associated server
86+
- `ip_address` - The IP address of the Flexible IP.
87+
- `server_id` - The ID of the associated server.
88+
- `status` - The status of the flexible IP.
89+
- `created_at` - The date and time of the creation of the Flexible IP (Format ISO 8601).
90+
- `updated_at` - The date and time of the last update of the Flexible IP (Format ISO 8601).
91+
- `zone` - The zone of the Flexible IP.
92+
- `organization_id` - The organization of the Flexible IP.
93+
- `project_id` - The project of the Flexible IP.
8294

8395
## Import
8496

scaleway/resource_flexible_ip.go

+19-4
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,12 @@ func resourceScalewayFlexibleIP() *schema.Resource {
3232
Optional: true,
3333
Description: "Description of the flexible IP",
3434
},
35-
"ip_address": {
36-
Type: schema.TypeString,
37-
Computed: true,
38-
Description: "The IPv4 address of the flexible IP",
35+
"is_ipv6": {
36+
Type: schema.TypeBool,
37+
Optional: true,
38+
ForceNew: true,
39+
Default: false,
40+
Description: "Defines whether the flexible IP has an IPv6 address",
3941
},
4042
"reverse": {
4143
Type: schema.TypeString,
@@ -59,6 +61,16 @@ func resourceScalewayFlexibleIP() *schema.Resource {
5961
"zone": zoneSchema(),
6062
"organization_id": organizationIDSchema(),
6163
"project_id": projectIDSchema(),
64+
"ip_address": {
65+
Type: schema.TypeString,
66+
Computed: true,
67+
Description: "The IP address of the flexible IP",
68+
},
69+
"status": {
70+
Type: schema.TypeString,
71+
Computed: true,
72+
Description: "The status of the flexible IP",
73+
},
6274
"created_at": {
6375
Type: schema.TypeString,
6476
Computed: true,
@@ -87,6 +99,7 @@ func resourceScalewayFlexibleIPCreate(ctx context.Context, d *schema.ResourceDat
8799
Tags: expandStrings(d.Get("tags")),
88100
ServerID: expandStringPtr(expandID(d.Get("server_id"))),
89101
Reverse: expandStringPtr(d.Get("reverse")),
102+
IsIPv6: d.Get("is_ipv6").(bool),
90103
}, scw.WithContext(ctx))
91104
if err != nil {
92105
return diag.FromErr(err)
@@ -133,6 +146,8 @@ func resourceScalewayFlexibleIPRead(ctx context.Context, d *schema.ResourceData,
133146
_ = d.Set("reverse", flexibleIP.Reverse)
134147
_ = d.Set("created_at", flattenTime(flexibleIP.CreatedAt))
135148
_ = d.Set("updated_at", flattenTime(flexibleIP.UpdatedAt))
149+
_ = d.Set("tags", flexibleIP.Tags)
150+
_ = d.Set("status", flexibleIP.Status.String())
136151

137152
if flexibleIP.ServerID != nil {
138153
_ = d.Set("server_id", newZonedIDString(zone, *flexibleIP.ServerID))

scaleway/resource_flexible_ip_test.go

+56-3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package scaleway
22

33
import (
44
"fmt"
5+
"net"
56
"testing"
67

78
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
@@ -60,9 +61,10 @@ func TestAccScalewayFlexibleIP_Basic(t *testing.T) {
6061
),
6162
},
6263
{
63-
ResourceName: "scaleway_flexible_ip.main",
64-
ImportState: true,
65-
ImportStateVerify: true,
64+
ResourceName: "scaleway_flexible_ip.main",
65+
ImportState: true,
66+
ImportStateVerify: true,
67+
ImportStateVerifyIgnore: []string{"is_ipv6"},
6668
},
6769
},
6870
})
@@ -99,6 +101,29 @@ func TestAccScalewayFlexibleIP_WithZone(t *testing.T) {
99101
})
100102
}
101103

104+
func TestAccScalewayFlexibleIP_IPv6(t *testing.T) {
105+
tt := NewTestTools(t)
106+
defer tt.Cleanup()
107+
resource.ParallelTest(t, resource.TestCase{
108+
ProviderFactories: tt.ProviderFactories,
109+
CheckDestroy: testAccCheckScalewayFlexibleIPDestroy(tt),
110+
Steps: []resource.TestStep{
111+
{
112+
Config: `
113+
resource "scaleway_flexible_ip" "main" {
114+
is_ipv6 = true
115+
}
116+
`,
117+
Check: resource.ComposeTestCheckFunc(
118+
testAccCheckScalewayFlexibleIPExists(tt, "scaleway_flexible_ip.main"),
119+
resource.TestCheckResourceAttr("scaleway_flexible_ip.main", "is_ipv6", "true"),
120+
testAccCheckScalewayFlexibleIPIsIPv6(tt, "scaleway_flexible_ip.main"),
121+
),
122+
},
123+
},
124+
})
125+
}
126+
102127
func TestAccScalewayFlexibleIP_CreateAndAttachToBaremetalServer(t *testing.T) {
103128
tt := NewTestTools(t)
104129
defer tt.Cleanup()
@@ -400,3 +425,31 @@ func testAccCheckScalewayFlexibleIPAttachedToBaremetalServer(tt *TestTools, ipRe
400425
return nil
401426
}
402427
}
428+
429+
func testAccCheckScalewayFlexibleIPIsIPv6(tt *TestTools, resourceName string) resource.TestCheckFunc {
430+
return func(s *terraform.State) error {
431+
rs, ok := s.RootModule().Resources[resourceName]
432+
if !ok {
433+
return fmt.Errorf("resource not found: %s", resourceName)
434+
}
435+
436+
fipAPI, zone, ID, err := fipAPIWithZoneAndID(tt.Meta, rs.Primary.ID)
437+
if err != nil {
438+
return err
439+
}
440+
441+
flexibleIP, err := fipAPI.GetFlexibleIP(&flexibleip.GetFlexibleIPRequest{
442+
Zone: zone,
443+
FipID: ID,
444+
})
445+
if err != nil {
446+
return err
447+
}
448+
449+
if len(flexibleIP.IPAddress.IP.To16()) != net.IPv6len {
450+
return fmt.Errorf("expected an IPv6 address but got: %s", flexibleIP.IPAddress.String())
451+
}
452+
453+
return nil
454+
}
455+
}

0 commit comments

Comments
 (0)