From c41457bd5cb2432257eb2bf811403bc7d6091c9b Mon Sep 17 00:00:00 2001 From: Alexander Hellbom Date: Thu, 20 Oct 2016 06:53:51 +0200 Subject: [PATCH] Add support for teams in escalation policies & vendor support --- .../pagerduty/data_source_on_call.go | 172 ------------------ .../pagerduty/data_source_on_call_test.go | 58 ------ .../pagerduty/data_source_pagerduty_vendor.go | 78 ++++++++ .../data_source_pagerduty_vendor_test.go | 49 +++++ .../pagerduty/import_pagerduty_team_test.go | 1 + builtin/providers/pagerduty/provider.go | 7 +- .../resource_pagerduty_escalation_policy.go | 52 +++--- ...source_pagerduty_escalation_policy_test.go | 130 +++++++++++++ .../pagerduty/resource_pagerduty_schedule.go | 34 ++-- .../pagerduty/resource_pagerduty_service.go | 46 +++-- .../resource_pagerduty_service_integration.go | 66 ++++--- ...urce_pagerduty_service_integration_test.go | 19 +- .../pagerduty/resource_pagerduty_team.go | 24 +-- .../pagerduty/resource_pagerduty_user.go | 40 ++-- builtin/providers/pagerduty/structure.go | 60 ++---- builtin/providers/pagerduty/util.go | 48 ++++- .../PagerDuty/go-pagerduty/vendor.go | 73 ++++++++ vendor/vendor.json | 6 +- .../pagerduty/d/on_call.html.markdown | 59 ------ .../pagerduty/d/vendor.html.markdown | 65 +++++++ .../r/escalation_policy.html.markdown | 9 +- .../r/service_integration.html.markdown | 30 ++- website/source/layouts/pagerduty.erb | 4 +- 23 files changed, 661 insertions(+), 469 deletions(-) delete mode 100644 builtin/providers/pagerduty/data_source_on_call.go delete mode 100644 builtin/providers/pagerduty/data_source_on_call_test.go create mode 100644 builtin/providers/pagerduty/data_source_pagerduty_vendor.go create mode 100644 builtin/providers/pagerduty/data_source_pagerduty_vendor_test.go create mode 100644 vendor/github.com/PagerDuty/go-pagerduty/vendor.go delete mode 100644 website/source/docs/providers/pagerduty/d/on_call.html.markdown create mode 100644 website/source/docs/providers/pagerduty/d/vendor.html.markdown diff --git a/builtin/providers/pagerduty/data_source_on_call.go b/builtin/providers/pagerduty/data_source_on_call.go deleted file mode 100644 index 93e9cbf9537e..000000000000 --- a/builtin/providers/pagerduty/data_source_on_call.go +++ /dev/null @@ -1,172 +0,0 @@ -package pagerduty - -import ( - "encoding/json" - "log" - "strconv" - - pagerduty "github.com/PagerDuty/go-pagerduty" - "github.com/hashicorp/terraform/helper/hashcode" - "github.com/hashicorp/terraform/helper/schema" -) - -func dataSourcePagerDutyOnCall() *schema.Resource { - return &schema.Resource{ - Read: dataSourcePagerDutyOnCallRead, - - Schema: map[string]*schema.Schema{ - "time_zone": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - }, - "include": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "user_ids": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "escalation_policy_ids": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "schedule_ids": &schema.Schema{ - Type: schema.TypeList, - Optional: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "since": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - }, - "until": &schema.Schema{ - Type: schema.TypeString, - Optional: true, - }, - "earliest": &schema.Schema{ - Type: schema.TypeBool, - Optional: true, - }, - "oncalls": &schema.Schema{ - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "escalation_level": &schema.Schema{ - Type: schema.TypeInt, - Computed: true, - }, - "start": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, - "end": &schema.Schema{ - Type: schema.TypeString, - Computed: true, - }, - "user": &schema.Schema{ - Type: schema.TypeMap, - Computed: true, - }, - "schedule": &schema.Schema{ - Type: schema.TypeMap, - Computed: true, - }, - "escalation_policy": &schema.Schema{ - Type: schema.TypeMap, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourcePagerDutyOnCallRead(d *schema.ResourceData, meta interface{}) error { - client := meta.(*pagerduty.Client) - - o := &pagerduty.ListOnCallOptions{} - - if attr, ok := d.GetOk("time_zone"); ok { - o.TimeZone = attr.(string) - } - - if attr, ok := d.GetOk("include"); ok { - includes := make([]string, 0, len(attr.([]interface{}))) - - for _, include := range attr.([]interface{}) { - includes = append(includes, include.(string)) - } - - o.Includes = includes - } - - if attr, ok := d.GetOk("user_ids"); ok { - userIDs := make([]string, 0, len(attr.([]interface{}))) - - for _, user := range attr.([]interface{}) { - userIDs = append(userIDs, user.(string)) - } - - o.UserIDs = userIDs - } - - if attr, ok := d.GetOk("escalation_policy_ids"); ok { - escalationPolicyIDs := make([]string, 0, len(attr.([]interface{}))) - - for _, escalationPolicy := range attr.([]interface{}) { - escalationPolicyIDs = append(escalationPolicyIDs, escalationPolicy.(string)) - } - - o.EscalationPolicyIDs = escalationPolicyIDs - } - - if attr, ok := d.GetOk("since"); ok { - o.Since = attr.(string) - } - - if attr, ok := d.GetOk("until"); ok { - o.Until = attr.(string) - } - - if attr, ok := d.GetOk("earliest"); ok { - o.Earliest = attr.(bool) - } - - log.Printf("[INFO] Reading On Calls with options: %v", *o) - - resp, err := client.ListOnCalls(*o) - - if err != nil { - return err - } - - data := flattenOnCalls(resp.OnCalls) - id, err := json.Marshal(data) - - if err != nil { - return err - } - - d.SetId(strconv.Itoa(hashcode.String(string(id)))) - - if err := d.Set("oncalls", data); err != nil { - return err - } - - return nil - -} diff --git a/builtin/providers/pagerduty/data_source_on_call_test.go b/builtin/providers/pagerduty/data_source_on_call_test.go deleted file mode 100644 index 20c4a957d4d5..000000000000 --- a/builtin/providers/pagerduty/data_source_on_call_test.go +++ /dev/null @@ -1,58 +0,0 @@ -package pagerduty - -import ( - "fmt" - "strconv" - "testing" - - "github.com/hashicorp/terraform/helper/resource" - "github.com/hashicorp/terraform/terraform" -) - -func TestAccPagerDutyOnCall_Basic(t *testing.T) { - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - Providers: testAccProviders, - CheckDestroy: testAccCheckPagerDutyScheduleDestroy, - Steps: []resource.TestStep{ - resource.TestStep{ - Config: testAccPagerDutyOnCallsConfig, - Check: resource.ComposeTestCheckFunc( - testAccPagerDutyOnCalls("data.pagerduty_on_call.foo"), - ), - }, - }, - }) -} - -func testAccPagerDutyOnCalls(n string) resource.TestCheckFunc { - return func(s *terraform.State) error { - - r := s.RootModule().Resources[n] - a := r.Primary.Attributes - - var size int - var err error - - if size, err = strconv.Atoi(a["oncalls.#"]); err != nil { - return err - } - - if size == 0 { - return fmt.Errorf("Expected at least one on call in the list. Found: %d", size) - } - - for i := range make([]string, size) { - escalationLevel := a[fmt.Sprintf("oncalls.%d.escalation_level", i)] - if escalationLevel == "" { - return fmt.Errorf("Expected the on call to have an escalation_level set") - } - } - - return nil - } -} - -const testAccPagerDutyOnCallsConfig = ` -data "pagerduty_on_call" "foo" {} -` diff --git a/builtin/providers/pagerduty/data_source_pagerduty_vendor.go b/builtin/providers/pagerduty/data_source_pagerduty_vendor.go new file mode 100644 index 000000000000..d3fca6db4e0b --- /dev/null +++ b/builtin/providers/pagerduty/data_source_pagerduty_vendor.go @@ -0,0 +1,78 @@ +package pagerduty + +import ( + "fmt" + "log" + "regexp" + + pagerduty "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/schema" +) + +func dataSourcePagerDutyVendor() *schema.Resource { + return &schema.Resource{ + Read: dataSourcePagerDutyVendorRead, + + Schema: map[string]*schema.Schema{ + "name_regex": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "name": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "type": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + }, + } +} + +func dataSourcePagerDutyVendorRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Reading PagerDuty vendors") + + resp, err := getVendors(client) + + if err != nil { + return err + } + + r := regexp.MustCompile("(?i)" + d.Get("name_regex").(string)) + + var vendors []pagerduty.Vendor + var vendorNames []string + + for _, v := range resp { + if r.MatchString(v.Name) { + vendors = append(vendors, v) + vendorNames = append(vendorNames, v.Name) + } + } + + if len(vendors) == 0 { + return fmt.Errorf("Unable to locate any vendor using the regex string: %s", r.String()) + } else if len(vendors) > 1 { + return fmt.Errorf("Your query returned more than one result using the regex string: %#v. Found vendors: %#v", r.String(), vendorNames) + } + + vendor := vendors[0] + + genericServiceType := vendor.GenericServiceType + + switch { + case genericServiceType == "email": + genericServiceType = "generic_email_inbound_integration" + case genericServiceType == "api": + genericServiceType = "generic_events_api_inbound_integration" + } + + d.SetId(vendor.ID) + d.Set("name", vendor.Name) + d.Set("type", genericServiceType) + + return nil +} diff --git a/builtin/providers/pagerduty/data_source_pagerduty_vendor_test.go b/builtin/providers/pagerduty/data_source_pagerduty_vendor_test.go new file mode 100644 index 000000000000..4aad914a2c52 --- /dev/null +++ b/builtin/providers/pagerduty/data_source_pagerduty_vendor_test.go @@ -0,0 +1,49 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccPagerDutyVendor_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyScheduleDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccPagerDutyVendorsConfig, + Check: resource.ComposeTestCheckFunc( + testAccPagerDutyVendors("data.pagerduty_vendor.datadog"), + ), + }, + }, + }) +} + +func testAccPagerDutyVendors(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"] != "PAM4FGS" { + return fmt.Errorf("Expected the Datadog Vendor ID to be: PAM4FGS, but got: %s", a["id"]) + } + + return nil + } +} + +const testAccPagerDutyVendorsConfig = ` +data "pagerduty_vendor" "datadog" { + name_regex = "Datadog" +} +` diff --git a/builtin/providers/pagerduty/import_pagerduty_team_test.go b/builtin/providers/pagerduty/import_pagerduty_team_test.go index 7bf00f919b00..5017167a3465 100644 --- a/builtin/providers/pagerduty/import_pagerduty_team_test.go +++ b/builtin/providers/pagerduty/import_pagerduty_team_test.go @@ -8,6 +8,7 @@ import ( func TestAccPagerDutyTeam_import(t *testing.T) { resourceName := "pagerduty_team.foo" + resource.Test(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) }, Providers: testAccProviders, diff --git a/builtin/providers/pagerduty/provider.go b/builtin/providers/pagerduty/provider.go index 9a4613e0efaa..a2231f0ed6c8 100644 --- a/builtin/providers/pagerduty/provider.go +++ b/builtin/providers/pagerduty/provider.go @@ -19,7 +19,7 @@ func Provider() terraform.ResourceProvider { }, DataSourcesMap: map[string]*schema.Resource{ - "pagerduty_on_call": dataSourcePagerDutyOnCall(), + "pagerduty_vendor": dataSourcePagerDutyVendor(), }, ResourcesMap: map[string]*schema.Resource{ @@ -36,10 +36,7 @@ func Provider() terraform.ResourceProvider { } func providerConfigure(data *schema.ResourceData) (interface{}, error) { - config := Config{ - Token: data.Get("token").(string), - } - + config := Config{Token: data.Get("token").(string)} log.Println("[INFO] Initializing PagerDuty client") return config.Client() } diff --git a/builtin/providers/pagerduty/resource_pagerduty_escalation_policy.go b/builtin/providers/pagerduty/resource_pagerduty_escalation_policy.go index 422e5f9754fd..35d74e8d0f29 100644 --- a/builtin/providers/pagerduty/resource_pagerduty_escalation_policy.go +++ b/builtin/providers/pagerduty/resource_pagerduty_escalation_policy.go @@ -30,6 +30,13 @@ func resourcePagerDutyEscalationPolicy() *schema.Resource { Type: schema.TypeInt, Optional: true, }, + "teams": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, "rule": &schema.Schema{ Type: schema.TypeList, Required: true, @@ -70,36 +77,40 @@ func resourcePagerDutyEscalationPolicy() *schema.Resource { func buildEscalationPolicyStruct(d *schema.ResourceData) *pagerduty.EscalationPolicy { escalationRules := d.Get("rule").([]interface{}) - policy := pagerduty.EscalationPolicy{ + escalationPolicy := pagerduty.EscalationPolicy{ Name: d.Get("name").(string), - EscalationRules: expandRules(escalationRules), + EscalationRules: expandEscalationRules(escalationRules), } if attr, ok := d.GetOk("description"); ok { - policy.Description = attr.(string) + escalationPolicy.Description = attr.(string) } if attr, ok := d.GetOk("num_loops"); ok { - policy.NumLoops = uint(attr.(int)) + escalationPolicy.NumLoops = uint(attr.(int)) + } + + if attr, ok := d.GetOk("teams"); ok { + escalationPolicy.Teams = expandTeams(attr.([]interface{})) } - return &policy + return &escalationPolicy } func resourcePagerDutyEscalationPolicyCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - e := buildEscalationPolicyStruct(d) + escalationPolicy := buildEscalationPolicyStruct(d) - log.Printf("[INFO] Creating PagerDuty escalation policy: %s", e.Name) + log.Printf("[INFO] Creating PagerDuty escalation policy: %s", escalationPolicy.Name) - e, err := client.CreateEscalationPolicy(*e) + escalationPolicy, err := client.CreateEscalationPolicy(*escalationPolicy) if err != nil { return err } - d.SetId(e.ID) + d.SetId(escalationPolicy.ID) return resourcePagerDutyEscalationPolicyRead(d, meta) } @@ -109,17 +120,20 @@ func resourcePagerDutyEscalationPolicyRead(d *schema.ResourceData, meta interfac log.Printf("[INFO] Reading PagerDuty escalation policy: %s", d.Id()) - e, err := client.GetEscalationPolicy(d.Id(), &pagerduty.GetEscalationPolicyOptions{}) + o := &pagerduty.GetEscalationPolicyOptions{} + + escalationPolicy, err := client.GetEscalationPolicy(d.Id(), o) if err != nil { return err } - d.Set("name", e.Name) - d.Set("description", e.Description) - d.Set("num_loops", e.NumLoops) + d.Set("name", escalationPolicy.Name) + d.Set("teams", escalationPolicy.Teams) + d.Set("description", escalationPolicy.Description) + d.Set("num_loops", escalationPolicy.NumLoops) - if err := d.Set("rule", flattenRules(e.EscalationRules)); err != nil { + if err := d.Set("rule", flattenEscalationRules(escalationPolicy.EscalationRules)); err != nil { return err } @@ -129,13 +143,11 @@ func resourcePagerDutyEscalationPolicyRead(d *schema.ResourceData, meta interfac func resourcePagerDutyEscalationPolicyUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - e := buildEscalationPolicyStruct(d) + escalationPolicy := buildEscalationPolicyStruct(d) log.Printf("[INFO] Updating PagerDuty escalation policy: %s", d.Id()) - e, err := client.UpdateEscalationPolicy(d.Id(), e) - - if err != nil { + if _, err := client.UpdateEscalationPolicy(d.Id(), escalationPolicy); err != nil { return err } @@ -147,9 +159,7 @@ func resourcePagerDutyEscalationPolicyDelete(d *schema.ResourceData, meta interf log.Printf("[INFO] Deleting PagerDuty escalation policy: %s", d.Id()) - err := client.DeleteEscalationPolicy(d.Id()) - - if err != nil { + if err := client.DeleteEscalationPolicy(d.Id()); err != nil { return err } diff --git a/builtin/providers/pagerduty/resource_pagerduty_escalation_policy_test.go b/builtin/providers/pagerduty/resource_pagerduty_escalation_policy_test.go index 265373c67d97..2ca484105725 100644 --- a/builtin/providers/pagerduty/resource_pagerduty_escalation_policy_test.go +++ b/builtin/providers/pagerduty/resource_pagerduty_escalation_policy_test.go @@ -25,6 +25,10 @@ func TestAccPagerDutyEscalationPolicy_Basic(t *testing.T) { "pagerduty_escalation_policy.foo", "description", "foo"), resource.TestCheckResourceAttr( "pagerduty_escalation_policy.foo", "num_loops", "1"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.#", "1"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.0.escalation_delay_in_minutes", "10"), ), }, resource.TestStep{ @@ -37,6 +41,60 @@ func TestAccPagerDutyEscalationPolicy_Basic(t *testing.T) { "pagerduty_escalation_policy.foo", "description", "bar"), resource.TestCheckResourceAttr( "pagerduty_escalation_policy.foo", "num_loops", "2"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.#", "2"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.0.escalation_delay_in_minutes", "10"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.1.escalation_delay_in_minutes", "20"), + ), + }, + }, + }) +} + +func TestAccPagerDutyEscalationPolicyWithTeams_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyEscalationPolicyDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckPagerDutyEscalationPolicyWithTeamsConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyEscalationPolicyExists("pagerduty_escalation_policy.foo"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "name", "foo"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "description", "foo"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "num_loops", "1"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.#", "1"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.0.escalation_delay_in_minutes", "10"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "teams.#", "1"), + ), + }, + resource.TestStep{ + Config: testAccCheckPagerDutyEscalationPolicyWithTeamsConfigUpdated, + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyEscalationPolicyExists("pagerduty_escalation_policy.foo"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "name", "bar"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "description", "bar"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "num_loops", "2"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.#", "2"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.0.escalation_delay_in_minutes", "10"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "rule.1.escalation_delay_in_minutes", "20"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "teams.#", "0"), ), }, }, @@ -145,3 +203,75 @@ resource "pagerduty_escalation_policy" "foo" { } } ` + +const testAccCheckPagerDutyEscalationPolicyWithTeamsConfig = ` +resource "pagerduty_user" "foo" { + name = "foo" + email = "foo@bar.com" + color = "green" + role = "user" + job_title = "foo" + description = "foo" +} + +resource "pagerduty_team" "foo" { + name = "foo" + description = "foo" +} + +resource "pagerduty_escalation_policy" "foo" { + name = "foo" + description = "foo" + num_loops = 1 + teams = ["${pagerduty_team.foo.id}"] + + rule { + escalation_delay_in_minutes = 10 + + target { + type = "user_reference" + id = "${pagerduty_user.foo.id}" + } + } +} +` + +const testAccCheckPagerDutyEscalationPolicyWithTeamsConfigUpdated = ` +resource "pagerduty_user" "foo" { + name = "foo" + email = "foo@bar.com" + color = "green" + role = "user" + job_title = "foo" + description = "foo" +} + +resource "pagerduty_team" "foo" { + name = "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}" + } + } + + rule { + escalation_delay_in_minutes = 20 + + target { + type = "user_reference" + id = "${pagerduty_user.foo.id}" + } + } +} +` diff --git a/builtin/providers/pagerduty/resource_pagerduty_schedule.go b/builtin/providers/pagerduty/resource_pagerduty_schedule.go index c289694fa342..e8ef10916ed1 100644 --- a/builtin/providers/pagerduty/resource_pagerduty_schedule.go +++ b/builtin/providers/pagerduty/resource_pagerduty_schedule.go @@ -109,36 +109,36 @@ func resourcePagerDutySchedule() *schema.Resource { } } -func buildScheduleStruct(d *schema.ResourceData) (*pagerduty.Schedule, error) { +func buildScheduleStruct(d *schema.ResourceData) *pagerduty.Schedule { scheduleLayers := d.Get("layer").([]interface{}) schedule := pagerduty.Schedule{ Name: d.Get("name").(string), TimeZone: d.Get("time_zone").(string), - ScheduleLayers: expandLayers(scheduleLayers), + ScheduleLayers: expandScheduleLayers(scheduleLayers), } if attr, ok := d.GetOk("description"); ok { schedule.Description = attr.(string) } - return &schedule, nil + return &schedule } func resourcePagerDutyScheduleCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - s, _ := buildScheduleStruct(d) + schedule := buildScheduleStruct(d) - log.Printf("[INFO] Creating PagerDuty schedule: %s", s.Name) + log.Printf("[INFO] Creating PagerDuty schedule: %s", schedule.Name) - e, err := client.CreateSchedule(*s) + schedule, err := client.CreateSchedule(*schedule) if err != nil { return err } - d.SetId(e.ID) + d.SetId(schedule.ID) return resourcePagerDutyScheduleRead(d, meta) } @@ -148,17 +148,17 @@ func resourcePagerDutyScheduleRead(d *schema.ResourceData, meta interface{}) err log.Printf("[INFO] Reading PagerDuty schedule: %s", d.Id()) - s, err := client.GetSchedule(d.Id(), pagerduty.GetScheduleOptions{}) + schedule, err := client.GetSchedule(d.Id(), pagerduty.GetScheduleOptions{}) if err != nil { return err } - d.Set("name", s.Name) - d.Set("time_zone", s.TimeZone) - d.Set("description", s.Description) + d.Set("name", schedule.Name) + d.Set("time_zone", schedule.TimeZone) + d.Set("description", schedule.Description) - if err := d.Set("layer", flattenLayers(s.ScheduleLayers)); err != nil { + if err := d.Set("layer", flattenScheduleLayers(schedule.ScheduleLayers)); err != nil { return err } @@ -168,13 +168,11 @@ func resourcePagerDutyScheduleRead(d *schema.ResourceData, meta interface{}) err func resourcePagerDutyScheduleUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - e, _ := buildScheduleStruct(d) + schedule := buildScheduleStruct(d) log.Printf("[INFO] Updating PagerDuty schedule: %s", d.Id()) - e, err := client.UpdateSchedule(d.Id(), *e) - - if err != nil { + if _, err := client.UpdateSchedule(d.Id(), *schedule); err != nil { return err } @@ -186,9 +184,7 @@ func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) e log.Printf("[INFO] Deleting PagerDuty schedule: %s", d.Id()) - err := client.DeleteSchedule(d.Id()) - - if err != nil { + if err := client.DeleteSchedule(d.Id()); err != nil { return err } diff --git a/builtin/providers/pagerduty/resource_pagerduty_service.go b/builtin/providers/pagerduty/resource_pagerduty_service.go index 7b1b4d93041b..bb4979474ae3 100644 --- a/builtin/providers/pagerduty/resource_pagerduty_service.go +++ b/builtin/providers/pagerduty/resource_pagerduty_service.go @@ -3,7 +3,7 @@ package pagerduty import ( "log" - "github.com/PagerDuty/go-pagerduty" + pagerduty "github.com/PagerDuty/go-pagerduty" "github.com/hashicorp/terraform/helper/schema" ) @@ -77,14 +77,14 @@ func buildServiceStruct(d *schema.ResourceData) *pagerduty.Service { service.AcknowledgementTimeout = &acknowledgementTimeout } - policy := &pagerduty.EscalationPolicy{ + escalationPolicy := &pagerduty.EscalationPolicy{ APIObject: pagerduty.APIObject{ ID: d.Get("escalation_policy").(string), - Type: "escalation_policy", + Type: "escalation_policy_reference", }, } - service.EscalationPolicy = *policy + service.EscalationPolicy = *escalationPolicy return &service } @@ -92,17 +92,17 @@ func buildServiceStruct(d *schema.ResourceData) *pagerduty.Service { func resourcePagerDutyServiceCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - s := buildServiceStruct(d) + service := buildServiceStruct(d) - log.Printf("[INFO] Creating PagerDuty service %s", s.Name) + log.Printf("[INFO] Creating PagerDuty service %s", service.Name) - s, err := client.CreateService(*s) + service, err := client.CreateService(*service) if err != nil { return err } - d.SetId(s.ID) + d.SetId(service.ID) return nil } @@ -112,20 +112,22 @@ func resourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) erro log.Printf("[INFO] Reading PagerDuty service %s", d.Id()) - s, err := client.GetService(d.Id(), &pagerduty.GetServiceOptions{}) + o := &pagerduty.GetServiceOptions{} + + service, err := client.GetService(d.Id(), o) if err != nil { return err } - d.Set("name", s.Name) - d.Set("status", s.Status) - d.Set("created_at", s.CreateAt) - d.Set("escalation_policy", s.EscalationPolicy.ID) - d.Set("description", s.Description) - d.Set("auto_resolve_timeout", s.AutoResolveTimeout) - d.Set("last_incident_timestamp", s.LastIncidentTimestamp) - d.Set("acknowledgement_timeout", s.AcknowledgementTimeout) + d.Set("name", service.Name) + d.Set("status", service.Status) + d.Set("created_at", service.CreateAt) + d.Set("escalation_policy", service.EscalationPolicy.ID) + d.Set("description", service.Description) + d.Set("auto_resolve_timeout", service.AutoResolveTimeout) + d.Set("last_incident_timestamp", service.LastIncidentTimestamp) + d.Set("acknowledgement_timeout", service.AcknowledgementTimeout) return nil } @@ -133,13 +135,11 @@ func resourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) erro func resourcePagerDutyServiceUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - s := buildServiceStruct(d) + service := buildServiceStruct(d) log.Printf("[INFO] Updating PagerDuty service %s", d.Id()) - s, err := client.UpdateService(*s) - - if err != nil { + if _, err := client.UpdateService(*service); err != nil { return err } @@ -151,9 +151,7 @@ func resourcePagerDutyServiceDelete(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] Deleting PagerDuty service %s", d.Id()) - err := client.DeleteService(d.Id()) - - if err != nil { + if err := client.DeleteService(d.Id()); err != nil { return err } diff --git a/builtin/providers/pagerduty/resource_pagerduty_service_integration.go b/builtin/providers/pagerduty/resource_pagerduty_service_integration.go index 6236632e9d90..d53c3f91dd6d 100644 --- a/builtin/providers/pagerduty/resource_pagerduty_service_integration.go +++ b/builtin/providers/pagerduty/resource_pagerduty_service_integration.go @@ -3,7 +3,7 @@ package pagerduty import ( "log" - "github.com/PagerDuty/go-pagerduty" + pagerduty "github.com/PagerDuty/go-pagerduty" "github.com/hashicorp/terraform/helper/schema" ) @@ -12,7 +12,6 @@ func resourcePagerDutyServiceIntegration() *schema.Resource { Create: resourcePagerDutyServiceIntegrationCreate, Read: resourcePagerDutyServiceIntegrationRead, Update: resourcePagerDutyServiceIntegrationUpdate, - // NOTE: It's currently not possible to delete integrations via the API. // Therefore it needs to be manually removed from the Web UI. Delete: resourcePagerDutyServiceIntegrationDelete, @@ -28,6 +27,7 @@ func resourcePagerDutyServiceIntegration() *schema.Resource { "type": &schema.Schema{ Type: schema.TypeString, Required: true, + ForceNew: true, ValidateFunc: validateValueFunc([]string{ "aws_cloudwatch_inbound_integration", "cloudkick_inbound_integration", @@ -40,12 +40,19 @@ func resourcePagerDutyServiceIntegration() *schema.Resource { "sql_monitor_inbound_integration", }), }, + "vendor": &schema.Schema{ + Type: schema.TypeString, + ForceNew: true, + Optional: true, + }, "integration_key": &schema.Schema{ Type: schema.TypeString, + Optional: true, Computed: true, }, "integration_email": &schema.Schema{ Type: schema.TypeString, + Optional: true, Computed: true, }, }, @@ -53,37 +60,53 @@ func resourcePagerDutyServiceIntegration() *schema.Resource { } func buildServiceIntegrationStruct(d *schema.ResourceData) *pagerduty.Integration { - service := pagerduty.Integration{ - Type: d.Get("type").(string), + serviceIntegration := pagerduty.Integration{ Name: d.Get("name").(string), + Type: d.Get("type").(string), Service: &pagerduty.APIObject{ - Type: "service", + Type: "service_reference", ID: d.Get("service").(string), }, APIObject: pagerduty.APIObject{ - ID: d.Id(), + ID: d.Id(), + Type: "service_integration", }, } - return &service + if attr, ok := d.GetOk("integration_key"); ok { + serviceIntegration.IntegrationKey = attr.(string) + } + + if attr, ok := d.GetOk("integration_email"); ok { + serviceIntegration.IntegrationEmail = attr.(string) + } + + if attr, ok := d.GetOk("vendor"); ok { + serviceIntegration.Vendor = &pagerduty.APIObject{ + ID: attr.(string), + Type: "vendor_reference", + } + } + + return &serviceIntegration } func resourcePagerDutyServiceIntegrationCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - i := buildServiceIntegrationStruct(d) + serviceIntegration := buildServiceIntegrationStruct(d) - log.Printf("[INFO] Creating PagerDuty service integration %s", i.Name) + log.Printf("[INFO] Creating PagerDuty service integration %s", serviceIntegration.Name) service := d.Get("service").(string) - s, err := client.CreateIntegration(service, *i) + serviceIntegration, err := client.CreateIntegration(service, *serviceIntegration) if err != nil { return err } - d.SetId(s.ID) + d.SetId(serviceIntegration.ID) return resourcePagerDutyServiceIntegrationRead(d, meta) } @@ -95,17 +118,20 @@ func resourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta interf service := d.Get("service").(string) - i, err := client.GetIntegration(service, d.Id(), pagerduty.GetIntegrationOptions{}) + o := &pagerduty.GetIntegrationOptions{} + + serviceIntegration, err := client.GetIntegration(service, d.Id(), *o) if err != nil { return err } - d.Set("name", i.Name) - d.Set("type", i.Type) - d.Set("service", i.Service) - d.Set("integration_key", i.IntegrationKey) - d.Set("integration_email", i.IntegrationEmail) + d.Set("name", serviceIntegration.Name) + d.Set("type", serviceIntegration.Type) + d.Set("service", serviceIntegration.Service) + d.Set("vendor", serviceIntegration.Vendor) + d.Set("integration_key", serviceIntegration.IntegrationKey) + d.Set("integration_email", serviceIntegration.IntegrationEmail) return nil } @@ -113,15 +139,13 @@ func resourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta interf func resourcePagerDutyServiceIntegrationUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - s := buildServiceIntegrationStruct(d) + serviceIntegration := buildServiceIntegrationStruct(d) service := d.Get("service").(string) log.Printf("[INFO] Updating PagerDuty service integration %s", d.Id()) - s, err := client.UpdateIntegration(service, *s) - - if err != nil { + if _, err := client.UpdateIntegration(service, *serviceIntegration); err != nil { return err } diff --git a/builtin/providers/pagerduty/resource_pagerduty_service_integration_test.go b/builtin/providers/pagerduty/resource_pagerduty_service_integration_test.go index f504d80c8572..876c82af95a0 100644 --- a/builtin/providers/pagerduty/resource_pagerduty_service_integration_test.go +++ b/builtin/providers/pagerduty/resource_pagerduty_service_integration_test.go @@ -23,6 +23,8 @@ func TestAccPagerDutyServiceIntegration_Basic(t *testing.T) { "pagerduty_service_integration.foo", "name", "foo"), resource.TestCheckResourceAttr( "pagerduty_service_integration.foo", "type", "generic_events_api_inbound_integration"), + resource.TestCheckResourceAttr( + "pagerduty_service_integration.foo", "vendor", "PAM4FGS"), ), }, resource.TestStep{ @@ -33,6 +35,8 @@ func TestAccPagerDutyServiceIntegration_Basic(t *testing.T) { "pagerduty_service_integration.foo", "name", "bar"), resource.TestCheckResourceAttr( "pagerduty_service_integration.foo", "type", "generic_events_api_inbound_integration"), + resource.TestCheckResourceAttr( + "pagerduty_service_integration.foo", "vendor", "PAM4FGS"), ), }, }, @@ -76,7 +80,6 @@ func testAccCheckPagerDutyServiceIntegrationExists(n string) resource.TestCheckF found, err := client.GetIntegration(service.Primary.ID, rs.Primary.ID, pagerduty.GetIntegrationOptions{}) if err != nil { return fmt.Errorf("Service integration not found: %v", rs.Primary.ID) - // return err } if found.ID != rs.Primary.ID { @@ -91,10 +94,6 @@ const testAccCheckPagerDutyServiceIntegrationConfig = ` resource "pagerduty_user" "foo" { name = "foo" email = "foo@bar.com" - color = "green" - role = "user" - job_title = "foo" - description = "foo" } resource "pagerduty_escalation_policy" "foo" { @@ -120,10 +119,15 @@ resource "pagerduty_service" "foo" { escalation_policy = "${pagerduty_escalation_policy.foo.id}" } +data "pagerduty_vendor" "datadog" { + name_regex = "datadog" +} + resource "pagerduty_service_integration" "foo" { name = "foo" type = "generic_events_api_inbound_integration" service = "${pagerduty_service.foo.id}" + vendor = "${data.pagerduty_vendor.datadog.id}" } ` @@ -160,9 +164,14 @@ resource "pagerduty_service" "foo" { escalation_policy = "${pagerduty_escalation_policy.foo.id}" } +data "pagerduty_vendor" "datadog" { + name_regex = "datadog" +} + resource "pagerduty_service_integration" "foo" { name = "bar" type = "generic_events_api_inbound_integration" service = "${pagerduty_service.foo.id}" + vendor = "${data.pagerduty_vendor.datadog.id}" } ` diff --git a/builtin/providers/pagerduty/resource_pagerduty_team.go b/builtin/providers/pagerduty/resource_pagerduty_team.go index a42cd9005321..076e98920dc6 100644 --- a/builtin/providers/pagerduty/resource_pagerduty_team.go +++ b/builtin/providers/pagerduty/resource_pagerduty_team.go @@ -45,17 +45,17 @@ func buildTeamStruct(d *schema.ResourceData) *pagerduty.Team { func resourcePagerDutyTeamCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - t := buildTeamStruct(d) + team := buildTeamStruct(d) - log.Printf("[INFO] Creating PagerDuty team %s", t.Name) + log.Printf("[INFO] Creating PagerDuty team %s", team.Name) - t, err := client.CreateTeam(t) + team, err := client.CreateTeam(team) if err != nil { return err } - d.SetId(t.ID) + d.SetId(team.ID) return nil @@ -66,14 +66,14 @@ func resourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Reading PagerDuty team %s", d.Id()) - t, err := client.GetTeam(d.Id()) + team, err := client.GetTeam(d.Id()) if err != nil { return err } - d.Set("name", t.Name) - d.Set("description", t.Description) + d.Set("name", team.Name) + d.Set("description", team.Description) return nil } @@ -81,13 +81,11 @@ func resourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error { func resourcePagerDutyTeamUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - t := buildTeamStruct(d) + team := buildTeamStruct(d) log.Printf("[INFO] Updating PagerDuty team %s", d.Id()) - t, err := client.UpdateTeam(d.Id(), t) - - if err != nil { + if _, err := client.UpdateTeam(d.Id(), team); err != nil { return err } @@ -99,9 +97,7 @@ func resourcePagerDutyTeamDelete(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Deleting PagerDuty team %s", d.Id()) - err := client.DeleteTeam(d.Id()) - - if err != nil { + if err := client.DeleteTeam(d.Id()); err != nil { return err } diff --git a/builtin/providers/pagerduty/resource_pagerduty_user.go b/builtin/providers/pagerduty/resource_pagerduty_user.go index 627fed686035..4ffcb171e25f 100644 --- a/builtin/providers/pagerduty/resource_pagerduty_user.go +++ b/builtin/providers/pagerduty/resource_pagerduty_user.go @@ -115,17 +115,17 @@ func buildUserStruct(d *schema.ResourceData) *pagerduty.User { func resourcePagerDutyUserCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - u := buildUserStruct(d) + user := buildUserStruct(d) - log.Printf("[INFO] Creating PagerDuty user %s", u.Name) + log.Printf("[INFO] Creating PagerDuty user %s", user.Name) - u, err := client.CreateUser(*u) + user, err := client.CreateUser(*user) if err != nil { return err } - d.SetId(u.ID) + d.SetId(user.ID) return resourcePagerDutyUserUpdate(d, meta) } @@ -135,21 +135,23 @@ func resourcePagerDutyUserRead(d *schema.ResourceData, meta interface{}) error { log.Printf("[INFO] Reading PagerDuty user %s", d.Id()) - u, err := client.GetUser(d.Id(), pagerduty.GetUserOptions{}) + o := &pagerduty.GetUserOptions{} + + user, err := client.GetUser(d.Id(), *o) if err != nil { return err } - d.Set("name", u.Name) - d.Set("email", u.Email) - d.Set("time_zone", u.Timezone) - d.Set("color", u.Color) - d.Set("role", u.Role) - d.Set("avatar_url", u.AvatarURL) - d.Set("description", u.Description) - d.Set("job_title", u.JobTitle) - d.Set("teams", u.Teams) + d.Set("name", user.Name) + d.Set("email", user.Email) + d.Set("time_zone", user.Timezone) + d.Set("color", user.Color) + d.Set("role", user.Role) + d.Set("avatar_url", user.AvatarURL) + d.Set("description", user.Description) + d.Set("job_title", user.JobTitle) + d.Set("teams", user.Teams) return nil } @@ -157,13 +159,11 @@ func resourcePagerDutyUserRead(d *schema.ResourceData, meta interface{}) error { func resourcePagerDutyUserUpdate(d *schema.ResourceData, meta interface{}) error { client := meta.(*pagerduty.Client) - u := buildUserStruct(d) + user := buildUserStruct(d) log.Printf("[INFO] Updating PagerDuty user %s", d.Id()) - u, err := client.UpdateUser(*u) - - if err != nil { + if _, err := client.UpdateUser(*user); err != nil { return err } @@ -218,9 +218,7 @@ func resourcePagerDutyUserDelete(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Deleting PagerDuty user %s", d.Id()) - err := client.DeleteUser(d.Id()) - - if err != nil { + if err := client.DeleteUser(d.Id()); err != nil { return err } diff --git a/builtin/providers/pagerduty/structure.go b/builtin/providers/pagerduty/structure.go index b2491f275d55..a48882ce208f 100644 --- a/builtin/providers/pagerduty/structure.go +++ b/builtin/providers/pagerduty/structure.go @@ -3,7 +3,7 @@ package pagerduty import pagerduty "github.com/PagerDuty/go-pagerduty" // Expands an array of escalation rules into []pagerduty.EscalationRules -func expandRules(list []interface{}) []pagerduty.EscalationRule { +func expandEscalationRules(list []interface{}) []pagerduty.EscalationRule { result := make([]pagerduty.EscalationRule, 0, len(list)) for _, r := range list { @@ -32,7 +32,7 @@ func expandRules(list []interface{}) []pagerduty.EscalationRule { } // Flattens an array of []pagerduty.EscalationRule into a map[string]interface{} -func flattenRules(list []pagerduty.EscalationRule) []map[string]interface{} { +func flattenEscalationRules(list []pagerduty.EscalationRule) []map[string]interface{} { result := make([]map[string]interface{}, 0, len(list)) for _, i := range list { @@ -58,7 +58,7 @@ func flattenRules(list []pagerduty.EscalationRule) []map[string]interface{} { } // Expands an array of schedules into []pagerduty.Schedule -func expandLayers(list []interface{}) []pagerduty.ScheduleLayer { +func expandScheduleLayers(list []interface{}) []pagerduty.ScheduleLayer { result := make([]pagerduty.ScheduleLayer, 0, len(list)) for _, l := range list { @@ -106,8 +106,24 @@ func expandLayers(list []interface{}) []pagerduty.ScheduleLayer { return result } +// Expands an array of teams into []pagerduty.APIReference +func expandTeams(list []interface{}) []pagerduty.APIReference { + result := make([]pagerduty.APIReference, 0, len(list)) + + for _, l := range list { + team := &pagerduty.APIReference{ + ID: l.(string), + Type: "team_reference", + } + + result = append(result, *team) + } + + return result +} + // Flattens an array of []pagerduty.ScheduleLayer into a map[string]interface{} -func flattenLayers(list []pagerduty.ScheduleLayer) []map[string]interface{} { +func flattenScheduleLayers(list []pagerduty.ScheduleLayer) []map[string]interface{} { result := make([]map[string]interface{}, 0, len(list)) for _, i := range list { @@ -152,42 +168,6 @@ func flattenLayers(list []pagerduty.ScheduleLayer) []map[string]interface{} { return resultReversed } -// Flattens an array of []pagerduty.User into a map[string]interface{} -func flattenOnCalls(list []pagerduty.OnCall) []map[string]interface{} { - result := make([]map[string]interface{}, 0, len(list)) - - for _, i := range list { - r := make(map[string]interface{}) - r["escalation_level"] = i.EscalationLevel - r["start"] = i.Start - r["end"] = i.End - - user := make(map[string]interface{}, 1) - user["id"] = i.User.ID - user["type"] = i.User.Type - user["name"] = i.User.Summary - user["summary"] = i.User.Summary - - schedule := make(map[string]interface{}, 1) - schedule["id"] = i.Schedule.ID - schedule["type"] = i.Schedule.Type - schedule["summary"] = i.Schedule.Summary - - policy := make(map[string]interface{}, 1) - policy["id"] = i.EscalationPolicy.ID - policy["type"] = i.EscalationPolicy.Type - policy["summary"] = i.EscalationPolicy.Summary - - r["user"] = user - r["schedule"] = schedule - r["escalation_policy"] = policy - - result = append(result, r) - } - - return result -} - // Takes the result of flatmap.Expand for an array of strings // and returns a []string func expandStringList(configured []interface{}) []string { diff --git a/builtin/providers/pagerduty/util.go b/builtin/providers/pagerduty/util.go index 541c914f84a2..20b1e70db083 100644 --- a/builtin/providers/pagerduty/util.go +++ b/builtin/providers/pagerduty/util.go @@ -3,6 +3,7 @@ package pagerduty import ( "fmt" + pagerduty "github.com/PagerDuty/go-pagerduty" "github.com/hashicorp/terraform/helper/schema" ) @@ -11,16 +12,57 @@ func validateValueFunc(values []string) schema.SchemaValidateFunc { return func(v interface{}, k string) (we []string, errors []error) { value := v.(string) valid := false - for _, role := range values { - if value == role { + for _, val := range values { + if value == val { valid = true break } } if !valid { - errors = append(errors, fmt.Errorf("%s is an invalid value for argument %s. Must be one of %v", value, k, values)) + errors = append(errors, fmt.Errorf("%#v is an invalid value for argument %s. Must be one of %#v", value, k, values)) } return } } + +// getVendors retrieves all PagerDuty vendors and returns a list of []pagerduty.Vendor +func getVendors(client *pagerduty.Client) ([]pagerduty.Vendor, error) { + var offset uint + var totalCount int + var vendors []pagerduty.Vendor + + for { + o := &pagerduty.ListVendorOptions{ + APIListObject: pagerduty.APIListObject{ + Limit: 100, + Total: 1, + Offset: offset, + }, + } + + resp, err := client.ListVendors(*o) + + if err != nil { + return nil, err + } + + for _, v := range resp.Vendors { + totalCount++ + vendors = append(vendors, v) + } + + rOffset := uint(resp.Offset) + returnedCount := uint(len(resp.Vendors)) + rTotal := uint(resp.Total) + + if resp.More && uint(totalCount) != uint(rTotal) { + offset = returnedCount + rOffset + continue + } + + break + } + + return vendors, nil +} diff --git a/vendor/github.com/PagerDuty/go-pagerduty/vendor.go b/vendor/github.com/PagerDuty/go-pagerduty/vendor.go new file mode 100644 index 000000000000..f5a5ad2bcfda --- /dev/null +++ b/vendor/github.com/PagerDuty/go-pagerduty/vendor.go @@ -0,0 +1,73 @@ +package pagerduty + +import ( + "fmt" + "net/http" + + "github.com/google/go-querystring/query" +) + +// Vendor represents a specific type of integration. AWS Cloudwatch, Splunk, Datadog, etc are all examples of vendors that can be integrated in PagerDuty by making an integration. +type Vendor struct { + APIObject + Name string `json:"name,omitempty"` + LogoURL string `json:"logo_url,omitempty"` + LongName string `json:"long_name,omitempty"` + WebsiteURL string `json:"website_url,omitempty"` + Description string `json:"description,omitempty"` + Connectable bool `json:"connectable,omitempty"` + ThumbnailURL string `json:"thumbnail_url,omitempty"` + GenericServiceType string `json:"generic_service_type,omitempty"` + IntegrationGuideURL string `json:"integration_guide_url,omitempty"` +} + +// ListVendorResponse is the data structure returned from calling the ListVendors API endpoint. +type ListVendorResponse struct { + APIListObject + Vendors []Vendor +} + +// ListVendorOptions is the data structure used when calling the ListVendors API endpoint. +type ListVendorOptions struct { + APIListObject +} + +// ListVendors lists existing vendors. +func (c *Client) ListVendors(o ListVendorOptions) (*ListVendorResponse, error) { + v, err := query.Values(o) + + if err != nil { + return nil, err + } + + resp, err := c.get("/vendors?" + v.Encode()) + + if err != nil { + return nil, err + } + + var result ListVendorResponse + return &result, c.decodeJSON(resp, &result) +} + +// GetVendor gets details about an existing vendor. +func (c *Client) GetVendor(id string) (*Vendor, error) { + resp, err := c.get("/vendors/" + id) + return getVendorFromResponse(c, resp, err) +} + +func getVendorFromResponse(c *Client, resp *http.Response, err error) (*Vendor, error) { + if err != nil { + return nil, err + } + var target map[string]Vendor + if dErr := c.decodeJSON(resp, &target); dErr != nil { + return nil, fmt.Errorf("Could not decode JSON response: %v", dErr) + } + rootNode := "vendor" + t, nodeOK := target[rootNode] + if !nodeOK { + return nil, fmt.Errorf("JSON response does not have %s field", rootNode) + } + return &t, nil +} diff --git a/vendor/vendor.json b/vendor/vendor.json index 187eebffac81..1745ef812fdd 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -296,10 +296,10 @@ "revision": "0290933f5e8afd933f2823fce32bf2847e6ea603" }, { - "checksumSHA1": "QH+vxSOfdjdSBQBCTXoahGFRY0g=", + "checksumSHA1": "O9o5S7D0E1PaN5ARQ72xLfOrIa0=", "path": "github.com/PagerDuty/go-pagerduty", - "revision": "21b2c2f0311f017d2c1d964e17a6037767bd8cbc", - "revisionTime": "2016-10-18T05:48:56Z" + "revision": "f4d5289481b2c05f2b23f81a64dff86aca960962", + "revisionTime": "2016-10-22T00:40:41Z" }, { "path": "github.com/Unknwon/com", diff --git a/website/source/docs/providers/pagerduty/d/on_call.html.markdown b/website/source/docs/providers/pagerduty/d/on_call.html.markdown deleted file mode 100644 index 43fe48b0f3b5..000000000000 --- a/website/source/docs/providers/pagerduty/d/on_call.html.markdown +++ /dev/null @@ -1,59 +0,0 @@ ---- -layout: "pagerduty" -page_title: "PagerDuty: pagerduty_on_call" -sidebar_current: "docs-pagerduty-datasource-on_call" -description: |- - Get information about who's on call. ---- - -# pagerduty\_on_call - -Use this data source to get all of the users [on call][1] in a given schedule. - -## Example Usage - -``` -resource "pagerduty_schedule" "foo" { - name = "Daily Engineering Rotation" - time_zone = "America/New_York" - - layer { - name = "Night Shift" - start = "2015-11-06T20:00:00-05:00" - rotation_virtual_start = "2015-11-06T20:00:00-05:00" - rotation_turn_length_seconds = 86400 - users = ["${pagerduty_user.foo.id}"] - - restriction { - type = "daily_restriction" - start_time_of_day = "08:00:00" - duration_seconds = 32400 - } - } -} - -data "pagerduty_on_call" "on_call" {} - -resource "pagerduty_team" "on_call" { - name = "On call" - description = "Primarily used by ${data.pagerduty_on_call.oncalls.0.id}" -} -``` - -## Argument Reference - -The following arguments are supported: - -* `time_zone` - (Optional) Time zone in which dates in the result will be rendered. -* `include` - (Optional) List of of additional details to include. Can be `escalation_policies`, `users`, `schedules`. -* `user_ids` - (Optional) Filters the results, showing only on-calls for the specified user IDs. -* `escalation_policy_ids` - (Optional) Filters the results, showing only on-calls for the specified escalation policy IDs. -* `user_ids` - (Optional) Filters the results, showing only on-calls for the specified schedule IDs. -* `since` - (Optional) The start of the time range over which you want to search. If an on-call period overlaps with the range, it will be included in the result. Defaults to current time. The search range cannot exceed 3 months. -* `until` - (Optional) The end of the time range over which you want to search. If an on-call period overlaps with the range, it will be included in the result. Defaults to current time. The search range cannot exceed 3 months, and the until time cannot be before the since time. -* `earliest` - (Optional) This will filter on-calls such that only the earliest on-call for each combination of escalation policy, escalation level, and user is returned. This is useful for determining when the "next" on-calls are for a given set of filters. - -## Attributes Reference -* `oncalls` - A list of on-call entries during a given time range. - -[1]: https://v2.developer.pagerduty.com/v2/page/api-reference#!/On-Calls/get_oncalls diff --git a/website/source/docs/providers/pagerduty/d/vendor.html.markdown b/website/source/docs/providers/pagerduty/d/vendor.html.markdown new file mode 100644 index 000000000000..dc6d0ac13422 --- /dev/null +++ b/website/source/docs/providers/pagerduty/d/vendor.html.markdown @@ -0,0 +1,65 @@ +--- +layout: "pagerduty" +page_title: "PagerDuty: pagerduty_vendor" +sidebar_current: "docs-pagerduty-datasource-vendor" +description: |- + Get information about a vendor that you can use for a service integration (e.g Amazon Cloudwatch, Splunk, Datadog). +--- + +# pagerduty\_vendor + +Use this data source to get information about a specific [vendor][1] that you can use for a service integration (e.g Amazon Cloudwatch, Splunk, Datadog). + +## Example Usage + +``` +data "pagerduty_vendor" "datadog" { + name_regex = "^Datadog$" +} + +resource "pagerduty_user" "example" { + name = "Earline Greenholt" + email = "125.greenholt.earline@graham.name" + teams = ["${pagerduty_team.example.id}"] +} + +resource "pagerduty_escalation_policy" "foo" { + name = "Engineering Escalation Policy" + num_loops = 2 + + rule { + escalation_delay_in_minutes = 10 + + target { + type = "user" + id = "${pagerduty_user.example.id}" + } + } +} + +resource "pagerduty_service" "example" { + name = "My Web App" + auto_resolve_timeout = 14400 + acknowledgement_timeout = 600 + escalation_policy = "${pagerduty_escalation_policy.example.id}" +} + +resource "pagerduty_service_integration" "example" { + name = "Datadog Integration" + vendor = "${data.pagerduty_vendor.datadog.id}" + service = "${pagerduty_service.example.id}" + type = "generic_events_api_inbound_integration" +} +``` + +## Argument Reference + +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. + +## Attributes Reference +* `name` - The short name of the found vendor. +* `type` - The generic service type for this vendor. + +[1]: https://v2.developer.pagerduty.com/v2/page/api-reference#!/Vendors/get_vendors diff --git a/website/source/docs/providers/pagerduty/r/escalation_policy.html.markdown b/website/source/docs/providers/pagerduty/r/escalation_policy.html.markdown index f962d248dc62..43027d6104e1 100644 --- a/website/source/docs/providers/pagerduty/r/escalation_policy.html.markdown +++ b/website/source/docs/providers/pagerduty/r/escalation_policy.html.markdown @@ -14,15 +14,21 @@ An [escalation policy](https://v2.developer.pagerduty.com/v2/page/api-reference# ## Example Usage ``` +resource "pagerduty_team" "example" { + name = "Engineering" + description = "All engineering" +} + resource "pagerduty_user" "example" { name = "Earline Greenholt" email = "125.greenholt.earline@graham.name" teams = ["${pagerduty_team.example.id}"] } -resource "pagerduty_escalation_policy" "foo" { +resource "pagerduty_escalation_policy" "example" { name = "Engineering Escalation Policy" num_loops = 2 + teams = ["${pagerduty_team.example.id}"] rule { escalation_delay_in_minutes = 10 @@ -40,6 +46,7 @@ resource "pagerduty_escalation_policy" "foo" { The following arguments are supported: * `name` - (Required) The name of the escalation policy. +* `teams` - (Optional) Teams associated with the policy. Account must have the `teams` ability to use this parameter. * `description` - (Optional) A human-friendly description of the escalation policy. If not set, a placeholder of "Managed by Terraform" will be set. * `num_loops` - (Optional) The number of times the escalation policy will repeat after reaching the end of its escalation. diff --git a/website/source/docs/providers/pagerduty/r/service_integration.html.markdown b/website/source/docs/providers/pagerduty/r/service_integration.html.markdown index f7a10df33c56..7f0cce6f161e 100644 --- a/website/source/docs/providers/pagerduty/r/service_integration.html.markdown +++ b/website/source/docs/providers/pagerduty/r/service_integration.html.markdown @@ -10,6 +10,8 @@ description: |- A [service integration](https://v2.developer.pagerduty.com/v2/page/api-reference#!/Services/post_services_id_integrations) is an integration that belongs to a service. +`Note`: A service integration `cannot` be deleted via Terraform nor the PagerDuty API so if you remove a service integration, be sure to remove it from the PagerDuty Web UI afterwards. However, if you delete the `service` attached to the `integration`, the integration will be removed. + ## Example Usage @@ -46,6 +48,28 @@ resource "pagerduty_service_integration" "example" { type = "generic_events_api_inbound_integration" service = "${pagerduty_service.example.id}" } + +data "pagerduty_vendor" "datadog" { + name = "Datadog" +} + +data "pagerduty_vendor" "cloudwatch" { + name_regex = "Amazon CloudWatch" +} + +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}" +} + +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}" +} ``` ## Argument Reference @@ -60,8 +84,12 @@ The following arguments are supported: `keynote_inbound_integration`, `nagios_inbound_integration`, `pingdom_inbound_integration`, - `sql_monitor_inbound_integration` + `sql_monitor_inbound_integration`. + + When integrating with a `vendor` this can usually be set to: `${data.pagerduty_vendor.datadog.type}` + * `service` - (Optional) The PagerDuty service that the integration belongs to. + * `vendor` - (Optional) The vendor that this integration integrates with, if applicable. (e.g Datadog) ## Attributes Reference diff --git a/website/source/layouts/pagerduty.erb b/website/source/layouts/pagerduty.erb index 802d9faeab65..66d02fade457 100644 --- a/website/source/layouts/pagerduty.erb +++ b/website/source/layouts/pagerduty.erb @@ -13,8 +13,8 @@ > Data Sources