Skip to content

Commit 03fdc67

Browse files
authored
fix(lb): check private network status (#1259)
1 parent 5bba67b commit 03fdc67

6 files changed

+6767
-1547
lines changed

docs/resources/lb.md

+75-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,80 @@ resource "scaleway_lb" "base" {
2222
ip_id = scaleway_lb_ip.ip.id
2323
zone = scaleway_lb_ip.ip.zone
2424
type = "LB-S"
25-
release_ip = false
25+
}
26+
```
27+
28+
### Multiple configurations
29+
30+
```hcl
31+
### IP for LB IP
32+
resource scaleway_lb_ip ip01 {
33+
}
34+
35+
### IP for Public Gateway
36+
resource "scaleway_vpc_public_gateway_ip" "main" {
37+
}
38+
39+
### Scaleway Private Network
40+
resource scaleway_vpc_private_network main {
41+
name = "private network with static config"
42+
}
43+
44+
### The Public Gateway with the Attached IP
45+
resource "scaleway_vpc_public_gateway" "main" {
46+
name = "tf-test-public-gw"
47+
type = "VPC-GW-S"
48+
ip_id = scaleway_vpc_public_gateway_ip.main.id
49+
}
50+
51+
### Scaleway Private Network
52+
resource "scaleway_vpc_private_network" "pn" {
53+
name = "private network with a DHCP config"
54+
}
55+
56+
### DHCP Space of VPC
57+
resource "scaleway_vpc_public_gateway_dhcp" "main" {
58+
subnet = "10.0.0.0/24"
59+
}
60+
61+
### VPC Gateway Network
62+
resource "scaleway_vpc_gateway_network" "main" {
63+
gateway_id = scaleway_vpc_public_gateway.main.id
64+
private_network_id = scaleway_vpc_private_network.pn.id
65+
dhcp_id = scaleway_vpc_public_gateway_dhcp.main.id
66+
cleanup_dhcp = true
67+
enable_masquerade = true
68+
}
69+
70+
### Scaleway Instance
71+
resource "scaleway_instance_server" "main" {
72+
name = "Scaleway Terraform Provider"
73+
type = "DEV1-S"
74+
image = "debian_bullseye"
75+
enable_ipv6 = false
76+
77+
private_network {
78+
pn_id = scaleway_vpc_private_network.pn.id
79+
}
80+
}
81+
82+
83+
resource scaleway_lb lb01 {
84+
ip_id = scaleway_lb_ip.ip01.id
85+
name = "test-lb-with-private-network-configs"
86+
type = "LB-S"
87+
88+
private_network {
89+
private_network_id = scaleway_vpc_private_network.main.id
90+
static_config = ["172.16.0.100", "172.16.0.101"]
91+
}
92+
93+
private_network {
94+
private_network_id = scaleway_vpc_private_network.pn.id
95+
dhcp_config = true
96+
}
97+
98+
depends_on = [scaleway_vpc_public_gateway.main]
2699
}
27100
```
28101

@@ -87,7 +160,7 @@ resource "scaleway_lb" "base" {
87160
}
88161
```
89162

90-
## Private Network
163+
## Private Network with static config
91164

92165
```hcl
93166
resource scaleway_lb_ip ip01 {

scaleway/helpers_lb.go

+38-4
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-log/tflog"
1112
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1213
lbSDK "github.com/scaleway/scaleway-sdk-go/api/lb/v1"
1314
"github.com/scaleway/scaleway-sdk-go/scw"
@@ -173,15 +174,14 @@ func privateNetworksToDetach(pns []*lbSDK.PrivateNetwork, updates interface{}) (
173174
return actions, nil
174175
}
175176

176-
func flattenPrivateNetworkConfigs(resList *lbSDK.ListLBPrivateNetworksResponse) interface{} {
177-
if len(resList.PrivateNetwork) == 0 || resList == nil {
177+
func flattenPrivateNetworkConfigs(privateNetworks []*lbSDK.PrivateNetwork) interface{} {
178+
if len(privateNetworks) == 0 || privateNetworks == nil {
178179
return nil
179180
}
180181

181-
pnConfigs := resList.PrivateNetwork
182182
pnI := []map[string]interface{}(nil)
183183
var dhcpConfigExist bool
184-
for _, pn := range pnConfigs {
184+
for _, pn := range privateNetworks {
185185
if pn.DHCPConfig != nil {
186186
dhcpConfigExist = true
187187
}
@@ -498,3 +498,37 @@ func waitForLBCertificate(ctx context.Context, lbAPI *lbSDK.ZonedAPI, zone scw.Z
498498

499499
return certificate, err
500500
}
501+
502+
func attachLBPrivateNetwork(ctx context.Context, lbAPI *lbSDK.ZonedAPI, zone scw.Zone, pnConfigs []*lbSDK.ZonedAPIAttachPrivateNetworkRequest, timeout time.Duration) ([]*lbSDK.PrivateNetwork, error) {
503+
var privateNetworks []*lbSDK.PrivateNetwork
504+
505+
for _, config := range pnConfigs {
506+
pn, err := lbAPI.AttachPrivateNetwork(config, scw.WithContext(ctx))
507+
if err != nil && !is404Error(err) {
508+
return nil, err
509+
}
510+
511+
privateNetworks, err = waitForLBPN(ctx, lbAPI, zone, pn.LB.ID, timeout)
512+
if err != nil && !is404Error(err) {
513+
return nil, err
514+
}
515+
516+
for _, pn := range privateNetworks {
517+
if pn.Status == lbSDK.PrivateNetworkStatusError {
518+
err = lbAPI.DetachPrivateNetwork(&lbSDK.ZonedAPIDetachPrivateNetworkRequest{
519+
Zone: zone,
520+
LBID: pn.LB.ID,
521+
PrivateNetworkID: pn.PrivateNetworkID,
522+
}, scw.WithContext(ctx))
523+
if err != nil && !is404Error(err) {
524+
return nil, err
525+
}
526+
tflog.Debug(ctx, fmt.Sprintf("DHCP config: %v", pn.DHCPConfig))
527+
tflog.Debug(ctx, fmt.Sprintf("Static config: %v", pn.StaticConfig))
528+
return nil, fmt.Errorf("attaching private network with id: %s on error state. please check your config", pn.PrivateNetworkID)
529+
}
530+
}
531+
}
532+
533+
return privateNetworks, nil
534+
}

scaleway/resource_lb.go

+27-17
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package scaleway
22

33
import (
44
"context"
5+
"fmt"
56
"strings"
67
"time"
78

9+
"github.com/hashicorp/terraform-plugin-log/tflog"
810
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
911
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1012
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
@@ -69,7 +71,6 @@ func resourceScalewayLb() *schema.Resource {
6971
"release_ip": {
7072
Type: schema.TypeBool,
7173
Optional: true,
72-
Default: false,
7374
Description: "Release the IPs related to this load-balancer",
7475
Deprecated: "The resource ip will be destroyed by it's own resource. Please set this to `false`",
7576
},
@@ -90,7 +91,6 @@ func resourceScalewayLb() *schema.Resource {
9091
Description: "Define two IP addresses in the subnet of your private network that will be assigned for the principal and standby node of your load balancer.",
9192
Type: schema.TypeList,
9293
Optional: true,
93-
Computed: true,
9494
Elem: &schema.Schema{
9595
Type: schema.TypeString,
9696
ValidateFunc: validation.IsIPAddress,
@@ -100,7 +100,6 @@ func resourceScalewayLb() *schema.Resource {
100100
Description: "Set to true if you want to let DHCP assign IP addresses",
101101
Type: schema.TypeBool,
102102
Optional: true,
103-
Computed: true,
104103
},
105104
// Readonly attributes
106105
"status": {
@@ -160,12 +159,11 @@ func resourceScalewayLbCreate(ctx context.Context, d *schema.ResourceData, meta
160159
return diag.FromErr(err)
161160
}
162161

163-
for _, config := range pnConfigs {
164-
_, err := lbAPI.AttachPrivateNetwork(config, scw.WithContext(ctx))
165-
if err != nil && !is404Error(err) {
166-
return diag.FromErr(err)
167-
}
162+
_, err = attachLBPrivateNetwork(ctx, lbAPI, zone, pnConfigs, d.Timeout(schema.TimeoutCreate))
163+
if err != nil {
164+
return diag.FromErr(err)
168165
}
166+
169167
_, err = waitForLB(ctx, lbAPI, zone, lb.ID, d.Timeout(schema.TimeoutCreate))
170168
if err != nil {
171169
return diag.FromErr(err)
@@ -208,17 +206,14 @@ func resourceScalewayLbRead(ctx context.Context, d *schema.ResourceData, meta in
208206
_ = d.Set("ip_address", lb.IP[0].IPAddress)
209207

210208
// retrieve attached private networks
211-
resPN, err := lbAPI.ListLBPrivateNetworks(&lbSDK.ZonedAPIListLBPrivateNetworksRequest{
212-
Zone: zone,
213-
LBID: ID,
214-
}, scw.WithContext(ctx))
209+
privateNetworks, err := waitForLBPN(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutRead))
215210
if err != nil {
216211
if is404Error(err) {
217212
return nil
218213
}
219214
return diag.FromErr(err)
220215
}
221-
_ = d.Set("private_network", flattenPrivateNetworkConfigs(resPN))
216+
_ = d.Set("private_network", flattenPrivateNetworkConfigs(privateNetworks))
222217

223218
return nil
224219
}
@@ -251,7 +246,7 @@ func resourceScalewayLbUpdate(ctx context.Context, d *schema.ResourceData, meta
251246
////
252247
// Attach / Detach Private Networks
253248
////
254-
if d.HasChangesExcept("private_network") {
249+
if d.HasChange("private_network") {
255250
// check that pns are in a stable state
256251
pns, err := waitForLBPN(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
257252
if err != nil && !is404Error(err) {
@@ -269,7 +264,7 @@ func resourceScalewayLbUpdate(ctx context.Context, d *schema.ResourceData, meta
269264
Zone: zone,
270265
LBID: ID,
271266
PrivateNetworkID: pnID,
272-
})
267+
}, scw.WithContext(ctx))
273268
if err != nil && !is404Error(err) {
274269
return diag.FromErr(err)
275270
}
@@ -301,10 +296,25 @@ func resourceScalewayLbUpdate(ctx context.Context, d *schema.ResourceData, meta
301296
}
302297
}
303298

304-
_, err = waitForLBPN(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
299+
privateNetworks, err := waitForLBPN(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
305300
if err != nil && !is404Error(err) {
306301
return diag.FromErr(err)
307302
}
303+
304+
for _, pn := range privateNetworks {
305+
tflog.Debug(ctx, fmt.Sprintf("PrivateNetwork ID %s state: %v", pn.PrivateNetworkID, pn.Status))
306+
if pn.Status == lbSDK.PrivateNetworkStatusError {
307+
err = lbAPI.DetachPrivateNetwork(&lbSDK.ZonedAPIDetachPrivateNetworkRequest{
308+
Zone: zone,
309+
LBID: ID,
310+
PrivateNetworkID: pn.PrivateNetworkID,
311+
}, scw.WithContext(ctx))
312+
if err != nil && !is404Error(err) {
313+
return diag.FromErr(err)
314+
}
315+
return diag.Errorf("attaching private network with id: %s on error state. please check your config", pn.PrivateNetworkID)
316+
}
317+
}
308318
}
309319
}
310320

@@ -338,7 +348,7 @@ func resourceScalewayLbDelete(ctx context.Context, d *schema.ResourceData, meta
338348
Zone: zone,
339349
LBID: ID,
340350
PrivateNetworkID: pn.PrivateNetworkID,
341-
})
351+
}, scw.WithContext(ctx))
342352
if err != nil && !is404Error(err) {
343353
return diag.FromErr(err)
344354
}

0 commit comments

Comments
 (0)