From e5fd91a2e32607347203fa4c42d5e3ab1efdc45c Mon Sep 17 00:00:00 2001 From: root Date: Fri, 27 Aug 2021 15:40:32 -0400 Subject: [PATCH 1/6] [#273] Handle race condition where a newly created resource can return a 404 on create --- go.sum | 2 + pagerduty/provider.go | 7 +- pagerduty/resource_pagerduty_service.go | 138 ++++++++++++------------ 3 files changed, 78 insertions(+), 69 deletions(-) diff --git a/go.sum b/go.sum index 6e06a9372..69cca87ff 100644 --- a/go.sum +++ b/go.sum @@ -77,6 +77,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= @@ -113,6 +114,7 @@ github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFU github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= diff --git a/pagerduty/provider.go b/pagerduty/provider.go index 80de9aae4..23e4341e5 100644 --- a/pagerduty/provider.go +++ b/pagerduty/provider.go @@ -87,14 +87,17 @@ func isErrCode(err error, code int) bool { return false } +func genError(err error, d *schema.ResourceData) error { + return fmt.Errorf("Error reading: %s: %s", d.Id(), err) +} + func handleNotFoundError(err error, d *schema.ResourceData) error { if isErrCode(err, 404) { log.Printf("[WARN] Removing %s because it's gone", d.Id()) d.SetId("") return nil } - - return fmt.Errorf("Error reading: %s: %s", d.Id(), err) + return genError(err, d) } func providerConfigure(data *schema.ResourceData, terraformVersion string) (interface{}, error) { diff --git a/pagerduty/resource_pagerduty_service.go b/pagerduty/resource_pagerduty_service.go index 1c4223935..1de521d96 100644 --- a/pagerduty/resource_pagerduty_service.go +++ b/pagerduty/resource_pagerduty_service.go @@ -328,36 +328,65 @@ func buildServiceStruct(d *schema.ResourceData) (*pagerduty.Service, error) { return &service, nil } -func resourcePagerDutyServiceCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - - service, err := buildServiceStruct(d) - if err != nil { - return err +func configureResource(d *schema.ResourceData, service *pagerduty.Service) *resource.RetryError { + d.Set("name", service.Name) + d.Set("html_url", service.HTMLURL) + d.Set("status", service.Status) + d.Set("created_at", service.CreatedAt) + d.Set("escalation_policy", service.EscalationPolicy.ID) + d.Set("description", service.Description) + if service.AutoResolveTimeout == nil { + d.Set("auto_resolve_timeout", "null") + } else { + d.Set("auto_resolve_timeout", strconv.Itoa(*service.AutoResolveTimeout)) } - - log.Printf("[INFO] Creating PagerDuty service %s", service.Name) - - service, _, err = client.Services.Create(service) - if err != nil { - return err + d.Set("last_incident_timestamp", service.LastIncidentTimestamp) + if service.AcknowledgementTimeout == nil { + d.Set("acknowledgement_timeout", "null") + } else { + d.Set("acknowledgement_timeout", strconv.Itoa(*service.AcknowledgementTimeout)) + } + d.Set("alert_creation", service.AlertCreation) + if service.AlertGrouping != nil && *service.AlertGrouping != "" { + d.Set("alert_grouping", *service.AlertGrouping) + } + if service.AlertGroupingTimeout == nil { + d.Set("alert_grouping_timeout", "null") + } else { + d.Set("alert_grouping_timeout", *service.AlertGroupingTimeout) + } + if service.AlertGroupingParameters != nil { + if err := d.Set("alert_grouping_parameters", flattenAlertGroupingParameters(service.AlertGroupingParameters)); err != nil { + return resource.NonRetryableError(err) + } + } + if service.IncidentUrgencyRule != nil { + if err := d.Set("incident_urgency_rule", flattenIncidentUrgencyRule(service.IncidentUrgencyRule)); err != nil { + return resource.NonRetryableError(err) + } } - d.SetId(service.ID) + if service.SupportHours != nil { + if err := d.Set("support_hours", flattenSupportHours(service.SupportHours)); err != nil { + return resource.NonRetryableError(err) + } + } - return resourcePagerDutyServiceRead(d, meta) + if service.ScheduledActions != nil { + if err := d.Set("scheduled_actions", flattenScheduledActions(service.ScheduledActions)); err != nil { + return resource.NonRetryableError(err) + } + } + return nil } -func resourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) error { +func fetchResource(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) - - log.Printf("[INFO] Reading PagerDuty service %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { service, _, err := client.Services.Get(d.Id(), &pagerduty.GetServiceOptions{}) if err != nil { log.Printf("[WARN] Service read error") - errResp := handleNotFoundError(err, d) + errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) return resource.RetryableError(errResp) @@ -365,57 +394,32 @@ func resourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) erro return nil } + return configureResource(d, service) + }) +} - d.Set("name", service.Name) - d.Set("html_url", service.HTMLURL) - d.Set("status", service.Status) - d.Set("created_at", service.CreatedAt) - d.Set("escalation_policy", service.EscalationPolicy.ID) - d.Set("description", service.Description) - if service.AutoResolveTimeout == nil { - d.Set("auto_resolve_timeout", "null") - } else { - d.Set("auto_resolve_timeout", strconv.Itoa(*service.AutoResolveTimeout)) - } - d.Set("last_incident_timestamp", service.LastIncidentTimestamp) - if service.AcknowledgementTimeout == nil { - d.Set("acknowledgement_timeout", "null") - } else { - d.Set("acknowledgement_timeout", strconv.Itoa(*service.AcknowledgementTimeout)) - } - d.Set("alert_creation", service.AlertCreation) - if service.AlertGrouping != nil && *service.AlertGrouping != "" { - d.Set("alert_grouping", *service.AlertGrouping) - } - if service.AlertGroupingTimeout == nil { - d.Set("alert_grouping_timeout", "null") - } else { - d.Set("alert_grouping_timeout", *service.AlertGroupingTimeout) - } - if service.AlertGroupingParameters != nil { - if err := d.Set("alert_grouping_parameters", flattenAlertGroupingParameters(service.AlertGroupingParameters)); err != nil { - return resource.NonRetryableError(err) - } - } - if service.IncidentUrgencyRule != nil { - if err := d.Set("incident_urgency_rule", flattenIncidentUrgencyRule(service.IncidentUrgencyRule)); err != nil { - return resource.NonRetryableError(err) - } - } +func resourcePagerDutyServiceCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + service, err := buildServiceStruct(d) + if err != nil { + return err + } - if service.SupportHours != nil { - if err := d.Set("support_hours", flattenSupportHours(service.SupportHours)); err != nil { - return resource.NonRetryableError(err) - } - } + log.Printf("[INFO] Creating PagerDuty service %s", service.Name) - if service.ScheduledActions != nil { - if err := d.Set("scheduled_actions", flattenScheduledActions(service.ScheduledActions)); err != nil { - return resource.NonRetryableError(err) - } - } - return nil - }) + service, _, err = client.Services.Create(service) + if err != nil { + return err + } + + d.SetId(service.ID) + + return fetchResource(d, meta, genError) +} + +func resourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Reading PagerDuty service %s", d.Id()) + return fetchResource(d, meta, handleNotFoundError) } func resourcePagerDutyServiceUpdate(d *schema.ResourceData, meta interface{}) error { From 7819cf81f71585a2bdd6f62ab2b8e8d5c6d9b94f Mon Sep 17 00:00:00 2001 From: root Date: Sat, 28 Aug 2021 13:59:18 -0400 Subject: [PATCH 2/6] [#273] updating pagerduty addons and extensions. Fixing pagerduty services retry. --- pagerduty/resource_pagerduty_addon.go | 47 ++++----- pagerduty/resource_pagerduty_extension.go | 46 ++++----- pagerduty/resource_pagerduty_service.go | 111 +++++++++++----------- 3 files changed, 104 insertions(+), 100 deletions(-) diff --git a/pagerduty/resource_pagerduty_addon.go b/pagerduty/resource_pagerduty_addon.go index 3c2f5b314..1858260fd 100644 --- a/pagerduty/resource_pagerduty_addon.go +++ b/pagerduty/resource_pagerduty_addon.go @@ -41,32 +41,13 @@ func buildAddonStruct(d *schema.ResourceData) *pagerduty.Addon { return addon } -func resourcePagerDutyAddonCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - - addon := buildAddonStruct(d) - - log.Printf("[INFO] Creating PagerDuty add-on %s", addon.Name) - - addon, _, err := client.Addons.Install(addon) - if err != nil { - return err - } - - d.SetId(addon.ID) - - return resourcePagerDutyAddonRead(d, meta) -} - -func resourcePagerDutyAddonRead(d *schema.ResourceData, meta interface{}) error { +func fetchPagerDutyAddon(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) - - log.Printf("[INFO] Reading PagerDuty add-on %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { addon, _, err := client.Addons.Get(d.Id()) if err != nil { - errResp := handleNotFoundError(err, d) + log.Printf("[WARN] Service read error") + errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) return resource.RetryableError(errResp) @@ -82,6 +63,28 @@ func resourcePagerDutyAddonRead(d *schema.ResourceData, meta interface{}) error }) } +func resourcePagerDutyAddonCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + addon := buildAddonStruct(d) + + log.Printf("[INFO] Creating PagerDuty add-on %s", addon.Name) + + addon, _, err := client.Addons.Install(addon) + if err != nil { + return err + } + + d.SetId(addon.ID) + // Retrying on creates incase of eventual consistency on creation + return fetchPagerDutyAddon(d, meta, genError) +} + +func resourcePagerDutyAddonRead(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Reading PagerDuty add-on %s", d.Id()) + return fetchPagerDutyAddon(d, meta, handleNotFoundError) +} + func resourcePagerDutyAddonUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) diff --git a/pagerduty/resource_pagerduty_extension.go b/pagerduty/resource_pagerduty_extension.go index fb6a1cd60..1a287de38 100644 --- a/pagerduty/resource_pagerduty_extension.go +++ b/pagerduty/resource_pagerduty_extension.go @@ -82,32 +82,12 @@ func buildExtensionStruct(d *schema.ResourceData) *pagerduty.Extension { return Extension } -func resourcePagerDutyExtensionCreate(d *schema.ResourceData, meta interface{}) error { +func fetchPagerDutyExtension(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) - - extension := buildExtensionStruct(d) - - log.Printf("[INFO] Creating PagerDuty extension %s", extension.Name) - - extension, _, err := client.Extensions.Create(extension) - if err != nil { - return err - } - - d.SetId(extension.ID) - - return resourcePagerDutyExtensionRead(d, meta) -} - -func resourcePagerDutyExtensionRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - - log.Printf("[INFO] Reading PagerDuty extension %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { extension, _, err := client.Extensions.Get(d.Id()) if err != nil { - errResp := handleNotFoundError(err, d) + errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) return resource.RetryableError(errResp) @@ -133,6 +113,28 @@ func resourcePagerDutyExtensionRead(d *schema.ResourceData, meta interface{}) er }) } +func resourcePagerDutyExtensionCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + extension := buildExtensionStruct(d) + + log.Printf("[INFO] Creating PagerDuty extension %s", extension.Name) + + extension, _, err := client.Extensions.Create(extension) + if err != nil { + return err + } + + d.SetId(extension.ID) + + return fetchPagerDutyExtension(d, meta, genError) +} + +func resourcePagerDutyExtensionRead(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Reading PagerDuty extension %s", d.Id()) + return fetchPagerDutyExtension(d, meta, handleNotFoundError) +} + func resourcePagerDutyExtensionUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) diff --git a/pagerduty/resource_pagerduty_service.go b/pagerduty/resource_pagerduty_service.go index 1de521d96..8727b8718 100644 --- a/pagerduty/resource_pagerduty_service.go +++ b/pagerduty/resource_pagerduty_service.go @@ -328,59 +328,7 @@ func buildServiceStruct(d *schema.ResourceData) (*pagerduty.Service, error) { return &service, nil } -func configureResource(d *schema.ResourceData, service *pagerduty.Service) *resource.RetryError { - d.Set("name", service.Name) - d.Set("html_url", service.HTMLURL) - d.Set("status", service.Status) - d.Set("created_at", service.CreatedAt) - d.Set("escalation_policy", service.EscalationPolicy.ID) - d.Set("description", service.Description) - if service.AutoResolveTimeout == nil { - d.Set("auto_resolve_timeout", "null") - } else { - d.Set("auto_resolve_timeout", strconv.Itoa(*service.AutoResolveTimeout)) - } - d.Set("last_incident_timestamp", service.LastIncidentTimestamp) - if service.AcknowledgementTimeout == nil { - d.Set("acknowledgement_timeout", "null") - } else { - d.Set("acknowledgement_timeout", strconv.Itoa(*service.AcknowledgementTimeout)) - } - d.Set("alert_creation", service.AlertCreation) - if service.AlertGrouping != nil && *service.AlertGrouping != "" { - d.Set("alert_grouping", *service.AlertGrouping) - } - if service.AlertGroupingTimeout == nil { - d.Set("alert_grouping_timeout", "null") - } else { - d.Set("alert_grouping_timeout", *service.AlertGroupingTimeout) - } - if service.AlertGroupingParameters != nil { - if err := d.Set("alert_grouping_parameters", flattenAlertGroupingParameters(service.AlertGroupingParameters)); err != nil { - return resource.NonRetryableError(err) - } - } - if service.IncidentUrgencyRule != nil { - if err := d.Set("incident_urgency_rule", flattenIncidentUrgencyRule(service.IncidentUrgencyRule)); err != nil { - return resource.NonRetryableError(err) - } - } - - if service.SupportHours != nil { - if err := d.Set("support_hours", flattenSupportHours(service.SupportHours)); err != nil { - return resource.NonRetryableError(err) - } - } - - if service.ScheduledActions != nil { - if err := d.Set("scheduled_actions", flattenScheduledActions(service.ScheduledActions)); err != nil { - return resource.NonRetryableError(err) - } - } - return nil -} - -func fetchResource(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { +func fetchService(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) return resource.Retry(2*time.Minute, func() *resource.RetryError { service, _, err := client.Services.Get(d.Id(), &pagerduty.GetServiceOptions{}) @@ -394,12 +342,63 @@ func fetchResource(d *schema.ResourceData, meta interface{}, errCallback func(er return nil } - return configureResource(d, service) + + d.Set("name", service.Name) + d.Set("html_url", service.HTMLURL) + d.Set("status", service.Status) + d.Set("created_at", service.CreatedAt) + d.Set("escalation_policy", service.EscalationPolicy.ID) + d.Set("description", service.Description) + if service.AutoResolveTimeout == nil { + d.Set("auto_resolve_timeout", "null") + } else { + d.Set("auto_resolve_timeout", strconv.Itoa(*service.AutoResolveTimeout)) + } + d.Set("last_incident_timestamp", service.LastIncidentTimestamp) + if service.AcknowledgementTimeout == nil { + d.Set("acknowledgement_timeout", "null") + } else { + d.Set("acknowledgement_timeout", strconv.Itoa(*service.AcknowledgementTimeout)) + } + d.Set("alert_creation", service.AlertCreation) + if service.AlertGrouping != nil && *service.AlertGrouping != "" { + d.Set("alert_grouping", *service.AlertGrouping) + } + if service.AlertGroupingTimeout == nil { + d.Set("alert_grouping_timeout", "null") + } else { + d.Set("alert_grouping_timeout", *service.AlertGroupingTimeout) + } + if service.AlertGroupingParameters != nil { + if err := d.Set("alert_grouping_parameters", flattenAlertGroupingParameters(service.AlertGroupingParameters)); err != nil { + return resource.NonRetryableError(err) + } + } + if service.IncidentUrgencyRule != nil { + if err := d.Set("incident_urgency_rule", flattenIncidentUrgencyRule(service.IncidentUrgencyRule)); err != nil { + return resource.NonRetryableError(err) + } + } + + if service.SupportHours != nil { + if err := d.Set("support_hours", flattenSupportHours(service.SupportHours)); err != nil { + return resource.NonRetryableError(err) + } + } + + if service.ScheduledActions != nil { + if err := d.Set("scheduled_actions", flattenScheduledActions(service.ScheduledActions)); err != nil { + return resource.NonRetryableError(err) + } + } + return nil + }) } func resourcePagerDutyServiceCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) + service, err := buildServiceStruct(d) if err != nil { return err @@ -414,12 +413,12 @@ func resourcePagerDutyServiceCreate(d *schema.ResourceData, meta interface{}) er d.SetId(service.ID) - return fetchResource(d, meta, genError) + return fetchService(d, meta, genError) } func resourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Reading PagerDuty service %s", d.Id()) - return fetchResource(d, meta, handleNotFoundError) + return fetchService(d, meta, handleNotFoundError) } func resourcePagerDutyServiceUpdate(d *schema.ResourceData, meta interface{}) error { From 0c53f96b1a9d363674bb2d76042cebfee6e401d1 Mon Sep 17 00:00:00 2001 From: root Date: Sat, 28 Aug 2021 17:19:21 -0400 Subject: [PATCH 3/6] [#273] adding servince now extension --- ...resource_pagerduty_extension_servicenow.go | 45 ++++++++++--------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/pagerduty/resource_pagerduty_extension_servicenow.go b/pagerduty/resource_pagerduty_extension_servicenow.go index c375eb356..cb8ac3e52 100644 --- a/pagerduty/resource_pagerduty_extension_servicenow.go +++ b/pagerduty/resource_pagerduty_extension_servicenow.go @@ -116,32 +116,12 @@ func buildExtensionServiceNowStruct(d *schema.ResourceData) *pagerduty.Extension return Extension } -func resourcePagerDutyExtensionServiceNowCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - - extension := buildExtensionServiceNowStruct(d) - - log.Printf("[INFO] Creating PagerDuty extension %s", extension.Name) - - extension, _, err := client.Extensions.Create(extension) - if err != nil { - return err - } - - d.SetId(extension.ID) - - return resourcePagerDutyExtensionServiceNowRead(d, meta) -} - -func resourcePagerDutyExtensionServiceNowRead(d *schema.ResourceData, meta interface{}) error { +func fetchPagerDutyExtensionServiceNowCreate(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) - - log.Printf("[INFO] Reading PagerDuty extension %s", d.Id()) - return resource.Retry(2*time.Minute, func() *resource.RetryError { extension, _, err := client.Extensions.Get(d.Id()) if err != nil { - errResp := handleNotFoundError(err, d) + errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) return resource.RetryableError(errResp) @@ -173,6 +153,27 @@ func resourcePagerDutyExtensionServiceNowRead(d *schema.ResourceData, meta inter }) } +func resourcePagerDutyExtensionServiceNowCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + extension := buildExtensionServiceNowStruct(d) + + log.Printf("[INFO] Creating PagerDuty extension %s", extension.Name) + + extension, _, err := client.Extensions.Create(extension) + if err != nil { + return err + } + + d.SetId(extension.ID) + return fetchPagerDutyExtensionServiceNowCreate(d, meta, genError) +} + +func resourcePagerDutyExtensionServiceNowRead(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Reading PagerDuty extension %s", d.Id()) + return fetchPagerDutyExtensionServiceNowCreate(d, meta, handleNotFoundError) +} + func resourcePagerDutyExtensionServiceNowUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) From 3a65abb6255eb791d96bef20231d59ddaa630574 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 29 Aug 2021 11:14:03 -0400 Subject: [PATCH 4/6] [#273] Updating ruleset, service integration, team membership, user contact, and notifications rules to have similar safeguards against eventual consistent reads. --- pagerduty/resource_pagerduty_ruleset.go | 55 +++++++------- .../resource_pagerduty_service_integration.go | 72 ++++++++++--------- .../resource_pagerduty_team_membership.go | 67 ++++++++--------- .../resource_pagerduty_user_contact_method.go | 40 ++++++----- ...source_pagerduty_user_notification_rule.go | 43 +++++------ 5 files changed, 145 insertions(+), 132 deletions(-) diff --git a/pagerduty/resource_pagerduty_ruleset.go b/pagerduty/resource_pagerduty_ruleset.go index f8210b84f..d054702fe 100644 --- a/pagerduty/resource_pagerduty_ruleset.go +++ b/pagerduty/resource_pagerduty_ruleset.go @@ -99,6 +99,33 @@ func flattenTeam(v *pagerduty.RulesetObject) []interface{} { return []interface{}{team} } + +func fetchPagerDutyRuleset(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { + client := meta.(*pagerduty.Client) + return resource.Retry(2*time.Minute, func() *resource.RetryError { + ruleset, _, err := client.Rulesets.Get(d.Id()) + if err != nil { + errResp := errCallback(err, d) + if errResp != nil { + time.Sleep(2 * time.Second) + return resource.RetryableError(errResp) + } + + return nil + } + d.Set("name", ruleset.Name) + d.Set("type", ruleset.Type) + + // if ruleset is found set to ResourceData + if ruleset.Team != nil { + d.Set("team", flattenTeam(ruleset.Team)) + } + d.Set("routing_keys", ruleset.RoutingKeys) + + return nil + }) +} + func resourcePagerDutyRulesetCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) @@ -122,37 +149,13 @@ func resourcePagerDutyRulesetCreate(d *schema.ResourceData, meta interface{}) er if retryErr != nil { return retryErr } - - return resourcePagerDutyRulesetRead(d, meta) + return fetchPagerDutyRuleset(d, meta, genError) } func resourcePagerDutyRulesetRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - log.Printf("[INFO] Reading PagerDuty ruleset: %s", d.Id()) + return fetchPagerDutyRuleset(d, meta, handleNotFoundError) - return resource.Retry(2*time.Minute, func() *resource.RetryError { - ruleset, _, err := client.Rulesets.Get(d.Id()) - if err != nil { - errResp := handleNotFoundError(err, d) - if errResp != nil { - time.Sleep(2 * time.Second) - return resource.RetryableError(errResp) - } - - return nil - } - d.Set("name", ruleset.Name) - d.Set("type", ruleset.Type) - - // if ruleset is found set to ResourceData - if ruleset.Team != nil { - d.Set("team", flattenTeam(ruleset.Team)) - } - d.Set("routing_keys", ruleset.RoutingKeys) - - return nil - }) } func resourcePagerDutyRulesetUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) diff --git a/pagerduty/resource_pagerduty_service_integration.go b/pagerduty/resource_pagerduty_service_integration.go index 55e374311..0bdef5795 100644 --- a/pagerduty/resource_pagerduty_service_integration.go +++ b/pagerduty/resource_pagerduty_service_integration.go @@ -106,41 +106,8 @@ func buildServiceIntegrationStruct(d *schema.ResourceData) *pagerduty.Integratio return serviceIntegration } -func resourcePagerDutyServiceIntegrationCreate(d *schema.ResourceData, meta interface{}) error { +func fetchPagerDutyServiceIntegration(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) - - serviceIntegration := buildServiceIntegrationStruct(d) - - log.Printf("[INFO] Creating PagerDuty service integration %s", serviceIntegration.Name) - - service := d.Get("service").(string) - - retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { - if serviceIntegration, _, err := client.Services.CreateIntegration(service, serviceIntegration); err != nil { - if isErrCode(err, 400) { - time.Sleep(2 * time.Second) - return resource.RetryableError(err) - } - - return resource.NonRetryableError(err) - } else if serviceIntegration != nil { - d.SetId(serviceIntegration.ID) - } - return nil - }) - - if retryErr != nil { - return retryErr - } - - return resourcePagerDutyServiceIntegrationRead(d, meta) -} - -func resourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - - log.Printf("[INFO] Reading PagerDuty service integration %s", d.Id()) - service := d.Get("service").(string) o := &pagerduty.GetIntegrationOptions{} @@ -149,7 +116,7 @@ func resourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta interf serviceIntegration, _, err := client.Services.GetIntegration(service, d.Id(), o) if err != nil { log.Printf("[WARN] Service integration read error") - errResp := handleNotFoundError(err, d) + errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) return resource.RetryableError(errResp) @@ -185,6 +152,41 @@ func resourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta interf }) } +func resourcePagerDutyServiceIntegrationCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + serviceIntegration := buildServiceIntegrationStruct(d) + + log.Printf("[INFO] Creating PagerDuty service integration %s", serviceIntegration.Name) + + service := d.Get("service").(string) + + retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { + if serviceIntegration, _, err := client.Services.CreateIntegration(service, serviceIntegration); err != nil { + if isErrCode(err, 400) { + time.Sleep(2 * time.Second) + return resource.RetryableError(err) + } + + return resource.NonRetryableError(err) + } else if serviceIntegration != nil { + d.SetId(serviceIntegration.ID) + } + return nil + }) + + if retryErr != nil { + return retryErr + } + + return fetchPagerDutyServiceIntegration(d, meta, genError) +} + +func resourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Reading PagerDuty service integration %s", d.Id()) + return fetchPagerDutyServiceIntegration(d, meta, handleNotFoundError) +} + func resourcePagerDutyServiceIntegrationUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) diff --git a/pagerduty/resource_pagerduty_team_membership.go b/pagerduty/resource_pagerduty_team_membership.go index 1db825b30..85fcd45ef 100644 --- a/pagerduty/resource_pagerduty_team_membership.go +++ b/pagerduty/resource_pagerduty_team_membership.go @@ -44,46 +44,15 @@ func resourcePagerDutyTeamMembership() *schema.Resource { }, } } -func resourcePagerDutyTeamMembershipCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - - userID := d.Get("user_id").(string) - teamID := d.Get("team_id").(string) - role := d.Get("role").(string) - - log.Printf("[DEBUG] Adding user: %s to team: %s with role: %s", userID, teamID, role) - retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { - if _, err := client.Teams.AddUserWithRole(teamID, userID, role); err != nil { - if isErrCode(err, 500) { - return resource.RetryableError(err) - } - - return resource.NonRetryableError(err) - } - - return nil - }) - if retryErr != nil { - return retryErr - } - - d.SetId(fmt.Sprintf("%s:%s", userID, teamID)) - - return resourcePagerDutyTeamMembershipRead(d, meta) -} - -func resourcePagerDutyTeamMembershipRead(d *schema.ResourceData, meta interface{}) error { +func fetchPagerDutyTeamMembership(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) - userID, teamID := resourcePagerDutyTeamMembershipParseID(d.Id()) - log.Printf("[DEBUG] Reading user: %s from team: %s", userID, teamID) - return resource.Retry(2*time.Minute, func() *resource.RetryError { resp, _, err := client.Teams.GetMembers(teamID, &pagerduty.GetMembersOptions{}) if err != nil { - errResp := handleNotFoundError(err, d) + errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) return resource.RetryableError(errResp) @@ -108,6 +77,38 @@ func resourcePagerDutyTeamMembershipRead(d *schema.ResourceData, meta interface{ return nil }) } +func resourcePagerDutyTeamMembershipCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + userID := d.Get("user_id").(string) + teamID := d.Get("team_id").(string) + role := d.Get("role").(string) + + log.Printf("[DEBUG] Adding user: %s to team: %s with role: %s", userID, teamID, role) + + retryErr := resource.Retry(2*time.Minute, func() *resource.RetryError { + if _, err := client.Teams.AddUserWithRole(teamID, userID, role); err != nil { + if isErrCode(err, 500) { + return resource.RetryableError(err) + } + + return resource.NonRetryableError(err) + } + + return nil + }) + if retryErr != nil { + return retryErr + } + + d.SetId(fmt.Sprintf("%s:%s", userID, teamID)) + + return fetchPagerDutyTeamMembership(d, meta, genError) +} + +func resourcePagerDutyTeamMembershipRead(d *schema.ResourceData, meta interface{}) error { + return fetchPagerDutyTeamMembership(d, meta, handleNotFoundError) +} func resourcePagerDutyTeamMembershipUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) diff --git a/pagerduty/resource_pagerduty_user_contact_method.go b/pagerduty/resource_pagerduty_user_contact_method.go index 3b0f1d52a..57c7b05bb 100644 --- a/pagerduty/resource_pagerduty_user_contact_method.go +++ b/pagerduty/resource_pagerduty_user_contact_method.go @@ -92,26 +92,9 @@ func buildUserContactMethodStruct(d *schema.ResourceData) *pagerduty.ContactMeth return contactMethod } -func resourcePagerDutyUserContactMethodCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - - userID := d.Get("user_id").(string) - - contactMethod := buildUserContactMethodStruct(d) - resp, _, err := client.Users.CreateContactMethod(userID, contactMethod) - if err != nil { - return err - } - - d.SetId(resp.ID) - - return resourcePagerDutyUserContactMethodRead(d, meta) -} - -func resourcePagerDutyUserContactMethodRead(d *schema.ResourceData, meta interface{}) error { +func fetchPagerDutyUserContactMethod(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) - userID := d.Get("user_id").(string) return resource.Retry(2*time.Minute, func() *resource.RetryError { @@ -138,6 +121,27 @@ func resourcePagerDutyUserContactMethodRead(d *schema.ResourceData, meta interfa }) } +func resourcePagerDutyUserContactMethodCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + userID := d.Get("user_id").(string) + + contactMethod := buildUserContactMethodStruct(d) + + resp, _, err := client.Users.CreateContactMethod(userID, contactMethod) + if err != nil { + return err + } + + d.SetId(resp.ID) + + return fetchPagerDutyUserContactMethod(d, meta, genError) +} + +func resourcePagerDutyUserContactMethodRead(d *schema.ResourceData, meta interface{}) error { + return fetchPagerDutyUserContactMethod(d, meta, handleNotFoundError) +} + func resourcePagerDutyUserContactMethodUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) diff --git a/pagerduty/resource_pagerduty_user_notification_rule.go b/pagerduty/resource_pagerduty_user_notification_rule.go index c5f1402bc..d73a09c2b 100644 --- a/pagerduty/resource_pagerduty_user_notification_rule.go +++ b/pagerduty/resource_pagerduty_user_notification_rule.go @@ -76,32 +76,14 @@ func buildUserNotificationRuleStruct(d *schema.ResourceData) *pagerduty.Notifica return notificationRule } -func resourcePagerDutyUserNotificationRuleCreate(d *schema.ResourceData, meta interface{}) error { +func fetchPagerDutyUserNotificationRule(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { client := meta.(*pagerduty.Client) - - userID := d.Get("user_id").(string) - - notificationRule := buildUserNotificationRuleStruct(d) - - resp, _, err := client.Users.CreateNotificationRule(userID, notificationRule) - if err != nil { - return err - } - - d.SetId(resp.ID) - - return resourcePagerDutyUserNotificationRuleRead(d, meta) -} - -func resourcePagerDutyUserNotificationRuleRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - userID := d.Get("user_id").(string) return resource.Retry(2*time.Minute, func() *resource.RetryError { resp, _, err := client.Users.GetNotificationRule(userID, d.Id()) if err != nil { - errResp := handleNotFoundError(err, d) + errResp := errCallback(err, d) if errResp != nil { time.Sleep(2 * time.Second) return resource.RetryableError(errResp) @@ -119,6 +101,27 @@ func resourcePagerDutyUserNotificationRuleRead(d *schema.ResourceData, meta inte }) } +func resourcePagerDutyUserNotificationRuleCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + userID := d.Get("user_id").(string) + + notificationRule := buildUserNotificationRuleStruct(d) + + resp, _, err := client.Users.CreateNotificationRule(userID, notificationRule) + if err != nil { + return err + } + + d.SetId(resp.ID) + + return fetchPagerDutyUserNotificationRule(d, meta, genError) +} + +func resourcePagerDutyUserNotificationRuleRead(d *schema.ResourceData, meta interface{}) error { + return fetchPagerDutyUserNotificationRule(d, meta, handleNotFoundError) +} + func resourcePagerDutyUserNotificationRuleUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) From 59af718de5bcaabb4ee8d7d7276459627c42c583 Mon Sep 17 00:00:00 2001 From: root Date: Sun, 14 Nov 2021 17:28:18 -0500 Subject: [PATCH 5/6] fix merge bug --- pagerduty/resource_pagerduty_user_notification_rule.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pagerduty/resource_pagerduty_user_notification_rule.go b/pagerduty/resource_pagerduty_user_notification_rule.go index 9bfce5712..2fc157e2a 100644 --- a/pagerduty/resource_pagerduty_user_notification_rule.go +++ b/pagerduty/resource_pagerduty_user_notification_rule.go @@ -100,7 +100,10 @@ func resourcePagerDutyUserNotificationRuleCreate(d *schema.ResourceData, meta in userID := d.Get("user_id").(string) - notificationRule := buildUserNotificationRuleStruct(d) + notificationRule, err := buildUserNotificationRuleStruct(d) + if err != nil { + return err + } resp, _, err := client.Users.CreateNotificationRule(userID, notificationRule) if err != nil { From e1edf15118c3526ab5f91e8a5fbab5523c6a2025 Mon Sep 17 00:00:00 2001 From: eric-spence-code Date: Fri, 19 Nov 2021 23:40:10 -0500 Subject: [PATCH 6/6] resolve client issue - Fix merge issues. --- pagerduty/resource_pagerduty_extension_servicenow.go | 2 +- pagerduty/resource_pagerduty_ruleset.go | 2 +- pagerduty/resource_pagerduty_service.go | 2 +- pagerduty/resource_pagerduty_service_integration.go | 2 +- pagerduty/resource_pagerduty_team_membership.go | 2 +- pagerduty/resource_pagerduty_user_contact_method.go | 2 +- pagerduty/resource_pagerduty_user_notification_rule.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pagerduty/resource_pagerduty_extension_servicenow.go b/pagerduty/resource_pagerduty_extension_servicenow.go index 3c7d0f000..9bb2b3fde 100644 --- a/pagerduty/resource_pagerduty_extension_servicenow.go +++ b/pagerduty/resource_pagerduty_extension_servicenow.go @@ -159,7 +159,7 @@ func fetchPagerDutyExtensionServiceNowCreate(d *schema.ResourceData, meta interf } func resourcePagerDutyExtensionServiceNowCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) + client, _ := meta.(*Config).Client() extension := buildExtensionServiceNowStruct(d) diff --git a/pagerduty/resource_pagerduty_ruleset.go b/pagerduty/resource_pagerduty_ruleset.go index a97fe6020..6618814d3 100644 --- a/pagerduty/resource_pagerduty_ruleset.go +++ b/pagerduty/resource_pagerduty_ruleset.go @@ -101,7 +101,7 @@ func flattenTeam(v *pagerduty.RulesetObject) []interface{} { } func fetchPagerDutyRuleset(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { - client := meta.(*pagerduty.Client) + client, _ := meta.(*Config).Client() return resource.Retry(2*time.Minute, func() *resource.RetryError { ruleset, _, err := client.Rulesets.Get(d.Id()) if err != nil { diff --git a/pagerduty/resource_pagerduty_service.go b/pagerduty/resource_pagerduty_service.go index 62cd58a91..152b73305 100644 --- a/pagerduty/resource_pagerduty_service.go +++ b/pagerduty/resource_pagerduty_service.go @@ -351,7 +351,7 @@ func buildServiceStruct(d *schema.ResourceData) (*pagerduty.Service, error) { } func fetchService(d *schema.ResourceData, meta interface{}, errCallback func(error, *schema.ResourceData) error) error { - client := meta.(*pagerduty.Client) + client, _ := meta.(*Config).Client() return resource.Retry(2*time.Minute, func() *resource.RetryError { service, _, err := client.Services.Get(d.Id(), &pagerduty.GetServiceOptions{}) if err != nil { diff --git a/pagerduty/resource_pagerduty_service_integration.go b/pagerduty/resource_pagerduty_service_integration.go index 3c778f32e..abf37bad5 100644 --- a/pagerduty/resource_pagerduty_service_integration.go +++ b/pagerduty/resource_pagerduty_service_integration.go @@ -161,7 +161,7 @@ func fetchPagerDutyServiceIntegration(d *schema.ResourceData, meta interface{}, } func resourcePagerDutyServiceIntegrationCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) + client, _ := meta.(*Config).Client() serviceIntegration := buildServiceIntegrationStruct(d) diff --git a/pagerduty/resource_pagerduty_team_membership.go b/pagerduty/resource_pagerduty_team_membership.go index 6606a8ce0..482ef2300 100644 --- a/pagerduty/resource_pagerduty_team_membership.go +++ b/pagerduty/resource_pagerduty_team_membership.go @@ -78,7 +78,7 @@ func fetchPagerDutyTeamMembership(d *schema.ResourceData, meta interface{}, errC }) } func resourcePagerDutyTeamMembershipCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) + client, _ := meta.(*Config).Client() userID := d.Get("user_id").(string) teamID := d.Get("team_id").(string) diff --git a/pagerduty/resource_pagerduty_user_contact_method.go b/pagerduty/resource_pagerduty_user_contact_method.go index 3cfef75de..085146a05 100644 --- a/pagerduty/resource_pagerduty_user_contact_method.go +++ b/pagerduty/resource_pagerduty_user_contact_method.go @@ -122,7 +122,7 @@ func fetchPagerDutyUserContactMethod(d *schema.ResourceData, meta interface{}, e } func resourcePagerDutyUserContactMethodCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) + client, _ := meta.(*Config).Client() userID := d.Get("user_id").(string) diff --git a/pagerduty/resource_pagerduty_user_notification_rule.go b/pagerduty/resource_pagerduty_user_notification_rule.go index 9bfce5712..a4f13d406 100644 --- a/pagerduty/resource_pagerduty_user_notification_rule.go +++ b/pagerduty/resource_pagerduty_user_notification_rule.go @@ -96,7 +96,7 @@ func fetchPagerDutyUserNotificationRule(d *schema.ResourceData, meta interface{} } func resourcePagerDutyUserNotificationRuleCreate(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) + client, _ := meta.(*Config).Client() userID := d.Get("user_id").(string)