Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

r/pagerduty_schedule: Add support for overflow #23

Merged
merged 4 commits into from
Aug 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 63 additions & 10 deletions pagerduty/resource_pagerduty_schedule.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,23 @@ func resourcePagerDutySchedule() *schema.Resource {
Type: schema.TypeString,
Optional: true,
},

"time_zone": {
Type: schema.TypeString,
Required: true,
},

"overflow": {
Type: schema.TypeBool,
Optional: true,
},

"description": {
Type: schema.TypeString,
Optional: true,
Default: "Managed by Terraform",
},

"layer": {
Type: schema.TypeList,
Required: true,
Expand All @@ -40,34 +48,41 @@ func resourcePagerDutySchedule() *schema.Resource {
Type: schema.TypeString,
Computed: true,
},

"name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
},

"start": {
Type: schema.TypeString,
Required: true,
},

"end": {
Type: schema.TypeString,
Optional: true,
},

"rotation_virtual_start": {
Type: schema.TypeString,
Required: 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,
Expand All @@ -77,14 +92,17 @@ func resourcePagerDutySchedule() *schema.Resource {
Type: schema.TypeString,
Required: true,
},

"start_time_of_day": {
Type: schema.TypeString,
Required: true,
},

"start_day_of_week": {
Type: schema.TypeInt,
Optional: true,
},

"duration_seconds": {
Type: schema.TypeInt,
Required: true,
Expand All @@ -99,28 +117,42 @@ func resourcePagerDutySchedule() *schema.Resource {
}
}

func buildScheduleStruct(d *schema.ResourceData) *pagerduty.Schedule {
func buildScheduleStruct(d *schema.ResourceData) (*pagerduty.Schedule, error) {
layers, err := expandScheduleLayers(d.Get("layer"))
if err != nil {
return nil, err
}

schedule := &pagerduty.Schedule{
Name: d.Get("name").(string),
TimeZone: d.Get("time_zone").(string),
ScheduleLayers: expandScheduleLayers(d.Get("layer")),
ScheduleLayers: layers,
}

if attr, ok := d.GetOk("description"); ok {
schedule.Description = attr.(string)
}

return schedule
return schedule, nil
}

func resourcePagerDutyScheduleCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)

schedule := buildScheduleStruct(d)
schedule, err := buildScheduleStruct(d)
if err != nil {
return err
}

o := &pagerduty.CreateScheduleOptions{}

if v, ok := d.GetOk("overflow"); ok {
o.Overflow = v.(bool)
}

log.Printf("[INFO] Creating PagerDuty schedule: %s", schedule.Name)

schedule, _, err := client.Schedules.Create(schedule)
schedule, _, err = client.Schedules.Create(schedule, o)
if err != nil {
return err
}
Expand Down Expand Up @@ -154,11 +186,20 @@ func resourcePagerDutyScheduleRead(d *schema.ResourceData, meta interface{}) err
func resourcePagerDutyScheduleUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*pagerduty.Client)

schedule := buildScheduleStruct(d)
schedule, err := buildScheduleStruct(d)
if err != nil {
return err
}

o := &pagerduty.UpdateScheduleOptions{}

if v, ok := d.GetOk("overflow"); ok {
o.Overflow = v.(bool)
}

log.Printf("[INFO] Updating PagerDuty schedule: %s", d.Id())

if _, _, err := client.Schedules.Update(d.Id(), schedule); err != nil {
if _, _, err := client.Schedules.Update(d.Id(), schedule, o); err != nil {
return err
}

Expand All @@ -179,17 +220,29 @@ func resourcePagerDutyScheduleDelete(d *schema.ResourceData, meta interface{}) e
return nil
}

func expandScheduleLayers(v interface{}) []*pagerduty.ScheduleLayer {
func expandScheduleLayers(v interface{}) ([]*pagerduty.ScheduleLayer, error) {
var scheduleLayers []*pagerduty.ScheduleLayer

for _, sl := range v.([]interface{}) {
rsl := sl.(map[string]interface{})

// This is a temporary fix to prevent getting back the wrong rotation_virtual_start time.
// The background here is that if a user specifies a rotation_virtual_start time to be:
// "2017-09-01T10:00:00+02:00" the API returns back "2017-09-01T12:00:00+02:00".
// With this fix in place, we get the correct rotation_virtual_start time, thus
// eliminating the diff issues we've been seeing in the past.
// This has been confirmed working by PagerDuty support.
rvs, err := timeToUTC(rsl["rotation_virtual_start"].(string))
if err != nil {
return nil, err
}

scheduleLayer := &pagerduty.ScheduleLayer{
ID: rsl["id"].(string),
Name: rsl["name"].(string),
Start: rsl["start"].(string),
End: rsl["end"].(string),
RotationVirtualStart: rsl["rotation_virtual_start"].(string),
RotationVirtualStart: rvs,
RotationTurnLengthSeconds: rsl["rotation_turn_length_seconds"].(int),
}

Expand Down Expand Up @@ -219,7 +272,7 @@ func expandScheduleLayers(v interface{}) []*pagerduty.ScheduleLayer {
scheduleLayers = append(scheduleLayers, scheduleLayer)
}

return scheduleLayers
return scheduleLayers, nil
}

func flattenScheduleLayers(v []*pagerduty.ScheduleLayer) []map[string]interface{} {
Expand Down
88 changes: 88 additions & 0 deletions pagerduty/resource_pagerduty_schedule_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,36 @@ func TestAccPagerDutySchedule_Basic(t *testing.T) {
})
}

func TestAccPagerDutyScheduleOverflow_Basic(t *testing.T) {
username := fmt.Sprintf("tf-%s", acctest.RandString(5))
email := fmt.Sprintf("%s@foo.com", username)
schedule := fmt.Sprintf("tf-%s", acctest.RandString(5))
scheduleUpdated := fmt.Sprintf("tf-%s", acctest.RandString(5))
location := "America/New_York"
start := timeNowInLoc(location).Add(30 * time.Hour).Round(1 * time.Hour).Format(time.RFC3339)
rotationVirtualStart := timeNowInLoc(location).Add(30 * time.Hour).Round(1 * time.Hour).Format(time.RFC3339)

resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: testAccCheckPagerDutyScheduleDestroy,
Steps: []resource.TestStep{
{
Config: testAccCheckPagerDutyScheduleOverflowConfig(username, email, schedule, location, start, rotationVirtualStart),
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyScheduleExists("pagerduty_schedule.foo"),
),
},
{
Config: testAccCheckPagerDutyScheduleOverflowConfigUpdated(username, email, scheduleUpdated, location, start, rotationVirtualStart),
Check: resource.ComposeTestCheckFunc(
testAccCheckPagerDutyScheduleExists("pagerduty_schedule.foo"),
),
},
},
})
}

func TestAccPagerDutySchedule_BasicWeek(t *testing.T) {
username := fmt.Sprintf("tf-%s", acctest.RandString(5))
email := fmt.Sprintf("%s@foo.com", username)
Expand Down Expand Up @@ -346,6 +376,64 @@ resource "pagerduty_schedule" "foo" {
`, username, email, schedule, location, start, rotationVirtualStart)
}

func testAccCheckPagerDutyScheduleOverflowConfig(username, email, schedule, location, start, rotationVirtualStart string) string {
return fmt.Sprintf(`
resource "pagerduty_user" "foo" {
name = "%s"
email = "%s"
}

resource "pagerduty_schedule" "foo" {
name = "%s"
overflow = true
time_zone = "%s"

layer {
name = "foo"
start = "%s"
rotation_virtual_start = "%s"
rotation_turn_length_seconds = 86400
users = ["${pagerduty_user.foo.id}"]

restriction {
type = "daily_restriction"
start_time_of_day = "08:00:00"
duration_seconds = 32101
}
}
}
`, username, email, schedule, location, start, rotationVirtualStart)
}

func testAccCheckPagerDutyScheduleOverflowConfigUpdated(username, email, schedule, location, start, rotationVirtualStart string) string {
return fmt.Sprintf(`
resource "pagerduty_user" "foo" {
name = "%s"
email = "%s"
}

resource "pagerduty_schedule" "foo" {
name = "%s"
overflow = false
time_zone = "%s"

layer {
name = "foo"
start = "%s"
rotation_virtual_start = "%s"
rotation_turn_length_seconds = 86400
users = ["${pagerduty_user.foo.id}"]

restriction {
type = "daily_restriction"
start_time_of_day = "08:00:00"
duration_seconds = 32101
}
}
}
`, username, email, schedule, location, start, rotationVirtualStart)
}

func testAccCheckPagerDutyScheduleConfigWeek(username, email, schedule, location, start, rotationVirtualStart string) string {
return fmt.Sprintf(`
resource "pagerduty_user" "foo" {
Expand Down
9 changes: 9 additions & 0 deletions pagerduty/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ import (
"github.com/hashicorp/terraform/helper/schema"
)

func timeToUTC(v string) (string, error) {
t, err := time.Parse(time.RFC3339, v)
if err != nil {
return "", err
}

return t.UTC().String(), nil
}

// validateRFC3339 validates that a date string has the correct RFC3339 layout
func validateRFC3339(v interface{}, k string) (we []string, errors []error) {
value := v.(string)
Expand Down
Loading