Add data source for on call users

This commit is contained in:
Alexander Hellbom 2016-10-18 23:43:25 +02:00
parent 9ab1093633
commit 97e48f659f
6 changed files with 341 additions and 3 deletions

View File

@ -0,0 +1,172 @@
package pagerduty
import (
"encoding/json"
"log"
"strconv"
pagerduty "github.com/PagerDuty/go-pagerduty"
"github.com/hashicorp/terraform/helper/hashcode"
"github.com/hashicorp/terraform/helper/schema"
)
func dataSourcePagerDutyOnCall() *schema.Resource {
return &schema.Resource{
Read: dataSourcePagerDutyOnCallRead,
Schema: map[string]*schema.Schema{
"time_zone": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"include": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"user_ids": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"escalation_policy_ids": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"schedule_ids": &schema.Schema{
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"since": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"until": &schema.Schema{
Type: schema.TypeString,
Optional: true,
},
"earliest": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"oncalls": &schema.Schema{
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"escalation_level": &schema.Schema{
Type: schema.TypeInt,
Computed: true,
},
"start": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"end": &schema.Schema{
Type: schema.TypeString,
Computed: true,
},
"user": &schema.Schema{
Type: schema.TypeMap,
Computed: true,
},
"schedule": &schema.Schema{
Type: schema.TypeMap,
Computed: true,
},
"escalation_policy": &schema.Schema{
Type: schema.TypeMap,
Computed: true,
},
},
},
},
},
}
}
func dataSourcePagerDutyOnCallRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)
o := &pagerduty.ListOnCallOptions{}
if attr, ok := d.GetOk("time_zone"); ok {
o.TimeZone = attr.(string)
}
if attr, ok := d.GetOk("include"); ok {
includes := make([]string, 0, len(attr.([]interface{})))
for _, include := range attr.([]interface{}) {
includes = append(includes, include.(string))
}
o.Includes = includes
}
if attr, ok := d.GetOk("user_ids"); ok {
userIDs := make([]string, 0, len(attr.([]interface{})))
for _, user := range attr.([]interface{}) {
userIDs = append(userIDs, user.(string))
}
o.UserIDs = userIDs
}
if attr, ok := d.GetOk("escalation_policy_ids"); ok {
escalationPolicyIDs := make([]string, 0, len(attr.([]interface{})))
for _, escalationPolicy := range attr.([]interface{}) {
escalationPolicyIDs = append(escalationPolicyIDs, escalationPolicy.(string))
}
o.EscalationPolicyIDs = escalationPolicyIDs
}
if attr, ok := d.GetOk("since"); ok {
o.Since = attr.(string)
}
if attr, ok := d.GetOk("until"); ok {
o.Until = attr.(string)
}
if attr, ok := d.GetOk("earliest"); ok {
o.Earliest = attr.(bool)
}
log.Printf("[INFO] Reading On Calls with options: %v", *o)
resp, err := client.ListOnCalls(*o)
if err != nil {
return err
}
data := flattenOnCalls(resp.OnCalls)
id, err := json.Marshal(data)
if err != nil {
return err
}
d.SetId(strconv.Itoa(hashcode.String(string(id))))
if err := d.Set("oncalls", data); err != nil {
return err
}
return nil
}

View File

@ -0,0 +1,58 @@
package pagerduty
import (
"fmt"
"strconv"
"testing"
"github.com/hashicorp/terraform/helper/resource"
"github.com/hashicorp/terraform/terraform"
)
func TestAccPagerDutyOnCall_Basic(t *testing.T) {
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyScheduleDestroy,
Steps: []resource.TestStep{
resource.TestStep{
Config: testAccPagerDutyOnCallsConfig,
Check: resource.ComposeTestCheckFunc(
testAccPagerDutyOnCalls("data.pagerduty_on_call.foo"),
),
},
},
})
}
func testAccPagerDutyOnCalls(n string) resource.TestCheckFunc {
return func(s *terraform.State) error {
r := s.RootModule().Resources[n]
a := r.Primary.Attributes
var size int
var err error
if size, err = strconv.Atoi(a["oncalls.#"]); err != nil {
return err
}
if size == 0 {
return fmt.Errorf("Expected at least one on call in the list. Found: %d", size)
}
for i := range make([]string, size) {
escalationLevel := a[fmt.Sprintf("oncalls.%d.escalation_level", i)]
if escalationLevel == "" {
return fmt.Errorf("Expected the on call to have an escalation_level set")
}
}
return nil
}
}
const testAccPagerDutyOnCallsConfig = `
data "pagerduty_on_call" "foo" {}
`

View File

@ -18,6 +18,10 @@ func Provider() terraform.ResourceProvider {
},
},
DataSourcesMap: map[string]*schema.Resource{
"pagerduty_on_call": dataSourcePagerDutyOnCall(),
},
ResourcesMap: map[string]*schema.Resource{
"pagerduty_user": resourcePagerDutyUser(),
"pagerduty_team": resourcePagerDutyTeam(),

View File

@ -152,6 +152,42 @@ func flattenLayers(list []pagerduty.ScheduleLayer) []map[string]interface{} {
return resultReversed
}
// Flattens an array of []pagerduty.User into a map[string]interface{}
func flattenOnCalls(list []pagerduty.OnCall) []map[string]interface{} {
result := make([]map[string]interface{}, 0, len(list))
for _, i := range list {
r := make(map[string]interface{})
r["escalation_level"] = i.EscalationLevel
r["start"] = i.Start
r["end"] = i.End
user := make(map[string]interface{}, 1)
user["id"] = i.User.ID
user["type"] = i.User.Type
user["name"] = i.User.Summary
user["summary"] = i.User.Summary
schedule := make(map[string]interface{}, 1)
schedule["id"] = i.Schedule.ID
schedule["type"] = i.Schedule.Type
schedule["summary"] = i.Schedule.Summary
policy := make(map[string]interface{}, 1)
policy["id"] = i.EscalationPolicy.ID
policy["type"] = i.EscalationPolicy.Type
policy["summary"] = i.EscalationPolicy.Summary
r["user"] = user
r["schedule"] = schedule
r["escalation_policy"] = policy
result = append(result, r)
}
return result
}
// Takes the result of flatmap.Expand for an array of strings
// and returns a []string
func expandStringList(configured []interface{}) []string {

View File

@ -0,0 +1,59 @@
---
layout: "pagerduty"
page_title: "PagerDuty: pagerduty_on_call"
sidebar_current: "docs-pagerduty-datasource-on_call"
description: |-
Get information about who's on call.
---
# pagerduty\_on_call
Use this data source to get all of the users [on call][1] in a given schedule.
## Example Usage
```
resource "pagerduty_schedule" "foo" {
name = "Daily Engineering Rotation"
time_zone = "America/New_York"
schedule_layer {
name = "Night Shift"
start = "2015-11-06T20:00:00-05:00"
rotation_virtual_start = "2015-11-06T20:00:00-05:00"
rotation_turn_length_seconds = 86400
users = ["${pagerduty_user.foo.id}"]
restriction {
type = "daily_restriction"
start_time_of_day = "08:00:00"
duration_seconds = 32400
}
}
}
data "pagerduty_on_call" "on_call" {}
resource "pagerduty_team" "on_call" {
name = "On call"
description = "Primarily used by ${data.pagerduty_on_call.oncalls.0.id}"
}
```
## Argument Reference
The following arguments are supported:
* `time_zone` - (Optional) Time zone in which dates in the result will be rendered.
* `include` - (Optional) List of of additional details to include. Can be `escalation_policies`, `users`, `schedules`.
* `user_ids` - (Optional) Filters the results, showing only on-calls for the specified user IDs.
* `escalation_policy_ids` - (Optional) Filters the results, showing only on-calls for the specified escalation policy IDs.
* `user_ids` - (Optional) Filters the results, showing only on-calls for the specified schedule IDs.
* `since` - (Optional) The start of the time range over which you want to search. If an on-call period overlaps with the range, it will be included in the result. Defaults to current time. The search range cannot exceed 3 months.
* `until` - (Optional) The end of the time range over which you want to search. If an on-call period overlaps with the range, it will be included in the result. Defaults to current time. The search range cannot exceed 3 months, and the until time cannot be before the since time.
* `earliest` - (Optional) This will filter on-calls such that only the earliest on-call for each combination of escalation policy, escalation level, and user is returned. This is useful for determining when the "next" on-calls are for a given set of filters.
## Attributes Reference
* `oncalls` - A list of on-call entries during a given time range.
[1]: https://v2.developer.pagerduty.com/v2/page/api-reference#!/On-Calls/get_oncalls

View File

@ -10,16 +10,25 @@
<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-on_call") %>>
<a href="/docs/providers/pagerduty/d/on_call.html">pagerduty_on_call</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-device") %>>
<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-project") %>>
<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") %>>
<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") %>>