Skip to content

Commit

Permalink
Merge branch 'main' into CXF-90011-Metal-NIMF-Update
Browse files Browse the repository at this point in the history
  • Loading branch information
srushti-patl authored Mar 29, 2024
2 parents 5a65da5 + 4d0b305 commit 8868f87
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 93 deletions.
4 changes: 2 additions & 2 deletions equinix/data_source_fabric_cloud_router_acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestAccDataSourceFabricCloudRouter_PFCR(t *testing.T) {
resource.TestCheckResourceAttr("data.equinix_fabric_cloud_router.example", "notifications.0.emails.0", "[email protected]"),
resource.TestCheckResourceAttr("data.equinix_fabric_cloud_router.example", "order.0.purchase_order_number", "1-323292"),
resource.TestCheckResourceAttr("data.equinix_fabric_cloud_router.example", "location.0.metro_code", "SV"),
resource.TestCheckResourceAttr("data.equinix_fabric_cloud_router.example", "package.0.code", "LAB"),
resource.TestCheckResourceAttr("data.equinix_fabric_cloud_router.example", "package.0.code", "STANDARD"),
resource.TestCheckResourceAttrSet("data.equinix_fabric_cloud_router.example", "project.0.project_id"),
resource.TestCheckResourceAttrSet("data.equinix_fabric_cloud_router.example", "account.0.account_number"),
resource.TestCheckResourceAttrSet("data.equinix_fabric_cloud_router.example", "href"),
Expand Down Expand Up @@ -62,7 +62,7 @@ func ConfigCreateCloudRouterResource_PFCR() string {
metro_code= "SV"
}
package {
code="LAB"
code="STANDARD"
}
project {
project_id = "291639000636552"
Expand Down
33 changes: 20 additions & 13 deletions equinix/resource_fabric_cloud_router.go
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,10 @@ func fabricCloudRouterResourceSchema() map[string]*schema.Schema {
func resourceFabricCloudRouter() *schema.Resource {
return &schema.Resource{
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(6 * time.Minute),
Create: schema.DefaultTimeout(10 * time.Minute),
Update: schema.DefaultTimeout(10 * time.Minute),
Delete: schema.DefaultTimeout(6 * time.Minute),
Read: schema.DefaultTimeout(6 * time.Minute),
Delete: schema.DefaultTimeout(10 * time.Minute),
Read: schema.DefaultTimeout(10 * time.Minute),
},
ReadContext: resourceFabricCloudRouterRead,
CreateContext: resourceFabricCloudRouterCreate,
Expand Down Expand Up @@ -278,13 +278,15 @@ func resourceFabricCloudRouterCreate(ctx context.Context, d *schema.ResourceData
createRequest.Order = &order
}

start := time.Now()
fcr, _, err := client.CloudRoutersApi.CreateCloudRouter(ctx, createRequest)
if err != nil {
return diag.FromErr(equinix_errors.FormatFabricError(err))
}
d.SetId(fcr.Uuid)

if _, err = waitUntilCloudRouterIsProvisioned(d.Id(), meta, ctx); err != nil {
createTimeout := d.Timeout(schema.TimeoutCreate) - 30*time.Second - time.Since(start)
if _, err = waitUntilCloudRouterIsProvisioned(d.Id(), meta, ctx, createTimeout); err != nil {
return diag.Errorf("error waiting for Cloud Router (%s) to be created: %s", d.Id(), err)
}

Expand Down Expand Up @@ -387,7 +389,9 @@ func getCloudRouterUpdateRequest(conn v4.CloudRouter, d *schema.ResourceData) (v
func resourceFabricCloudRouterUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*config.Config).FabricClient
ctx = context.WithValue(ctx, v4.ContextAccessToken, meta.(*config.Config).FabricAuthToken)
dbConn, err := waitUntilCloudRouterIsProvisioned(d.Id(), meta, ctx)
start := time.Now()
updateTimeout := d.Timeout(schema.TimeoutUpdate) - 30*time.Second - time.Since(start)
dbConn, err := waitUntilCloudRouterIsProvisioned(d.Id(), meta, ctx, updateTimeout)
if err != nil {
if !strings.Contains(err.Error(), "500") {
d.SetId("")
Expand All @@ -405,7 +409,8 @@ func resourceFabricCloudRouterUpdate(ctx context.Context, d *schema.ResourceData
return diag.FromErr(equinix_errors.FormatFabricError(err))
}
updateFg := v4.CloudRouter{}
updateFg, err = waitForCloudRouterUpdateCompletion(d.Id(), meta, ctx)
updateTimeout = d.Timeout(schema.TimeoutUpdate) - 30*time.Second - time.Since(start)
updateFg, err = waitForCloudRouterUpdateCompletion(d.Id(), meta, ctx, updateTimeout)

if err != nil {
if !strings.Contains(err.Error(), "500") {
Expand All @@ -418,7 +423,7 @@ func resourceFabricCloudRouterUpdate(ctx context.Context, d *schema.ResourceData
return setCloudRouterMap(d, updateFg)
}

func waitForCloudRouterUpdateCompletion(uuid string, meta interface{}, ctx context.Context) (v4.CloudRouter, error) {
func waitForCloudRouterUpdateCompletion(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) (v4.CloudRouter, error) {
log.Printf("Waiting for Cloud Router update to complete, uuid %s", uuid)
stateConf := &retry.StateChangeConf{
Target: []string{string(v4.PROVISIONED_CloudRouterAccessPointState)},
Expand All @@ -430,7 +435,7 @@ func waitForCloudRouterUpdateCompletion(uuid string, meta interface{}, ctx conte
}
return dbConn, string(*dbConn.State), nil
},
Timeout: 2 * time.Minute,
Timeout: timeout,
Delay: 30 * time.Second,
MinTimeout: 30 * time.Second,
}
Expand All @@ -444,7 +449,7 @@ func waitForCloudRouterUpdateCompletion(uuid string, meta interface{}, ctx conte
return dbConn, err
}

func waitUntilCloudRouterIsProvisioned(uuid string, meta interface{}, ctx context.Context) (v4.CloudRouter, error) {
func waitUntilCloudRouterIsProvisioned(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) (v4.CloudRouter, error) {
log.Printf("Waiting for Cloud Router to be provisioned, uuid %s", uuid)
stateConf := &retry.StateChangeConf{
Pending: []string{
Expand All @@ -461,7 +466,7 @@ func waitUntilCloudRouterIsProvisioned(uuid string, meta interface{}, ctx contex
}
return dbConn, string(*dbConn.State), nil
},
Timeout: 5 * time.Minute,
Timeout: timeout,
Delay: 30 * time.Second,
MinTimeout: 30 * time.Second,
}
Expand All @@ -479,6 +484,7 @@ func resourceFabricCloudRouterDelete(ctx context.Context, d *schema.ResourceData
diags := diag.Diagnostics{}
client := meta.(*config.Config).FabricClient
ctx = context.WithValue(ctx, v4.ContextAccessToken, meta.(*config.Config).FabricAuthToken)
start := time.Now()
_, err := client.CloudRoutersApi.DeleteCloudRouterByUuid(ctx, d.Id())
if err != nil {
errors, ok := err.(v4.GenericSwaggerError).Model().([]v4.ModelError)
Expand All @@ -491,14 +497,15 @@ func resourceFabricCloudRouterDelete(ctx context.Context, d *schema.ResourceData
return diag.FromErr(equinix_errors.FormatFabricError(err))
}

err = WaitUntilCloudRouterDeprovisioned(d.Id(), meta, ctx)
deleteTimeout := d.Timeout(schema.TimeoutDelete) - 30*time.Second - time.Since(start)
err = WaitUntilCloudRouterDeprovisioned(d.Id(), meta, ctx, deleteTimeout)
if err != nil {
return diag.FromErr(fmt.Errorf("API call failed while waiting for resource deletion. Error %v", err))
}
return diags
}

func WaitUntilCloudRouterDeprovisioned(uuid string, meta interface{}, ctx context.Context) error {
func WaitUntilCloudRouterDeprovisioned(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) error {
log.Printf("Waiting for Fabric Cloud Router to be deprovisioned, uuid %s", uuid)
stateConf := &retry.StateChangeConf{
Pending: []string{
Expand All @@ -515,7 +522,7 @@ func WaitUntilCloudRouterDeprovisioned(uuid string, meta interface{}, ctx contex
}
return dbConn, string(*dbConn.State), nil
},
Timeout: 5 * time.Minute,
Timeout: timeout,
Delay: 30 * time.Second,
MinTimeout: 30 * time.Second,
}
Expand Down
7 changes: 4 additions & 3 deletions equinix/resource_fabric_cloud_router_acc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"
"testing"
"time"

v4 "github.com/equinix-labs/fabric-go/fabric/v4"

Expand Down Expand Up @@ -41,7 +42,7 @@ func TestAccCloudRouterCreateOnlyRequiredParameters_PFCR(t *testing.T) {
resource.TestCheckResourceAttr("equinix_fabric_cloud_router.test", "notifications.0.emails.0", "[email protected]"),
resource.TestCheckResourceAttr("equinix_fabric_cloud_router.test", "order.0.purchase_order_number", "1-234567"),
resource.TestCheckResourceAttr("equinix_fabric_cloud_router.test", "location.0.metro_code", "SV"),
resource.TestCheckResourceAttr("equinix_fabric_cloud_router.test", "package.0.code", "LAB"),
resource.TestCheckResourceAttr("equinix_fabric_cloud_router.test", "package.0.code", "STANDARD"),
resource.TestCheckResourceAttrSet("equinix_fabric_cloud_router.test", "project.0.project_id"),
resource.TestCheckResourceAttrSet("equinix_fabric_cloud_router.test", "account.0.account_number"),
resource.TestCheckResourceAttrSet("equinix_fabric_cloud_router.test", "href"),
Expand Down Expand Up @@ -79,7 +80,7 @@ func testAccCloudRouterCreateOnlyRequiredParameterConfig_PFCR(name string) strin
metro_code = "SV"
}
package{
code = "LAB"
code = "STANDARD"
}
order{
purchase_order_number = "1-234567"
Expand Down Expand Up @@ -176,7 +177,7 @@ func checkCloudRouterDelete(s *terraform.State) error {
if rs.Type != "equinix_fabric_cloud_router" {
continue
}
err := equinix.WaitUntilCloudRouterDeprovisioned(rs.Primary.ID, acceptance.TestAccProvider.Meta(), ctx)
err := equinix.WaitUntilCloudRouterDeprovisioned(rs.Primary.ID, acceptance.TestAccProvider.Meta(), ctx, 10*time.Minute)
if err != nil {
return fmt.Errorf("API call failed while waiting for resource deletion")
}
Expand Down
48 changes: 28 additions & 20 deletions equinix/resource_fabric_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -592,10 +592,10 @@ func connectionRedundancySch() map[string]*schema.Schema {
func resourceFabricConnection() *schema.Resource {
return &schema.Resource{
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(6 * time.Minute),
Update: schema.DefaultTimeout(10 * time.Minute),
Delete: schema.DefaultTimeout(6 * time.Minute),
Read: schema.DefaultTimeout(6 * time.Minute),
Create: schema.DefaultTimeout(15 * time.Minute),
Update: schema.DefaultTimeout(15 * time.Minute),
Delete: schema.DefaultTimeout(15 * time.Minute),
Read: schema.DefaultTimeout(10 * time.Minute),
},
ReadContext: resourceFabricConnectionRead,
CreateContext: resourceFabricConnectionCreate,
Expand Down Expand Up @@ -686,13 +686,15 @@ func resourceFabricConnectionCreate(ctx context.Context, d *schema.ResourceData,
Project: project,
}

start := time.Now()
conn, _, err := client.ConnectionsApi.CreateConnection(ctx, createRequest)
if err != nil {
return diag.FromErr(equinix_errors.FormatFabricError(err))
}
d.SetId(conn.Uuid)

if err = waitUntilConnectionIsCreated(d.Id(), meta, ctx); err != nil {
createTimeout := d.Timeout(schema.TimeoutCreate) - 30*time.Second - time.Since(start)
if err = waitUntilConnectionIsCreated(d.Id(), meta, ctx, createTimeout); err != nil {
return diag.Errorf("error waiting for connection (%s) to be created: %s", d.Id(), err)
}

Expand All @@ -711,7 +713,8 @@ func resourceFabricConnectionCreate(ctx context.Context, d *schema.ResourceData,
return diag.FromErr(equinix_errors.FormatFabricError(patchErr))
}

if _, statusChangeErr := waitForConnectionProviderStatusChange(d.Id(), meta, ctx); statusChangeErr != nil {
createTimeout := d.Timeout(schema.TimeoutCreate) - 30*time.Second - time.Since(start)
if _, statusChangeErr := waitForConnectionProviderStatusChange(d.Id(), meta, ctx, createTimeout); statusChangeErr != nil {
return diag.Errorf("error waiting for AWS Approval for connection %s: %v", d.Id(), statusChangeErr)
}
}
Expand Down Expand Up @@ -800,7 +803,9 @@ func setFabricMap(d *schema.ResourceData, conn v4.Connection) diag.Diagnostics {
func resourceFabricConnectionUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
client := meta.(*config.Config).FabricClient
ctx = context.WithValue(ctx, v4.ContextAccessToken, meta.(*config.Config).FabricAuthToken)
dbConn, err := verifyConnectionCreated(d.Id(), meta, ctx)
start := time.Now()
updateTimeout := d.Timeout(schema.TimeoutUpdate) - 30*time.Second - time.Since(start)
dbConn, err := verifyConnectionCreated(d.Id(), meta, ctx, updateTimeout)
if err != nil {
if !strings.Contains(err.Error(), "500") {
d.SetId("")
Expand All @@ -823,7 +828,7 @@ func resourceFabricConnectionUpdate(ctx context.Context, d *schema.ResourceData,
continue
}

var waitFunction func(uuid string, meta interface{}, ctx context.Context) (v4.Connection, error)
var waitFunction func(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) (v4.Connection, error)
if update[0].Op == "replace" {
// Update type is either name or bandwidth
waitFunction = waitForConnectionUpdateCompletion
Expand All @@ -832,7 +837,8 @@ func resourceFabricConnectionUpdate(ctx context.Context, d *schema.ResourceData,
waitFunction = waitForConnectionProviderStatusChange
}

conn, err := waitFunction(d.Id(), meta, ctx)
updateTimeout := d.Timeout(schema.TimeoutUpdate) - 30*time.Second - time.Since(start)
conn, err := waitFunction(d.Id(), meta, ctx, updateTimeout)

if err != nil {
diags = append(diags, diag.Diagnostic{Severity: 0, Summary: fmt.Sprintf("connection property update completion timeout error: %v [update payload: %v] (other updates will be successful if the payload is not shown)", err, update)})
Expand All @@ -845,7 +851,7 @@ func resourceFabricConnectionUpdate(ctx context.Context, d *schema.ResourceData,
return append(diags, setFabricMap(d, updatedConn)...)
}

func waitForConnectionUpdateCompletion(uuid string, meta interface{}, ctx context.Context) (v4.Connection, error) {
func waitForConnectionUpdateCompletion(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) (v4.Connection, error) {
log.Printf("[DEBUG] Waiting for connection update to complete, uuid %s", uuid)
stateConf := &retry.StateChangeConf{
Target: []string{"COMPLETED"},
Expand All @@ -861,7 +867,7 @@ func waitForConnectionUpdateCompletion(uuid string, meta interface{}, ctx contex
}
return dbConn, updatableState, nil
},
Timeout: 3 * time.Minute,
Timeout: timeout,
Delay: 30 * time.Second,
MinTimeout: 30 * time.Second,
}
Expand All @@ -875,7 +881,7 @@ func waitForConnectionUpdateCompletion(uuid string, meta interface{}, ctx contex
return dbConn, err
}

func waitUntilConnectionIsCreated(uuid string, meta interface{}, ctx context.Context) error {
func waitUntilConnectionIsCreated(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) error {
log.Printf("Waiting for connection to be created, uuid %s", uuid)
stateConf := &retry.StateChangeConf{
Pending: []string{
Expand All @@ -894,7 +900,7 @@ func waitUntilConnectionIsCreated(uuid string, meta interface{}, ctx context.Con
}
return dbConn, string(*dbConn.State), nil
},
Timeout: 5 * time.Minute,
Timeout: timeout,
Delay: 30 * time.Second,
MinTimeout: 30 * time.Second,
}
Expand All @@ -904,7 +910,7 @@ func waitUntilConnectionIsCreated(uuid string, meta interface{}, ctx context.Con
return err
}

func waitForConnectionProviderStatusChange(uuid string, meta interface{}, ctx context.Context) (v4.Connection, error) {
func waitForConnectionProviderStatusChange(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) (v4.Connection, error) {
log.Printf("DEBUG: wating for provider status to update. Connection uuid: %s", uuid)
stateConf := &retry.StateChangeConf{
Pending: []string{
Expand All @@ -922,7 +928,7 @@ func waitForConnectionProviderStatusChange(uuid string, meta interface{}, ctx co
}
return dbConn, string(*dbConn.Operation.ProviderStatus), nil
},
Timeout: 5 * time.Minute,
Timeout: timeout,
Delay: 30 * time.Second,
MinTimeout: 30 * time.Second,
}
Expand All @@ -936,7 +942,7 @@ func waitForConnectionProviderStatusChange(uuid string, meta interface{}, ctx co
return dbConn, err
}

func verifyConnectionCreated(uuid string, meta interface{}, ctx context.Context) (v4.Connection, error) {
func verifyConnectionCreated(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) (v4.Connection, error) {
log.Printf("Waiting for connection to be in created state, uuid %s", uuid)
stateConf := &retry.StateChangeConf{
Target: []string{
Expand All @@ -952,7 +958,7 @@ func verifyConnectionCreated(uuid string, meta interface{}, ctx context.Context)
}
return dbConn, string(*dbConn.State), nil
},
Timeout: 5 * time.Minute,
Timeout: timeout,
Delay: 30 * time.Second,
MinTimeout: 30 * time.Second,
}
Expand All @@ -970,6 +976,7 @@ func resourceFabricConnectionDelete(ctx context.Context, d *schema.ResourceData,
diags := diag.Diagnostics{}
client := meta.(*config.Config).FabricClient
ctx = context.WithValue(ctx, v4.ContextAccessToken, meta.(*config.Config).FabricAuthToken)
start := time.Now()
_, _, err := client.ConnectionsApi.DeleteConnectionByUuid(ctx, d.Id())
if err != nil {
errors, ok := err.(v4.GenericSwaggerError).Model().([]v4.ModelError)
Expand All @@ -982,14 +989,15 @@ func resourceFabricConnectionDelete(ctx context.Context, d *schema.ResourceData,
return diag.FromErr(equinix_errors.FormatFabricError(err))
}

err = WaitUntilConnectionDeprovisioned(d.Id(), meta, ctx)
deleteTimeout := d.Timeout(schema.TimeoutDelete) - 30*time.Second - time.Since(start)
err = WaitUntilConnectionDeprovisioned(d.Id(), meta, ctx, deleteTimeout)
if err != nil {
return diag.FromErr(fmt.Errorf("API call failed while waiting for resource deletion. Error %v", err))
}
return diags
}

func WaitUntilConnectionDeprovisioned(uuid string, meta interface{}, ctx context.Context) error {
func WaitUntilConnectionDeprovisioned(uuid string, meta interface{}, ctx context.Context, timeout time.Duration) error {
log.Printf("Waiting for connection to be deprovisioned, uuid %s", uuid)
stateConf := &retry.StateChangeConf{
Pending: []string{
Expand All @@ -1006,7 +1014,7 @@ func WaitUntilConnectionDeprovisioned(uuid string, meta interface{}, ctx context
}
return dbConn, string(*dbConn.State), nil
},
Timeout: 6 * time.Minute,
Timeout: timeout,
Delay: 30 * time.Second,
MinTimeout: 30 * time.Second,
}
Expand Down
Loading

0 comments on commit 8868f87

Please sign in to comment.