provider/pagerduty: Updated implementation of pagerduty_vendor & pagerduty_service_integration (#12357)

* Vendor update

* Updated implementation of pagerduty_vendor

* Update pagerduty_vendor tests

* Update pagerduty_vendor documentation

* Updated implementation of pagerduty_service_integration

* Update pagerduty_service_integration tests

* Update pagerduty_service_integration documentation
This commit is contained in:
Alexander 2017-03-02 00:59:16 +01:00 committed by Paul Stack
parent 2cfe385653
commit 59d1d7056c
10 changed files with 277 additions and 51 deletions

View File

@ -16,11 +16,15 @@ func dataSourcePagerDutyVendor() *schema.Resource {
Schema: map[string]*schema.Schema{ Schema: map[string]*schema.Schema{
"name_regex": { "name_regex": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Optional: true,
Deprecated: "Use field name instead",
ConflictsWith: []string{"name"},
}, },
"name": { "name": {
Type: schema.TypeString, Type: schema.TypeString,
Computed: true, Computed: true,
Optional: true,
ConflictsWith: []string{"name_regex"},
}, },
"type": { "type": {
Type: schema.TypeString, Type: schema.TypeString,
@ -33,7 +37,58 @@ func dataSourcePagerDutyVendor() *schema.Resource {
func dataSourcePagerDutyVendorRead(d *schema.ResourceData, meta interface{}) error { func dataSourcePagerDutyVendorRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client) client := meta.(*pagerduty.Client)
log.Printf("[INFO] Reading PagerDuty vendors") // Check if we're doing a normal or legacy lookup
_, ok := d.GetOk("name")
_, legacyOk := d.GetOk("name_regex")
if !ok && !legacyOk {
return fmt.Errorf("Either name or name_regex must be set")
}
// If name_regex is set, we're doing a legacy lookup
if legacyOk {
return dataSourcePagerDutyVendorLegacyRead(d, meta)
}
log.Printf("[INFO] Reading PagerDuty vendor")
searchName := d.Get("name").(string)
o := &pagerduty.ListVendorOptions{
Query: searchName,
}
resp, err := client.ListVendors(*o)
if err != nil {
return err
}
var found *pagerduty.Vendor
r := regexp.MustCompile("(?i)" + searchName)
for _, vendor := range resp.Vendors {
if r.MatchString(vendor.Name) {
found = &vendor
break
}
}
if found == nil {
return fmt.Errorf("Unable to locate any vendor with the name: %s", searchName)
}
d.SetId(found.ID)
d.Set("name", found.Name)
d.Set("type", found.GenericServiceType)
return nil
}
func dataSourcePagerDutyVendorLegacyRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
log.Printf("[INFO] Reading PagerDuty vendor (legacy)")
resp, err := getVendors(client) resp, err := getVendors(client)

View File

@ -8,23 +8,65 @@ import (
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
) )
func TestAccPagerDutyVendor_Basic(t *testing.T) { func TestAccDataSourcePagerDutyVendor_Basic(t *testing.T) {
resource.Test(t, resource.TestCase{ resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) }, PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders, Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyScheduleDestroy, CheckDestroy: testAccCheckPagerDutyScheduleDestroy,
Steps: []resource.TestStep{ Steps: []resource.TestStep{
resource.TestStep{ resource.TestStep{
Config: testAccPagerDutyVendorsConfig, Config: testAccDataSourcePagerDutyVendorConfig,
Check: resource.ComposeTestCheckFunc( Check: resource.ComposeTestCheckFunc(
testAccPagerDutyVendors("data.pagerduty_vendor.datadog"), testAccDataSourcePagerDutyVendor("data.pagerduty_vendor.foo"),
), ),
}, },
}, },
}) })
} }
func testAccPagerDutyVendors(n string) resource.TestCheckFunc { func TestAccDataSourcePagerDutyVendorLegacy_Basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyScheduleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccDataSourcePagerDutyVendorLegacyConfig,
Check: resource.ComposeTestCheckFunc(
testAccDataSourcePagerDutyVendorLegacy("data.pagerduty_vendor.foo"),
),
},
},
})
}
func testAccDataSourcePagerDutyVendor(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
r := s.RootModule().Resources[n]
a := r.Primary.Attributes
if a["id"] == "" {
return fmt.Errorf("Expected to get a vendor ID from PagerDuty")
}
if a["id"] != "PZQ6AUS" {
return fmt.Errorf("Expected the Datadog Vendor ID to be: PZQ6AUS, but got: %s", a["id"])
}
if a["name"] != "Amazon Cloudwatch" {
return fmt.Errorf("Expected the Datadog Vendor Name to be: Datadog, but got: %s", a["name"])
}
if a["type"] != "api" {
return fmt.Errorf("Expected the Datadog Vendor Type to be: api, but got: %s", a["type"])
}
return nil
}
}
func testAccDataSourcePagerDutyVendorLegacy(n string) resource.TestCheckFunc {
return func(s *terraform.State) error { return func(s *terraform.State) error {
r := s.RootModule().Resources[n] r := s.RootModule().Resources[n]
@ -50,8 +92,14 @@ func testAccPagerDutyVendors(n string) resource.TestCheckFunc {
} }
} }
const testAccPagerDutyVendorsConfig = ` const testAccDataSourcePagerDutyVendorConfig = `
data "pagerduty_vendor" "datadog" { data "pagerduty_vendor" "foo" {
name = "cloudwatch"
}
`
const testAccDataSourcePagerDutyVendorLegacyConfig = `
data "pagerduty_vendor" "foo" {
name_regex = "Datadog" name_regex = "Datadog"
} }
` `

View File

@ -28,8 +28,10 @@ func resourcePagerDutyServiceIntegration() *schema.Resource {
}, },
"type": { "type": {
Type: schema.TypeString, Type: schema.TypeString,
Required: true, Optional: true,
ForceNew: true, ForceNew: true,
Computed: true,
ConflictsWith: []string{"vendor"},
ValidateFunc: validateValueFunc([]string{ ValidateFunc: validateValueFunc([]string{
"aws_cloudwatch_inbound_integration", "aws_cloudwatch_inbound_integration",
"cloudkick_inbound_integration", "cloudkick_inbound_integration",
@ -46,6 +48,8 @@ func resourcePagerDutyServiceIntegration() *schema.Resource {
Type: schema.TypeString, Type: schema.TypeString,
ForceNew: true, ForceNew: true,
Optional: true, Optional: true,
ConflictsWith: []string{"type"},
Computed: true,
}, },
"integration_key": { "integration_key": {
Type: schema.TypeString, Type: schema.TypeString,
@ -64,9 +68,8 @@ func resourcePagerDutyServiceIntegration() *schema.Resource {
func buildServiceIntegrationStruct(d *schema.ResourceData) *pagerduty.Integration { func buildServiceIntegrationStruct(d *schema.ResourceData) *pagerduty.Integration {
serviceIntegration := pagerduty.Integration{ serviceIntegration := pagerduty.Integration{
Name: d.Get("name").(string), Name: d.Get("name").(string),
Type: d.Get("type").(string),
Service: &pagerduty.APIObject{ Service: &pagerduty.APIObject{
Type: "service_reference", Type: "service",
ID: d.Get("service").(string), ID: d.Get("service").(string),
}, },
APIObject: pagerduty.APIObject{ APIObject: pagerduty.APIObject{
@ -83,10 +86,14 @@ func buildServiceIntegrationStruct(d *schema.ResourceData) *pagerduty.Integratio
serviceIntegration.IntegrationEmail = attr.(string) serviceIntegration.IntegrationEmail = attr.(string)
} }
if attr, ok := d.GetOk("type"); ok {
serviceIntegration.Type = attr.(string)
}
if attr, ok := d.GetOk("vendor"); ok { if attr, ok := d.GetOk("vendor"); ok {
serviceIntegration.Vendor = &pagerduty.APIObject{ serviceIntegration.Vendor = &pagerduty.APIObject{
ID: attr.(string), ID: attr.(string),
Type: "vendor_reference", Type: "vendor",
} }
} }

View File

@ -43,6 +43,36 @@ func TestAccPagerDutyServiceIntegration_Basic(t *testing.T) {
}) })
} }
func TestAccPagerDutyServiceIntegrationGeneric_Basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyServiceIntegrationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyServiceIntegrationGenericConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyServiceIntegrationExists("pagerduty_service_integration.foo"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "name", "foo"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "type", "generic_events_api_inbound_integration"),
),
},
resource.TestStep{
Config: testAccCheckPagerDutyServiceIntegrationGenericConfigUpdated,
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyServiceIntegrationExists("pagerduty_service_integration.foo"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "name", "bar"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "type", "generic_events_api_inbound_integration"),
),
},
},
})
}
func testAccCheckPagerDutyServiceIntegrationDestroy(s *terraform.State) error { func testAccCheckPagerDutyServiceIntegrationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*pagerduty.Client) client := testAccProvider.Meta().(*pagerduty.Client)
for _, r := range s.RootModule().Resources { for _, r := range s.RootModule().Resources {
@ -125,12 +155,11 @@ resource "pagerduty_service" "foo" {
} }
data "pagerduty_vendor" "datadog" { data "pagerduty_vendor" "datadog" {
name_regex = "datadog" name = "datadog"
} }
resource "pagerduty_service_integration" "foo" { resource "pagerduty_service_integration" "foo" {
name = "foo" name = "foo"
type = "generic_events_api_inbound_integration"
service = "${pagerduty_service.foo.id}" service = "${pagerduty_service.foo.id}"
vendor = "${data.pagerduty_vendor.datadog.id}" vendor = "${data.pagerduty_vendor.datadog.id}"
} }
@ -175,13 +204,98 @@ resource "pagerduty_service" "foo" {
} }
data "pagerduty_vendor" "datadog" { data "pagerduty_vendor" "datadog" {
name_regex = "datadog" name = "datadog"
} }
resource "pagerduty_service_integration" "foo" { resource "pagerduty_service_integration" "foo" {
name = "bar" name = "bar"
type = "generic_events_api_inbound_integration"
service = "${pagerduty_service.foo.id}" service = "${pagerduty_service.foo.id}"
vendor = "${data.pagerduty_vendor.datadog.id}" vendor = "${data.pagerduty_vendor.datadog.id}"
} }
` `
const testAccCheckPagerDutyServiceIntegrationGenericConfig = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
}
resource "pagerduty_escalation_policy" "foo" {
name = "foo"
description = "foo"
num_loops = 1
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
}
resource "pagerduty_service" "foo" {
name = "foo"
description = "foo"
auto_resolve_timeout = 1800
acknowledgement_timeout = 1800
escalation_policy = "${pagerduty_escalation_policy.foo.id}"
incident_urgency_rule {
type = "constant"
urgency = "high"
}
}
resource "pagerduty_service_integration" "foo" {
name = "foo"
service = "${pagerduty_service.foo.id}"
type = "generic_events_api_inbound_integration"
}
`
const testAccCheckPagerDutyServiceIntegrationGenericConfigUpdated = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
color = "green"
role = "user"
job_title = "foo"
description = "foo"
}
resource "pagerduty_escalation_policy" "foo" {
name = "bar"
description = "bar"
num_loops = 2
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
}
resource "pagerduty_service" "foo" {
name = "bar"
description = "bar"
auto_resolve_timeout = 3600
acknowledgement_timeout = 3600
escalation_policy = "${pagerduty_escalation_policy.foo.id}"
incident_urgency_rule {
type = "constant"
urgency = "high"
}
}
resource "pagerduty_service_integration" "foo" {
name = "bar"
service = "${pagerduty_service.foo.id}"
type = "generic_events_api_inbound_integration"
}
`

View File

@ -40,11 +40,11 @@ func CreateEvent(e Event) (*EventResponse, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK { if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP Status Code: %d", resp.StatusCode) return nil, fmt.Errorf("HTTP Status Code: %d", resp.StatusCode)
} }
var eventResponse EventResponse var eventResponse EventResponse
defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(&eventResponse); err != nil { if err := json.NewDecoder(resp.Body).Decode(&eventResponse); err != nil {
return nil, err return nil, err
} }

View File

@ -46,8 +46,8 @@ type ListLogEntryResponse struct {
type ListLogEntriesOptions struct { type ListLogEntriesOptions struct {
APIListObject APIListObject
TimeZone string `url:"time_zone"` TimeZone string `url:"time_zone"`
Since string `url:"omitempty"` Since string `url:"since,omitempty"`
Until string `url:"omitempty"` Until string `url:"until,omitempty"`
IsOverview bool `url:"is_overview,omitempty"` IsOverview bool `url:"is_overview,omitempty"`
Includes []string `url:"include,omitempty,brackets"` Includes []string `url:"include,omitempty,brackets"`
} }

View File

@ -30,6 +30,7 @@ type ListVendorResponse struct {
// ListVendorOptions is the data structure used when calling the ListVendors API endpoint. // ListVendorOptions is the data structure used when calling the ListVendors API endpoint.
type ListVendorOptions struct { type ListVendorOptions struct {
APIListObject APIListObject
Query string `url:"query,omitempty"`
} }
// ListVendors lists existing vendors. // ListVendors lists existing vendors.

6
vendor/vendor.json vendored
View File

@ -381,10 +381,10 @@
"revisionTime": "2016-11-03T18:56:17Z" "revisionTime": "2016-11-03T18:56:17Z"
}, },
{ {
"checksumSHA1": "trj+UY2oSzP0O1WJKz8auncslVs=", "checksumSHA1": "ibs+ylGiQibNx5GeZlCKx7A/zH8=",
"path": "github.com/PagerDuty/go-pagerduty", "path": "github.com/PagerDuty/go-pagerduty",
"revision": "fad777c9c72ec7c62aeec0194f01684d6a2efd0e", "revision": "fcea06d066d768bf90755d1071dd444c6abff524",
"revisionTime": "2017-01-28T02:14:22Z" "revisionTime": "2017-03-01T18:59:23Z"
}, },
{ {
"checksumSHA1": "NX4v3cbkXAJxFlrncqT9yEUBuoA=", "checksumSHA1": "NX4v3cbkXAJxFlrncqT9yEUBuoA=",

View File

@ -14,7 +14,7 @@ Use this data source to get information about a specific [vendor][1] that you ca
``` ```
data "pagerduty_vendor" "datadog" { data "pagerduty_vendor" "datadog" {
name_regex = "^Datadog$" name = "Datadog"
} }
resource "pagerduty_user" "example" { resource "pagerduty_user" "example" {
@ -56,7 +56,7 @@ resource "pagerduty_service_integration" "example" {
The following arguments are supported: The following arguments are supported:
* `name_regex` - (Required) A regex string to apply to the vendor list returned by the PagerDuty API. This regex should be very specific. If your regex matches several vendors a list of found vendors will be returned so you can tweak your regex further. The final regex string is made case insensitive. * `name` - (Required) The vendor name to use to find a vendor in the PagerDuty API.
## Attributes Reference ## Attributes Reference
* `name` - The short name of the found vendor. * `name` - The short name of the found vendor.

View File

@ -50,22 +50,20 @@ data "pagerduty_vendor" "datadog" {
name = "Datadog" name = "Datadog"
} }
resource "pagerduty_service_integration" "datadog" {
name = "${data.pagerduty_vendor.datadog.name}"
service = "${pagerduty_service.example.id}"
vendor = "${data.pagerduty_vendor.datadog.id}"
}
data "pagerduty_vendor" "cloudwatch" { data "pagerduty_vendor" "cloudwatch" {
name_regex = "Amazon CloudWatch" name = "Cloudwatch"
} }
resource "pagerduty_service_integration" "datadog" { resource "pagerduty_service_integration" "cloudwatch" {
name = "${data.pagerduty_vendor.datadog.name}" name = "${data.pagerduty_vendor.cloudwatch.name}"
type = "generic_events_api_inbound_integration"
service = "${pagerduty_service.example.id}" service = "${pagerduty_service.example.id}"
vendor = "${data.pagerduty_vendor.datadog.id}" vendor = "${data.pagerduty_vendor.cloudwatch.id}"
}
resource "pagerduty_service_integration" "datadog" {
name = "${data.pagerduty_vendor.datadog.name}"
type = "generic_events_api_inbound_integration"
service = "${pagerduty_service.example.id}"
vendor = "${data.pagerduty_vendor.datadog.id}"
} }
``` ```
@ -74,20 +72,23 @@ resource "pagerduty_service_integration" "datadog" {
The following arguments are supported: The following arguments are supported:
* `name` - (Optional) The name of the service integration. * `name` - (Optional) The name of the service integration.
* `type` - (Optional) The service type. Can be `aws_cloudwatch_inbound_integration`, `cloudkick_inbound_integration`, * `type` - (Optional) The service type. Can be:
`aws_cloudwatch_inbound_integration`,
`cloudkick_inbound_integration`,
`event_transformer_api_inbound_integration`, `event_transformer_api_inbound_integration`,
`generic_email_inbound_integration`, `generic_email_inbound_integration`,
`generic_events_api_inbound_integration`, `generic_events_api_inbound_integration`,
`keynote_inbound_integration`, `keynote_inbound_integration`,
`nagios_inbound_integration`, `nagios_inbound_integration`,
`pingdom_inbound_integration`, `pingdom_inbound_integration`or `sql_monitor_inbound_integration`.
`sql_monitor_inbound_integration`.
When integrating with a `vendor` this can usually be set to: `${data.pagerduty_vendor.datadog.type}` **Note:** This is meant for **generic** service integrations.
To integrate with a **vendor** (e.g Datadog or Amazon Cloudwatch) use the `vendor` field instead.
* `service` - (Optional) The PagerDuty service that the integration belongs to. * `service` - (Optional) The ID of the service the integration should belong to.
* `vendor` - (Optional) The vendor that this integration integrates with, if applicable. (e.g Datadog) * `vendor` - (Optional) The ID of the vendor the integration should integrate with (e.g Datadog or Amazon Cloudwatch).
**Note:** You can use the `pagerduty_vendor` data source to locate the appropriate vendor ID.
## Attributes Reference ## Attributes Reference
The following attributes are exported: The following attributes are exported: