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

chore(vpc): add support for quick retries with cassettes #1198

Merged
merged 14 commits into from
Apr 12, 2022
35 changes: 34 additions & 1 deletion scaleway/helpers_vpcgw.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package scaleway

import (
"context"
"time"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
Expand All @@ -9,8 +10,8 @@ import (
)

const (
gatewayWaitForTimeout = 10 * time.Minute
defaultVPCGatewayTimeout = 10 * time.Minute
defaultVPCGatewayRetry = 5 * time.Second
)

// vpcgwAPIWithZone returns a new VPC API and the zone for a Create request
Expand All @@ -36,3 +37,35 @@ func vpcgwAPIWithZoneAndID(m interface{}, id string) (*vpcgw.API, scw.Zone, stri
}
return vpcgwAPI, zone, ID, nil
}

func waitForVPCPublicGateway(ctx context.Context, api *vpcgw.API, zone scw.Zone, id string, timeout time.Duration) (*vpcgw.Gateway, error) {
retryInterval := defaultVPCGatewayRetry
if DefaultWaitRetryInterval != nil {
retryInterval = *DefaultWaitRetryInterval
}

gateway, err := api.WaitForGateway(&vpcgw.WaitForGatewayRequest{
Timeout: scw.TimeDurationPtr(timeout),
GatewayID: id,
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))

return gateway, err
}

func waitForVPCGatewayNetwork(ctx context.Context, api *vpcgw.API, zone scw.Zone, id string, timeout time.Duration) (*vpcgw.GatewayNetwork, error) {
retryIntervalGWNetwork := defaultVPCGatewayRetry
if DefaultWaitRetryInterval != nil {
retryIntervalGWNetwork = *DefaultWaitRetryInterval
}

gatewayNetwork, err := api.WaitForGatewayNetwork(&vpcgw.WaitForGatewayNetworkRequest{
GatewayNetworkID: id,
Timeout: scw.TimeDurationPtr(timeout),
RetryInterval: &retryIntervalGWNetwork,
Zone: zone,
}, scw.WithContext(ctx))

return gatewayNetwork, err
}
149 changes: 24 additions & 125 deletions scaleway/resource_vpc_gateway_network.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ import (
"github.com/scaleway/scaleway-sdk-go/scw"
)

const (
retryIntervalVPCGatewayNetwork = 1 * time.Minute
retryGWTimeout = 2 * time.Minute
)

func resourceScalewayVPCGatewayNetwork() *schema.Resource {
return &schema.Resource{
CreateContext: resourceScalewayVPCGatewayNetworkCreate,
Expand Down Expand Up @@ -91,27 +86,21 @@ func resourceScalewayVPCGatewayNetwork() *schema.Resource {
}

func resourceScalewayVPCGatewayNetworkCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vpcgwNetworkAPI, zone, err := vpcgwAPIWithZone(d, meta)
vpcgwAPI, zone, err := vpcgwAPIWithZone(d, meta)
if err != nil {
return diag.FromErr(err)
}

retryInterval := retryGWTimeout
gatewayID := expandZonedID(d.Get("gateway_id").(string)).ID
gw, err := vpcgwNetworkAPI.WaitForGateway(&vpcgw.WaitForGatewayRequest{
GatewayID: gatewayID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
// check err waiting process

gateway, err := waitForVPCPublicGateway(ctx, vpcgwAPI, zone, gatewayID, d.Timeout(schema.TimeoutCreate))
if err != nil {
return diag.FromErr(err)
}

req := &vpcgw.CreateGatewayNetworkRequest{
Zone: zone,
GatewayID: gw.ID,
GatewayID: gateway.ID,
PrivateNetworkID: expandZonedID(d.Get("private_network_id").(string)).ID,
EnableMasquerade: *expandBoolPtr(d.Get("enable_masquerade")),
EnableDHCP: expandBoolPtr(d.Get("enable_dhcp")),
Expand All @@ -131,63 +120,37 @@ func resourceScalewayVPCGatewayNetworkCreate(ctx context.Context, d *schema.Reso
req.DHCPID = &dhcpZoned.ID
}

gatewayNetwork, err := vpcgwNetworkAPI.CreateGatewayNetwork(req, scw.WithContext(ctx))
gatewayNetwork, err := vpcgwAPI.CreateGatewayNetwork(req, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

gw, err = vpcgwNetworkAPI.WaitForGateway(&vpcgw.WaitForGatewayRequest{
GatewayID: gatewayID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
// check err waiting process
d.SetId(newZonedIDString(zone, gatewayNetwork.ID))

_, err = waitForVPCPublicGateway(ctx, vpcgwAPI, zone, gatewayNetwork.GatewayID, d.Timeout(schema.TimeoutCreate))
if err != nil {
return diag.FromErr(err)
}

retryInterval = retryIntervalVPCGatewayNetwork
gatewayNetwork, err = vpcgwNetworkAPI.WaitForGatewayNetwork(&vpcgw.WaitForGatewayNetworkRequest{
GatewayNetworkID: gatewayNetwork.ID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
_, err = waitForVPCGatewayNetwork(ctx, vpcgwAPI, zone, gatewayNetwork.ID, d.Timeout(schema.TimeoutCreate))
if err != nil {
return diag.FromErr(err)
}

d.SetId(newZonedIDString(zone, gatewayNetwork.ID))

return resourceScalewayVPCGatewayNetworkRead(ctx, d, meta)
}

func resourceScalewayVPCGatewayNetworkRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vpcgwNetworkAPI, zone, ID, err := vpcgwAPIWithZoneAndID(meta, d.Id())
vpcgwAPI, zone, ID, err := vpcgwAPIWithZoneAndID(meta, d.Id())
if err != nil {
return diag.FromErr(err)
}

readGWNetwork := &vpcgw.GetGatewayNetworkRequest{
GatewayNetworkID: ID,
Zone: zone,
}

gatewayID := expandZonedID(d.Get("gateway_id").(string)).ID
retryInterval := retryGWTimeout
_, err = vpcgwNetworkAPI.WaitForGateway(&vpcgw.WaitForGatewayRequest{
GatewayID: gatewayID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
// check err waiting process
gatewayNetwork, err := waitForVPCGatewayNetwork(ctx, vpcgwAPI, zone, ID, d.Timeout(schema.TimeoutRead))
if err != nil {
return diag.FromErr(err)
}

gatewayNetwork, err := vpcgwNetworkAPI.GetGatewayNetwork(readGWNetwork, scw.WithContext(ctx))
_, err = waitForVPCPublicGateway(ctx, vpcgwAPI, zone, gatewayNetwork.GatewayID, d.Timeout(schema.TimeoutRead))
if err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -218,13 +181,7 @@ func resourceScalewayVPCGatewayNetworkRead(ctx context.Context, d *schema.Resour
cleanUpDHCPValue = *expandBoolPtr(cleanUpDHCP)
}

retryInterval = retryIntervalVPCGatewayNetwork
gatewayNetwork, err = vpcgwNetworkAPI.WaitForGatewayNetwork(&vpcgw.WaitForGatewayNetworkRequest{
GatewayNetworkID: gatewayNetwork.ID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
gatewayNetwork, err = waitForVPCGatewayNetwork(ctx, vpcgwAPI, zone, gatewayNetwork.ID, d.Timeout(schema.TimeoutRead))
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -246,26 +203,7 @@ func resourceScalewayVPCGatewayNetworkUpdate(ctx context.Context, d *schema.Reso
return diag.FromErr(err)
}

gatewayID := expandZonedID(d.Get("gateway_id").(string)).ID
retryInterval := retryGWTimeout
_, err = vpcgwAPI.WaitForGateway(&vpcgw.WaitForGatewayRequest{
GatewayID: gatewayID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
// check err waiting process
if err != nil {
return diag.FromErr(err)
}

retryInterval = retryIntervalVPCGatewayNetwork
_, err = vpcgwAPI.WaitForGatewayNetwork(&vpcgw.WaitForGatewayNetworkRequest{
GatewayNetworkID: ID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
_, err = waitForVPCGatewayNetwork(ctx, vpcgwAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
if err != nil {
return diag.FromErr(err)
}
Expand Down Expand Up @@ -294,24 +232,7 @@ func resourceScalewayVPCGatewayNetworkUpdate(ctx context.Context, d *schema.Reso
}
}

_, err = vpcgwAPI.WaitForGatewayNetwork(&vpcgw.WaitForGatewayNetworkRequest{
GatewayNetworkID: ID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

retryInterval = retryGWTimeout
_, err = vpcgwAPI.WaitForGateway(&vpcgw.WaitForGatewayRequest{
GatewayID: gatewayID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
// check err waiting process
_, err = waitForVPCGatewayNetwork(ctx, vpcgwAPI, zone, ID, d.Timeout(schema.TimeoutUpdate))
if err != nil {
return diag.FromErr(err)
}
Expand All @@ -320,54 +241,32 @@ func resourceScalewayVPCGatewayNetworkUpdate(ctx context.Context, d *schema.Reso
}

func resourceScalewayVPCGatewayNetworkDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vpcgwAPI, zone, ID, err := vpcgwAPIWithZoneAndID(meta, d.Id())
vpcgwAPI, zone, id, err := vpcgwAPIWithZoneAndID(meta, d.Id())
if err != nil {
return diag.FromErr(err)
}

gatewayID := expandZonedID(d.Get("gateway_id").(string)).ID
retryInterval := retryGWTimeout
_, err = vpcgwAPI.WaitForGateway(&vpcgw.WaitForGatewayRequest{
GatewayID: gatewayID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
// check err waiting process
if err != nil {
return diag.FromErr(err)
}

retryInterval = retryIntervalVPCGatewayNetwork
gwNetwork, err := vpcgwAPI.WaitForGatewayNetwork(&vpcgw.WaitForGatewayNetworkRequest{
GatewayNetworkID: ID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
gwNetwork, err := waitForVPCGatewayNetwork(ctx, vpcgwAPI, zone, id, d.Timeout(schema.TimeoutDelete))
if err != nil {
return diag.FromErr(err)
}

req := &vpcgw.DeleteGatewayNetworkRequest{
GatewayNetworkID: gwNetwork.ID,
Zone: zone,
Zone: gwNetwork.Zone,
CleanupDHCP: *expandBoolPtr(d.Get("cleanup_dhcp")),
}

err = vpcgwAPI.DeleteGatewayNetwork(req, scw.WithContext(ctx))
if err != nil {
return diag.FromErr(err)
}

//check gateway is in stable state.
retryInterval = retryGWTimeout
_, err = vpcgwAPI.WaitForGateway(&vpcgw.WaitForGatewayRequest{
GatewayID: gatewayID,
Timeout: scw.TimeDurationPtr(defaultVPCGatewayTimeout),
RetryInterval: &retryInterval,
Zone: zone,
}, scw.WithContext(ctx))
_, err = waitForVPCGatewayNetwork(ctx, vpcgwAPI, zone, id, d.Timeout(schema.TimeoutDelete))
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}

_, err = waitForVPCPublicGateway(ctx, vpcgwAPI, zone, gwNetwork.GatewayID, d.Timeout(schema.TimeoutDelete))
if err != nil && !is404Error(err) {
return diag.FromErr(err)
}
Expand Down
Loading