Skip to content

Commit

Permalink
pager/pagerduty: import layers of schedule
Browse files Browse the repository at this point in the history
  • Loading branch information
wilsonehusin committed Apr 9, 2024
1 parent d6f50eb commit 81d408f
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 52 deletions.
63 changes: 29 additions & 34 deletions pager/pagerduty.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package pager

import (
"context"
"database/sql"
"fmt"
"strings"
"time"
Expand Down Expand Up @@ -58,43 +57,39 @@ func (p *PagerDuty) LoadSchedules(ctx context.Context) error {
}

func (p *PagerDuty) saveScheduleToDB(ctx context.Context, schedule pagerduty.Schedule) error {
for _, layer := range schedule.ScheduleLayers {
if err := p.saveLayerToDB(ctx, schedule, layer); err != nil {
return fmt.Errorf("saving layer to db: %w", err)
}
}
return nil
}

func (p *PagerDuty) saveLayerToDB(ctx context.Context, schedule pagerduty.Schedule, layer pagerduty.ScheduleLayer) error {
s := store.InsertExtScheduleParams{
ID: schedule.ID,
Name: schedule.Name,
ID: schedule.ID + "-" + layer.ID,
Name: schedule.Name + "-" + layer.Name,
Timezone: schedule.TimeZone,

// Add fallback values and override them later if API provides valid information.
Description: sql.NullString{Valid: false},
Description: fmt.Sprintf("%s (%s)", schedule.Description, layer.Name),
HandoffTime: "11:00",
HandoffDay: "wednesday",
Strategy: "weekly",
}
if schedule.Description != "" {
s.Description.String = schedule.Description
s.Description.Valid = true
}
if len(schedule.ScheduleLayers) > 0 {
// TODO: PagerDuty schedule with N layers should create N schedules in the DB.
if len(schedule.ScheduleLayers) > 1 {
console.Warnf("Schedule '%s' has more than one layer, only the first one will be used\n", s.Name)
}
layer := schedule.ScheduleLayers[0]

// TODO: support custom strategy. For now:
// - any less than "weekly" is considered "daily"
// - any more than "weekly" is considered "weekly" anyway
if layer.RotationTurnLengthSeconds < 60*60*24*7 {
s.Strategy = "daily"
}
virtualStart, err := time.Parse(time.RFC3339, layer.RotationVirtualStart)
if err == nil {
s.HandoffTime = fmt.Sprintf("%02d:%02d", virtualStart.Hour(), virtualStart.Minute())
s.HandoffDay = strings.ToLower(virtualStart.Weekday().String())
} else {
console.Errorf("unable to parse virtual start time '%v', assuming default values", layer.RotationVirtualStart)
}
// TODO: support custom strategy. For now:
// - any less than "weekly" is considered "daily"
// - any more than "weekly" is considered "weekly" anyway
if layer.RotationTurnLengthSeconds < 60*60*24*7 {
s.Strategy = "daily"
}
virtualStart, err := time.Parse(time.RFC3339, layer.RotationVirtualStart)
if err == nil {
s.HandoffTime = fmt.Sprintf("%02d:%02d", virtualStart.Hour(), virtualStart.Minute())
s.HandoffDay = strings.ToLower(virtualStart.Weekday().String())
} else {
console.Errorf("schedule %s has no layers, assuming default values", s.Name)
console.Errorf("unable to parse virtual start time '%v', assuming default values", layer.RotationVirtualStart)
}

q := store.UseQueries(ctx)
Expand All @@ -117,23 +112,23 @@ func (p *PagerDuty) saveScheduleToDB(ctx context.Context, schedule pagerduty.Sch
}
}

// Root-level Users slice contains aggregate of all users in the schedule layers.
// If we move to creating new schedule for every layer, use the users from each layer.
for _, user := range schedule.Users {
for _, user := range layer.Users {
if err := q.InsertExtScheduleMember(ctx, store.InsertExtScheduleMemberParams{
ScheduleID: s.ID,
UserID: user.ID,
UserID: user.User.ID,
}); err != nil {
if strings.Contains(err.Error(), "FOREIGN KEY constraint") {
console.Warnf("User %s not found for schedule %s, skipping...\n", user.ID, s.ID)
console.Warnf("User %s not found for schedule %s, skipping...\n", user.User.ID, s.ID)
} else if strings.Contains(err.Error(), "UNIQUE constraint") {
console.Warnf("User %s already exists for schedule %s, skipping duplicate...\n", user.ID, s.ID)
console.Warnf("User %s already exists for schedule %s, skipping duplicate...\n", user.User.ID, s.ID)
} else {
return fmt.Errorf("saving schedule user: %w", err)
}
}
}

// TODO: add restrictions

return nil
}

Expand Down
14 changes: 7 additions & 7 deletions store/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 7 additions & 7 deletions store/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion store/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ CREATE TABLE IF NOT EXISTS ext_memberships (
CREATE TABLE IF NOT EXISTS ext_schedules (
id TEXT PRIMARY KEY,
name TEXT NOT NULL,
description TEXT,
description TEXT NOT NULL,
timezone TEXT NOT NULL,
strategy TEXT NOT NULL,
handoff_time TEXT NOT NULL,
Expand Down
4 changes: 2 additions & 2 deletions tfrender/tfrender.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ func (r *TFRender) ResourceFireHydrantOnCallSchedule(ctx context.Context) error

b := r.root.AppendNewBlock("resource", []string{"firehydrant_on_call_schedule", s.TFSlug()}).Body()
b.SetAttributeValue("name", cty.StringVal(s.Name))
if s.Description.Valid {
b.SetAttributeValue("description", cty.StringVal(s.Description.String))
if s.Description != "" {
b.SetAttributeValue("description", cty.StringVal(s.Description))
}
b.SetAttributeTraversal("team_id", hcl.Traversal{
hcl.TraverseRoot{Name: "resource"},
Expand Down
2 changes: 1 addition & 1 deletion tfrender/tfrender_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ func TestRenderOnCallScheduleResource(t *testing.T) {
if err := store.UseQueries(ctx).InsertExtSchedule(ctx, store.InsertExtScheduleParams{
ID: "id-for-ext-schedule-0",
Name: "Schedule 0",
Description: sql.NullString{String: "Schedule 0 description", Valid: true},
Description: "Schedule 0 description",
HandoffTime: "11:00",
HandoffDay: "wednesday",
Strategy: "daily",
Expand Down

0 comments on commit 81d408f

Please sign in to comment.