Add PagerDuty provider

This commit is contained in:
Alexander Hellbom 2016-09-23 21:43:06 +02:00
parent b1bf972d4d
commit d02067a75e
19 changed files with 1689 additions and 0 deletions

View File

@ -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,
})
}

View File

@ -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
}

View File

@ -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"
}
}
}
`

View File

@ -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"
}
`

View File

@ -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"
}
`

View File

@ -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"
}
`)
}

View File

@ -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()
}

View File

@ -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")

View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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)
}

View File

@ -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
}

View File

@ -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"
}
`

View File

@ -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
}

View File

@ -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"
}
`

View File

@ -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
}

View File

@ -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,