Skip to content

Commit

Permalink
Add support for wait_until_time in policy steps (#118)
Browse files Browse the repository at this point in the history
  • Loading branch information
nilclass authored Oct 10, 2024
1 parent a31616a commit 3c53720
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 22 deletions.
2 changes: 2 additions & 0 deletions docs/data-sources/betteruptime_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ Read-Only:
- **type** (String)
- **urgency_id** (Number)
- **wait_before** (Number)
- **wait_until_time** (String)
- **wait_until_timezone** (String)

<a id="nestedobjatt--steps--step_members"></a>
### Nested Schema for `steps.step_members`
Expand Down
4 changes: 3 additions & 1 deletion docs/resources/betteruptime_policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ https://betterstack.com/docs/uptime/api/list-all-escalation-policies/
Required:

- **type** (String) The type of the step. Can be either escalation, time_branching, or metadata_branching.
- **wait_before** (Number) How long to wait before executing this step since previous step.

Optional:

Expand All @@ -51,6 +50,9 @@ Optional:
- **time_to** (String) A time at which the branching rule will step being executed. Use HH:MM format. Used when step type is time_branching.
- **timezone** (String) What timezone to use when evaluating time based branching rules. Used when step type is time_branching. The accepted values can be found in the Rails TimeZone documentation. https://api.rubyonrails.org/classes/ActiveSupport/TimeZone.html
- **urgency_id** (Number) Which severity to use for this step. Used when step type is escalation.
- **wait_before** (Number) How long to wait in seconds before executing this step since previous step. Omit if wait_until_time is set.
- **wait_until_time** (String) Execute this step at the specified time. Use HH:MM format. Omit if wait_before is set.
- **wait_until_timezone** (String) Timezone to use when interpreting wait_until_time. Omit if wait_before is set.

<a id="nestedblock--steps--step_members"></a>
### Nested Schema for `steps.step_members`
Expand Down
10 changes: 3 additions & 7 deletions examples/advanced/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -241,10 +241,6 @@ resource "betteruptime_incoming_webhook" "this" {
}
}

data "betteruptime_severity" "this" {
name = var.betteruptime_severity_name
}

resource "betteruptime_policy_group" "this" {
name = "Policies from Terraform"
}
Expand All @@ -258,7 +254,7 @@ resource "betteruptime_policy" "this" {
steps {
type = "escalation"
wait_before = 0
urgency_id = data.betteruptime_severity.this.id
urgency_id = betteruptime_severity.this.id
step_members { type = "all_slack_integrations" }
step_members { type = "all_webhook_integrations" }
step_members { type = "current_on_call" }
Expand All @@ -282,7 +278,7 @@ resource "betteruptime_policy" "this" {
steps {
type = "escalation"
wait_before = 180
urgency_id = data.betteruptime_severity.this.id
urgency_id = betteruptime_severity.this.id
step_members { type = "entire_team" }
}
}
Expand All @@ -292,7 +288,7 @@ resource "betteruptime_severity_group" "this" {
}

resource "betteruptime_severity" "this" {
name = "Terraform"
name = var.betteruptime_severity_name
call = false
email = false
push = false
Expand Down
2 changes: 1 addition & 1 deletion examples/advanced/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,5 @@ EOF
variable "betteruptime_severity_name" {
type = string
description = "Name of the severity from Better Uptime you want to use with Escalation policies created using Terraform"
default = "Low Severity"
default = "Terraform Severity"
}
39 changes: 26 additions & 13 deletions internal/provider/resource_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,20 @@ var policyStepSchema = map[string]*schema.Schema{
Required: true,
},
"wait_before": {
Description: "How long to wait before executing this step since previous step.",
Description: "How long to wait in seconds before executing this step since previous step. Omit if wait_until_time is set.",
Type: schema.TypeInt,
Required: true,
Optional: true,
},
"wait_until_time": {
Description: "Execute this step at the specified time. Use HH:MM format. Omit if wait_before is set.",
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringMatch(regexp.MustCompile(`^(2[0-3]|[01][0-9]):[0-5][0-9]$`), "use HH:MM format"),
},
"wait_until_timezone": {
Description: "Timezone to use when interpreting wait_until_time. Omit if wait_before is set.",
Type: schema.TypeString,
Optional: true,
},
"urgency_id": {
Description: "Which severity to use for this step. Used when step type is escalation.",
Expand Down Expand Up @@ -180,17 +191,19 @@ type policyStepMember struct {
}

type policyStep struct {
Type *string `mapstructure:"type,omitempty" json:"type,omitempty"`
WaitBefore *int `mapstructure:"wait_before,omitempty" json:"wait_before,omitempty"`
UrgencyId *int `mapstructure:"urgency_id,omitempty" json:"urgency_id,omitempty"`
Steps *[]policyStepMember `mapstructure:"step_members" json:"step_members"`
Timezone *string `mapstructure:"timezone,omitempty" json:"timezone,omitempty"`
Days *[]string `mapstructure:"days,omitempty" json:"days,omitempty"`
TimeFrom *string `mapstructure:"time_from,omitempty" json:"time_from,omitempty"`
TimeTo *string `mapstructure:"time_to,omitempty" json:"time_to,omitempty"`
MetadataKey *string `mapstructure:"metadata_key,omitempty" json:"metadata_key,omitempty"`
MetadataValues *[]string `mapstructure:"metadata_values,omitempty" json:"metadata_values,omitempty"`
PolicyId *int `mapstructure:"policy_id,omitempty" json:"policy_id,omitempty"`
Type *string `mapstructure:"type,omitempty" json:"type,omitempty"`
WaitBefore *int `mapstructure:"wait_before,omitempty" json:"wait_before,omitempty"`
WaitUntilTime *string `mapstructure:"wait_until_time,omitempty" json:"wait_until_time,omitempty"`
WaitUntilTimezone *string `mapstructure:"wait_until_timezone,omitempty" json:"wait_until_timezone,omitempty"`
UrgencyId *int `mapstructure:"urgency_id,omitempty" json:"urgency_id,omitempty"`
Steps *[]policyStepMember `mapstructure:"step_members" json:"step_members"`
Timezone *string `mapstructure:"timezone,omitempty" json:"timezone,omitempty"`
Days *[]string `mapstructure:"days,omitempty" json:"days,omitempty"`
TimeFrom *string `mapstructure:"time_from,omitempty" json:"time_from,omitempty"`
TimeTo *string `mapstructure:"time_to,omitempty" json:"time_to,omitempty"`
MetadataKey *string `mapstructure:"metadata_key,omitempty" json:"metadata_key,omitempty"`
MetadataValues *[]string `mapstructure:"metadata_values,omitempty" json:"metadata_values,omitempty"`
PolicyId *int `mapstructure:"policy_id,omitempty" json:"policy_id,omitempty"`
}

type policy struct {
Expand Down
106 changes: 106 additions & 0 deletions internal/provider/resource_policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,110 @@ func TestResourcePolicy(t *testing.T) {
},
},
})

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProviderFactories: map[string]func() (*schema.Provider, error){
"betteruptime": func() (*schema.Provider, error) {
return New(WithURL(server.URL)), nil
},
},
Steps: []resource.TestStep{
// Test wait_until_time / wait_until_timezone
{
Config: `
provider "betteruptime" {
api_token = "foo"
}
resource "betteruptime_policy" "this" {
name = "Terraform - Test"
repeat_count = 3
repeat_delay = 60
steps {
type = "escalation"
wait_before = 0
urgency_id = 123
step_members { type = "current_on_call" }
step_members {
type = "slack_integration"
id = 123
}
}
steps {
type = "escalation"
wait_until_time = "07:45"
wait_until_timezone = "UTC"
urgency_id = 123
step_members {
type = "entire_team"
id = 123
}
}
}
`,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("betteruptime_policy.this", "id"),
resource.TestCheckResourceAttr("betteruptime_policy.this", "steps.0.wait_before", "0"),
resource.TestCheckResourceAttr("betteruptime_policy.this", "steps.1.wait_until_time", "07:45"),
resource.TestCheckResourceAttr("betteruptime_policy.this", "steps.1.wait_until_timezone", "UTC"),
),
PreConfig: func() {
t.Log("test valid wait_until_time")
},
},
},
})

resource.Test(t, resource.TestCase{
IsUnitTest: true,
ProviderFactories: map[string]func() (*schema.Provider, error){
"betteruptime": func() (*schema.Provider, error) {
return New(WithURL(server.URL)), nil
},
},
Steps: []resource.TestStep{
// Test wait_until_time validation
{
Config: `
provider "betteruptime" {
api_token = "foo"
}
resource "betteruptime_policy" "this" {
name = "Terraform - Test"
repeat_count = 3
repeat_delay = 60
steps {
type = "escalation"
wait_before = 0
urgency_id = 123
step_members { type = "current_on_call" }
step_members {
type = "slack_integration"
id = 123
}
}
steps {
type = "escalation"
wait_until_time = "9 AM"
wait_until_timezone = "UTC"
urgency_id = 123
step_members {
type = "entire_team"
id = 123
}
}
}
`,
Check: resource.ComposeTestCheckFunc(),
ExpectError: regexp.MustCompile(`invalid value for steps\.1\.wait_until_time \(use HH:MM format\)`),
PreConfig: func() {
t.Log("test validation: wait_until_time")
},
},
},
})
}

0 comments on commit 3c53720

Please sign in to comment.