Merge pull request #9022 from heimweh/master

Adding PagerDuty provider
This commit is contained in:
Paul Stack 2016-10-24 17:07:22 +01:00 committed by GitHub
commit 765dc19286
58 changed files with 5176 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,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": {
Type: schema.TypeString,
Required: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"type": {
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
}

View File

@ -0,0 +1,57 @@
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"])
}
if a["name"] != "Datadog" {
return fmt.Errorf("Expected the Datadog Vendor Name to be: Datadog, but got: %s", a["name"])
}
if a["type"] != "generic_events_api_inbound_integration" {
return fmt.Errorf("Expected the Datadog Vendor Type to be: generic_events_api_inbound_integration, but got: %s", a["type"])
}
return nil
}
}
const testAccPagerDutyVendorsConfig = `
data "pagerduty_vendor" "datadog" {
name_regex = "Datadog"
}
`

View File

@ -0,0 +1,28 @@
package pagerduty
import (
"testing"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccPagerDutyEscalationPolicy_import(t *testing.T) {
resourceName := "pagerduty_escalation_policy.foo"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyEscalationPolicyDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyEscalationPolicyConfig,
},
resource.TestStep{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,28 @@
package pagerduty
import (
"testing"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccPagerDutySchedule_import(t *testing.T) {
resourceName := "pagerduty_schedule.foo"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyUserDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyScheduleConfig,
},
resource.TestStep{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,28 @@
package pagerduty
import (
"testing"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccPagerDutyService_import(t *testing.T) {
resourceName := "pagerduty_service.foo"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyServiceDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyServiceConfig,
},
resource.TestStep{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,28 @@
package pagerduty
import (
"testing"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccPagerDutyTeam_import(t *testing.T) {
resourceName := "pagerduty_team.foo"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyTeamDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyTeamConfig,
},
resource.TestStep{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,28 @@
package pagerduty
import (
"testing"
"github.com/hashicorp/terraform/helper/resource"
)
func TestAccPagerDutyUser_import(t *testing.T) {
resourceName := "pagerduty_user.foo"
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyUserDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyUserConfig,
},
resource.TestStep{
ResourceName: resourceName,
ImportState: true,
ImportStateVerify: true,
},
},
})
}

View File

@ -0,0 +1,42 @@
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": {
Type: schema.TypeString,
Required: true,
DefaultFunc: schema.EnvDefaultFunc("PAGERDUTY_TOKEN", nil),
},
},
DataSourcesMap: map[string]*schema.Resource{
"pagerduty_vendor": dataSourcePagerDutyVendor(),
},
ResourcesMap: map[string]*schema.Resource{
"pagerduty_user": resourcePagerDutyUser(),
"pagerduty_team": resourcePagerDutyTeam(),
"pagerduty_service": resourcePagerDutyService(),
"pagerduty_service_integration": resourcePagerDutyServiceIntegration(),
"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,35 @@
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")
}
}

View File

@ -0,0 +1,176 @@
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": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
Default: "Managed by Terraform",
},
"num_loops": {
Type: schema.TypeInt,
Optional: true,
},
"teams": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"rule": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"escalation_delay_in_minutes": {
Type: schema.TypeInt,
Required: true,
},
"target": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Optional: true,
Default: "user_reference",
},
"id": {
Type: schema.TypeString,
Required: true,
},
},
},
},
},
},
},
},
}
}
func buildEscalationPolicyStruct(d *schema.ResourceData) *pagerduty.EscalationPolicy {
escalationRules := d.Get("rule").([]interface{})
escalationPolicy := pagerduty.EscalationPolicy{
Name: d.Get("name").(string),
EscalationRules: expandEscalationRules(escalationRules),
}
if attr, ok := d.GetOk("description"); ok {
escalationPolicy.Description = attr.(string)
}
if attr, ok := d.GetOk("num_loops"); ok {
escalationPolicy.NumLoops = uint(attr.(int))
}
if attr, ok := d.GetOk("teams"); ok {
escalationPolicy.Teams = expandTeams(attr.([]interface{}))
}
return &escalationPolicy
}
func resourcePagerDutyEscalationPolicyCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
escalationPolicy := buildEscalationPolicyStruct(d)
log.Printf("[INFO] Creating PagerDuty escalation policy: %s", escalationPolicy.Name)
escalationPolicy, err := client.CreateEscalationPolicy(*escalationPolicy)
if err != nil {
return err
}
d.SetId(escalationPolicy.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())
o := &pagerduty.GetEscalationPolicyOptions{}
escalationPolicy, err := client.GetEscalationPolicy(d.Id(), o)
if err != nil {
return err
}
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", flattenEscalationRules(escalationPolicy.EscalationRules)); err != nil {
return err
}
return nil
}
func resourcePagerDutyEscalationPolicyUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
escalationPolicy := buildEscalationPolicyStruct(d)
log.Printf("[INFO] Updating PagerDuty escalation policy: %s", d.Id())
if _, err := client.UpdateEscalationPolicy(d.Id(), escalationPolicy); 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())
if err := client.DeleteEscalationPolicy(d.Id()); 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,277 @@
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,
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.TestStep{
Config: testAccCheckPagerDutyEscalationPolicyConfigUpdated,
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"),
),
},
},
})
}
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"),
),
},
},
})
}
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 {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Escalation Policy ID is set")
}
client := testAccProvider.Meta().(*pagerduty.Client)
found, err := client.GetEscalationPolicy(rs.Primary.ID, &pagerduty.GetEscalationPolicyOptions{})
if err != nil {
return err
}
if found.ID != rs.Primary.ID {
return fmt.Errorf("Escalation policy not found: %v - %v", rs.Primary.ID, found)
}
return nil
}
}
const testAccCheckPagerDutyEscalationPolicyConfig = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
color = "green"
role = "user"
job_title = "foo"
description = "foo"
}
resource "pagerduty_escalation_policy" "foo" {
name = "foo"
description = "foo"
num_loops = 1
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
}
`
const testAccCheckPagerDutyEscalationPolicyConfigUpdated = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
color = "green"
role = "user"
job_title = "foo"
description = "foo"
}
resource "pagerduty_escalation_policy" "foo" {
name = "bar"
description = "bar"
num_loops = 2
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
rule {
escalation_delay_in_minutes = 20
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
}
`
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}"
}
}
}
`

View File

@ -0,0 +1,201 @@
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": {
Type: schema.TypeString,
Optional: true,
},
"time_zone": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
Default: "Managed by Terraform",
},
"layer": {
Type: schema.TypeList,
Required: true,
ForceNew: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"start": {
Type: schema.TypeString,
Optional: true,
Computed: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
if old == "" {
return false
}
return true
},
},
"end": {
Type: schema.TypeString,
Optional: true,
},
"rotation_virtual_start": {
Type: schema.TypeString,
Optional: true,
Computed: true,
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
if old == "" {
return false
}
return true
},
},
"rotation_turn_length_seconds": {
Type: schema.TypeInt,
Required: true,
},
"users": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"restriction": {
Optional: true,
Type: schema.TypeList,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"type": {
Type: schema.TypeString,
Required: true,
},
"start_time_of_day": {
Type: schema.TypeString,
Required: true,
},
"duration_seconds": {
Type: schema.TypeInt,
Required: true,
},
},
},
},
},
},
},
},
}
}
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: expandScheduleLayers(scheduleLayers),
}
if attr, ok := d.GetOk("description"); ok {
schedule.Description = attr.(string)
}
return &schedule
}
func resourcePagerDutyScheduleCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
schedule := buildScheduleStruct(d)
log.Printf("[INFO] Creating PagerDuty schedule: %s", schedule.Name)
schedule, err := client.CreateSchedule(*schedule)
if err != nil {
return err
}
d.SetId(schedule.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())
schedule, err := client.GetSchedule(d.Id(), pagerduty.GetScheduleOptions{})
if err != nil {
return err
}
d.Set("name", schedule.Name)
d.Set("time_zone", schedule.TimeZone)
d.Set("description", schedule.Description)
if err := d.Set("layer", flattenScheduleLayers(schedule.ScheduleLayers)); err != nil {
return err
}
return nil
}
func resourcePagerDutyScheduleUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
schedule := buildScheduleStruct(d)
log.Printf("[INFO] Updating PagerDuty schedule: %s", d.Id())
if _, err := client.UpdateSchedule(d.Id(), *schedule); 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())
if err := client.DeleteSchedule(d.Id()); 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,235 @@
package pagerduty
import (
"fmt"
"testing"
"github.com/PagerDuty/go-pagerduty"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccPagerDutySchedule_Basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyScheduleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyScheduleConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyScheduleExists("pagerduty_schedule.foo"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "name", "foo"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "description", "foo"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "time_zone", "Europe/Berlin"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "layer.#", "1"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "layer.0.name", "foo"),
),
},
resource.TestStep{
Config: testAccCheckPagerDutyScheduleConfigUpdated,
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyScheduleExists("pagerduty_schedule.foo"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "name", "bar"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "description", "Managed by Terraform"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "time_zone", "America/New_York"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "layer.#", "1"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "layer.0.name", "foo"),
),
},
},
})
}
func TestAccPagerDutySchedule_Multi(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyScheduleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyScheduleConfigMulti,
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyScheduleExists("pagerduty_schedule.foo"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "name", "foo"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "description", "foo"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "time_zone", "America/New_York"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "layer.#", "3"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "layer.0.name", "foo"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "layer.1.name", "bar"),
resource.TestCheckResourceAttr(
"pagerduty_schedule.foo", "layer.2.name", "foobar"),
),
},
},
})
}
func testAccCheckPagerDutyScheduleDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*pagerduty.Client)
for _, r := range s.RootModule().Resources {
if r.Type != "pagerduty_schedule" {
continue
}
_, err := client.GetSchedule(r.Primary.ID, pagerduty.GetScheduleOptions{})
if err == nil {
return fmt.Errorf("Schedule still exists")
}
}
return nil
}
func testAccCheckPagerDutyScheduleExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Schedule ID is set")
}
client := testAccProvider.Meta().(*pagerduty.Client)
found, err := client.GetSchedule(rs.Primary.ID, pagerduty.GetScheduleOptions{})
if err != nil {
return err
}
if found.ID != rs.Primary.ID {
return fmt.Errorf("Schedule not found: %v - %v", rs.Primary.ID, found)
}
return nil
}
}
const testAccCheckPagerDutyScheduleConfig = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
}
resource "pagerduty_schedule" "foo" {
name = "foo"
time_zone = "Europe/Berlin"
description = "foo"
layer {
name = "foo"
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 = 32101
}
}
}
`
const testAccCheckPagerDutyScheduleConfigUpdated = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
}
resource "pagerduty_schedule" "foo" {
name = "bar"
time_zone = "America/New_York"
layer {
name = "foo"
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 = 32101
}
}
}
`
const testAccCheckPagerDutyScheduleConfigMulti = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
}
resource "pagerduty_schedule" "foo" {
name = "foo"
time_zone = "America/New_York"
description = "foo"
layer {
name = "foo"
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 = 32101
}
}
layer {
name = "bar"
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 = 32101
}
}
layer {
name = "foobar"
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 = 32101
}
}
}
`

View File

@ -0,0 +1,168 @@
package pagerduty
import (
"log"
pagerduty "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": {
Type: schema.TypeString,
Optional: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
Default: "Managed by Terraform",
},
"auto_resolve_timeout": {
Type: schema.TypeInt,
Optional: true,
},
"last_incident_timestamp": {
Type: schema.TypeString,
Computed: true,
},
"created_at": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"acknowledgement_timeout": {
Type: schema.TypeInt,
Optional: true,
},
"escalation_policy": {
Type: schema.TypeString,
Required: true,
},
},
}
}
func buildServiceStruct(d *schema.ResourceData) *pagerduty.Service {
service := pagerduty.Service{
Name: d.Get("name").(string),
Status: d.Get("status").(string),
APIObject: pagerduty.APIObject{
ID: d.Id(),
},
}
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
}
escalationPolicy := &pagerduty.EscalationPolicy{
APIObject: pagerduty.APIObject{
ID: d.Get("escalation_policy").(string),
Type: "escalation_policy_reference",
},
}
service.EscalationPolicy = *escalationPolicy
return &service
}
func resourcePagerDutyServiceCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
service := buildServiceStruct(d)
log.Printf("[INFO] Creating PagerDuty service %s", service.Name)
service, err := client.CreateService(*service)
if err != nil {
return err
}
d.SetId(service.ID)
return nil
}
func resourcePagerDutyServiceRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
log.Printf("[INFO] Reading PagerDuty service %s", d.Id())
o := &pagerduty.GetServiceOptions{}
service, err := client.GetService(d.Id(), o)
if err != nil {
return err
}
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
}
func resourcePagerDutyServiceUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
service := buildServiceStruct(d)
log.Printf("[INFO] Updating PagerDuty service %s", d.Id())
if _, err := client.UpdateService(*service); 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())
if err := client.DeleteService(d.Id()); 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,161 @@
package pagerduty
import (
"log"
pagerduty "github.com/PagerDuty/go-pagerduty"
"github.com/hashicorp/terraform/helper/schema"
)
func resourcePagerDutyServiceIntegration() *schema.Resource {
return &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,
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Optional: true,
},
"service": {
Type: schema.TypeString,
Optional: true,
},
"type": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validateValueFunc([]string{
"aws_cloudwatch_inbound_integration",
"cloudkick_inbound_integration",
"event_transformer_api_inbound_integration",
"generic_email_inbound_integration",
"generic_events_api_inbound_integration",
"keynote_inbound_integration",
"nagios_inbound_integration",
"pingdom_inbound_integration",
"sql_monitor_inbound_integration",
}),
},
"vendor": {
Type: schema.TypeString,
ForceNew: true,
Optional: true,
},
"integration_key": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"integration_email": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
},
}
}
func buildServiceIntegrationStruct(d *schema.ResourceData) *pagerduty.Integration {
serviceIntegration := pagerduty.Integration{
Name: d.Get("name").(string),
Type: d.Get("type").(string),
Service: &pagerduty.APIObject{
Type: "service_reference",
ID: d.Get("service").(string),
},
APIObject: pagerduty.APIObject{
ID: d.Id(),
Type: "service_integration",
},
}
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)
serviceIntegration := buildServiceIntegrationStruct(d)
log.Printf("[INFO] Creating PagerDuty service integration %s", serviceIntegration.Name)
service := d.Get("service").(string)
serviceIntegration, err := client.CreateIntegration(service, *serviceIntegration)
if err != nil {
return err
}
d.SetId(serviceIntegration.ID)
return resourcePagerDutyServiceIntegrationRead(d, meta)
}
func resourcePagerDutyServiceIntegrationRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
log.Printf("[INFO] Reading PagerDuty service integration %s", d.Id())
service := d.Get("service").(string)
o := &pagerduty.GetIntegrationOptions{}
serviceIntegration, err := client.GetIntegration(service, d.Id(), *o)
if err != nil {
return err
}
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
}
func resourcePagerDutyServiceIntegrationUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
serviceIntegration := buildServiceIntegrationStruct(d)
service := d.Get("service").(string)
log.Printf("[INFO] Updating PagerDuty service integration %s", d.Id())
if _, err := client.UpdateIntegration(service, *serviceIntegration); err != nil {
return err
}
return nil
}
func resourcePagerDutyServiceIntegrationDelete(d *schema.ResourceData, meta interface{}) error {
log.Printf("[INFO] Removing PagerDuty service integration %s", d.Id())
d.SetId("")
return nil
}

View File

@ -0,0 +1,177 @@
package pagerduty
import (
"fmt"
"testing"
"github.com/PagerDuty/go-pagerduty"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccPagerDutyServiceIntegration_Basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyServiceIntegrationDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyServiceIntegrationConfig,
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyServiceIntegrationExists("pagerduty_service_integration.foo"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "name", "foo"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "type", "generic_events_api_inbound_integration"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "vendor", "PAM4FGS"),
),
},
resource.TestStep{
Config: testAccCheckPagerDutyServiceIntegrationConfigUpdated,
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyServiceIntegrationExists("pagerduty_service_integration.foo"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "name", "bar"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "type", "generic_events_api_inbound_integration"),
resource.TestCheckResourceAttr(
"pagerduty_service_integration.foo", "vendor", "PAM4FGS"),
),
},
},
})
}
func testAccCheckPagerDutyServiceIntegrationDestroy(s *terraform.State) error {
client := testAccProvider.Meta().(*pagerduty.Client)
for _, r := range s.RootModule().Resources {
if r.Type != "pagerduty_service_integration" {
continue
}
service, _ := s.RootModule().Resources["pagerduty_service.foo"]
_, err := client.GetIntegration(service.Primary.ID, r.Primary.ID, pagerduty.GetIntegrationOptions{})
if err == nil {
return fmt.Errorf("Service Integration still exists")
}
}
return nil
}
func testAccCheckPagerDutyServiceIntegrationExists(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Service Integration ID is set")
}
service, _ := s.RootModule().Resources["pagerduty_service.foo"]
client := testAccProvider.Meta().(*pagerduty.Client)
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)
}
if found.ID != rs.Primary.ID {
return fmt.Errorf("Service Integration not found: %v - %v", rs.Primary.ID, found)
}
return nil
}
}
const testAccCheckPagerDutyServiceIntegrationConfig = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
}
resource "pagerduty_escalation_policy" "foo" {
name = "foo"
description = "foo"
num_loops = 1
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
}
resource "pagerduty_service" "foo" {
name = "foo"
description = "foo"
auto_resolve_timeout = 1800
acknowledgement_timeout = 1800
escalation_policy = "${pagerduty_escalation_policy.foo.id}"
}
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}"
}
`
const testAccCheckPagerDutyServiceIntegrationConfigUpdated = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
color = "green"
role = "user"
job_title = "foo"
description = "foo"
}
resource "pagerduty_escalation_policy" "foo" {
name = "bar"
description = "bar"
num_loops = 2
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
}
resource "pagerduty_service" "foo" {
name = "bar"
description = "bar"
auto_resolve_timeout = 3600
acknowledgement_timeout = 3600
escalation_policy = "${pagerduty_escalation_policy.foo.id}"
}
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}"
}
`

View File

@ -0,0 +1,158 @@
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,
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.TestStep{
Config: testAccCheckPagerDutyServiceConfigUpdated,
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"),
),
},
},
})
}
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 {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No Service ID is set")
}
client := testAccProvider.Meta().(*pagerduty.Client)
found, err := client.GetService(rs.Primary.ID, &pagerduty.GetServiceOptions{})
if err != nil {
return err
}
if found.ID != rs.Primary.ID {
return fmt.Errorf("Service not found: %v - %v", rs.Primary.ID, found)
}
return nil
}
}
const testAccCheckPagerDutyServiceConfig = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
color = "green"
role = "user"
job_title = "foo"
description = "foo"
}
resource "pagerduty_escalation_policy" "foo" {
name = "bar"
description = "bar"
num_loops = 2
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
}
resource "pagerduty_service" "foo" {
name = "foo"
description = "foo"
auto_resolve_timeout = 1800
acknowledgement_timeout = 1800
escalation_policy = "${pagerduty_escalation_policy.foo.id}"
}
`
const testAccCheckPagerDutyServiceConfigUpdated = `
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
color = "green"
role = "user"
job_title = "foo"
description = "foo"
}
resource "pagerduty_escalation_policy" "foo" {
name = "bar"
description = "bar"
num_loops = 2
rule {
escalation_delay_in_minutes = 10
target {
type = "user_reference"
id = "${pagerduty_user.foo.id}"
}
}
}
resource "pagerduty_service" "foo" {
name = "bar"
description = "bar"
auto_resolve_timeout = 3600
acknowledgement_timeout = 3600
escalation_policy = "${pagerduty_escalation_policy.foo.id}"
}
`

View File

@ -0,0 +1,114 @@
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": {
Type: schema.TypeString,
Required: true,
},
"description": {
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)
team := buildTeamStruct(d)
log.Printf("[INFO] Creating PagerDuty team %s", team.Name)
team, err := client.CreateTeam(team)
if err != nil {
return err
}
d.SetId(team.ID)
return nil
}
func resourcePagerDutyTeamRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
log.Printf("[INFO] Reading PagerDuty team %s", d.Id())
team, err := client.GetTeam(d.Id())
if err != nil {
return err
}
d.Set("name", team.Name)
d.Set("description", team.Description)
return nil
}
func resourcePagerDutyTeamUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
team := buildTeamStruct(d)
log.Printf("[INFO] Updating PagerDuty team %s", d.Id())
if _, err := client.UpdateTeam(d.Id(), team); 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())
if err := client.DeleteTeam(d.Id()); 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,235 @@
package pagerduty
import (
"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": {
Type: schema.TypeString,
Required: true,
},
"email": {
Type: schema.TypeString,
Required: true,
},
"color": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},
"role": {
Type: schema.TypeString,
Optional: true,
Default: "user",
ValidateFunc: validateValueFunc([]string{
"admin",
"limited_user",
"owner",
"read_only_user",
"user",
}),
},
"job_title": {
Type: schema.TypeString,
Optional: true,
},
"avatar_url": {
Type: schema.TypeString,
Computed: true,
},
"teams": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Set: schema.HashString,
},
"time_zone": {
Type: schema.TypeString,
Computed: true,
},
"html_url": {
Type: schema.TypeString,
Computed: true,
},
"invitation_sent": {
Type: schema.TypeBool,
Computed: true,
},
"description": {
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),
APIObject: pagerduty.APIObject{
ID: d.Id(),
},
}
if attr, ok := d.GetOk("color"); ok {
user.Color = attr.(string)
}
if attr, ok := d.GetOk("role"); ok {
role := attr.(string)
// Skip setting the role if the user is the owner of the account.
// Can't change this through the API.
if role != "owner" {
user.Role = role
}
}
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)
user := buildUserStruct(d)
log.Printf("[INFO] Creating PagerDuty user %s", user.Name)
user, err := client.CreateUser(*user)
if err != nil {
return err
}
d.SetId(user.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())
o := &pagerduty.GetUserOptions{}
user, err := client.GetUser(d.Id(), *o)
if err != nil {
return err
}
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
}
func resourcePagerDutyUserUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
user := buildUserStruct(d)
log.Printf("[INFO] Updating PagerDuty user %s", d.Id())
if _, err := client.UpdateUser(*user); 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())
if err := client.DeleteUser(d.Id()); 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
}

View File

@ -0,0 +1,210 @@
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 TestAccPagerDutyUserWithTeams_Basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyUserDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccCheckPagerDutyUserWithTeamsConfig,
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", "teams.#", "1"),
),
},
resource.TestStep{
Config: testAccCheckPagerDutyUserWithTeamsConfigUpdated,
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", "teams.#", "2"),
),
},
resource.TestStep{
Config: testAccCheckPagerDutyUserWithNoTeamsConfig,
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", "teams.#", "0"),
),
},
},
})
}
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 {
rs, ok := s.RootModule().Resources[n]
if !ok {
return fmt.Errorf("Not found: %s", n)
}
if rs.Primary.ID == "" {
return fmt.Errorf("No user ID is set")
}
client := testAccProvider.Meta().(*pagerduty.Client)
found, err := client.GetUser(rs.Primary.ID, pagerduty.GetUserOptions{})
if err != nil {
return err
}
if found.ID != rs.Primary.ID {
return fmt.Errorf("User not found: %v - %v", rs.Primary.ID, found)
}
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"
}
`
const testAccCheckPagerDutyUserWithTeamsConfig = `
resource "pagerduty_team" "foo" {
name = "Foo team"
}
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
teams = ["${pagerduty_team.foo.id}"]
}
`
const testAccCheckPagerDutyUserWithTeamsConfigUpdated = `
resource "pagerduty_team" "foo" {
name = "Foo team"
}
resource "pagerduty_team" "bar" {
name = "Bar team"
}
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
teams = ["${pagerduty_team.foo.id}", "${pagerduty_team.bar.id}"]
}
`
const testAccCheckPagerDutyUserWithNoTeamsConfig = `
resource "pagerduty_team" "foo" {
name = "Foo team"
}
resource "pagerduty_team" "bar" {
name = "Bar team"
}
resource "pagerduty_user" "foo" {
name = "foo"
email = "foo@bar.com"
}
`

View File

@ -0,0 +1,179 @@
package pagerduty
import pagerduty "github.com/PagerDuty/go-pagerduty"
// Expands an array of escalation rules into []pagerduty.EscalationRules
func expandEscalationRules(list []interface{}) []pagerduty.EscalationRule {
result := make([]pagerduty.EscalationRule, 0, len(list))
for _, r := range list {
rule := r.(map[string]interface{})
escalationRule := &pagerduty.EscalationRule{
Delay: uint(rule["escalation_delay_in_minutes"].(int)),
}
for _, t := range rule["target"].([]interface{}) {
target := t.(map[string]interface{})
escalationRule.Targets = append(
escalationRule.Targets,
pagerduty.APIObject{
ID: target["id"].(string),
Type: target["type"].(string),
},
)
}
result = append(result, *escalationRule)
}
return result
}
// Flattens an array of []pagerduty.EscalationRule into a map[string]interface{}
func flattenEscalationRules(list []pagerduty.EscalationRule) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(list))
for _, i := range list {
r := make(map[string]interface{})
r["id"] = i.ID
r["escalation_delay_in_minutes"] = i.Delay
if len(i.Targets) > 0 {
targets := make([]map[string]interface{}, 0, len(i.Targets))
for _, t := range i.Targets {
targets = append(targets, map[string]interface{}{
"id": t.ID,
"type": t.Type,
})
}
r["target"] = targets
}
result = append(result, r)
}
return result
}
// Expands an array of schedules into []pagerduty.Schedule
func expandScheduleLayers(list []interface{}) []pagerduty.ScheduleLayer {
result := make([]pagerduty.ScheduleLayer, 0, len(list))
for _, l := range list {
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"] != "" {
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",
},
},
)
}
for _, r := range layer["restriction"].([]interface{}) {
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)),
},
)
}
result = append(result, *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 flattenScheduleLayers(list []pagerduty.ScheduleLayer) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(list))
for _, i := range list {
r := make(map[string]interface{})
r["id"] = i.ID
r["name"] = i.Name
r["end"] = i.End
r["start"] = i.Start
r["rotation_virtual_start"] = i.RotationVirtualStart
r["rotation_turn_length_seconds"] = i.RotationTurnLengthSeconds
if len(i.Users) > 0 {
users := make([]string, 0, len(i.Users))
for _, u := range i.Users {
users = append(users, u.User.ID)
}
r["users"] = users
}
if len(i.Restrictions) > 0 {
restrictions := make([]map[string]interface{}, 0, len(i.Restrictions))
for _, r := range i.Restrictions {
restrictions = append(restrictions, map[string]interface{}{
"duration_seconds": r.DurationSeconds,
"start_time_of_day": r.StartTimeOfDay,
"type": r.Type,
})
}
r["restriction"] = restrictions
}
result = append(result, r)
}
// Reverse the final result and return it
resultReversed := make([]map[string]interface{}, 0, len(result))
for i := len(result) - 1; i >= 0; i-- {
resultReversed = append(resultReversed, result[i])
}
return resultReversed
}
// 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
}

View File

@ -0,0 +1,68 @@
package pagerduty
import (
"fmt"
pagerduty "github.com/PagerDuty/go-pagerduty"
"github.com/hashicorp/terraform/helper/schema"
)
// Validate a value against a set of possible values
func validateValueFunc(values []string) schema.SchemaValidateFunc {
return func(v interface{}, k string) (we []string, errors []error) {
value := v.(string)
valid := false
for _, val := range values {
if value == val {
valid = true
break
}
}
if !valid {
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
}

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,

4
vendor/github.com/PagerDuty/go-pagerduty/Dockerfile generated vendored Normal file
View File

@ -0,0 +1,4 @@
FROM golang
ADD . /go/src/github.com/PagerDuty/go-pagerduty
WORKDIR /go/src/github.com/PagerDuty/go-pagerduty
RUN go get ./... && go test -v -race -cover ./...

14
vendor/github.com/PagerDuty/go-pagerduty/LICENSE.txt generated vendored Normal file
View File

@ -0,0 +1,14 @@
Copyright:: Copyright (c) 2016 PagerDuty, Inc.
License:: Apache License, Version 2.0
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

19
vendor/github.com/PagerDuty/go-pagerduty/Makefile generated vendored Normal file
View File

@ -0,0 +1,19 @@
SOURCEDIR=.
SOURCES = $(shell find $(SOURCEDIR) -name '*.go')
VERSION=$(git describe --always --tags)
BINARY=bin/pd
bin: $(BINARY)
$(BINARY): $(SOURCES)
go build -o $(BINARY) command/*
.PHONY: build
build:
go get ./...
go test ./...
go vet ./...
.PHONY: test
test:
go test ./...

73
vendor/github.com/PagerDuty/go-pagerduty/README.md generated vendored Normal file
View File

@ -0,0 +1,73 @@
# go-pagerduty
go-pagerduty is a CLI and [go](https://golang.org/) client library for [PagerDuty v2 API](https://v2.developer.pagerduty.com/v2/page/api-reference).
[godoc](http://godoc.org/github.com/PagerDuty/go-pagerduty)
## Installation
```
go get github.com/PagerDuty/go-pagerduty
```
## Usage
### CLI
The CLI requires authentication token, which can be sepcified in `.pd.yml`
file in home directory of the user, or passed as command line argument.
Example of config file:
```yaml
---
authtoken: fooBar
```
`pd` command provides a single entrypoint for all the API endpoints, with individual
API represented by their own sub commands. For an exhaustive list of sub-commands, try:
```
pd --help
```
An example of the `service` sub-command
```
pd service list
```
### From golang libraries
```go
package main
import (
"fmt"
"github.com/PagerDuty/go-pagerduty"
)
var authtoken = "" // Set your auth token here
func main() {
var opts pagerduty.ListEscalationPoliciesOptions
client := pagerduty.NewClient(authtoken)
if eps, err := client.ListEscalationPolicies(opts); err != nil {
panic(err)
} else {
for _, p := range eps.EscalationPolicies {
fmt.Println(p.Name)
}
}
}
```
## License
[Apache 2](http://www.apache.org/licenses/LICENSE-2.0)
## Contributing
1. Fork it ( https://github.com/PagerDuty/go-pagerduty/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request

22
vendor/github.com/PagerDuty/go-pagerduty/ability.go generated vendored Normal file
View File

@ -0,0 +1,22 @@
package pagerduty
// ListAbilityResponse is the response when calling the ListAbility API endpoint.
type ListAbilityResponse struct {
Abilities []string `json:"abilities"`
}
// ListAbilities lists all abilities on your account.
func (c *Client) ListAbilities() (*ListAbilityResponse, error) {
resp, err := c.get("/abilities")
if err != nil {
return nil, err
}
var result ListAbilityResponse
return &result, c.decodeJSON(resp, &result)
}
// TestAbility Check if your account has the given ability.
func (c *Client) TestAbility(ability string) error {
_, err := c.get("/abilities/" + ability)
return err
}

96
vendor/github.com/PagerDuty/go-pagerduty/addon.go generated vendored Normal file
View File

@ -0,0 +1,96 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
"net/http"
)
// Addon is a third-party add-on to PagerDuty's UI.
type Addon struct {
APIObject
Name string `json:"name,omitempty"`
Src string `json:"src,omitempty"`
Services []APIObject `json:"services,omitempty"`
}
// ListAddonOptions are the options available when calling the ListAddons API endpoint.
type ListAddonOptions struct {
APIListObject
Includes []string `url:"include,omitempty,brackets"`
ServiceIDs []string `url:"service_ids,omitempty,brackets"`
Filter string `url:"filter,omitempty"`
}
// ListAddonResponse is the response when calling the ListAddons API endpoint.
type ListAddonResponse struct {
APIListObject
Addons []Addon `json:"addons"`
}
// ListAddons lists all of the add-ons installed on your account.
func (c *Client) ListAddons(o ListAddonOptions) (*ListAddonResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/addons?" + v.Encode())
if err != nil {
return nil, err
}
var result ListAddonResponse
return &result, c.decodeJSON(resp, &result)
}
// InstallAddon installs an add-on for your account.
func (c *Client) InstallAddon(a Addon) (*Addon, error) {
data := make(map[string]Addon)
data["addon"] = a
resp, err := c.post("/addons", data)
defer resp.Body.Close()
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusCreated {
return nil, fmt.Errorf("Failed to create. HTTP Status code: %d", resp.StatusCode)
}
return getAddonFromResponse(c, resp)
}
// DeleteAddon deletes an add-on from your account.
func (c *Client) DeleteAddon(id string) error {
_, err := c.delete("/addons/" + id)
return err
}
// GetAddon gets details about an existing add-on.
func (c *Client) GetAddon(id string) (*Addon, error) {
resp, err := c.get("/addons/" + id)
if err != nil {
return nil, err
}
return getAddonFromResponse(c, resp)
}
// UpdateAddon updates an existing add-on.
func (c *Client) UpdateAddon(id string, a Addon) (*Addon, error) {
v := make(map[string]Addon)
v["addon"] = a
resp, err := c.put("/addons/"+id, v, nil)
if err != nil {
return nil, err
}
return getAddonFromResponse(c, resp)
}
func getAddonFromResponse(c *Client, resp *http.Response) (*Addon, error) {
var result map[string]Addon
if err := c.decodeJSON(resp, &result); err != nil {
return nil, err
}
a, ok := result["addon"]
if !ok {
return nil, fmt.Errorf("JSON response does not have 'addon' field")
}
return &a, nil
}

132
vendor/github.com/PagerDuty/go-pagerduty/client.go generated vendored Normal file
View File

@ -0,0 +1,132 @@
package pagerduty
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
const (
apiEndpoint = "https://api.pagerduty.com"
)
// APIObject represents generic api json response that is shared by most
// domain object (like escalation
type APIObject struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Summary string `json:"summary,omitempty"`
Self string `json:"self,omitempty"`
HTMLURL string `json:"html_url,omitempty"`
}
// APIListObject are the fields used to control pagination when listing objects.
type APIListObject struct {
Limit uint `url:"limit,omitempty"`
Offset uint `url:"offset,omitempty"`
More bool `url:"more,omitempty"`
Total uint `url:"total,omitempty"`
}
// APIReference are the fields required to reference another API object.
type APIReference struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
}
type errorObject struct {
Code int `json:"code,omitempty"`
Mesage string `json:"message,omitempty"`
Errors []string `json:"errors,omitempty"`
}
// Client wraps http client
type Client struct {
authToken string
}
// NewClient creates an API client
func NewClient(authToken string) *Client {
return &Client{
authToken: authToken,
}
}
func (c *Client) delete(path string) (*http.Response, error) {
return c.do("DELETE", path, nil, nil)
}
func (c *Client) put(path string, payload interface{}, headers *map[string]string) (*http.Response, error) {
if payload != nil {
data, err := json.Marshal(payload)
if err != nil {
return nil, err
}
return c.do("PUT", path, bytes.NewBuffer(data), headers)
}
return c.do("PUT", path, nil, headers)
}
func (c *Client) post(path string, payload interface{}) (*http.Response, error) {
data, err := json.Marshal(payload)
if err != nil {
return nil, err
}
return c.do("POST", path, bytes.NewBuffer(data), nil)
}
func (c *Client) get(path string) (*http.Response, error) {
return c.do("GET", path, nil, nil)
}
func (c *Client) do(method, path string, body io.Reader, headers *map[string]string) (*http.Response, error) {
endpoint := apiEndpoint + path
req, _ := http.NewRequest(method, endpoint, body)
req.Header.Set("Accept", "application/vnd.pagerduty+json;version=2")
if headers != nil {
for k, v := range *headers {
req.Header.Set(k, v)
}
}
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Token token="+c.authToken)
resp, err := http.DefaultClient.Do(req)
return c.checkResponse(resp, err)
}
func (c *Client) decodeJSON(resp *http.Response, payload interface{}) error {
defer resp.Body.Close()
decoder := json.NewDecoder(resp.Body)
return decoder.Decode(payload)
}
func (c *Client) checkResponse(resp *http.Response, err error) (*http.Response, error) {
if err != nil {
return resp, fmt.Errorf("Error calling the API endpoint: %v", err)
}
if 199 >= resp.StatusCode || 300 <= resp.StatusCode {
var eo *errorObject
var getErr error
if eo, getErr = c.getErrorFromResponse(resp); getErr != nil {
return resp, fmt.Errorf("Response did not contain formatted error: %s. HTTP response code: %v. Raw response: %+v", getErr, resp.StatusCode, resp)
}
return resp, fmt.Errorf("Failed call API endpoint. HTTP response code: %v. Error: %v", resp.StatusCode, eo)
}
return resp, nil
}
func (c *Client) getErrorFromResponse(resp *http.Response) (*errorObject, error) {
var result map[string]errorObject
if err := c.decodeJSON(resp, &result); err != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", err)
}
s, ok := result["error"]
if !ok {
return nil, fmt.Errorf("JSON response does not have error field")
}
return &s, nil
}

View File

@ -0,0 +1,114 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
"net/http"
)
const (
escPath = "/escalation_policies"
)
// EscalationRule is a rule for an escalation policy to trigger.
type EscalationRule struct {
ID string `json:"id,omitempty"`
Delay uint `json:"escalation_delay_in_minutes,omitempty"`
Targets []APIObject `json:"targets"`
}
// EscalationPolicy is a collection of escalation rules.
type EscalationPolicy struct {
APIObject
Name string `json:"name,omitempty"`
EscalationRules []EscalationRule `json:"escalation_rules,omitempty"`
Services []APIReference `json:"services,omitempty"`
NumLoops uint `json:"num_loops,omitempty"`
Teams []APIReference `json:"teams,omitempty"`
Description string `json:"description,omitempty"`
RepeatEnabled bool `json:"repeat_enabled,omitempty"`
}
// ListEscalationPoliciesResponse is the data structure returned from calling the ListEscalationPolicies API endpoint.
type ListEscalationPoliciesResponse struct {
APIListObject
EscalationPolicies []EscalationPolicy `json:"escalation_policies"`
}
// ListEscalationPoliciesOptions is the data structure used when calling the ListEscalationPolicies API endpoint.
type ListEscalationPoliciesOptions struct {
APIListObject
Query string `url:"query,omitempty"`
UserIDs []string `url:"user_ids,omitempty,brackets"`
TeamIDs []string `url:"team_ids,omitempty,brackets"`
Includes []string `url:"include,omitempty,brackets"`
SortBy string `url:"sort_by,omitempty"`
}
// ListEscalationPolicies lists all of the existing escalation policies.
func (c *Client) ListEscalationPolicies(o ListEscalationPoliciesOptions) (*ListEscalationPoliciesResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get(escPath + "?" + v.Encode())
if err != nil {
return nil, err
}
var result ListEscalationPoliciesResponse
return &result, c.decodeJSON(resp, &result)
}
// CreateEscalationPolicy creates a new escalation policy.
func (c *Client) CreateEscalationPolicy(e EscalationPolicy) (*EscalationPolicy, error) {
data := make(map[string]EscalationPolicy)
data["escalation_policy"] = e
resp, err := c.post(escPath, data)
return getEscalationPolicyFromResponse(c, resp, err)
}
// DeleteEscalationPolicy deletes an existing escalation policy and rules.
func (c *Client) DeleteEscalationPolicy(id string) error {
_, err := c.delete(escPath + "/" + id)
return err
}
// GetEscalationPolicyOptions is the data structure used when calling the GetEscalationPolicy API endpoint.
type GetEscalationPolicyOptions struct {
Includes []string `url:"include,omitempty,brackets"`
}
// GetEscalationPolicy gets information about an existing escalation policy and its rules.
func (c *Client) GetEscalationPolicy(id string, o *GetEscalationPolicyOptions) (*EscalationPolicy, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get(escPath + "/" + id + "?" + v.Encode())
return getEscalationPolicyFromResponse(c, resp, err)
}
// UpdateEscalationPolicy updates an existing escalation policy and its rules.
func (c *Client) UpdateEscalationPolicy(id string, e *EscalationPolicy) (*EscalationPolicy, error) {
data := make(map[string]EscalationPolicy)
data["escalation_policy"] = *e
resp, err := c.put(escPath+"/"+id, data, nil)
return getEscalationPolicyFromResponse(c, resp, err)
}
func getEscalationPolicyFromResponse(c *Client, resp *http.Response, err error) (*EscalationPolicy, error) {
defer resp.Body.Close()
if err != nil {
return nil, err
}
var target map[string]EscalationPolicy
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "escalation_policy"
t, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &t, nil
}

52
vendor/github.com/PagerDuty/go-pagerduty/event.go generated vendored Normal file
View File

@ -0,0 +1,52 @@
package pagerduty
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
)
const eventEndPoint = "https://events.pagerduty.com/generic/2010-04-15/create_event.json"
// Event stores data for problem reporting, acknowledgement, and resolution.
type Event struct {
ServiceKey string `json:"service_key"`
Type string `json:"event_type"`
IncidentKey string `json:"incident_key,omitempty"`
Description string `json:"description"`
Client string `json:"client,omitempty"`
ClientURL string `json:"client_url,omitempty"`
Details interface{} `json:"details,omitempty"`
Contexts []interface{} `json:"contexts,omitempty"`
}
// EventResponse is the data returned from the CreateEvent API endpoint.
type EventResponse struct {
Status string `json:"status"`
Message string `json:"message"`
IncidentKey string `json:"incident_key"`
}
// CreateEvent sends PagerDuty an event to report, acknowledge, or resolve a problem.
func CreateEvent(e Event) (*EventResponse, error) {
data, err := json.Marshal(e)
if err != nil {
return nil, err
}
req, _ := http.NewRequest("POST", eventEndPoint, bytes.NewBuffer(data))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("HTTP Status Code: %d", resp.StatusCode)
}
var eventResponse EventResponse
defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(&eventResponse); err != nil {
return nil, err
}
return &eventResponse, nil
}

147
vendor/github.com/PagerDuty/go-pagerduty/incident.go generated vendored Normal file
View File

@ -0,0 +1,147 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
)
// Acknowledgement is the data structure of an acknoledgement of an incident.
type Acknowledgement struct {
At string
Acknowledger APIObject
}
// PendingAction is the data structure for any pending actions on an incident.
type PendingAction struct {
Type string
At string
}
// Assignment is the data structure for an assignment of an incident
type Assignment struct {
At string
Assignee APIObject
}
// Incident is a normalized, de-duplicated event generated by a PagerDuty integration.
type Incident struct {
APIObject
IncidentNumber uint `json:"incident_number,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
PendingActions []PendingAction `json:"pending_actions,omitempty"`
IncidentKey string `json:"incident_key,omitempty"`
Service APIObject `json:"service,omitempty"`
Assignments []Assignment `json:"assignments,omitempty"`
Acknowledgements []Acknowledgement `json:"acknowledgements,omitempty"`
LastStatusChangeAt string `json:"last_status_change_at,omitempty"`
LastStatusChangeBy APIObject `json:"last_status_change_by,omitempty"`
FirstTriggerLogEntry APIObject `json:"last_trigger_log_entry,omitempty"`
EscalationPolicy APIObject `json:"escalation_policy,omitempty"`
Teams []APIObject `json:"teams,omitempty"`
Urgency string `json:"urgency,omitempty"`
}
// ListIncidentsResponse is the response structure when calling the ListIncident API endpoint.
type ListIncidentsResponse struct {
APIListObject
Incidents []Incident `json:"incidents,omitempty"`
}
// ListIncidentsOptions is the structure used when passing parameters to the ListIncident API endpoint.
type ListIncidentsOptions struct {
APIListObject
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
DateRange string `url:"date_range,omitempty"`
Statuses []string `url:"statuses,omitempty,brackets"`
IncidentKey string `url:"incident_key,omitempty"`
ServiceIDs []string `url:"service_ids,omitempty,brackets"`
TeamIDs []string `url:"team_ids,omitempty,brackets"`
UserIDs []string `url:"user_ids,omitempty,brackets"`
Urgencies []string `url:"urgencies,omitempty,brackets"`
TimeZone string `url:"time_zone,omitempty"`
SortBy string `url:"sort_by,omitempty"`
Includes []string `url:"include,omitempty,brackets"`
}
// ListIncidents lists existing incidents.
func (c *Client) ListIncidents(o ListIncidentsOptions) (*ListIncidentsResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/incidents?" + v.Encode())
if err != nil {
return nil, err
}
var result ListIncidentsResponse
return &result, c.decodeJSON(resp, &result)
}
// ManageIncidents acknowledges, resolves, escalates, or reassigns one or more incidents.
func (c *Client) ManageIncidents(from string, incidents []Incident) error {
r := make(map[string][]Incident)
headers := make(map[string]string)
headers["From"] = from
r["incidents"] = incidents
_, e := c.put("/incidents", r, &headers)
return e
}
// GetIncident shows detailed information about an incident.
func (c *Client) GetIncident(id string) (*Incident, error) {
resp, err := c.get("/incidents/" + id)
if err != nil {
return nil, err
}
var result map[string]Incident
if err := c.decodeJSON(resp, &result); err != nil {
return nil, err
}
i, ok := result["incident"]
if !ok {
return nil, fmt.Errorf("JSON response does not have incident field")
}
return &i, nil
}
// IncidentNote is a note for the specified incident.
type IncidentNote struct {
ID string `json:"id,omitempty"`
User APIObject `json:"user,omitempty"`
Content string `json:"content,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
}
// ListIncidentNotes lists existing notes for the specified incident.
func (c *Client) ListIncidentNotes(id string) ([]IncidentNote, error) {
resp, err := c.get("/incidents/" + id + "/notes")
if err != nil {
return nil, err
}
var result map[string][]IncidentNote
if err := c.decodeJSON(resp, &result); err != nil {
return nil, err
}
notes, ok := result["notes"]
if !ok {
return nil, fmt.Errorf("JSON response does not have notes field")
}
return notes, nil
}
// CreateIncidentNote creates a new note for the specified incident.
func (c *Client) CreateIncidentNote(id string, note IncidentNote) error {
data := make(map[string]IncidentNote)
data["note"] = note
_, err := c.post("/incidents/"+id+"/notes", data)
return err
}
// SnoozeIncident sets an incident to not alert for a specified period of time.
func (c *Client) SnoozeIncident(id string, duration uint) error {
data := make(map[string]uint)
data["duration"] = duration
_, err := c.post("/incidents/"+id+"/snooze", data)
return err
}

83
vendor/github.com/PagerDuty/go-pagerduty/log_entry.go generated vendored Normal file
View File

@ -0,0 +1,83 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
)
// Agent is the actor who carried out the action.
type Agent APIObject
// Channel is the means by which the action was carried out.
type Channel struct {
Type string
}
// LogEntry is a list of all of the events that happened to an incident.
type LogEntry struct {
APIObject
CreatedAt string `json:"created_at"`
Agent Agent
Channel Channel
Incident Incident
Teams []Team
Contexts []string
EventDetails map[string]string
}
// ListLogEntryResponse is the response data when calling the ListLogEntry API endpoint.
type ListLogEntryResponse struct {
APIListObject
LogEntries []LogEntry `json:"log_entries"`
}
// ListLogEntriesOptions is the data structure used when calling the ListLogEntry API endpoint.
type ListLogEntriesOptions struct {
APIListObject
TimeZone string `url:"time_zone"`
Since string `url:"omitempty"`
Until string `url:"omitempty"`
IsOverview bool `url:"is_overview,omitempty"`
Includes []string `url:"include,omitempty,brackets"`
}
// ListLogEntries lists all of the incident log entries across the entire account.
func (c *Client) ListLogEntries(o ListLogEntriesOptions) (*ListLogEntryResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/log_entries?" + v.Encode())
if err != nil {
return nil, err
}
var result ListLogEntryResponse
return &result, c.decodeJSON(resp, &result)
}
// GetLogEntryOptions is the data structure used when calling the GetLogEntry API endpoint.
type GetLogEntryOptions struct {
TimeZone string `url:"timezone,omitempty"`
Includes []string `url:"include,omitempty,brackets"`
}
// GetLogEntry list log entries for the specified incident.
func (c *Client) GetLogEntry(id string, o GetLogEntryOptions) (*LogEntry, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/log_entries/" + id + "?" + v.Encode())
if err != nil {
return nil, err
}
var result map[string]LogEntry
if err := c.decodeJSON(resp, &result); err != nil {
return nil, err
}
le, ok := result["log_entry"]
if !ok {
return nil, fmt.Errorf("JSON response does not have log_entry field")
}
return &le, nil
}

View File

@ -0,0 +1,100 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
"net/http"
)
// MaintenanceWindow is used to temporarily disable one or more services for a set period of time.
type MaintenanceWindow struct {
APIObject
SequenceNumber uint `json:"sequence_number,omitempty"`
StartTime string `json:"start_time"`
EndTime string `json:"end_time"`
Description string
Services []APIObject
Teams []APIListObject
CreatedBy APIListObject `json:"created_by"`
}
// ListMaintenanceWindowsResponse is the data structur returned from calling the ListMaintenanceWindows API endpoint.
type ListMaintenanceWindowsResponse struct {
APIListObject
MaintenanceWindows []MaintenanceWindow `json:"maintenance_windows"`
}
// ListMaintenanceWindowsOptions is the data structure used when calling the ListMaintenanceWindows API endpoint.
type ListMaintenanceWindowsOptions struct {
APIListObject
Query string `url:"query,omitempty"`
Includes []string `url:"include,omitempty,brackets"`
TeamIDs []string `url:"team_ids,omitempty,brackets"`
ServiceIDs []string `url:"service_ids,omitempty,brackets"`
Filter string `url:"filter,omitempty,brackets"`
}
// ListMaintenanceWindows lists existing maintenance windows, optionally filtered by service and/or team, or whether they are from the past, present or future.
func (c *Client) ListMaintenanceWindows(o ListMaintenanceWindowsOptions) (*ListMaintenanceWindowsResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/maintenance_windows?" + v.Encode())
if err != nil {
return nil, err
}
var result ListMaintenanceWindowsResponse
return &result, c.decodeJSON(resp, &result)
}
// CreateMaintaienanceWindows creates a new maintenance window for the specified services.
func (c *Client) CreateMaintaienanceWindows(m MaintenanceWindow) (*MaintenanceWindow, error) {
data := make(map[string]MaintenanceWindow)
data["maintenance_window"] = m
resp, err := c.post("/mainteance_windows", data)
return getMaintenanceWindowFromResponse(c, resp, err)
}
// DeleteMaintenanceWindow deletes an existing maintenance window if it's in the future, or ends it if it's currently on-going.
func (c *Client) DeleteMaintenanceWindow(id string) error {
_, err := c.delete("/mainteance_windows/" + id)
return err
}
// GetMaintenanceWindowOptions is the data structure used when calling the GetMaintenanceWindow API endpoint.
type GetMaintenanceWindowOptions struct {
Includes []string `url:"include,omitempty,brackets"`
}
// GetMaintenanceWindow gets an existing maintenance window.
func (c *Client) GetMaintenanceWindow(id string, o GetMaintenanceWindowOptions) (*MaintenanceWindow, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/mainteance_windows/" + id + "?" + v.Encode())
return getMaintenanceWindowFromResponse(c, resp, err)
}
// UpdateMaintenanceWindow updates an existing maintenance window.
func (c *Client) UpdateMaintenanceWindow(m MaintenanceWindow) (*MaintenanceWindow, error) {
resp, err := c.put("/maintenance_windows/"+m.ID, m, nil)
return getMaintenanceWindowFromResponse(c, resp, err)
}
func getMaintenanceWindowFromResponse(c *Client, resp *http.Response, err error) (*MaintenanceWindow, error) {
if err != nil {
return nil, err
}
var target map[string]MaintenanceWindow
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "maintenance_window"
t, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &t, nil
}

View File

@ -0,0 +1,44 @@
package pagerduty
import (
"github.com/google/go-querystring/query"
)
// Notification is a message containing the details of the incident.
type Notification struct {
ID string `json:"id"`
Type string
StartedAt string `json:"started_at"`
Address string
User APIObject
}
// ListNotificationOptions is the data structure used when calling the ListNotifications API endpoint.
type ListNotificationOptions struct {
APIListObject
TimeZone string `url:"time_zone,omitempty"`
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
Filter string `url:"filter,omitempty"`
Includes []string `url:"include,omitempty"`
}
// ListNotificationsResponse is the data structure returned from the ListNotifications API endpoint.
type ListNotificationsResponse struct {
APIListObject
Notifications []Notification
}
// ListNotifications lists notifications for a given time range, optionally filtered by type (sms_notification, email_notification, phone_notification, or push_notification).
func (c *Client) ListNotifications(o ListNotificationOptions) (*ListNotificationsResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/notifications?" + v.Encode())
if err != nil {
return nil, err
}
var result ListNotificationsResponse
return &result, c.decodeJSON(resp, &result)
}

47
vendor/github.com/PagerDuty/go-pagerduty/on_call.go generated vendored Normal file
View File

@ -0,0 +1,47 @@
package pagerduty
import (
"github.com/google/go-querystring/query"
)
// OnCall represents a contiguous unit of time for which a user will be on call for a given escalation policy and escalation rule.
type OnCall struct {
User APIObject `json:"user,omitempty"`
Schedule APIObject `json:"schedule,omitempty"`
EscalationPolicy APIObject `json:"escalation_policy,omitempty"`
EscalationLevel uint `json:"escalation_level,omitempty"`
Start string `json:"start,omitempty"`
End string `json:"end,omitempty"`
}
// ListOnCallsResponse is the data structure returned from calling the ListOnCalls API endpoint.
type ListOnCallsResponse struct {
OnCalls []OnCall `json:"oncalls"`
}
// ListOnCallOptions is the data structure used when calling the ListOnCalls API endpoint.
type ListOnCallOptions struct {
APIListObject
TimeZone string `url:"time_zone,omitempty"`
Includes []string `url:"include,omitempty,brackets"`
UserIDs []string `url:"user_ids,omitempty,brackets"`
EscalationPolicyIDs []string `url:"escalation_policy_ids,omitempty,brackets"`
ScheduleIDs []string `url:"schedule_ids,omitempty,brackets"`
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
Earliest bool `url:"earliest,omitempty"`
}
// ListOnCalls list the on-call entries during a given time range.
func (c *Client) ListOnCalls(o ListOnCallOptions) (*ListOnCallsResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/oncalls?" + v.Encode())
if err != nil {
return nil, err
}
var result ListOnCallsResponse
return &result, c.decodeJSON(resp, &result)
}

262
vendor/github.com/PagerDuty/go-pagerduty/schedule.go generated vendored Normal file
View File

@ -0,0 +1,262 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
"net/http"
)
// Restriction limits on-call responsibility for a layer to certain times of the day or week.
type Restriction struct {
Type string `json:"type,omitempty"`
StartTimeOfDay string `json:"start_time_of_day,omitempty"`
DurationSeconds uint `json:"duration_seconds,omitempty"`
}
// RenderedScheduleEntry represents the computed set of schedule layer entries that put users on call for a schedule, and cannot be modified directly.
type RenderedScheduleEntry struct {
Start string `json:"start,omitempty"`
End string `json:"end,omitempty"`
User APIObject `json:"user,omitempty"`
}
// ScheduleLayer is an entry that puts users on call for a schedule.
type ScheduleLayer struct {
APIObject
Name string `json:"name,omitempty"`
Start string `json:"start,omitempty"`
End string `json:"end,omitempty"`
RotationVirtualStart string `json:"rotation_virtual_start,omitempty"`
RotationTurnLengthSeconds uint `json:"rotation_turn_length_seconds,omitempty"`
Users []UserReference `json:"users,omitempty"`
Restrictions []Restriction `json:"restrictions,omitempty"`
RenderedScheduleEntries []RenderedScheduleEntry `json:"rendered_schedule_entries,omitempty"`
RenderedCoveragePercentage float64 `json:"rendered_coverage_percentage,omitempty"`
}
// Schedule determines the time periods that users are on call.
type Schedule struct {
APIObject
Name string `json:"name,omitempty"`
TimeZone string `json:"time_zone,omitempty"`
Description string `json:"description,omitempty"`
EscalationPolicies []APIObject `json:"escalation_policies,omitempty"`
Users []APIObject `json:"users,omitempty"`
ScheduleLayers []ScheduleLayer `json:"schedule_layers,omitempty"`
OverrideSubschedule ScheduleLayer `json:"override_subschedule,omitempty"`
FinalSchedule ScheduleLayer `json:"final_schedule,omitempty"`
}
// ListSchedulesOptions is the data structure used when calling the ListSchedules API endpoint.
type ListSchedulesOptions struct {
APIListObject
Query string `url:"query,omitempty"`
}
// ListSchedulesResponse is the data structure returned from calling the ListSchedules API endpoint.
type ListSchedulesResponse struct {
APIListObject
Schedules []Schedule
}
// UserReference is a reference to an authorized PagerDuty user.
type UserReference struct {
User APIObject `json:"user"`
}
// ListSchedules lists the on-call schedules.
func (c *Client) ListSchedules(o ListSchedulesOptions) (*ListSchedulesResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/schedules?" + v.Encode())
if err != nil {
return nil, err
}
var result ListSchedulesResponse
return &result, c.decodeJSON(resp, &result)
}
// CreateSchedule creates a new on-call schedule.
func (c *Client) CreateSchedule(s Schedule) (*Schedule, error) {
data := make(map[string]Schedule)
data["schedule"] = s
resp, err := c.post("/schedules", data)
if err != nil {
return nil, err
}
return getScheduleFromResponse(c, resp)
}
// PreviewScheduleOptions is the data structure used when calling the PreviewSchedule API endpoint.
type PreviewScheduleOptions struct {
APIListObject
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
Overflow bool `url:"overflow,omitempty"`
}
// PreviewSchedule previews what an on-call schedule would look like without saving it.
func (c *Client) PreviewSchedule(s Schedule, o PreviewScheduleOptions) error {
v, err := query.Values(o)
if err != nil {
return err
}
var data map[string]Schedule
data["schedule"] = s
_, e := c.post("/schedules/preview?"+v.Encode(), data)
return e
}
// DeleteSchedule deletes an on-call schedule.
func (c *Client) DeleteSchedule(id string) error {
_, err := c.delete("/schedules/" + id)
return err
}
// GetScheduleOptions is the data structure used when calling the GetSchedule API endpoint.
type GetScheduleOptions struct {
APIListObject
TimeZone string `url:"time_zone,omitempty"`
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
}
// GetSchedule shows detailed information about a schedule, including entries for each layer and sub-schedule.
func (c *Client) GetSchedule(id string, o GetScheduleOptions) (*Schedule, error) {
v, err := query.Values(o)
if err != nil {
return nil, fmt.Errorf("Could not parse values for query: %v", err)
}
resp, err := c.get("/schedules/" + id + "?" + v.Encode())
if err != nil {
return nil, err
}
return getScheduleFromResponse(c, resp)
}
// UpdateScheduleOptions is the data structure used when calling the UpdateSchedule API endpoint.
type UpdateScheduleOptions struct {
Overflow bool `url:"overflow,omitempty"`
}
// UpdateSchedule updates an existing on-call schedule.
func (c *Client) UpdateSchedule(id string, s Schedule) (*Schedule, error) {
v := make(map[string]Schedule)
v["schedule"] = s
resp, err := c.put("/schedules/"+id, v, nil)
if err != nil {
return nil, err
}
return getScheduleFromResponse(c, resp)
}
// ListOverridesOptions is the data structure used when calling the ListOverrides API endpoint.
type ListOverridesOptions struct {
APIListObject
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
Editable bool `url:"editable,omitempty"`
Overflow bool `url:"overflow,omitempty"`
}
// Overrides are any schedule layers from the override layer.
type Override struct {
ID string `json:"id,omitempty"`
Start string `json:"start,omitempty"`
End string `json:"end,omitempty"`
User APIObject `json:"user,omitempty"`
}
// ListOverrides lists overrides for a given time range.
func (c *Client) ListOverrides(id string, o ListOverridesOptions) ([]Override, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/schedules/" + id + "/overrides?" + v.Encode())
if err != nil {
return nil, err
}
var result map[string][]Override
if err := c.decodeJSON(resp, &result); err != nil {
return nil, err
}
overrides, ok := result["overrides"]
if !ok {
return nil, fmt.Errorf("JSON response does not have overrides field")
}
return overrides, nil
}
// CreateOverride creates an override for a specific user covering the specified time range.
func (c *Client) CreateOverride(id string, o Override) (*Override, error) {
data := make(map[string]Override)
data["override"] = o
resp, err := c.post("/schedules/"+id+"/overrides", data)
if err != nil {
return nil, err
}
return getOverrideFromResponse(c, resp)
}
// DeleteOverride removes an override.
func (c *Client) DeleteOverride(scheduleID, overrideID string) error {
_, err := c.delete("/schedules/" + scheduleID + "/overrides/" + overrideID)
return err
}
// ListOnCallUsersOptions is the data structure used when calling the ListOnCallUsers API endpoint.
type ListOnCallUsersOptions struct {
APIListObject
Since string `url:"since,omitempty"`
Until string `url:"until,omitempty"`
}
// ListOnCallUsers lists all of the users on call in a given schedule for a given time range.
func (c *Client) ListOnCallUsers(id string, o ListOnCallUsersOptions) ([]User, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/schedules/" + id + "/users?" + v.Encode())
if err != nil {
return nil, err
}
var result map[string][]User
if err := c.decodeJSON(resp, &result); err != nil {
return nil, err
}
u, ok := result["users"]
if !ok {
return nil, fmt.Errorf("JSON response does not have users field")
}
return u, nil
}
func getScheduleFromResponse(c *Client, resp *http.Response) (*Schedule, error) {
var target map[string]Schedule
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "schedule"
t, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &t, nil
}
func getOverrideFromResponse(c *Client, resp *http.Response) (*Override, error) {
var target map[string]Override
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "override"
o, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &o, nil
}

202
vendor/github.com/PagerDuty/go-pagerduty/service.go generated vendored Normal file
View File

@ -0,0 +1,202 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
"net/http"
)
// Integration is an endpoint (like Nagios, email, or an API call) that generates events, which are normalized and de-duplicated by PagerDuty to create incidents.
type Integration struct {
APIObject
Name string `json:"name,omitempty"`
Service *APIObject `json:"service,omitempty"`
CreatedAt string `json:"created_at,omitempty"`
Vendor *APIObject `json:"vendor,omitempty"`
Type string `json:"type,omitempty"`
IntegrationKey string `json:"integration_key,omitempty"`
IntegrationEmail string `json:"integration_email,omitempty"`
}
// InlineModel represents when a scheduled action will occur.
type InlineModel struct {
Type string `json:"type,omitempty"`
Name string `json:"name,omitempty"`
}
// ScheduledAction contains scheduled actions for the service.
type ScheduledAction struct {
Type string `json:"type,omitempty"`
At InlineModel `json:"at,omitempty"`
ToUrgency string `json:"to_urgency"`
}
// IncidentUrgencyType are the incidents urgency during or outside support hours.
type IncidentUrgencyType struct {
Type string `json:"type,omitempty"`
Urgency string `json:"urgency,omitempty"`
}
// SupportHours are the support hours for the service.
type SupportHours struct {
Type string `json:"type,omitempty"`
Timezone string `json:"time_zone,omitempty"`
StartTime string `json:"start_time,omitempty"`
EndTime string `json:"end_time,omitempty"`
DaysOfWeek []uint `json:"days_of_week,omitempty"`
}
// IncidentUrgencyRule is the default urgency for new incidents.
type IncidentUrgencyRule struct {
Type string `json:"type,omitempty"`
Urgency string `json:"urgency,omitempty"`
DuringSupportHours *IncidentUrgencyType `json:"during_support_hours,omitempty"`
OutsideSupportHours *IncidentUrgencyType `json:"outside_support_hours,omitempty"`
}
// Service represents something you monitor (like a web service, email service, or database service).
type Service struct {
APIObject
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
AutoResolveTimeout *uint `json:"auto_resolve_timeout,omitempty"`
AcknowledgementTimeout *uint `json:"acknowledgement_timeout,omitempty"`
CreateAt string `json:"created_at,omitempty"`
Status string `json:"status,omitempty"`
LastIncidentTimestamp string `json:"last_incident_timestamp,omitempty"`
Integrations []Integration `json:"integrations,omitempty"`
EscalationPolicy EscalationPolicy `json:"escalation_policy,omitempty"`
Teams []Team `json:"teams,omitempty"`
IncidentUrgencyRule *IncidentUrgencyRule `json:"incident_urgency_rule,omitempty"`
SupportHours *SupportHours `json:"support_hours,omitempty"`
ScheduledActions []ScheduledAction `json:"scheduled_actions,omitempty"`
}
// ListServiceOptions is the data structure used when calling the ListServices API endpoint.
type ListServiceOptions struct {
APIListObject
TeamIDs []string `url:"team_ids,omitempty,brackets"`
TimeZone string `url:"time_zone,omitempty"`
SortBy string `url:"sort_by,omitempty"`
Query string `url:"query,omitempty"`
Includes []string `url:"include,omitempty,brackets"`
}
// ListServiceResponse is the data structure returned from calling the ListServices API endpoint.
type ListServiceResponse struct {
APIListObject
Services []Service
}
// ListServices lists existing services.
func (c *Client) ListServices(o ListServiceOptions) (*ListServiceResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/services?" + v.Encode())
if err != nil {
return nil, err
}
var result ListServiceResponse
return &result, c.decodeJSON(resp, &result)
}
// GetServiceOptions is the data structure used when calling the GetService API endpoint.
type GetServiceOptions struct {
Includes []string `url:"include,brackets,omitempty"`
}
// GetService gets details about an existing service.
func (c *Client) GetService(id string, o *GetServiceOptions) (*Service, error) {
v, err := query.Values(o)
resp, err := c.get("/services/" + id + "?" + v.Encode())
return getServiceFromResponse(c, resp, err)
}
// CreateService creates a new service.
func (c *Client) CreateService(s Service) (*Service, error) {
data := make(map[string]Service)
data["service"] = s
resp, err := c.post("/services", data)
return getServiceFromResponse(c, resp, err)
}
// UpdateService updates an existing service.
func (c *Client) UpdateService(s Service) (*Service, error) {
resp, err := c.put("/services/"+s.ID, s, nil)
return getServiceFromResponse(c, resp, err)
}
// DeleteService deletes an existing service.
func (c *Client) DeleteService(id string) error {
_, err := c.delete("/services/" + id)
return err
}
// CreateIntegration creates a new integration belonging to a service.
func (c *Client) CreateIntegration(id string, i Integration) (*Integration, error) {
data := make(map[string]Integration)
data["integration"] = i
resp, err := c.post("/services/"+id+"/integrations", data)
return getIntegrationFromResponse(c, resp, err)
}
// GetIntegrationOptions is the data structure used when calling the GetIntegration API endpoint.
type GetIntegrationOptions struct {
Includes []string `url:"include,omitempty,brackets"`
}
// GetIntegration gets details about an integration belonging to a service.
func (c *Client) GetIntegration(serviceID, integrationID string, o GetIntegrationOptions) (*Integration, error) {
v, queryErr := query.Values(o)
if queryErr != nil {
return nil, queryErr
}
resp, err := c.get("/services/" + serviceID + "/integrations/" + integrationID + "?" + v.Encode())
return getIntegrationFromResponse(c, resp, err)
}
// UpdateIntegration updates an integration belonging to a service.
func (c *Client) UpdateIntegration(serviceID string, i Integration) (*Integration, error) {
resp, err := c.put("/services/"+serviceID+"/integrations/"+i.ID, i, nil)
return getIntegrationFromResponse(c, resp, err)
}
// DeleteIntegration deletes an existing integration.
func (c *Client) DeleteIntegration(serviceID string, integrationID string) error {
_, err := c.delete("/services/" + serviceID + "/integrations" + integrationID)
return err
}
func getServiceFromResponse(c *Client, resp *http.Response, err error) (*Service, error) {
if err != nil {
return nil, err
}
var target map[string]Service
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "service"
t, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &t, nil
}
func getIntegrationFromResponse(c *Client, resp *http.Response, err error) (*Integration, error) {
if err != nil {
return nil, err
}
var target map[string]Integration
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", err)
}
rootNode := "integration"
t, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &t, nil
}

105
vendor/github.com/PagerDuty/go-pagerduty/team.go generated vendored Normal file
View File

@ -0,0 +1,105 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
"net/http"
)
// Team is a collection of users and escalation policies that represent a group of people within an organization.
type Team struct {
APIObject
Name string `json:"name,omitempty"`
Description string `json:"description,omitempty"`
}
// ListTeamResponse is the structure used when calling the ListTeams API endpoint.
type ListTeamResponse struct {
APIListObject
Teams []Team
}
// ListTeamOptions are the input parameters used when calling the ListTeams API endpoint.
type ListTeamOptions struct {
APIListObject
Query string `url:"query,omitempty"`
}
// ListTeams lists teams of your PagerDuty account, optionally filtered by a search query.
func (c *Client) ListTeams(o ListTeamOptions) (*ListTeamResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/teams?" + v.Encode())
if err != nil {
return nil, err
}
var result ListTeamResponse
return &result, c.decodeJSON(resp, &result)
}
// CreateTeam creates a new team.
func (c *Client) CreateTeam(t *Team) (*Team, error) {
resp, err := c.post("/teams", t)
return getTeamFromResponse(c, resp, err)
}
// DeleteTeam removes an existing team.
func (c *Client) DeleteTeam(id string) error {
_, err := c.delete("/teams/" + id)
return err
}
// GetTeam gets details about an existing team.
func (c *Client) GetTeam(id string) (*Team, error) {
resp, err := c.get("/teams/" + id)
return getTeamFromResponse(c, resp, err)
}
// UpdateTeam updates an existing team.
func (c *Client) UpdateTeam(id string, t *Team) (*Team, error) {
resp, err := c.put("/teams/"+id, t, nil)
return getTeamFromResponse(c, resp, err)
}
// RemoveEscalationPolicyFromTeam removes an escalation policy from a team.
func (c *Client) RemoveEscalationPolicyFromTeam(teamID, epID string) error {
_, err := c.delete("/teams/" + teamID + "/escalation_policies/" + epID)
return err
}
// AddEscalationPolicyToTeam adds an escalation policy to a team.
func (c *Client) AddEscalationPolicyToTeam(teamID, epID string) error {
_, err := c.put("/teams/"+teamID+"/escalation_policies/"+epID, nil, nil)
return err
}
// RemoveUserFromTeam removes a user from a team.
func (c *Client) RemoveUserFromTeam(teamID, userID string) error {
_, err := c.delete("/teams/" + teamID + "/users/" + userID)
return err
}
// AddUserToTeam adds a user to a team.
func (c *Client) AddUserToTeam(teamID, userID string) error {
_, err := c.put("/teams/"+teamID+"/users/"+userID, nil, nil)
return err
}
func getTeamFromResponse(c *Client, resp *http.Response, err error) (*Team, error) {
if err != nil {
return nil, err
}
var target map[string]Team
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "team"
t, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &t, nil
}

124
vendor/github.com/PagerDuty/go-pagerduty/user.go generated vendored Normal file
View File

@ -0,0 +1,124 @@
package pagerduty
import (
"fmt"
"github.com/google/go-querystring/query"
"net/http"
)
// ContactMethod is a way of contacting the user.
type ContactMethod struct {
ID string
Label string
Address string
Type string
SendShortEmail bool `json:"send_short_email"`
}
// NotificationRule is a rule for notifying the user.
type NotificationRule struct {
ID string
StartDelayInMinutes uint `json:"start_delay_in_minutes"`
CreatedAt string `json:"created_at"`
ContactMethod ContactMethod `json:"contact_method"`
Urgency string
Type string
}
// User is a member of a PagerDuty account that has the ability to interact with incidents and other data on the account.
type User struct {
APIObject
Name string `json:"name"`
Email string `json:"email"`
Timezone string `json:"timezone,omitempty"`
Color string `json:"color,omitempty"`
Role string `json:"role,omitempty"`
AvatarURL string `json:"avatar_url,omitempty"`
Description string `json:"description,omitempty"`
InvitationSent bool
ContactMethods []ContactMethod `json:"contact_methods"`
NotificationRules []NotificationRule `json:"notification_rules"`
JobTitle string `json:"job_title,omitempty"`
Teams []Team
}
// ListUsersResponse is the data structure returned from calling the ListUsers API endpoint.
type ListUsersResponse struct {
APIListObject
Users []User
}
// ListUsersOptions is the data structure used when calling the ListUsers API endpoint.
type ListUsersOptions struct {
APIListObject
Query string `url:"query,omitempty"`
TeamIDs []string `url:"team_ids,omitempty,brackets"`
Includes []string `url:"include,omitempty,brackets"`
}
// GetUserOptions is the data structure used when calling the GetUser API endpoint.
type GetUserOptions struct {
Includes []string `url:"include,omitempty,brackets"`
}
// ListUsers lists users of your PagerDuty account, optionally filtered by a search query.
func (c *Client) ListUsers(o ListUsersOptions) (*ListUsersResponse, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/users?" + v.Encode())
if err != nil {
return nil, err
}
var result ListUsersResponse
return &result, c.decodeJSON(resp, &result)
}
// CreateUser creates a new user.
func (c *Client) CreateUser(u User) (*User, error) {
data := make(map[string]User)
data["user"] = u
resp, err := c.post("/users", data)
return getUserFromResponse(c, resp, err)
}
// DeleteUser deletes a user.
func (c *Client) DeleteUser(id string) error {
_, err := c.delete("/users/" + id)
return err
}
// GetUser gets details about an existing user.
func (c *Client) GetUser(id string, o GetUserOptions) (*User, error) {
v, err := query.Values(o)
if err != nil {
return nil, err
}
resp, err := c.get("/users/" + id + "?" + v.Encode())
return getUserFromResponse(c, resp, err)
}
// UpdateUser updates an existing user.
func (c *Client) UpdateUser(u User) (*User, error) {
v := make(map[string]User)
v["user"] = u
resp, err := c.put("/users/"+u.ID, v, nil)
return getUserFromResponse(c, resp, err)
}
func getUserFromResponse(c *Client, resp *http.Response, err error) (*User, error) {
if err != nil {
return nil, err
}
var target map[string]User
if dErr := c.decodeJSON(resp, &target); dErr != nil {
return nil, fmt.Errorf("Could not decode JSON response: %v", dErr)
}
rootNode := "user"
t, nodeOK := target[rootNode]
if !nodeOK {
return nil, fmt.Errorf("JSON response does not have %s field", rootNode)
}
return &t, nil
}

73
vendor/github.com/PagerDuty/go-pagerduty/vendor.go generated vendored Normal file
View File

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

37
vendor/github.com/PagerDuty/go-pagerduty/webhook.go generated vendored Normal file
View File

@ -0,0 +1,37 @@
package pagerduty
import (
"encoding/json"
"io"
)
// IncidentDetail contains a representation of the incident associated with the action that caused this webhook message.
type IncidentDetail struct {
ID string `json:"id"`
IncidentNumber uint `json:"incident_number"`
CreatedOn string `json:"created_on"`
Status string `json:"status"`
HTMLUrl string `json:"html_url"`
Service string `json:"service"`
AssignedToUser *json.RawMessage `json:"assigned_to_user"`
AssignedTo []string `json:"assigned_to"`
TriggerSummaryData *json.RawMessage `json:"trigger_summary_data"`
TriggerDeatilsHTMLUrl string `json:"trigger_details_html_url"`
}
// WebhookPayload is a single message array for a webhook.
type WebhookPayload struct {
ID string `json:"id"`
Type string `json:"type"`
CreatedOn string `json:"created_on"`
Data *json.RawMessage `json:"data"`
}
// DecodeWebhook decodes a webhook from a response object.
func DecodeWebhook(r io.Reader) (*WebhookPayload, error) {
var payload WebhookPayload
if err := json.NewDecoder(r).Decode(&payload); err != nil {
return nil, err
}
return &payload, nil
}

6
vendor/vendor.json vendored
View File

@ -295,6 +295,12 @@
"path": "github.com/Ensighten/udnssdk",
"revision": "0290933f5e8afd933f2823fce32bf2847e6ea603"
},
{
"checksumSHA1": "O9o5S7D0E1PaN5ARQ72xLfOrIa0=",
"path": "github.com/PagerDuty/go-pagerduty",
"revision": "f4d5289481b2c05f2b23f81a64dff86aca960962",
"revisionTime": "2016-10-22T00:40:41Z"
},
{
"path": "github.com/Unknwon/com",
"revision": "28b053d5a2923b87ce8c5a08f3af779894a72758"

View File

@ -37,6 +37,7 @@ body.layout-mailgun,
body.layout-mysql,
body.layout-openstack,
body.layout-packet,
body.layout-pagerduty,
body.layout-postgresql,
body.layout-powerdns,
body.layout-rabbitmq,

View File

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

View File

@ -0,0 +1,41 @@
---
layout: "pagerduty"
page_title: "Provider: PagerDuty"
sidebar_current: "docs-pagerduty-index"
description: |-
PagerDuty is an alarm aggregation and dispatching service
---
# PagerDuty Provider
[PagerDuty](https://www.pagerduty.com/) is an alarm aggregation and dispatching service for system administrators and support teams. It collects alerts from your monitoring tools, gives you an overall view of all of your monitoring alarms, and alerts an on duty engineer if theres a problem.
Use the navigation to the left to read about the available resources.
## Example Usage
```
# Configure the PagerDuty provider
provider "pagerduty" {
token = "${var.pagerduty_token}"
}
# Create a PagerDuty team
resource "pagerduty_team" "engineering" {
name = "Engineering"
description = "All engineering"
}
# Create a PagerDuty user
resource "pagerduty_user" "earline" {
name = "Earline Greenholt"
email = "125.greenholt.earline@graham.name"
teams = ["${pagerduty_team.engineering.id}"]
}
```
## Argument Reference
The following arguments are supported:
* `token` - (Required) The v2 authorization token. See [API Documentation](https://v2.developer.pagerduty.com/docs/authentication) for more information.

View File

@ -0,0 +1,79 @@
---
layout: "pagerduty"
page_title: "PagerDuty: pagerduty_escalation_policy"
sidebar_current: "docs-pagerduty-resource-escalation_policy"
description: |-
Creates and manages an escalation policy in PagerDuty.
---
# pagerduty\_escalation_policy
An [escalation policy](https://v2.developer.pagerduty.com/v2/page/api-reference#!/Escalation_Policies/get_escalation_policies) determines what user or schedule will be notified first, second, and so on when an incident is triggered. Escalation policies are used by one or more services.
## 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" "example" {
name = "Engineering Escalation Policy"
num_loops = 2
teams = ["${pagerduty_team.example.id}"]
rule {
escalation_delay_in_minutes = 10
target {
type = "user"
id = "${pagerduty_user.example.id}"
}
}
}
```
## Argument Reference
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.
* `rule` - (Required) An Escalation rule block. Escalation rules documented below.
Escalation rules (`rule`) supports the following:
* `escalation_delay_in_minutes` - (Required) The number of minutes before an unacknowledged incident escalates away from this rule.
* `targets` - (Required) A target block. Target blocks documented below.
Targets (`target`) supports the following:
* `type` - (Optional) Can be `user`, `schedule`, `user_reference` or `schedule_reference`. Defaults to `user_reference`
* `id` - (Required) A target ID
## Attributes Reference
The following attributes are exported:
* `id` - The ID of the escalation policy.
## Import
Escalation policies can be imported using the `id`, e.g.
```
$ terraform import pagerduty_escalation_policy.main PLBP09X
```

View File

@ -0,0 +1,82 @@
---
layout: "pagerduty"
page_title: "PagerDuty: pagerduty_schedule"
sidebar_current: "docs-pagerduty-resource-schedule"
description: |-
Creates and manages a schedule in PagerDuty.
---
# pagerduty\_schedule
A [schedule](https://v2.developer.pagerduty.com/v2/page/api-reference#!/Schedules/get_schedules) determines the time periods that users are on call. Only on-call users are eligible to receive notifications from incidents.
## Example Usage
```
resource "pagerduty_user" "example" {
name = "Earline Greenholt"
email = "125.greenholt.earline@graham.name"
teams = ["${pagerduty_team.example.id}"]
}
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
}
}
}
```
## Argument Reference
The following arguments are supported:
* `name` - (Optional) The name of the escalation policy.
* `time_zone` - (Required) The time zone of the schedule (e.g Europe/Berlin).
* `description` - (Optional) The description of the schedule
* `layer` - (Required) A schedule layer block. Schedule layers documented below.
Schedule layers (`layer`) supports the following:
* `name` - (Optional) The name of the schedule layer.
* `start` - (Required) The start time of the schedule layer.
* `end` - (Optional) The end time of the schedule layer. If not specified, the layer does not end.
* `rotation_virtual_start` - (Required) The effective start time of the schedule layer. This can be before the start time of the schedule.
* `rotation_turn_length_seconds` - (Required) The duration of each on-call shift in `seconds`.
* `users` - (Required) The ordered list of users on this layer. The position of the user on the list determines their order in the layer.
* `restriction` - (Optional) A schedule layer restriction block. Restriction blocks documented below.
Restriction blocks (`restriction`) supports the following:
* `type` - (Required) Can be `daily_restriction` or `weekly_restriction`
* `start_time_of_day` - (Required) The duration of the restriction in `seconds`.
* `duration_seconds` - (Required) The start time in `HH:mm:ss` format.
## Attributes Reference
The following attributes are exported:
* `id` - The ID of the schedule
## Import
Schedules can be imported using the `id`, e.g.
```
$ terraform import pagerduty_schedule.main PLBP09X
```

View File

@ -0,0 +1,68 @@
---
layout: "pagerduty"
page_title: "PagerDuty: pagerduty_service"
sidebar_current: "docs-pagerduty-resource-service"
description: |-
Creates and manages a service in PagerDuty.
---
# pagerduty\_service
A [service](https://v2.developer.pagerduty.com/v2/page/api-reference#!/Services/get_services) represents something you monitor (like a web service, email service, or database service). It is a container for related incidents that associates them with escalation policies.
## Example Usage
```
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}"
}
```
## Argument Reference
The following arguments are supported:
* `name` - (Required) The name of the service.
* `description` - (Optional) A human-friendly description of the escalation policy.
If not set, a placeholder of "Managed by Terraform" will be set.
* `auto_resolve_timeout` - (Optional) Time in seconds that an incident is automatically resolved if left open for that long. Value is "null" is the feature is disabled.
* `acknowledgement_timeout` - (Optional) Time in seconds that an incident changes to the Triggered State after being Acknowledged. Value is "null" is the feature is disabled.
* `escalation_policy` - (Required) The escalation policy used by this service.
## Attributes Reference
The following attributes are exported:
* `id` - The ID of the service.
## Import
Services can be imported using the `id`, e.g.
```
$ terraform import pagerduty_service.main PLBP09X
```

View File

@ -0,0 +1,100 @@
---
layout: "pagerduty"
page_title: "PagerDuty: pagerduty_service_integration"
sidebar_current: "docs-pagerduty-resource-service-integration"
description: |-
Creates and manages a service integration in PagerDuty.
---
# pagerduty\_service_integration
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
```
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 = "Generic API Service Integration"
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
The following arguments are supported:
* `name` - (Optional) The name of the service integration.
* `type` - (Optional) The service type. Can be `aws_cloudwatch_inbound_integration`, `cloudkick_inbound_integration`,
`event_transformer_api_inbound_integration`,
`generic_email_inbound_integration`,
`generic_events_api_inbound_integration`,
`keynote_inbound_integration`,
`nagios_inbound_integration`,
`pingdom_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
The following attributes are exported:
* `id` - The ID of the service integration.
* `integration_key` - This is the unique key used to route events to this integration when received via the PagerDuty Events API.
* `integration_email` - This is the unique fully-qualified email address used for routing emails to this integration for processing.

View File

@ -0,0 +1,44 @@
---
layout: "pagerduty"
page_title: "PagerDuty: pagerduty_team"
sidebar_current: "docs-pagerduty-resource-team"
description: |-
Creates and manages a team in PagerDuty.
---
# pagerduty\_team
A [team](https://v2.developer.pagerduty.com/v2/page/api-reference#!/Teams/get_teams) is a collection of users and escalation policies that represent a group of people within an organization.
The account must have the `teams` ability to use the following resource.
## Example Usage
```
resource "pagerduty_team" "example" {
name = "Engineering"
description = "All engineering"
}
```
## Argument Reference
The following arguments are supported:
* `name` - (Required) The name of the group.
* `description` - (Optional) A human-friendly description of the team.
If not set, a placeholder of "Managed by Terraform" will be set.
## Attributes Reference
The following attributes are exported:
* `id` - The ID of the team.
## Import
Teams can be imported using the `id`, e.g.
```
$ terraform import pagerduty_team.main PLBP09X
```

View File

@ -0,0 +1,57 @@
---
layout: "pagerduty"
page_title: "PagerDuty: pagerduty_user"
sidebar_current: "docs-pagerduty-resource-user"
description: |-
Creates and manages a user in PagerDuty.
---
# pagerduty\_user
A [user](https://v2.developer.pagerduty.com/v2/page/api-reference#!/Users/get_users) is a member of a PagerDuty account that have the ability to interact with incidents and other data on the account.
## 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}"]
}
```
## Argument Reference
The following arguments are supported:
* `name` - (Required) The name of the user.
* `email` - (Required) The user's email address.
* `color` - (Optional) The schedule color for the user.
* `role` - (Optional) The user role. Account must have the `read_only_users` ability to set a user as a `read_only_user`. Can be `admin`, `limited_user`, `owner`, `read_only_user` or `user`
* `job_title` - (Optional) The user's title.
* `teams` - (Optional) A list of teams the user should belong to.
* `description` - (Optional) A human-friendly description of the user.
If not set, a placeholder of "Managed by Terraform" will be set.
## Attributes Reference
The following attributes are exported:
* `id` - The ID of the user.
* `avatar_url` - The URL of the user's avatar.
* `html_url` - URL at which the entity is uniquely displayed in the Web app
* `invitation_sent` - If true, the user has an outstanding invitation.
## Import
Users can be imported using the `id`, e.g.
```
$ terraform import pagerduty_user.main PLBP09X
```

View File

@ -282,6 +282,10 @@
<a href="/docs/providers/packet/index.html">Packet</a>
</li>
<li<%= sidebar_current("docs-providers-pagerduty") %>>
<a href="/docs/providers/pagerduty/index.html">PagerDuty</a>
</li>
<li<%= sidebar_current("docs-providers-postgresql") %>>
<a href="/docs/providers/postgresql/index.html">PostgreSQL</a>
</li>

View File

@ -0,0 +1,50 @@
<% wrap_layout :inner do %>
<% content_for :sidebar do %>
<div class="docs-sidebar hidden-print affix-top" role="complementary">
<ul class="nav docs-sidenav">
<li<%= sidebar_current("docs-home") %>>
<a href="/docs/providers/index.html">&laquo; Documentation Home</a>
</li>
<li<%= sidebar_current("docs-pagerduty-index") %>>
<a href="/docs/providers/pagerduty/index.html">PagerDuty Provider</a>
</li>
<li<%= sidebar_current(/^docs-pagerduty-datasource/) %>>
<a href="#">Data Sources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-pagerduty-datasource-vendor") %>>
<a href="/docs/providers/pagerduty/d/vendor.html">pagerduty_vendor</a>
</li>
</ul>
</li>
<li<%= sidebar_current(/^docs-pagerduty-resource/) %>>
<a href="#">Resources</a>
<ul class="nav nav-visible">
<li<%= sidebar_current("docs-pagerduty-resource-user") %>>
<a href="/docs/providers/pagerduty/r/user.html">pagerduty_user</a>
</li>
<li<%= sidebar_current("docs-pagerduty-resource-team") %>>
<a href="/docs/providers/pagerduty/r/team.html">pagerduty_team</a>
</li>
<li<%= sidebar_current("docs-pagerduty-resource-escalation_policy") %>>
<a href="/docs/providers/pagerduty/r/escalation_policy.html">pagerduty_escalation_policy</a>
</li>
<li<%= sidebar_current("docs-pagerduty-resource-schedule") %>>
<a href="/docs/providers/pagerduty/r/schedule.html">pagerduty_schedule</a>
</li>
<li<%= sidebar_current("docs-pagerduty-resource-service") %>>
<a href="/docs/providers/pagerduty/r/service.html">pagerduty_service</a>
</li>
<li<%= sidebar_current("docs-pagerduty-resource-service-integration") %>>
<a href="/docs/providers/pagerduty/r/service_integration.html">pagerduty_service_integration</a>
</li>
</ul>
</li>
</ul>
</div>
<% end %>
<%= yield %>
<% end %>