commit
765dc19286
|
@ -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,
|
||||
})
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
`
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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,
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
|
@ -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()
|
||||
}
|
|
@ -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")
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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}"
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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}"
|
||||
}
|
||||
`
|
|
@ -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}"
|
||||
}
|
||||
`
|
|
@ -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
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
`
|
|
@ -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
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
`
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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 ./...
|
|
@ -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.
|
|
@ -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 ./...
|
|
@ -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
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
|
@ -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 there’s 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.
|
|
@ -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
|
||||
```
|
|
@ -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
|
||||
```
|
|
@ -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
|
||||
```
|
|
@ -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.
|
|
@ -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
|
||||
```
|
|
@ -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
|
||||
```
|
|
@ -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>
|
||||
|
|
|
@ -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">« 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 %>
|
Loading…
Reference in New Issue