From d02067a75ed48fadf6abd1bda1aad1fdee76cbb6 Mon Sep 17 00:00:00 2001 From: Alexander Hellbom Date: Fri, 23 Sep 2016 21:43:06 +0200 Subject: [PATCH] Add PagerDuty provider --- builtin/bins/provider-pagerduty/main.go | 12 + builtin/providers/pagerduty/config.go | 21 ++ ...import_pagerduty_escalation_policy_test.go | 38 +++ .../import_pagerduty_service_test.go | 35 +++ .../pagerduty/import_pagerduty_team_test.go | 32 ++ .../pagerduty/import_pagerduty_user_test.go | 35 +++ builtin/providers/pagerduty/provider.go | 40 +++ builtin/providers/pagerduty/provider_test.go | 48 +++ .../resource_pagerduty_escalation_policy.go | 187 ++++++++++++ ...source_pagerduty_escalation_policy_test.go | 137 +++++++++ .../pagerduty/resource_pagerduty_schedule.go | 280 ++++++++++++++++++ .../pagerduty/resource_pagerduty_service.go | 148 +++++++++ .../resource_pagerduty_service_test.go | 105 +++++++ .../pagerduty/resource_pagerduty_team.go | 118 ++++++++ .../pagerduty/resource_pagerduty_team_test.go | 83 ++++++ .../pagerduty/resource_pagerduty_user.go | 236 +++++++++++++++ .../pagerduty/resource_pagerduty_user_test.go | 110 +++++++ builtin/providers/pagerduty/structure.go | 22 ++ command/internal_plugin_list.go | 2 + 19 files changed, 1689 insertions(+) create mode 100644 builtin/bins/provider-pagerduty/main.go create mode 100644 builtin/providers/pagerduty/config.go create mode 100644 builtin/providers/pagerduty/import_pagerduty_escalation_policy_test.go create mode 100644 builtin/providers/pagerduty/import_pagerduty_service_test.go create mode 100644 builtin/providers/pagerduty/import_pagerduty_team_test.go create mode 100644 builtin/providers/pagerduty/import_pagerduty_user_test.go create mode 100644 builtin/providers/pagerduty/provider.go create mode 100644 builtin/providers/pagerduty/provider_test.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_escalation_policy.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_escalation_policy_test.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_schedule.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_service.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_service_test.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_team.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_team_test.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_user.go create mode 100644 builtin/providers/pagerduty/resource_pagerduty_user_test.go create mode 100644 builtin/providers/pagerduty/structure.go diff --git a/builtin/bins/provider-pagerduty/main.go b/builtin/bins/provider-pagerduty/main.go new file mode 100644 index 000000000..551efe182 --- /dev/null +++ b/builtin/bins/provider-pagerduty/main.go @@ -0,0 +1,12 @@ +package main + +import ( + "github.com/hashicorp/terraform/builtin/providers/pagerduty" + "github.com/hashicorp/terraform/plugin" +) + +func main() { + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: pagerduty.Provider, + }) +} diff --git a/builtin/providers/pagerduty/config.go b/builtin/providers/pagerduty/config.go new file mode 100644 index 000000000..00f55e71c --- /dev/null +++ b/builtin/providers/pagerduty/config.go @@ -0,0 +1,21 @@ +package pagerduty + +import ( + "log" + + "github.com/PagerDuty/go-pagerduty" +) + +// Config defines the configuration options for the PagerDuty client +type Config struct { + Token string +} + +// Client returns a new PagerDuty client +func (c *Config) Client() (*pagerduty.Client, error) { + client := pagerduty.NewClient(c.Token) + + log.Printf("[INFO] PagerDuty client configured") + + return client, nil +} diff --git a/builtin/providers/pagerduty/import_pagerduty_escalation_policy_test.go b/builtin/providers/pagerduty/import_pagerduty_escalation_policy_test.go new file mode 100644 index 000000000..f263fb871 --- /dev/null +++ b/builtin/providers/pagerduty/import_pagerduty_escalation_policy_test.go @@ -0,0 +1,38 @@ +package pagerduty + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccPagerDutyEscalationPolicy_import(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyEscalationPolicyDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccPagerDutyEscalationPolicyConfigImported, + }, + resource.TestStep{ + ResourceName: "pagerduty_escalation_policy.foo", + ImportState: true, + ImportStateVerify: false, + }, + }, + }) +} + +const testAccPagerDutyEscalationPolicyConfigImported = ` +resource "pagerduty_escalation_policy" "foo" { + name = "foo" + escalation_rule { + escalation_delay_in_minutes = 10 + target { + id = "PLBP04G" + type = "user" + } + } +} +` diff --git a/builtin/providers/pagerduty/import_pagerduty_service_test.go b/builtin/providers/pagerduty/import_pagerduty_service_test.go new file mode 100644 index 000000000..84a9bbb51 --- /dev/null +++ b/builtin/providers/pagerduty/import_pagerduty_service_test.go @@ -0,0 +1,35 @@ +package pagerduty + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccPagerDutyService_import(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyServiceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccPagerDutyServiceConfigImported, + }, + resource.TestStep{ + ResourceName: "pagerduty_service.foo", + ImportState: true, + ImportStateVerify: false, + }, + }, + }) +} + +const testAccPagerDutyServiceConfigImported = ` +resource "pagerduty_service" "foo" { + name = "foo" + description = "foo" + acknowledgement_timeout = "1800" + auto_resolve_timeout = "14400" + escalation_policy = "PGOMBUU" +} +` diff --git a/builtin/providers/pagerduty/import_pagerduty_team_test.go b/builtin/providers/pagerduty/import_pagerduty_team_test.go new file mode 100644 index 000000000..78f677dcf --- /dev/null +++ b/builtin/providers/pagerduty/import_pagerduty_team_test.go @@ -0,0 +1,32 @@ +package pagerduty + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccPagerDutyTeam_import(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyTeamDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccPagerDutyTeamConfigImported, + }, + resource.TestStep{ + ResourceName: "pagerduty_team.foo", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +const testAccPagerDutyTeamConfigImported = ` +resource "pagerduty_team" "foo" { + name = "foo" + description = "foo" +} +` diff --git a/builtin/providers/pagerduty/import_pagerduty_user_test.go b/builtin/providers/pagerduty/import_pagerduty_user_test.go new file mode 100644 index 000000000..c39e8f2b8 --- /dev/null +++ b/builtin/providers/pagerduty/import_pagerduty_user_test.go @@ -0,0 +1,35 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" +) + +func TestAccPagerDutyUser_import(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyUserDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccPagerDutyUserConfigImported(importUserID), + }, + resource.TestStep{ + ResourceName: "pagerduty_user.foo", + ImportState: true, + ImportStateVerify: true, + }, + }, + }) +} + +func testAccPagerDutyUserConfigImported(id string) string { + return fmt.Sprintf(` + resource "pagerduty_user" "foo" { + name = "foo" + email = "foo@bar.com" + } + `) +} diff --git a/builtin/providers/pagerduty/provider.go b/builtin/providers/pagerduty/provider.go new file mode 100644 index 000000000..2be5bc633 --- /dev/null +++ b/builtin/providers/pagerduty/provider.go @@ -0,0 +1,40 @@ +package pagerduty + +import ( + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +// Provider represents a resource provider in Terraform +func Provider() terraform.ResourceProvider { + return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "token": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: schema.EnvDefaultFunc("PAGERDUTY_TOKEN", nil), + }, + }, + + ResourcesMap: map[string]*schema.Resource{ + "pagerduty_user": resourcePagerDutyUser(), + "pagerduty_team": resourcePagerDutyTeam(), + "pagerduty_service": resourcePagerDutyService(), + "pagerduty_schedule": resourcePagerDutySchedule(), + "pagerduty_escalation_policy": resourcePagerDutyEscalationPolicy(), + }, + + ConfigureFunc: providerConfigure, + } +} + +func providerConfigure(data *schema.ResourceData) (interface{}, error) { + config := Config{ + Token: data.Get("token").(string), + } + + log.Println("[INFO] Initializing PagerDuty client") + return config.Client() +} diff --git a/builtin/providers/pagerduty/provider_test.go b/builtin/providers/pagerduty/provider_test.go new file mode 100644 index 000000000..4057873b0 --- /dev/null +++ b/builtin/providers/pagerduty/provider_test.go @@ -0,0 +1,48 @@ +package pagerduty + +import ( + "os" + "testing" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +var testAccProviders map[string]terraform.ResourceProvider +var testAccProvider *schema.Provider + +func init() { + testAccProvider = Provider().(*schema.Provider) + testAccProviders = map[string]terraform.ResourceProvider{ + "pagerduty": testAccProvider, + } +} + +func TestProvider(t *testing.T) { + if err := Provider().(*schema.Provider).InternalValidate(); err != nil { + t.Fatalf("err: %s", err) + } +} + +func TestProviderImpl(t *testing.T) { + var _ terraform.ResourceProvider = Provider() +} + +func testAccPreCheck(t *testing.T) { + if v := os.Getenv("PAGERDUTY_TOKEN"); v == "" { + t.Fatal("PAGERDUTY_TOKEN must be set for acceptance tests") + } + + if v := os.Getenv("PAGERDUTY_USER_ID"); v == "" { + t.Fatal("PAGERDUTY_USER_ID must be set for acceptance tests") + } + + if v := os.Getenv("PAGERDUTY_ESCALATION_POLICY_ID"); v == "" { + t.Fatal("PAGERDUTY_ESCALATION_POLICY_ID must be set for acceptance tests") + } +} + +var importEscalationPolicyID = os.Getenv("PAGERDUTY_ESCALATION_POLICY_ID") +var importUserID = os.Getenv("PAGERDUTY_USER_ID") +var userID = os.Getenv("PAGERDUTY_USER_ID") +var escalationPolicyID = os.Getenv("PAGERDUTY_ESCALATION_POLICY_ID") diff --git a/builtin/providers/pagerduty/resource_pagerduty_escalation_policy.go b/builtin/providers/pagerduty/resource_pagerduty_escalation_policy.go new file mode 100644 index 000000000..76cf4d709 --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_escalation_policy.go @@ -0,0 +1,187 @@ +package pagerduty + +import ( + "log" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourcePagerDutyEscalationPolicy() *schema.Resource { + return &schema.Resource{ + Create: resourcePagerDutyEscalationPolicyCreate, + Read: resourcePagerDutyEscalationPolicyRead, + Update: resourcePagerDutyEscalationPolicyUpdate, + Delete: resourcePagerDutyEscalationPolicyDelete, + Importer: &schema.ResourceImporter{ + State: resourcePagerDutyEscalationPolicyImport, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "Managed by Terraform", + }, + "num_loops": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "escalation_rule": &schema.Schema{ + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "escalation_delay_in_minutes": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + "target": &schema.Schema{ + Type: schema.TypeList, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "user_reference", + }, + "id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func buildEscalationPolicyRules(escalationRules *[]interface{}) *[]pagerduty.EscalationRule { + + rules := make([]pagerduty.EscalationRule, len(*escalationRules)) + + for i, l := range *escalationRules { + rule := l.(map[string]interface{}) + + escalationPolicyRule := pagerduty.EscalationRule{ + Delay: uint(rule["escalation_delay_in_minutes"].(int)), + } + + for _, t := range rule["target"].([]interface{}) { + target := t.(map[string]interface{}) + escalationPolicyRule.Targets = append( + escalationPolicyRule.Targets, + pagerduty.APIObject{ + Type: target["type"].(string), + ID: target["id"].(string), + }, + ) + } + + rules[i] = escalationPolicyRule + } + + return &rules +} + +func buildEscalationPolicyStruct(d *schema.ResourceData) *pagerduty.EscalationPolicy { + escalationRules := d.Get("escalation_rule").([]interface{}) + + policy := pagerduty.EscalationPolicy{ + Name: d.Get("name").(string), + EscalationRules: *buildEscalationPolicyRules(&escalationRules), + } + + if attr, ok := d.GetOk("description"); ok { + policy.Description = attr.(string) + } + + if attr, ok := d.GetOk("num_loops"); ok { + policy.NumLoops = uint(attr.(int)) + } + + return &policy +} + +func resourcePagerDutyEscalationPolicyCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + e := buildEscalationPolicyStruct(d) + + log.Printf("[INFO] Creating PagerDuty escalation policy: %s", e.Name) + + e, err := client.CreateEscalationPolicy(*e) + + if err != nil { + return err + } + + d.SetId(e.ID) + + return resourcePagerDutyEscalationPolicyRead(d, meta) +} + +func resourcePagerDutyEscalationPolicyRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Reading PagerDuty escalation policy: %s", d.Id()) + + e, err := client.GetEscalationPolicy(d.Id(), &pagerduty.GetEscalationPolicyOptions{}) + + if err != nil { + return err + } + + d.Set("name", e.Name) + d.Set("description", e.Description) + d.Set("num_loops", e.NumLoops) + d.Set("escalation_rules", e.EscalationRules) + + return nil +} + +func resourcePagerDutyEscalationPolicyUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + e := buildEscalationPolicyStruct(d) + + log.Printf("[INFO] Updating PagerDuty escalation policy: %s", d.Id()) + + e, err := client.UpdateEscalationPolicy(d.Id(), e) + + if err != nil { + return err + } + + return nil +} + +func resourcePagerDutyEscalationPolicyDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Deleting PagerDuty escalation policy: %s", d.Id()) + + err := client.DeleteEscalationPolicy(d.Id()) + + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func resourcePagerDutyEscalationPolicyImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + if err := resourcePagerDutyEscalationPolicyRead(d, meta); err != nil { + return nil, err + } + return []*schema.ResourceData{d}, nil +} diff --git a/builtin/providers/pagerduty/resource_pagerduty_escalation_policy_test.go b/builtin/providers/pagerduty/resource_pagerduty_escalation_policy_test.go new file mode 100644 index 000000000..8e07df040 --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_escalation_policy_test.go @@ -0,0 +1,137 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccPagerDutyEscalationPolicy_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyEscalationPolicyDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckPagerDutyEscalationPolicyConfig(userID), + 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", "escalation_rule.#", "1"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "escalation_rule.0.escalation_delay_in_minutes", "10"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "escalation_rule.0.target.#", "1"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "escalation_rule.0.target.0.id", userID), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "escalation_rule.0.target.0.type", "user"), + ), + }, + resource.TestStep{ + Config: testAccCheckPagerDutyEscalationPolicyConfigUpdated(userID), + 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", "escalation_rule.#", "2"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "escalation_rule.0.escalation_delay_in_minutes", "10"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "escalation_rule.0.target.#", "1"), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "escalation_rule.0.target.0.id", userID), + resource.TestCheckResourceAttr( + "pagerduty_escalation_policy.foo", "escalation_rule.0.target.0.type", "user"), + ), + }, + }, + }) +} + +func testAccCheckPagerDutyEscalationPolicyDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*pagerduty.Client) + for _, r := range s.RootModule().Resources { + if r.Type != "pagerduty_escalation_policy" { + continue + } + + _, err := client.GetEscalationPolicy(r.Primary.ID, &pagerduty.GetEscalationPolicyOptions{}) + + if err == nil { + return fmt.Errorf("Escalation Policy still exists") + } + + } + return nil +} + +func testAccCheckPagerDutyEscalationPolicyExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*pagerduty.Client) + for _, r := range s.RootModule().Resources { + if _, err := client.GetEscalationPolicy(r.Primary.ID, &pagerduty.GetEscalationPolicyOptions{}); err != nil { + return fmt.Errorf("Received an error retrieving escalation_policy %s ID: %s", err, r.Primary.ID) + } + } + return nil + } +} + +func testAccCheckPagerDutyEscalationPolicyConfig(id string) string { + return fmt.Sprintf(` +resource "pagerduty_escalation_policy" "foo" { + name = "foo" + description = "foo" + num_loops = 1 + + escalation_rule { + escalation_delay_in_minutes = 10 + target { + type = "user" + id = "%s" + } + } +} + `, id) +} + +func testAccCheckPagerDutyEscalationPolicyConfigUpdated(id string) string { + return fmt.Sprintf(` +resource "pagerduty_escalation_policy" "foo" { + name = "bar" + description = "bar" + num_loops = 2 + + escalation_rule { + escalation_delay_in_minutes = 10 + target { + type = "user" + id = "%[1]v" + } + } + + escalation_rule { + escalation_delay_in_minutes = 20 + target { + type = "user" + id = "%[1]v" + } + } +} +`, userID) +} diff --git a/builtin/providers/pagerduty/resource_pagerduty_schedule.go b/builtin/providers/pagerduty/resource_pagerduty_schedule.go new file mode 100644 index 000000000..acfb7ab47 --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_schedule.go @@ -0,0 +1,280 @@ +package pagerduty + +import ( + "log" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourcePagerDutySchedule() *schema.Resource { + return &schema.Resource{ + Create: resourcePagerDutyScheduleCreate, + Read: resourcePagerDutyScheduleRead, + Update: resourcePagerDutyScheduleUpdate, + Delete: resourcePagerDutyScheduleDelete, + Importer: &schema.ResourceImporter{ + State: resourcePagerDutyScheduleImport, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "time_zone": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "Managed by Terraform", + }, + "schedule_layer": &schema.Schema{ + Type: schema.TypeList, + Required: true, + ForceNew: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "start": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + if old == "" { + return false + } + return true + }, + }, + "end": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "rotation_virtual_start": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "rotation_turn_length_seconds": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + "users": &schema.Schema{ + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "restriction": &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "type": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "start_time_of_day": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "duration_seconds": &schema.Schema{ + Type: schema.TypeInt, + Required: true, + }, + }, + }, + }, + }, + }, + }, + }, + } +} + +func buildScheduleLayers(d *schema.ResourceData, scheduleLayers *[]interface{}) *[]pagerduty.ScheduleLayer { + + pagerdutyLayers := make([]pagerduty.ScheduleLayer, len(*scheduleLayers)) + + for i, l := range *scheduleLayers { + layer := l.(map[string]interface{}) + + scheduleLayer := pagerduty.ScheduleLayer{ + Name: layer["name"].(string), + Start: layer["start"].(string), + End: layer["end"].(string), + RotationVirtualStart: layer["rotation_virtual_start"].(string), + RotationTurnLengthSeconds: uint(layer["rotation_turn_length_seconds"].(int)), + } + + if layer["id"] != nil || layer["id"] != "" { + scheduleLayer.ID = layer["id"].(string) + } + + for _, u := range layer["users"].([]interface{}) { + scheduleLayer.Users = append( + scheduleLayer.Users, + pagerduty.UserReference{ + User: pagerduty.APIObject{ + ID: u.(string), + Type: "user_reference"}, + }, + ) + } + + restrictions := layer["restriction"].([]interface{}) + + if len(restrictions) > 0 { + for _, r := range restrictions { + restriction := r.(map[string]interface{}) + scheduleLayer.Restrictions = append( + scheduleLayer.Restrictions, + pagerduty.Restriction{ + Type: restriction["type"].(string), + StartTimeOfDay: restriction["start_time_of_day"].(string), + DurationSeconds: uint(restriction["duration_seconds"].(int)), + }, + ) + } + } + + pagerdutyLayers[i] = scheduleLayer + + } + + return &pagerdutyLayers +} + +func buildScheduleStruct(d *schema.ResourceData) (*pagerduty.Schedule, error) { + pagerdutyLayers := d.Get("schedule_layer").([]interface{}) + + schedule := pagerduty.Schedule{ + Name: d.Get("name").(string), + TimeZone: d.Get("time_zone").(string), + } + + schedule.ScheduleLayers = *buildScheduleLayers(d, &pagerdutyLayers) + + if attr, ok := d.GetOk("description"); ok { + schedule.Description = attr.(string) + } + + return &schedule, nil +} + +func resourcePagerDutyScheduleCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + s, _ := buildScheduleStruct(d) + + log.Printf("[INFO] Creating PagerDuty schedule: %s", s.Name) + + e, err := client.CreateSchedule(*s) + + if err != nil { + return err + } + + d.SetId(e.ID) + + return resourcePagerDutyScheduleRead(d, meta) +} + +func resourcePagerDutyScheduleRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Reading PagerDuty schedule: %s", d.Id()) + + s, err := client.GetSchedule(d.Id(), pagerduty.GetScheduleOptions{}) + + if err != nil { + return err + } + + d.Set("name", s.Name) + d.Set("description", s.Description) + + scheduleLayers := make([]map[string]interface{}, 0, len(s.ScheduleLayers)) + + for _, layer := range s.ScheduleLayers { + restrictions := make([]map[string]interface{}, 0, len(layer.Restrictions)) + + for _, r := range layer.Restrictions { + restrictions = append(restrictions, map[string]interface{}{ + "duration_seconds": r.DurationSeconds, + "start_time_of_day": r.StartTimeOfDay, + "type": r.Type, + }) + } + + users := make([]string, 0, len(layer.Users)) + + for _, u := range layer.Users { + users = append(users, u.User.ID) + } + + scheduleLayers = append(scheduleLayers, map[string]interface{}{ + "id": layer.ID, + "name": layer.Name, + "start": layer.Start, + "end": layer.End, + "users": users, + "rotation_turn_length_seconds": layer.RotationTurnLengthSeconds, + "rotation_virtual_start": layer.RotationVirtualStart, + "restriction": restrictions, + }) + } + + d.Set("schedule_layer", scheduleLayers) + + return nil +} + +func resourcePagerDutyScheduleUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + e, _ := buildScheduleStruct(d) + + d.MarkNewResource() + + log.Printf("[INFO] Updating PagerDuty schedule: %s", d.Id()) + + e, err := client.UpdateSchedule(d.Id(), *e) + + if err != nil { + return err + } + + return nil +} + +func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Deleting PagerDuty schedule: %s", d.Id()) + + err := client.DeleteSchedule(d.Id()) + + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func resourcePagerDutyScheduleImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + if err := resourcePagerDutyScheduleRead(d, meta); err != nil { + return nil, err + } + return []*schema.ResourceData{d}, nil +} diff --git a/builtin/providers/pagerduty/resource_pagerduty_service.go b/builtin/providers/pagerduty/resource_pagerduty_service.go new file mode 100644 index 000000000..eb68f83c5 --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_service.go @@ -0,0 +1,148 @@ +package pagerduty + +import ( + "log" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourcePagerDutyService() *schema.Resource { + return &schema.Resource{ + Create: resourcePagerDutyServiceCreate, + Read: resourcePagerDutyServiceRead, + Update: resourcePagerDutyServiceUpdate, + Delete: resourcePagerDutyServiceDelete, + Importer: &schema.ResourceImporter{ + State: resourcePagerDutyServiceImport, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "Managed by Terraform", + }, + "auto_resolve_timeout": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "acknowledgement_timeout": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "escalation_policy": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + } +} + +func buildServiceStruct(d *schema.ResourceData) *pagerduty.Service { + service := pagerduty.Service{ + Name: d.Get("name").(string), + } + + if attr, ok := d.GetOk("description"); ok { + service.Description = attr.(string) + } + + if attr, ok := d.GetOk("auto_resolve_timeout"); ok { + autoResolveTimeout := uint(attr.(int)) + service.AutoResolveTimeout = &autoResolveTimeout + } + + if attr, ok := d.GetOk("acknowledgement_timeout"); ok { + acknowledgementTimeout := uint(attr.(int)) + service.AcknowledgementTimeout = &acknowledgementTimeout + } + + policy := &pagerduty.EscalationPolicy{} + policy.ID = d.Get("escalation_policy").(string) + policy.Type = "escalation_policy" + service.EscalationPolicy = *policy + + return &service +} + +func resourcePagerDutyServiceCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + s := buildServiceStruct(d) + + log.Printf("[INFO] Creating PagerDuty service %s", s.Name) + + s, err := client.CreateService(*s) + + if err != nil { + return err + } + + d.SetId(s.ID) + + return nil +} + +func resourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Reading PagerDuty service %s", d.Id()) + + s, err := client.GetService(d.Id(), pagerduty.GetServiceOptions{}) + + if err != nil { + return err + } + + d.Set("name", s.Name) + d.Set("escalation_policy", s.EscalationPolicy) + d.Set("description", s.Description) + d.Set("auto_resolve_timeout", s.AutoResolveTimeout) + d.Set("acknowledgement_timeout", s.AcknowledgementTimeout) + + return nil +} + +func resourcePagerDutyServiceUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + s := buildServiceStruct(d) + s.ID = d.Id() + + log.Printf("[INFO] Updating PagerDuty service %s", d.Id()) + + s, err := client.UpdateService(*s) + + if err != nil { + return err + } + + return nil +} + +func resourcePagerDutyServiceDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Deleting PagerDuty service %s", d.Id()) + + err := client.DeleteService(d.Id()) + + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func resourcePagerDutyServiceImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + if err := resourcePagerDutyServiceRead(d, meta); err != nil { + return nil, err + } + return []*schema.ResourceData{d}, nil +} diff --git a/builtin/providers/pagerduty/resource_pagerduty_service_test.go b/builtin/providers/pagerduty/resource_pagerduty_service_test.go new file mode 100644 index 000000000..d270c7872 --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_service_test.go @@ -0,0 +1,105 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccPagerDutyService_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyServiceDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckPagerDutyServiceConfig(escalationPolicyID), + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyServiceExists("pagerduty_service.foo"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "name", "foo"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "description", "foo"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "auto_resolve_timeout", "1800"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "acknowledgement_timeout", "1800"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "escalation_policy", escalationPolicyID), + ), + }, + resource.TestStep{ + Config: testAccCheckPagerDutyServiceConfigUpdated(escalationPolicyID), + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyServiceExists("pagerduty_service.foo"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "name", "bar"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "description", "bar"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "auto_resolve_timeout", "3600"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "acknowledgement_timeout", "3600"), + resource.TestCheckResourceAttr( + "pagerduty_service.foo", "escalation_policy", escalationPolicyID), + ), + }, + }, + }) +} + +func testAccCheckPagerDutyServiceDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*pagerduty.Client) + for _, r := range s.RootModule().Resources { + if r.Type != "pagerduty_service" { + continue + } + + _, err := client.GetService(r.Primary.ID, pagerduty.GetServiceOptions{}) + + if err == nil { + return fmt.Errorf("Service still exists") + } + + } + return nil +} + +func testAccCheckPagerDutyServiceExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*pagerduty.Client) + for _, r := range s.RootModule().Resources { + if _, err := client.GetService(r.Primary.ID, pagerduty.GetServiceOptions{}); err != nil { + return fmt.Errorf("Received an error retrieving service %s ID: %s", err, r.Primary.ID) + } + } + return nil + } +} + +func testAccCheckPagerDutyServiceConfig(id string) string { + return fmt.Sprintf(` + resource "pagerduty_service" "foo" { + name = "foo" + description = "foo" + auto_resolve_timeout = 1800 + acknowledgement_timeout = 1800 + escalation_policy = "%s" + } + `, escalationPolicyID) +} + +func testAccCheckPagerDutyServiceConfigUpdated(id string) string { + return fmt.Sprintf(` +resource "pagerduty_service" "foo" { + name = "bar" + description = "bar" + auto_resolve_timeout = 3600 + acknowledgement_timeout = 3600 + escalation_policy = "%s" +} +`, escalationPolicyID) +} diff --git a/builtin/providers/pagerduty/resource_pagerduty_team.go b/builtin/providers/pagerduty/resource_pagerduty_team.go new file mode 100644 index 000000000..a42cd9005 --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_team.go @@ -0,0 +1,118 @@ +package pagerduty + +import ( + "log" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourcePagerDutyTeam() *schema.Resource { + return &schema.Resource{ + Create: resourcePagerDutyTeamCreate, + Read: resourcePagerDutyTeamRead, + Update: resourcePagerDutyTeamUpdate, + Delete: resourcePagerDutyTeamDelete, + Importer: &schema.ResourceImporter{ + State: resourcePagerDutyTeamImport, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "Managed by Terraform", + }, + }, + } +} + +func buildTeamStruct(d *schema.ResourceData) *pagerduty.Team { + team := pagerduty.Team{ + Name: d.Get("name").(string), + } + + if attr, ok := d.GetOk("description"); ok { + team.Description = attr.(string) + } + + return &team +} + +func resourcePagerDutyTeamCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + t := buildTeamStruct(d) + + log.Printf("[INFO] Creating PagerDuty team %s", t.Name) + + t, err := client.CreateTeam(t) + + if err != nil { + return err + } + + d.SetId(t.ID) + + return nil + +} + +func resourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Reading PagerDuty team %s", d.Id()) + + t, err := client.GetTeam(d.Id()) + + if err != nil { + return err + } + + d.Set("name", t.Name) + d.Set("description", t.Description) + + return nil +} + +func resourcePagerDutyTeamUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + t := buildTeamStruct(d) + + log.Printf("[INFO] Updating PagerDuty team %s", d.Id()) + + t, err := client.UpdateTeam(d.Id(), t) + + if err != nil { + return err + } + + return nil +} + +func resourcePagerDutyTeamDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Deleting PagerDuty team %s", d.Id()) + + err := client.DeleteTeam(d.Id()) + + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func resourcePagerDutyTeamImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + if err := resourcePagerDutyTeamRead(d, meta); err != nil { + return nil, err + } + return []*schema.ResourceData{d}, nil +} diff --git a/builtin/providers/pagerduty/resource_pagerduty_team_test.go b/builtin/providers/pagerduty/resource_pagerduty_team_test.go new file mode 100644 index 000000000..369440ee9 --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_team_test.go @@ -0,0 +1,83 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccPagerDutyTeam_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyTeamDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckPagerDutyTeamConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyTeamExists("pagerduty_team.foo"), + resource.TestCheckResourceAttr( + "pagerduty_team.foo", "name", "foo"), + resource.TestCheckResourceAttr( + "pagerduty_team.foo", "description", "foo"), + ), + }, + resource.TestStep{ + Config: testAccCheckPagerDutyTeamConfigUpdated, + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyTeamExists("pagerduty_team.foo"), + resource.TestCheckResourceAttr( + "pagerduty_team.foo", "name", "bar"), + resource.TestCheckResourceAttr( + "pagerduty_team.foo", "description", "bar"), + ), + }, + }, + }) +} + +func testAccCheckPagerDutyTeamDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*pagerduty.Client) + for _, r := range s.RootModule().Resources { + if r.Type != "pagerduty_team" { + continue + } + + _, err := client.GetTeam(r.Primary.ID) + + if err == nil { + return fmt.Errorf("Team still exists") + } + + } + return nil +} + +func testAccCheckPagerDutyTeamExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*pagerduty.Client) + for _, r := range s.RootModule().Resources { + if _, err := client.GetTeam(r.Primary.ID); err != nil { + return fmt.Errorf("Received an error retrieving team %s ID: %s", err, r.Primary.ID) + } + } + return nil + } +} + +const testAccCheckPagerDutyTeamConfig = ` +resource "pagerduty_team" "foo" { + name = "foo" + description = "foo" +} +` + +const testAccCheckPagerDutyTeamConfigUpdated = ` +resource "pagerduty_team" "foo" { + name = "bar" + description = "bar" +} +` diff --git a/builtin/providers/pagerduty/resource_pagerduty_user.go b/builtin/providers/pagerduty/resource_pagerduty_user.go new file mode 100644 index 000000000..02948283c --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_user.go @@ -0,0 +1,236 @@ +package pagerduty + +import ( + "fmt" + "log" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/schema" +) + +func resourcePagerDutyUser() *schema.Resource { + return &schema.Resource{ + Create: resourcePagerDutyUserCreate, + Read: resourcePagerDutyUserRead, + Update: resourcePagerDutyUserUpdate, + Delete: resourcePagerDutyUserDelete, + Importer: &schema.ResourceImporter{ + State: resourcePagerDutyUserImport, + }, + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "email": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "color": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Computed: true, + }, + "role": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "user", + ValidateFunc: validatePagerDutyUserRole, + }, + "job_title": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "avatar_url": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "teams": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Set: schema.HashString, + }, + "time_zone": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "html_url": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "invitation_sent": &schema.Schema{ + Type: schema.TypeBool, + Computed: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + Default: "Managed by Terraform", + }, + }, + } +} + +func buildUserStruct(d *schema.ResourceData) *pagerduty.User { + user := pagerduty.User{ + Name: d.Get("name").(string), + Email: d.Get("email").(string), + } + + if attr, ok := d.GetOk("color"); ok { + user.Color = attr.(string) + } + + if attr, ok := d.GetOk("role"); ok { + user.Role = attr.(string) + } + + if attr, ok := d.GetOk("job_title"); ok { + user.JobTitle = attr.(string) + } + + if attr, ok := d.GetOk("description"); ok { + user.Description = attr.(string) + } + + return &user +} + +func resourcePagerDutyUserCreate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + u := buildUserStruct(d) + + log.Printf("[INFO] Creating PagerDuty user %s", u.Name) + + u, err := client.CreateUser(*u) + + if err != nil { + return err + } + + d.SetId(u.ID) + + return resourcePagerDutyUserUpdate(d, meta) +} + +func resourcePagerDutyUserRead(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Reading PagerDuty user %s", d.Id()) + + u, err := client.GetUser(d.Id(), pagerduty.GetUserOptions{}) + + 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) + + return nil +} + +func resourcePagerDutyUserUpdate(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + u := buildUserStruct(d) + u.ID = d.Id() + + log.Printf("[INFO] Updating PagerDuty user %s", d.Id()) + + u, err := client.UpdateUser(*u) + + if err != nil { + return err + } + + if d.HasChange("teams") { + o, n := d.GetChange("teams") + + if o == nil { + o = new(schema.Set) + } + + if n == nil { + n = new(schema.Set) + } + + os := o.(*schema.Set) + ns := n.(*schema.Set) + + remove := expandStringList(os.Difference(ns).List()) + add := expandStringList(ns.Difference(os).List()) + + for _, t := range remove { + _, tErr := client.GetTeam(t) + + if tErr != nil { + log.Printf("[INFO] PagerDuty team: %s not found, removing dangling team reference for user %s", t, d.Id()) + continue + } + + log.Printf("[INFO] Removing PagerDuty user %s from team: %s", d.Id(), t) + + rErr := client.RemoveUserFromTeam(t, d.Id()) + if rErr != nil { + return rErr + } + } + + for _, t := range add { + log.Printf("[INFO] Adding PagerDuty user %s to team: %s", d.Id(), t) + + aErr := client.AddUserToTeam(t, d.Id()) + if aErr != nil { + return aErr + } + } + } + + return nil +} + +func resourcePagerDutyUserDelete(d *schema.ResourceData, meta interface{}) error { + client := meta.(*pagerduty.Client) + + log.Printf("[INFO] Deleting PagerDuty user %s", d.Id()) + + err := client.DeleteUser(d.Id()) + + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func resourcePagerDutyUserImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { + if err := resourcePagerDutyUserRead(d, meta); err != nil { + return nil, err + } + return []*schema.ResourceData{d}, nil +} + +func validatePagerDutyUserRole(v interface{}, k string) (ws []string, errors []error) { + validRoles := []string{"admin", "limited_user", "owner", "read_only_user", "user"} + role := v.(string) + + if !contains(validRoles, role) { + errors = append(errors, fmt.Errorf("%q must be one of %v", k, validRoles)) + } + + return +} diff --git a/builtin/providers/pagerduty/resource_pagerduty_user_test.go b/builtin/providers/pagerduty/resource_pagerduty_user_test.go new file mode 100644 index 000000000..bbe8f374f --- /dev/null +++ b/builtin/providers/pagerduty/resource_pagerduty_user_test.go @@ -0,0 +1,110 @@ +package pagerduty + +import ( + "fmt" + "testing" + + "github.com/PagerDuty/go-pagerduty" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccPagerDutyUser_Basic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccCheckPagerDutyUserDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccCheckPagerDutyUserConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyUserExists("pagerduty_user.foo"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "name", "foo"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "email", "foo@bar.com"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "color", "green"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "role", "user"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "job_title", "foo"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "description", "foo"), + ), + }, + resource.TestStep{ + Config: testAccCheckPagerDutyUserConfigUpdated, + Check: resource.ComposeTestCheckFunc( + testAccCheckPagerDutyUserExists("pagerduty_user.foo"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "name", "bar"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "email", "bar@foo.com"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "color", "red"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "role", "user"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "job_title", "bar"), + resource.TestCheckResourceAttr( + "pagerduty_user.foo", "description", "bar"), + ), + }, + }, + }) +} + +func testAccCheckPagerDutyUserDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*pagerduty.Client) + for _, r := range s.RootModule().Resources { + if r.Type != "pagerduty_user" { + continue + } + + opts := pagerduty.GetUserOptions{} + + _, err := client.GetUser(r.Primary.ID, opts) + + if err == nil { + return fmt.Errorf("User still exists") + } + + } + return nil +} + +func testAccCheckPagerDutyUserExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + client := testAccProvider.Meta().(*pagerduty.Client) + for _, r := range s.RootModule().Resources { + opts := pagerduty.GetUserOptions{} + if _, err := client.GetUser(r.Primary.ID, opts); err != nil { + return fmt.Errorf("Received an error retrieving user %s ID: %s", err, r.Primary.ID) + } + } + return nil + } +} + +const testAccCheckPagerDutyUserConfig = ` +resource "pagerduty_user" "foo" { + name = "foo" + email = "foo@bar.com" + color = "green" + role = "user" + job_title = "foo" + description = "foo" +} +` + +const testAccCheckPagerDutyUserConfigUpdated = ` +resource "pagerduty_user" "foo" { + name = "bar" + email = "bar@foo.com" + color = "red" + role = "user" + job_title = "bar" + description = "bar" +} +` diff --git a/builtin/providers/pagerduty/structure.go b/builtin/providers/pagerduty/structure.go new file mode 100644 index 000000000..461f3cdf1 --- /dev/null +++ b/builtin/providers/pagerduty/structure.go @@ -0,0 +1,22 @@ +package pagerduty + +// Takes the result of flatmap.Expand for an array of strings +// and returns a []string +func expandStringList(configured []interface{}) []string { + vs := make([]string, 0, len(configured)) + for _, v := range configured { + vs = append(vs, string(v.(string))) + } + return vs +} + +// Checks if a slice contains a string +func contains(slice []string, item string) bool { + set := make(map[string]struct{}, len(slice)) + for _, s := range slice { + set[s] = struct{}{} + } + + _, ok := set[item] + return ok +} diff --git a/command/internal_plugin_list.go b/command/internal_plugin_list.go index 077dfecbf..e40de2664 100644 --- a/command/internal_plugin_list.go +++ b/command/internal_plugin_list.go @@ -37,6 +37,7 @@ import ( nullprovider "github.com/hashicorp/terraform/builtin/providers/null" openstackprovider "github.com/hashicorp/terraform/builtin/providers/openstack" packetprovider "github.com/hashicorp/terraform/builtin/providers/packet" + pagerdutyprovider "github.com/hashicorp/terraform/builtin/providers/pagerduty" postgresqlprovider "github.com/hashicorp/terraform/builtin/providers/postgresql" powerdnsprovider "github.com/hashicorp/terraform/builtin/providers/powerdns" rabbitmqprovider "github.com/hashicorp/terraform/builtin/providers/rabbitmq" @@ -94,6 +95,7 @@ var InternalProviders = map[string]plugin.ProviderFunc{ "null": nullprovider.Provider, "openstack": openstackprovider.Provider, "packet": packetprovider.Provider, + "pagerduty": pagerdutyprovider.Provider, "postgresql": postgresqlprovider.Provider, "powerdns": powerdnsprovider.Provider, "rabbitmq": rabbitmqprovider.Provider,