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 sporadic panic when processing service dependencies #376

Merged
merged 5 commits into from
Oct 8, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
41 changes: 33 additions & 8 deletions pagerduty/resource_pagerduty_service_dependency.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ func resourcePagerDutyServiceDependency() *schema.Resource {
Type: schema.TypeList,
Required: true,
ForceNew: true,
MinItems: 1,
MaxItems: 1,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"supporting_service": {
Expand Down Expand Up @@ -74,14 +76,22 @@ func resourcePagerDutyServiceDependency() *schema.Resource {
}

func buildServiceDependencyStruct(d *schema.ResourceData) (*pagerduty.ServiceDependency, error) {
var rel *pagerduty.ServiceDependency
rel = new(pagerduty.ServiceDependency)
rel := new(pagerduty.ServiceDependency)
rel.ID = d.Id()

for _, r := range d.Get("dependency").([]interface{}) {
relmap := r.(map[string]interface{})
rel.SupportingService = expandService(relmap["supporting_service"].(interface{}))
rel.DependentService = expandService(relmap["dependent_service"].(interface{}))
rel.SupportingService = expandService(relmap["supporting_service"])
rel.DependentService = expandService(relmap["dependent_service"])
}

if rel.SupportingService == nil {
return nil, fmt.Errorf("dependent service not found for dependency: %v", d.Id())
}
if rel.DependentService == nil {
return nil, fmt.Errorf("supporting service not found for dependency: %v", d.Id())
}

if attr, ok := d.GetOk("type"); ok {
rel.Type = attr.(string)
}
Expand Down Expand Up @@ -126,6 +136,9 @@ func resourcePagerDutyServiceDependencyAssociate(d *schema.ResourceData, meta in
} else {
for _, r := range dependencies.Relationships {
d.SetId(r.ID)
if err := d.Set("dependency", flattenRelationship(r)); err != nil {
return resource.NonRetryableError(err)
}
}
}
return nil
Expand All @@ -134,7 +147,7 @@ func resourcePagerDutyServiceDependencyAssociate(d *schema.ResourceData, meta in
time.Sleep(2 * time.Second)
return retryErr
}
return resourcePagerDutyServiceDependencyRead(d, meta)
return nil
}

func resourcePagerDutyServiceDependencyDisassociate(d *schema.ResourceData, meta interface{}) error {
Expand Down Expand Up @@ -180,16 +193,28 @@ func resourcePagerDutyServiceDependencyDisassociate(d *schema.ResourceData, meta
input := pagerduty.ListServiceDependencies{
Relationships: r,
}
_, _, err = client.ServiceDependencies.DisassociateServiceDependencies(&input)
if err != nil {
return err
retryErr := resource.Retry(30*time.Second, func() *resource.RetryError {
if _, _, err = client.ServiceDependencies.DisassociateServiceDependencies(&input); err != nil {
if isErrCode(err, 404) {
return resource.RetryableError(err)
}
return resource.NonRetryableError(err)
}
return nil
})
if retryErr != nil {
time.Sleep(2 * time.Second)
return retryErr
}

return nil
}

func resourcePagerDutyServiceDependencyRead(d *schema.ResourceData, meta interface{}) error {
serviceDependency, err := buildServiceDependencyStruct(d)
if err != nil {
return err
}
log.Printf("[INFO] Reading PagerDuty dependency %s", serviceDependency.ID)

if err = findDependencySetState(d.Id(), serviceDependency.DependentService.ID, serviceDependency.DependentService.Type, d, meta); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions website/docs/r/service_dependency.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ resource "pagerduty_service_dependency" "bar" {

The following arguments are supported:

* `dependency` - (Required) The relationship between the `supporting_service` and `dependent_service`.
* `supporting_service` - (Required) The service that supports the dependent service.
* `dependent_service` - (Required) The service that id dependent on the supporting service.
* `dependency` - (Required) The relationship between the `supporting_service` and `dependent_service`. One and only one dependency block must be defined.
* `supporting_service` - (Required) The service that supports the dependent service.
* `dependent_service` - (Required) The service that dependents on the supporting service.

## Attributes Reference

Expand Down