Skip to content

Commit 2cfb0ef

Browse files
authored
feat(vpc): add subnets attribute in private_network resource (#1930) (#1933)
* refactor(vpc): split private_network tests and update cassettes * refactor(vpc): remove useless HasChanged() check The only reason for the update function to be called is if at least one of these attributes has changed. * docs(vpc): add private_network_id attribute on private_network datasource * feat(vpc): add subnets attribute in private_network resource and datasource (#1930)
1 parent 82ca284 commit 2cfb0ef

10 files changed

+949
-422
lines changed

docs/data-sources/vpc_private_network.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ N/A, the usage will be meaningful in the next releases of VPC.
1313

1414
## Argument Reference
1515

16-
* `name` - (Required) Exact name of the private network.
16+
* `name` - (Optional) Name of the private network. One of `name` and `private_network_id` should be specified.
17+
* `private_network_id` - (Optional) ID of the private network. One of `name` and `private_network_id` should be specified.
1718

1819
## Attributes Reference
1920

2021
In addition to all above arguments, the following attributes are exported:
2122

2223
- `id` - The ID of the private network.
24+
- `subnets` - The subnets CIDR associated with private network.
2325

2426
~> **Important:** Private networks' 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`
25-

docs/resources/vpc_private_network.md

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ The following arguments are supported:
2525
- `tags` - (Optional) The tags associated with the private network.
2626
- `zone` - (Defaults to [provider](../index.md#zone) `zone`) The [zone](../guides/regions_and_zones.md#zones) in which the private network should be created.
2727
- `project_id` - (Defaults to [provider](../index.md#project_id) `project_id`) The ID of the project the private network is associated with.
28+
- `subnets` - (Optional) The subnets CIDR associated with private network.
2829

2930
## Attributes Reference
3031

scaleway/data_source_vpc_private_network_test.go

+18
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,27 @@ func TestAccScalewayDataSourceVPCPrivateNetwork_Basic(t *testing.T) {
4141
resource.TestCheckResourceAttrPair(
4242
"data.scaleway_vpc_private_network.pn_test_by_name", "name",
4343
"scaleway_vpc_private_network.pn_test", "name"),
44+
resource.TestCheckResourceAttr(
45+
"data.scaleway_vpc_private_network.pn_test_by_name",
46+
"subnets.#", "2"),
47+
resource.TestCheckTypeSetElemAttrPair(
48+
"data.scaleway_vpc_private_network.pn_test_by_name", "subnets.*",
49+
"scaleway_vpc_private_network.pn_test", "subnets.0"),
50+
resource.TestCheckTypeSetElemAttrPair(
51+
"data.scaleway_vpc_private_network.pn_test_by_name", "subnets.*",
52+
"scaleway_vpc_private_network.pn_test", "subnets.1"),
4453
resource.TestCheckResourceAttrPair(
4554
"data.scaleway_vpc_private_network.pn_test_by_id", "private_network_id",
4655
"scaleway_vpc_private_network.pn_test", "id"),
56+
resource.TestCheckResourceAttr(
57+
"data.scaleway_vpc_private_network.pn_test_by_id",
58+
"subnets.#", "2"),
59+
resource.TestCheckTypeSetElemAttrPair(
60+
"data.scaleway_vpc_private_network.pn_test_by_id", "subnets.*",
61+
"scaleway_vpc_private_network.pn_test", "subnets.0"),
62+
resource.TestCheckTypeSetElemAttrPair(
63+
"data.scaleway_vpc_private_network.pn_test_by_id", "subnets.*",
64+
"scaleway_vpc_private_network.pn_test", "subnets.1"),
4765
),
4866
},
4967
},

scaleway/helpers_vpc.go

+26
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,29 @@ func vpcAPI(m interface{}) (*vpc.API, error) {
4040

4141
return vpc.NewAPI(meta.scwClient), nil
4242
}
43+
44+
func expandSubnets(data interface{}) ([]scw.IPNet, error) {
45+
var ipNets []scw.IPNet
46+
for _, s := range data.([]interface{}) {
47+
if s == nil {
48+
s = ""
49+
}
50+
ipNet, err := expandIPNet(s.(string))
51+
if err != nil {
52+
return nil, err
53+
}
54+
ipNets = append(ipNets, ipNet)
55+
}
56+
57+
return ipNets, nil
58+
}
59+
60+
func flattenSubnets(subnets []scw.IPNet) *schema.Set {
61+
var rawSubnets []interface{}
62+
for _, s := range subnets {
63+
rawSubnets = append(rawSubnets, s.String())
64+
}
65+
return schema.NewSet(func(i interface{}) int {
66+
return StringHashcode(i.(string))
67+
}, rawSubnets)
68+
}

scaleway/resource_vpc_private_network.go

+27-12
Original file line numberDiff line numberDiff line change
@@ -6,6 +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/hashicorp/terraform-plugin-sdk/v2/helper/validation"
910
"github.com/scaleway/scaleway-sdk-go/api/vpc/v1"
1011
"github.com/scaleway/scaleway-sdk-go/scw"
1112
)
@@ -27,6 +28,17 @@ func resourceScalewayVPCPrivateNetwork() *schema.Resource {
2728
Description: "The name of the private network",
2829
Computed: true,
2930
},
31+
"subnets": {
32+
Type: schema.TypeSet,
33+
Optional: true,
34+
Description: "The subnets CIDR associated with private network",
35+
Computed: true,
36+
ForceNew: true, // Updating the subnets is deprecated and has no effect
37+
Elem: &schema.Schema{
38+
Type: schema.TypeString,
39+
ValidateDiagFunc: validation.ToDiagFunc(validation.IsCIDR),
40+
},
41+
},
3042
"tags": {
3143
Type: schema.TypeList,
3244
Optional: true,
@@ -59,11 +71,17 @@ func resourceScalewayVPCPrivateNetworkCreate(ctx context.Context, d *schema.Reso
5971
return diag.FromErr(err)
6072
}
6173

74+
subnets, err := expandSubnets(d.Get("subnets").(*schema.Set).List())
75+
if err != nil {
76+
return diag.FromErr(err)
77+
}
78+
6279
pn, err := vpcAPI.CreatePrivateNetwork(&vpc.CreatePrivateNetworkRequest{
6380
Name: expandOrGenerateString(d.Get("name"), "pn"),
6481
Tags: expandStrings(d.Get("tags")),
6582
ProjectID: d.Get("project_id").(string),
6683
Zone: zone,
84+
Subnets: subnets,
6785
}, scw.WithContext(ctx))
6886
if err != nil {
6987
return diag.FromErr(err)
@@ -97,6 +115,7 @@ func resourceScalewayVPCPrivateNetworkRead(ctx context.Context, d *schema.Resour
97115
_ = d.Set("project_id", pn.ProjectID)
98116
_ = d.Set("created_at", pn.CreatedAt.Format(time.RFC3339))
99117
_ = d.Set("updated_at", pn.UpdatedAt.Format(time.RFC3339))
118+
_ = d.Set("subnets", flattenSubnets(pn.Subnets))
100119
_ = d.Set("zone", zone)
101120
_ = d.Set("tags", pn.Tags)
102121

@@ -109,18 +128,14 @@ func resourceScalewayVPCPrivateNetworkUpdate(ctx context.Context, d *schema.Reso
109128
return diag.FromErr(err)
110129
}
111130

112-
if d.HasChanges("name", "tags") {
113-
updateRequest := &vpc.UpdatePrivateNetworkRequest{
114-
PrivateNetworkID: ID,
115-
Zone: zone,
116-
Name: scw.StringPtr(d.Get("name").(string)),
117-
Tags: expandUpdatedStringsPtr(d.Get("tags")),
118-
}
119-
120-
_, err = vpcAPI.UpdatePrivateNetwork(updateRequest, scw.WithContext(ctx))
121-
if err != nil {
122-
return diag.FromErr(err)
123-
}
131+
_, err = vpcAPI.UpdatePrivateNetwork(&vpc.UpdatePrivateNetworkRequest{
132+
PrivateNetworkID: ID,
133+
Zone: zone,
134+
Name: scw.StringPtr(d.Get("name").(string)),
135+
Tags: expandUpdatedStringsPtr(d.Get("tags")),
136+
}, scw.WithContext(ctx))
137+
if err != nil {
138+
return diag.FromErr(err)
124139
}
125140

126141
return resourceScalewayVPCPrivateNetworkRead(ctx, d, meta)

scaleway/resource_vpc_private_network_test.go

+64
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,18 @@ func TestAccScalewayVPCPrivateNetwork_Basic(t *testing.T) {
9393
),
9494
),
9595
},
96+
},
97+
})
98+
}
99+
100+
func TestAccScalewayVPCPrivateNetwork_DefaultName(t *testing.T) {
101+
tt := NewTestTools(t)
102+
defer tt.Cleanup()
103+
resource.ParallelTest(t, resource.TestCase{
104+
PreCheck: func() { testAccPreCheck(t) },
105+
ProviderFactories: tt.ProviderFactories,
106+
CheckDestroy: testAccCheckScalewayVPCPrivateNetworkDestroy(tt),
107+
Steps: []resource.TestStep{
96108
{
97109
Config: `resource scaleway_vpc_private_network main {}`,
98110
Check: resource.ComposeTestCheckFunc(
@@ -107,6 +119,58 @@ func TestAccScalewayVPCPrivateNetwork_Basic(t *testing.T) {
107119
})
108120
}
109121

122+
func TestAccScalewayVPCPrivateNetwork_Subnets(t *testing.T) {
123+
tt := NewTestTools(t)
124+
defer tt.Cleanup()
125+
resource.ParallelTest(t, resource.TestCase{
126+
PreCheck: func() { testAccPreCheck(t) },
127+
ProviderFactories: tt.ProviderFactories,
128+
CheckDestroy: testAccCheckScalewayVPCPrivateNetworkDestroy(tt),
129+
Steps: []resource.TestStep{
130+
{
131+
Config: `resource scaleway_vpc_private_network test {}`,
132+
Check: resource.ComposeTestCheckFunc(
133+
testAccCheckScalewayVPCPrivateNetworkExists(
134+
tt,
135+
"scaleway_vpc_private_network.test",
136+
),
137+
resource.TestCheckResourceAttr(
138+
"scaleway_vpc_private_network.test",
139+
"subnets.#",
140+
"2",
141+
),
142+
),
143+
},
144+
{
145+
Config: `resource scaleway_vpc_private_network test {
146+
subnets = ["10.20.0.0/22", "fd21:e31e:86f0:f2c6::/64"]
147+
}`,
148+
Check: resource.ComposeTestCheckFunc(
149+
testAccCheckScalewayVPCPrivateNetworkExists(
150+
tt,
151+
"scaleway_vpc_private_network.test",
152+
),
153+
resource.TestCheckTypeSetElemAttr(
154+
"scaleway_vpc_private_network.test",
155+
"subnets.*",
156+
"10.20.0.0/22",
157+
),
158+
resource.TestCheckTypeSetElemAttr(
159+
"scaleway_vpc_private_network.test",
160+
"subnets.*",
161+
"fd21:e31e:86f0:f2c6::/64",
162+
),
163+
resource.TestCheckResourceAttr(
164+
"scaleway_vpc_private_network.test",
165+
"subnets.#",
166+
"2",
167+
),
168+
),
169+
},
170+
},
171+
})
172+
}
173+
110174
func testAccCheckScalewayVPCPrivateNetworkExists(tt *TestTools, n string) resource.TestCheckFunc {
111175
return func(s *terraform.State) error {
112176
rs, ok := s.RootModule().Resources[n]

0 commit comments

Comments
 (0)