Skip to content

Commit 476c467

Browse files
yfodilCodelax
andauthored
feat(vpc): migrate from zonal to regional (#2045)
* feat(vpc): migrate from zonal to regional * update cassettes * update cassettes * fix * fix doc * Update scaleway/resource_baremetal_server.go Co-authored-by: Jules Castéran <[email protected]> * Update scaleway/helpers_lb.go Co-authored-by: Jules Castéran <[email protected]> * fix --------- Co-authored-by: Jules Castéran <[email protected]>
1 parent ff936d8 commit 476c467

File tree

52 files changed

+26564
-23445
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+26564
-23445
lines changed

docs/resources/vpc_private_network.md

+4-27
Original file line numberDiff line numberDiff line change
@@ -38,40 +38,21 @@ resource "scaleway_vpc_private_network" "pn_priv" {
3838
}
3939
```
4040

41-
-> **Note:** Regional Private Network is now in Public Beta. You can create a regional private network directly using this resource by setting `is_regional` to `true`.
42-
43-
```hcl
44-
resource "scaleway_vpc" "vpc01" {
45-
name = "test-vpc"
46-
tags = ["terraform", "vpc"]
47-
}
48-
49-
resource "scaleway_vpc_private_network" "regional_pn" {
50-
name = "my_regiona_pn"
51-
tags = ["terraform", "pn", "regional"]
52-
is_regional = true
53-
vpc_id = scaleway_vpc.vpc01.id
54-
}
55-
```
56-
5741
## Arguments Reference
5842

5943
The following arguments are supported:
6044

6145
- `name` - (Optional) The name of the private network. If not provided it will be randomly generated.
6246
- `tags` - (Optional) The tags associated with the private network.
63-
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the private network should be created.
6447
- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the private network is associated with.
6548
- `ipv4_subnet` - (Optional) The IPv4 subnet to associate with the private network.
6649
- `subnet` - (Optional) The subnet CIDR.
6750
- `ipv6_subnets` - (Optional) The IPv6 subnets to associate with the private network.
6851
- `subnet` - (Optional) The subnet CIDR.
69-
70-
-> **Note:** If using Regional Private Network:
71-
7252
- `region` - (Defaults to [provider](../index.md#region) `region`) The [region](../guides/regions_and_zones.md#regions) of the private network.
7353
- `vpc_id` - (Optional) The VPC in which to create the private network.
74-
- `is_regional` - (Optional) Defines whether the private network is Regional. By default, it will be Zonal.
54+
- `is_regional` - (Deprecated) The private networks are necessarily regional now.
55+
- `zone` - (Deprecated) please use `region` instead - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the private network should be created.
7556

7657
## Attributes Reference
7758

@@ -95,17 +76,13 @@ In addition to all above arguments, the following attributes are exported:
9576
- `subnet_mask` - The subnet mask expressed in dotted decimal notation, e.g., '255.255.255.0' for a /24 subnet
9677
- `prefix_length` - The length of the network prefix, e.g., 24 for a 255.255.255.0 mask.
9778

98-
~> **Important:** Private networks' IDs are [zoned](../guides/regions_and_zones.md#resource-ids) or [regional](../guides/regions_and_zones.md#resource-ids) if using beta, which means they are of the form `{zone}/{id}`, e.g. `fr-par-1/11111111-1111-1111-1111-111111111111` or `{region}/{id}`, e.g. `fr-par/11111111-1111-1111-1111-111111111111
79+
~> **Important:** Private networks' IDs are [regional](../guides/regions_and_zones.md#resource-ids), which means they are of the form of `{region}/{id}`, e.g. `fr-par/11111111-1111-1111-1111-111111111111
9980

10081
- `organization_id` - The organization ID the private network is associated with.
10182

10283
## Import
10384

104-
Private networks can be imported using the `{zone}/{id}` or `{region}/{id}` using beta, e.g.
105-
106-
```bash
107-
$ terraform import scaleway_vpc_private_network.vpc_demo fr-par-1/11111111-1111-1111-1111-111111111111
108-
```
85+
Private networks can be imported using the `{region}/{id}`, e.g.
10986

11087
```bash
11188
$ terraform import scaleway_vpc_private_network.vpc_demo fr-par/11111111-1111-1111-1111-111111111111

scaleway/data_source_vpc_private_network.go

+17-8
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66

77
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
88
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9-
"github.com/scaleway/scaleway-sdk-go/api/vpc/v1"
9+
"github.com/scaleway/scaleway-sdk-go/api/vpc/v2"
1010
"github.com/scaleway/scaleway-sdk-go/scw"
1111
)
1212

@@ -33,7 +33,7 @@ func dataSourceScalewayVPCPrivateNetwork() *schema.Resource {
3333
}
3434

3535
func dataSourceScalewayVPCPrivateNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
36-
vpcAPI, zone, err := vpcAPIWithZone(d, meta)
36+
vpcAPI, region, err := vpcAPIWithRegion(d, meta)
3737
if err != nil {
3838
return diag.FromErr(err)
3939
}
@@ -42,8 +42,8 @@ func dataSourceScalewayVPCPrivateNetworkRead(ctx context.Context, d *schema.Reso
4242
if !ok {
4343
res, err := vpcAPI.ListPrivateNetworks(
4444
&vpc.ListPrivateNetworksRequest{
45-
Name: expandStringPtr(d.Get("name").(string)),
46-
Zone: zone,
45+
Name: expandStringPtr(d.Get("name").(string)),
46+
Region: region,
4747
}, scw.WithContext(ctx))
4848
if err != nil {
4949
return diag.FromErr(err)
@@ -68,8 +68,17 @@ func dataSourceScalewayVPCPrivateNetworkRead(ctx context.Context, d *schema.Reso
6868
privateNetworkID = res.PrivateNetworks[0].ID
6969
}
7070

71-
zonedID := datasourceNewZonedID(privateNetworkID, zone)
72-
d.SetId(zonedID)
73-
_ = d.Set("private_network_id", zonedID)
74-
return resourceScalewayVPCPrivateNetworkRead(ctx, d, meta)
71+
regionalID := datasourceNewRegionalID(privateNetworkID, region)
72+
d.SetId(regionalID)
73+
_ = d.Set("private_network_id", regionalID)
74+
diags := resourceScalewayVPCPrivateNetworkRead(ctx, d, meta)
75+
if diags != nil {
76+
return append(diags, diag.Errorf("failed to read private network state")...)
77+
}
78+
79+
if d.Id() == "" {
80+
return diag.Errorf("private network (%s) not found", regionalID)
81+
}
82+
83+
return nil
7584
}

scaleway/helpers_baremetal.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,11 @@ func flattenBaremetalOptions(zone scw.Zone, options []*baremetal.ServerOption) i
212212
return flattenedOptions
213213
}
214214

215-
func flattenBaremetalPrivateNetworks(privateNetworks []*baremetal.ServerPrivateNetwork) interface{} {
215+
func flattenBaremetalPrivateNetworks(region scw.Region, privateNetworks []*baremetal.ServerPrivateNetwork) interface{} {
216216
flattenedPrivateNetworks := []map[string]interface{}(nil)
217217
for _, privateNetwork := range privateNetworks {
218218
flattenedPrivateNetworks = append(flattenedPrivateNetworks, map[string]interface{}{
219-
"id": privateNetwork.PrivateNetworkID,
219+
"id": newRegionalIDString(region, privateNetwork.PrivateNetworkID),
220220
"vlan": flattenUint32Ptr(privateNetwork.Vlan),
221221
"status": privateNetwork.Status,
222222
"created_at": flattenTime(privateNetwork.CreatedAt),

scaleway/helpers_lb.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/hashicorp/go-cty/cty"
1414
"github.com/hashicorp/terraform-plugin-log/tflog"
15+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1516
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1617
lbSDK "github.com/scaleway/scaleway-sdk-go/api/lb/v1"
1718
"github.com/scaleway/scaleway-sdk-go/scw"
@@ -203,8 +204,13 @@ func flattenPrivateNetworkConfigs(privateNetworks []*lbSDK.PrivateNetwork) inter
203204
if pn.DHCPConfig != nil {
204205
dhcpConfigExist = true
205206
}
207+
pnRegion, err := pn.LB.Zone.Region()
208+
if err != nil {
209+
return diag.FromErr(err)
210+
}
211+
pnRegionalID := newRegionalIDString(pnRegion, pn.PrivateNetworkID)
206212
pnI = append(pnI, map[string]interface{}{
207-
"private_network_id": pn.PrivateNetworkID,
213+
"private_network_id": pnRegionalID,
208214
"dhcp_config": dhcpConfigExist,
209215
"status": pn.Status.String(),
210216
"zone": pn.LB.Zone.String(),

scaleway/helpers_rdb.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"time"
99

1010
"github.com/hashicorp/go-cty/cty"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1213
"github.com/scaleway/scaleway-sdk-go/api/rdb/v1"
1314
"github.com/scaleway/scaleway-sdk-go/scw"
@@ -211,6 +212,11 @@ func flattenPrivateNetwork(endpoints []*rdb.Endpoint) (interface{}, bool) {
211212
for _, endpoint := range endpoints {
212213
if endpoint.PrivateNetwork != nil {
213214
pn := endpoint.PrivateNetwork
215+
fetchRegion, err := pn.Zone.Region()
216+
if err != nil {
217+
return diag.FromErr(err), false
218+
}
219+
pnRegionalID := newRegionalIDString(fetchRegion, pn.PrivateNetworkID)
214220
serviceIP, err := flattenIPNet(pn.ServiceIP)
215221
if err != nil {
216222
return pnI, false
@@ -221,7 +227,7 @@ func flattenPrivateNetwork(endpoints []*rdb.Endpoint) (interface{}, bool) {
221227
"port": int(endpoint.Port),
222228
"name": endpoint.Name,
223229
"ip_net": serviceIP,
224-
"pn_id": pn.PrivateNetworkID,
230+
"pn_id": pnRegionalID,
225231
"hostname": flattenStringPtr(endpoint.Hostname),
226232
})
227233
return pnI, true
@@ -316,7 +322,12 @@ func flattenReadReplicaEndpoints(endpoints []*rdb.Endpoint) (directAccess, priva
316322
directAccess = rawEndpoint
317323
}
318324
if endpoint.PrivateNetwork != nil {
319-
rawEndpoint["private_network_id"] = endpoint.PrivateNetwork.PrivateNetworkID
325+
fetchRegion, err := endpoint.PrivateNetwork.Zone.Region()
326+
if err != nil {
327+
return diag.FromErr(err), false
328+
}
329+
pnRegionalID := newRegionalIDString(fetchRegion, endpoint.PrivateNetwork.PrivateNetworkID)
330+
rawEndpoint["private_network_id"] = pnRegionalID
320331
rawEndpoint["service_ip"] = endpoint.PrivateNetwork.ServiceIP.String()
321332
rawEndpoint["zone"] = endpoint.PrivateNetwork.Zone
322333
privateNetwork = rawEndpoint

scaleway/helpers_redis.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"sort"
88
"time"
99

10+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1112
"github.com/scaleway/scaleway-sdk-go/api/redis/v1"
1213
"github.com/scaleway/scaleway-sdk-go/scw"
@@ -148,14 +149,19 @@ func flattenRedisPrivateNetwork(endpoints []*redis.Endpoint) (interface{}, bool)
148149
continue
149150
}
150151
pn := endpoint.PrivateNetwork
152+
fetchRegion, err := pn.Zone.Region()
153+
if err != nil {
154+
return diag.FromErr(err), false
155+
}
156+
pnRegionalID := newRegionalIDString(fetchRegion, pn.ID)
151157
serviceIps := []interface{}(nil)
152158
for _, ip := range pn.ServiceIPs {
153159
serviceIps = append(serviceIps, ip.String())
154160
}
155161
pnFlat = append(pnFlat, map[string]interface{}{
156162
"endpoint_id": endpoint.ID,
157163
"zone": pn.Zone,
158-
"id": pn.ID,
164+
"id": pnRegionalID,
159165
"service_ips": serviceIps,
160166
})
161167
}

scaleway/helpers_test.go

-51
Original file line numberDiff line numberDiff line change
@@ -302,54 +302,3 @@ func TestStringHashcode_positiveIndex(t *testing.T) {
302302
}
303303
}
304304
}
305-
306-
func testAccCheckRawIDsMatch(res1, attr1, res2, attr2 string) resource.TestCheckFunc {
307-
return func(s *terraform.State) error {
308-
rs1, ok1 := s.RootModule().Resources[res1]
309-
if !ok1 {
310-
return fmt.Errorf("not found: %s", res1)
311-
}
312-
313-
rs2, ok2 := s.RootModule().Resources[res2]
314-
if !ok2 {
315-
return fmt.Errorf("not found: %s", res2)
316-
}
317-
318-
// Check if attr1 uses the wildcard syntax
319-
if strings.Contains(attr1, ".*.") {
320-
parts := strings.SplitN(attr1, ".*.", 2)
321-
prefix, suffix := parts[0], parts[1]
322-
323-
var id1s []string
324-
for key, value := range rs1.Primary.Attributes {
325-
if strings.HasPrefix(key, prefix+".") && strings.HasSuffix(key, "."+suffix) {
326-
id1s = append(id1s, expandID(value))
327-
}
328-
}
329-
330-
id2 := expandID(rs2.Primary.Attributes[attr2])
331-
332-
matches := false
333-
for _, id1 := range id1s {
334-
if id1 == id2 {
335-
matches = true
336-
break
337-
}
338-
}
339-
340-
if !matches {
341-
return fmt.Errorf("ID %s from resource %s does not match ID %s from resource %s", strings.Join(id1s, ", "), res1, id2, res2)
342-
}
343-
} else {
344-
// attr1 doesn't use the wildcard syntax, so use it as is
345-
id1 := expandID(rs1.Primary.Attributes[attr1])
346-
id2 := expandID(rs2.Primary.Attributes[attr2])
347-
348-
if id1 != id2 {
349-
return fmt.Errorf("ID %s from resource %s does not match ID %s from resource %s", id1, res1, id2, res2)
350-
}
351-
}
352-
353-
return nil
354-
}
355-
}

scaleway/helpers_vpc.go

+43-12
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,20 @@
11
package scaleway
22

33
import (
4+
"context"
45
"fmt"
56
"net"
67
"strconv"
78
"strings"
89

10+
"github.com/hashicorp/go-cty/cty"
911
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1012
v1 "github.com/scaleway/scaleway-sdk-go/api/vpc/v1"
1113
v2 "github.com/scaleway/scaleway-sdk-go/api/vpc/v2"
1214
"github.com/scaleway/scaleway-sdk-go/scw"
15+
validator "github.com/scaleway/scaleway-sdk-go/validation"
1316
)
1417

15-
// vpcAPIWithZone returns a new VPC API and the zone for a Create request
16-
func vpcAPIWithZone(d *schema.ResourceData, m interface{}) (*v1.API, scw.Zone, error) {
17-
meta := m.(*Meta)
18-
vpcAPI := v1.NewAPI(meta.scwClient)
19-
20-
zone, err := extractZone(d, meta)
21-
if err != nil {
22-
return nil, "", err
23-
}
24-
return vpcAPI, zone, err
25-
}
26-
2718
// vpcAPIWithZoneAndID
2819
func vpcAPIWithZoneAndID(m interface{}, id string) (*v1.API, scw.Zone, string, error) {
2920
meta := m.(*Meta)
@@ -203,3 +194,43 @@ func getPrefixLength(mask net.IPMask) int {
203194
ones, _ := mask.Size()
204195
return ones
205196
}
197+
198+
func vpcPrivateNetworkUpgradeV1SchemaType() cty.Type {
199+
return cty.Object(map[string]cty.Type{
200+
"id": cty.String,
201+
})
202+
}
203+
204+
func vpcPrivateNetworkV1SUpgradeFunc(_ context.Context, rawState map[string]interface{}, _ interface{}) (map[string]interface{}, error) {
205+
var err error
206+
207+
ID, exist := rawState["id"]
208+
if !exist {
209+
return nil, fmt.Errorf("upgrade: id not exist")
210+
}
211+
rawState["id"], err = vpcPrivateNetworkUpgradeV1ZonalToRegionalID(ID.(string))
212+
if err != nil {
213+
return nil, err
214+
}
215+
216+
return rawState, nil
217+
}
218+
219+
func vpcPrivateNetworkUpgradeV1ZonalToRegionalID(element string) (string, error) {
220+
locality, id, err := parseLocalizedID(element)
221+
// return error if can't parse
222+
if err != nil {
223+
return "", fmt.Errorf("upgrade: could not retrieve the locality from `%s`", element)
224+
}
225+
// if locality is already regional return
226+
if validator.IsRegion(locality) {
227+
return element, nil
228+
}
229+
230+
fetchRegion, err := scw.Zone(locality).Region()
231+
if err != nil {
232+
return "", err
233+
}
234+
235+
return fmt.Sprintf("%s/%s", fetchRegion.String(), id), nil
236+
}

scaleway/resource_baremetal_server.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,11 @@ func resourceScalewayBaremetalServerRead(ctx context.Context, d *schema.Resource
436436
if err != nil {
437437
return diag.FromErr(fmt.Errorf("failed to list server's private networks: %w", err))
438438
}
439-
_ = d.Set("private_network", flattenBaremetalPrivateNetworks(listPrivateNetworks.ServerPrivateNetworks))
439+
pnRegion, err := server.Zone.Region()
440+
if err != nil {
441+
return diag.FromErr(err)
442+
}
443+
_ = d.Set("private_network", flattenBaremetalPrivateNetworks(pnRegion, listPrivateNetworks.ServerPrivateNetworks))
440444

441445
return nil
442446
}

0 commit comments

Comments
 (0)