Skip to content

Commit

Permalink
Improve resilience of service_dependency and service resources
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaspj authored and imjaroiswebdev committed Mar 26, 2024
1 parent ac9c2a3 commit c6c95ac
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 3 deletions.
4 changes: 2 additions & 2 deletions pagerduty/resource_pagerduty_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -535,7 +535,7 @@ func resourcePagerDutyServiceUpdate(d *schema.ResourceData, meta interface{}) er

updatedService, _, err := client.Services.Update(d.Id(), service)
if err != nil {
return err
return handleNotFoundError(err, d)
}

return flattenService(d, updatedService)
Expand All @@ -550,7 +550,7 @@ func resourcePagerDutyServiceDelete(d *schema.ResourceData, meta interface{}) er
log.Printf("[INFO] Deleting PagerDuty service %s", d.Id())

if _, err := client.Services.Delete(d.Id()); err != nil {
return err
return handleNotFoundError(err, d)
}

d.SetId("")
Expand Down
7 changes: 7 additions & 0 deletions pagerduty/resource_pagerduty_service_dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,10 @@ func resourcePagerDutyServiceDependencyDisassociate(ctx context.Context, d *sche
return retry.NonRetryableError(err)
}

if err = handleNotFoundError(err, d); err == nil {
return nil
}

// Delaying retry by 30s as recommended by PagerDuty
// https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit
time.Sleep(30 * time.Second)
Expand Down Expand Up @@ -323,6 +327,9 @@ func findDependencySetState(ctx context.Context, depID, serviceID, serviceType s
if isErrCode(err, http.StatusBadRequest) {
return retry.NonRetryableError(err)
}
if err = handleNotFoundError(err, d); err == nil {
return nil
}

// Delaying retry by 30s as recommended by PagerDuty
// https://developer.pagerduty.com/docs/rest-api-v2/rate-limiting/#what-are-possible-workarounds-to-the-events-api-rate-limit
Expand Down
63 changes: 62 additions & 1 deletion pagerduty/resource_pagerduty_service_dependency_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,15 @@ func TestAccPagerDutyBusinessServiceDependency_Basic(t *testing.T) {
),
ExpectNonEmptyPlan: true,
},
// Validating that externally removed dependent service are
// detected and gracefully handled
{
Config: testAccCheckPagerDutyBusinessServiceDependencyConfig(service, businessService, username, email, escalationPolicy),
Check: resource.ComposeTestCheckFunc(
testAccExternallyDestroyedDependentService("pagerduty_service_dependency.bar", "pagerduty_service.dependBar", "pagerduty_service.supportBar"),
),
ExpectNonEmptyPlan: true,
},
},
})
}
Expand Down Expand Up @@ -326,13 +335,56 @@ func testAccExternallyDestroyServiceDependency(resName, depName, suppName string
return nil
}
}
func testAccExternallyDestroyedDependentService(resName, depName, suppName string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[resName]
if !ok {
return fmt.Errorf("Not found: %s", resName)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Service Dependency ID is set for %q", resName)
}

dep, ok := s.RootModule().Resources[depName]
if !ok {
return fmt.Errorf("Not found: %s", depName)
}
if dep.Primary.ID == "" {
return fmt.Errorf("No Dependent Business Service ID is set for %q", depName)
}
depServiceType := dep.Primary.Attributes["type"]

supp, ok := s.RootModule().Resources[suppName]
if !ok {
return fmt.Errorf("Not found: %s", suppName)
}
if supp.Primary.ID == "" {
return fmt.Errorf("No Supporting Service ID is set for %q", suppName)
}

client, _ := testAccProvider.Meta().(*Config).Client()
if depServiceType == "business_service" {
_, err := client.BusinessServices.Delete(dep.Primary.ID)
if err != nil {
return err
}
} else {
_, err := client.Services.Delete(dep.Primary.ID)
if err != nil {
return err
}
}

return nil
}
}

// Testing Technical Service Dependencies
func TestAccPagerDutyTechnicalServiceDependency_Basic(t *testing.T) {
dependentService := fmt.Sprintf("tf-%s", acctest.RandString(5))
supportingService := fmt.Sprintf("tf-%s", acctest.RandString(5))
username := fmt.Sprintf("tf-%s", acctest.RandString(5))
email := fmt.Sprintf("%s@foo.test", username)
email := fmt.Sprintf("%s@lego.com", username)
escalationPolicy := fmt.Sprintf("tf-%s", acctest.RandString(5))

resource.Test(t, resource.TestCase{
Expand Down Expand Up @@ -361,6 +413,15 @@ func TestAccPagerDutyTechnicalServiceDependency_Basic(t *testing.T) {
),
ExpectNonEmptyPlan: true,
},
// Validating that externally removed dependent service are
// detected and gracefully handled
{
Config: testAccCheckPagerDutyTechnicalServiceDependencyConfig(dependentService, supportingService, username, email, escalationPolicy),
Check: resource.ComposeTestCheckFunc(
testAccExternallyDestroyedDependentService("pagerduty_service_dependency.bar", "pagerduty_service.dependBar", "pagerduty_service.supportBar"),
),
ExpectNonEmptyPlan: true,
},
},
})
}
Expand Down

0 comments on commit c6c95ac

Please sign in to comment.