Skip to content

Commit

Permalink
Merge pull request #23 from heimweh/f-schedule-overflow
Browse files Browse the repository at this point in the history
r/pagerduty_schedule: Add support for overflow
  • Loading branch information
grubernaut authored Aug 15, 2017
2 parents 72fa145 + 753bc72 commit a478802
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 68 deletions.
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

0 comments on commit a478802

Please sign in to comment.