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

fix(lb): check private network status #1259

Merged
merged 7 commits into from
May 5, 2022
Merged
Show file tree
Hide file tree
Changes from 4 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
77 changes: 75 additions & 2 deletions docs/resources/lb.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,80 @@ resource "scaleway_lb" "base" {
ip_id = scaleway_lb_ip.ip.id
zone = scaleway_lb_ip.ip.zone
type = "LB-S"
release_ip = false
}
```

### Multiple configurations

```hcl
### IP for LB IP
resource scaleway_lb_ip ip01 {
}

### IP for Public Gateway
resource "scaleway_vpc_public_gateway_ip" "main" {
}

### Scaleway Private Network
resource scaleway_vpc_private_network main {
name = "private network with static config"
}

### The Public Gateway with the Attached IP
resource "scaleway_vpc_public_gateway" "main" {
name = "tf-test-public-gw"
type = "VPC-GW-S"
ip_id = scaleway_vpc_public_gateway_ip.main.id
}

### Scaleway Private Network
resource "scaleway_vpc_private_network" "pn" {
name = "private network with a DHCP config"
}

### DHCP Space of VPC
resource "scaleway_vpc_public_gateway_dhcp" "main" {
subnet = "10.0.0.0/24"
}

### VPC Gateway Network
resource "scaleway_vpc_gateway_network" "main" {
gateway_id = scaleway_vpc_public_gateway.main.id
private_network_id = scaleway_vpc_private_network.pn.id
dhcp_id = scaleway_vpc_public_gateway_dhcp.main.id
cleanup_dhcp = true
enable_masquerade = true
}

### Scaleway Instance
resource "scaleway_instance_server" "main" {
name = "Scaleway Terraform Provider"
type = "DEV1-S"
image = "debian_bullseye"
enable_ipv6 = false

private_network {
pn_id = scaleway_vpc_private_network.pn.id
}
}


resource scaleway_lb lb01 {
ip_id = scaleway_lb_ip.ip01.id
name = "test-lb-with-private-network-configs"
type = "LB-S"

private_network {
private_network_id = scaleway_vpc_private_network.main.id
static_config = ["172.16.0.100", "172.16.0.101"]
}

private_network {
private_network_id = scaleway_vpc_private_network.pn.id
dhcp_config = true
}

depends_on = [scaleway_vpc_public_gateway.main]
}
```

Expand Down Expand Up @@ -87,7 +160,7 @@ resource "scaleway_lb" "base" {
}
```

## Private Network
## Private Network with static config

```hcl
resource scaleway_lb_ip ip01 {
Expand Down
42 changes: 38 additions & 4 deletions scaleway/helpers_lb.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"time"

"github.com/hashicorp/go-cty/cty"
"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
lbSDK "github.com/scaleway/scaleway-sdk-go/api/lb/v1"
"github.com/scaleway/scaleway-sdk-go/scw"
Expand Down Expand Up @@ -173,15 +174,14 @@ func privateNetworksToDetach(pns []*lbSDK.PrivateNetwork, updates interface{}) (
return actions, nil
}

func flattenPrivateNetworkConfigs(resList *lbSDK.ListLBPrivateNetworksResponse) interface{} {
if len(resList.PrivateNetwork) == 0 || resList == nil {
func flattenPrivateNetworkConfigs(privateNetworks []*lbSDK.PrivateNetwork) interface{} {
if len(privateNetworks) == 0 || privateNetworks == nil {
return nil
}

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

return certificate, err
}

func attachLBPrivateNetwork(ctx context.Context, lbAPI *lbSDK.ZonedAPI, zone scw.Zone, pnConfigs []*lbSDK.ZonedAPIAttachPrivateNetworkRequest, timeout time.Duration) ([]*lbSDK.PrivateNetwork, error) {
var privateNetworks []*lbSDK.PrivateNetwork

for _, config := range pnConfigs {
pn, err := lbAPI.AttachPrivateNetwork(config, scw.WithContext(ctx))
if err != nil && !is404Error(err) {
return nil, err
}

privateNetworks, err = waitForLBPN(ctx, lbAPI, zone, pn.LB.ID, timeout)
if err != nil && !is404Error(err) {
return nil, err
}

for _, pn := range privateNetworks {
if pn.Status == lbSDK.PrivateNetworkStatusError {
err = lbAPI.DetachPrivateNetwork(&lbSDK.ZonedAPIDetachPrivateNetworkRequest{
Zone: zone,
LBID: pn.LB.ID,
PrivateNetworkID: pn.PrivateNetworkID,
}, scw.WithContext(ctx))
if err != nil && !is404Error(err) {
return nil, err
}
tflog.Debug(ctx, fmt.Sprintf("DHCP config: %v", pn.DHCPConfig))
tflog.Debug(ctx, fmt.Sprintf("Static config: %v", pn.StaticConfig))
return nil, fmt.Errorf("attaching private network with id: %s on error state. please check your config", pn.PrivateNetworkID)
}
}
}

return privateNetworks, nil
}
48 changes: 30 additions & 18 deletions scaleway/resource_lb.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ package scaleway

import (
"context"
"fmt"
"strings"
"time"

"github.com/hashicorp/terraform-plugin-log/tflog"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
Expand Down Expand Up @@ -69,7 +71,6 @@ func resourceScalewayLb() *schema.Resource {
"release_ip": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Release the IPs related to this load-balancer",
Deprecated: "The resource ip will be destroyed by it's own resource. Please set this to `false`",
},
Expand All @@ -90,7 +91,6 @@ func resourceScalewayLb() *schema.Resource {
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.",
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validation.IsIPAddress,
Expand All @@ -100,7 +100,6 @@ func resourceScalewayLb() *schema.Resource {
Description: "Set to true if you want to let DHCP assign IP addresses",
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
// Readonly attributes
"status": {
Expand Down Expand Up @@ -160,12 +159,11 @@ func resourceScalewayLbCreate(ctx context.Context, d *schema.ResourceData, meta
return diag.FromErr(err)
}

for _, config := range pnConfigs {
_, err := lbAPI.AttachPrivateNetwork(config, scw.WithContext(ctx))
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}
_, err = attachLBPrivateNetwork(ctx, lbAPI, zone, pnConfigs, d.Timeout(schema.TimeoutCreate))
if err != nil {
return diag.FromErr(err)
}

_, err = waitForLB(ctx, lbAPI, zone, lb.ID, d.Timeout(schema.TimeoutCreate))
if err != nil {
return diag.FromErr(err)
Expand Down Expand Up @@ -201,24 +199,23 @@ func resourceScalewayLbRead(ctx context.Context, d *schema.ResourceData, meta in
_ = d.Set("region", region.String())
_ = d.Set("organization_id", lb.OrganizationID)
_ = d.Set("project_id", lb.ProjectID)
_ = d.Set("tags", lb.Tags)
if len(lb.Tags) > 0 {
_ = d.Set("tags", lb.Tags)
}
// For now API return lowercase lb type. This should be fixed in a near future on the API side
_ = d.Set("type", strings.ToUpper(lb.Type))
_ = d.Set("ip_id", newZonedIDString(zone, lb.IP[0].ID))
_ = d.Set("ip_address", lb.IP[0].IPAddress)

// retrieve attached private networks
resPN, err := lbAPI.ListLBPrivateNetworks(&lbSDK.ZonedAPIListLBPrivateNetworksRequest{
Zone: zone,
LBID: ID,
}, scw.WithContext(ctx))
privateNetworks, err := waitForLBPN(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutRead))
if err != nil {
if is404Error(err) {
return nil
}
return diag.FromErr(err)
}
_ = d.Set("private_network", flattenPrivateNetworkConfigs(resPN))
_ = d.Set("private_network", flattenPrivateNetworkConfigs(privateNetworks))

return nil
}
Expand Down Expand Up @@ -251,7 +248,7 @@ func resourceScalewayLbUpdate(ctx context.Context, d *schema.ResourceData, meta
////
// Attach / Detach Private Networks
////
if d.HasChangesExcept("private_network") {
if d.HasChange("private_network") {
// check that pns are in a stable state
pns, err := waitForLBPN(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
if err != nil && !is404Error(err) {
Expand All @@ -269,7 +266,7 @@ func resourceScalewayLbUpdate(ctx context.Context, d *schema.ResourceData, meta
Zone: zone,
LBID: ID,
PrivateNetworkID: pnID,
})
}, scw.WithContext(ctx))
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -301,10 +298,25 @@ func resourceScalewayLbUpdate(ctx context.Context, d *schema.ResourceData, meta
}
}

_, err = waitForLBPN(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
privateNetworks, err := waitForLBPN(ctx, lbAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}

for _, pn := range privateNetworks {
tflog.Debug(ctx, fmt.Sprintf("PrivateNetwork ID %s state: %v", pn.PrivateNetworkID, pn.Status))
if pn.Status == lbSDK.PrivateNetworkStatusError {
err = lbAPI.DetachPrivateNetwork(&lbSDK.ZonedAPIDetachPrivateNetworkRequest{
Zone: zone,
LBID: ID,
PrivateNetworkID: pn.PrivateNetworkID,
}, scw.WithContext(ctx))
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}
return diag.Errorf("attaching private network with id: %s on error state. please check your config", pn.PrivateNetworkID)
}
}
}
}

Expand Down Expand Up @@ -338,7 +350,7 @@ func resourceScalewayLbDelete(ctx context.Context, d *schema.ResourceData, meta
Zone: zone,
LBID: ID,
PrivateNetworkID: pn.PrivateNetworkID,
})
}, scw.WithContext(ctx))
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}
Expand Down
Loading