diff --git a/pagerduty/data_source_pagerduty_service_integration.go b/pagerduty/data_source_pagerduty_service_integration.go new file mode 100644 index 000000000..67562112e --- /dev/null +++ b/pagerduty/data_source_pagerduty_service_integration.go @@ -0,0 +1,98 @@ +package pagerduty + +import ( + "fmt" + "log" + "strings" + "time" + + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/heimweh/go-pagerduty/pagerduty" +) + +func dataSourcePagerDutyServiceIntegration() *schema.Resource { + return &schema.Resource{ + Read: dataSourcePagerDutyServiceIntegrationRead, + + Schema: map[string]*schema.Schema{ + "service_name": { + Type: schema.TypeString, + Required: true, + }, + "integration_summary": { + Type: schema.TypeString, + Required: true, + Description: "examples 'Amazon CloudWatch', 'New Relic", + }, + + "integration_key": { + Type: schema.TypeString, + Computed: true, + Sensitive: true, + }, + }, + } +} + +func dataSourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Reading PagerDuty service") + + searchName := d.Get("service_name").(string) + + o := &pagerduty.ListServicesOptions{ + Query: searchName, + } + + return resource.Retry(2*time.Minute, func() *resource.RetryError { + resp, _, err := client.Services.List(o) + if err != nil { + return handleError(err) + } + + var found *pagerduty.Service + + for _, service := range resp.Services { + if service.Name == searchName { + found = service + break + } + } + + if found == nil { + return resource.NonRetryableError( + fmt.Errorf("unable to locate any service with the name: %s", searchName), + ) + } + + integrationSummary := d.Get("integration_summary").(string) + for _, integration := range found.Integrations { + if strings.EqualFold(integration.Summary, integrationSummary) { + integrationDetails, _, err := client.Services.GetIntegration(found.ID, integration.ID, &pagerduty.GetIntegrationOptions{}) + if err != nil { + return handleError(err) + } + d.SetId(integration.ID) + d.Set("service_name", found.Name) + d.Set("integration_key", integrationDetails.IntegrationKey) + + return nil + } + + } + return resource.NonRetryableError( + fmt.Errorf("unable to locate any integration of type %s on service %s", integrationSummary, searchName), + ) + }) +} + +func handleError(err error) *resource.RetryError { + if isErrCode(err, 429) { + time.Sleep(30 * time.Second) + return resource.RetryableError(err) + } + + return resource.NonRetryableError(err) +} diff --git a/pagerduty/data_source_pagerduty_service_integration_test.go b/pagerduty/data_source_pagerduty_service_integration_test.go new file mode 100644 index 000000000..0a348edc6 --- /dev/null +++ b/pagerduty/data_source_pagerduty_service_integration_test.go @@ -0,0 +1,107 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/helper/acctest" + "github.com/hashicorp/terraform-plugin-sdk/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +func TestAccDataSourcePagerDutyIntegration_Basic(t *testing.T) { + username := fmt.Sprintf("tf-%s", acctest.RandString(5)) + email := fmt.Sprintf("%s@foo.com", username) + service := fmt.Sprintf("tf-%s", acctest.RandString(5)) + escalationPolicy := fmt.Sprintf("tf-%s", acctest.RandString(5)) + serviceIntegration := "Datadog" + + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourcePagerDutyIntegrationConfigStep1(service, serviceIntegration, email, escalationPolicy), + Check: func(state *terraform.State) error { + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccDataSourcePagerDutyIntegrationConfigStep2(service, serviceIntegration), + Check: verifyOutput("output_id"), + }}, + }) + return nil + }, + }, + }, + }) +} + +func verifyOutput(name string) resource.TestCheckFunc { + return func(s *terraform.State) error { + ms := s.RootModule() + rs, ok := ms.Outputs[name] + if !ok { + return fmt.Errorf("Not found: %s", name) + } + + if rs.Type != "string" { + return fmt.Errorf("expected an error: %#v", rs) + } + + return nil + } +} + +func testAccDataSourcePagerDutyIntegrationConfigStep1(service, serviceIntegration, email, escalationPolicy string) string { + return fmt.Sprintf(` +resource "pagerduty_user" "pagerduty_user" { + email = "%s" + name = "test user" +} + +resource "pagerduty_escalation_policy" "escalation_policy" { + name = "%s" + rule { + escalation_delay_in_minutes = 5 + target { + type = "user_reference" + id = pagerduty_user.pagerduty_user.id + } + } + +} + +resource "pagerduty_service" "pagerduty_service" { + name = "%s" + escalation_policy = pagerduty_escalation_policy.escalation_policy.id +} + +resource "pagerduty_service_integration" "service_integration" { + name = "%s" + service = pagerduty_service.pagerduty_service.id + vendor = data.pagerduty_vendor.datadog.id +} + +data "pagerduty_vendor" "datadog" { + name = "datadog" +} + + +`, email, escalationPolicy, service, serviceIntegration) +} + +func testAccDataSourcePagerDutyIntegrationConfigStep2(service, serviceIntegration string) string { + return fmt.Sprintf(` + +data "pagerduty_service_integration" "service_integration" { + service_name = "%s" + integration_summary = "%s" +} + +output "output_id" { + value = data.pagerduty_service_integration.service_integration.integration_key +} +`, service, serviceIntegration) +} diff --git a/pagerduty/provider.go b/pagerduty/provider.go index 86f5aa945..80de9aae4 100644 --- a/pagerduty/provider.go +++ b/pagerduty/provider.go @@ -36,6 +36,7 @@ func Provider() terraform.ResourceProvider { "pagerduty_vendor": dataSourcePagerDutyVendor(), "pagerduty_extension_schema": dataSourcePagerDutyExtensionSchema(), "pagerduty_service": dataSourcePagerDutyService(), + "pagerduty_service_integration": dataSourcePagerDutyServiceIntegration(), "pagerduty_business_service": dataSourcePagerDutyBusinessService(), "pagerduty_priority": dataSourcePagerDutyPriority(), "pagerduty_ruleset": dataSourcePagerDutyRuleset(), diff --git a/website/docs/d/service_integration.html.markdown b/website/docs/d/service_integration.html.markdown new file mode 100644 index 000000000..c114839c1 --- /dev/null +++ b/website/docs/d/service_integration.html.markdown @@ -0,0 +1,30 @@ +--- +layout: "pagerduty" +page_title: "PagerDuty: pagerduty_service_integration" +sidebar_current: "docs-pagerduty-datasource-service_integration" +description: |- + Get information about a service integration. +--- + +# pagerduty\_service\_integration + +Use this data source to get information about a specific service_integration. + +## Example Usage + +```hcl +data "pagerduty_service_integration" "example" { + service_name = "My Service" + integration_summary = "Datadog" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `service_name` - (Required) The service name to use to find a service in the PagerDuty API. +* `integration_summary` - (Required) The integration summary used to find the desired integration on the service + +## Attributes Reference +* `integration_key` - The integration key for the integration. This can be used to configure alerts. diff --git a/website/pagerduty.erb b/website/pagerduty.erb index 5a478472e..32594c590 100644 --- a/website/pagerduty.erb +++ b/website/pagerduty.erb @@ -34,6 +34,9 @@ > pagerduty_service + > + pagerduty_service_integration + > pagerduty_user @@ -75,7 +78,7 @@ > pagerduty_response_play - + > pagerduty_ruleset @@ -87,7 +90,7 @@ > pagerduty_service - + > pagerduty_service_event_rule