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

feat(webhook recipient): notification variables #594

Draft
wants to merge 6 commits into
base: main
Choose a base branch
from
Draft
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
8 changes: 7 additions & 1 deletion client/recipient.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,14 @@ type RecipientDetails struct {
WebhookPayloads *WebhookPayloads `json:"webhook_payloads,omitempty"`
}

type NotificationVariable struct {
Name string `json:"name"`
Value string `json:"value"`
}

type NotificationRecipientDetails struct {
PDSeverity PagerDutySeverity `json:"pagerduty_severity,omitempty"`
Variables []NotificationVariable `json:"variables,omitempty"`
PDSeverity PagerDutySeverity `json:"pagerduty_severity,omitempty"`
}

type WebhookPayloads struct {
Expand Down
12 changes: 12 additions & 0 deletions internal/models/notification_recipients.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,20 @@ var NotificationRecipientAttrType = map[string]attr.Type{

type NotificationRecipientDetailsModel struct {
PDSeverity types.String `tfsdk:"pagerduty_severity"`
Variables types.Set `tfsdk:"variable"`
}

var NotificationRecipientDetailsAttrType = map[string]attr.Type{
"pagerduty_severity": types.StringType,
"variable": types.SetType{ElemType: types.ObjectType{AttrTypes: NotificationVariableAttrType}},
}

type NotificationVariableModel struct {
Name types.String `tfsdk:"name"`
Value types.String `tfsdk:"value"`
}

var NotificationVariableAttrType = map[string]attr.Type{
"name": types.StringType,
"value": types.StringType,
}
225 changes: 224 additions & 1 deletion internal/provider/burn_alert_resource_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,38 @@ func TestAcc_BurnAlertResource_exhaustionTimeBasic(t *testing.T) {
})
}

func TestAcc_BurnAlertResource_exhaustionTimeBasicWebhookRecipient(t *testing.T) {
dataset, sloID := burnAlertAccTestSetup(t)
burnAlert := &client.BurnAlert{}
exhaustionMinutes := 240

resource.Test(t, resource.TestCase{
PreCheck: testAccPreCheck(t),
ProtoV5ProviderFactories: testAccProtoV5MuxServerFactory,
CheckDestroy: testAccEnsureBurnAlertDestroyed(t),
Steps: []resource.TestStep{
// Create - basic
{
Config: testAccConfigBurnAlertExhaustionTime_basicWebhookRecipient(exhaustionMinutes, dataset, sloID, "warning"),
Check: testAccEnsureSuccessExhaustionTimeAlertWithWebhookRecip(t, burnAlert, exhaustionMinutes, sloID, "warning"),
},
// Update - change variable value
{
Config: testAccConfigBurnAlertExhaustionTime_basicWebhookRecipient(exhaustionMinutes, dataset, sloID, "info"),
Check: testAccEnsureSuccessExhaustionTimeAlertWithWebhookRecip(t, burnAlert, exhaustionMinutes, sloID, "info"),
},
// Import
{
ResourceName: "honeycombio_burn_alert.test",
ImportStateIdPrefix: fmt.Sprintf("%v/", dataset),
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"recipient"},
},
},
})
}

func TestAcc_BurnAlertResource_budgetRateBasic(t *testing.T) {
dataset, sloID := burnAlertAccTestSetup(t)
burnAlert := &client.BurnAlert{}
Expand Down Expand Up @@ -169,6 +201,39 @@ func TestAcc_BurnAlertResource_budgetRateBasic(t *testing.T) {
})
}

func TestAcc_BurnAlertResource_budgetRateBasicWebhookRecipient(t *testing.T) {
dataset, sloID := burnAlertAccTestSetup(t)
burnAlert := &client.BurnAlert{}
budgetRateWindowMinutes := 60
budgetRateDecreasePercent := float64(5)

resource.Test(t, resource.TestCase{
PreCheck: testAccPreCheck(t),
ProtoV5ProviderFactories: testAccProtoV5MuxServerFactory,
CheckDestroy: testAccEnsureBurnAlertDestroyed(t),
Steps: []resource.TestStep{
// Create - basic
{
Config: testAccConfigBurnAlertBudgetRate_basicWebhookRecipient(budgetRateWindowMinutes, budgetRateDecreasePercent, dataset, sloID, "warning"),
Check: testAccEnsureSuccessBudgetRateAlertWithWebhookRecip(t, burnAlert, budgetRateWindowMinutes, budgetRateDecreasePercent, sloID, "warning"),
},
// Update - change variable value
{
Config: testAccConfigBurnAlertBudgetRate_basicWebhookRecipient(budgetRateWindowMinutes, budgetRateDecreasePercent, dataset, sloID, "info"),
Check: testAccEnsureSuccessBudgetRateAlertWithWebhookRecip(t, burnAlert, budgetRateWindowMinutes, budgetRateDecreasePercent, sloID, "info"),
},
// Import
{
ResourceName: "honeycombio_burn_alert.test",
ImportStateIdPrefix: fmt.Sprintf("%v/", dataset),
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"recipient"},
},
},
})
}

// Check that creating a budget rate alert with a
// budget_rate_decrease_percent with trailing zeros works,
// doesn't produce spurious plans after apply, and imports successfully
Expand Down Expand Up @@ -551,6 +616,31 @@ func testAccEnsureSuccessExhaustionTimeAlert(t *testing.T, burnAlert *client.Bur
)
}

// Checks that the exhaustion time burn alert exists, has the correct attributes, and has the correct state
func testAccEnsureSuccessExhaustionTimeAlertWithWebhookRecip(t *testing.T, burnAlert *client.BurnAlert, exhaustionMinutes int, sloID, varValue string) resource.TestCheckFunc {
return resource.ComposeAggregateTestCheckFunc(
// Check that the burn alert exists
testAccEnsureBurnAlertExists(t, "honeycombio_burn_alert.test", burnAlert),

// Check that the burn alert has the correct attributes
testAccEnsureAttributesCorrectExhaustionTime(burnAlert, exhaustionMinutes, sloID),

// Check that the burn alert has the correct values in state
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "slo_id", sloID),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "description", testBADescription),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "alert_type", "exhaustion_time"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "exhaustion_minutes", fmt.Sprintf("%d", exhaustionMinutes)),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.#", "1"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.0.notification_details.#", "1"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.0.notification_details.0.variable.0.name", "severity"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.0.notification_details.0.variable.0.value", varValue),

// Budget rate attributes should not be set
resource.TestCheckNoResourceAttr("honeycombio_burn_alert.test", "budget_rate_window_minutes"),
resource.TestCheckNoResourceAttr("honeycombio_burn_alert.test", "budget_rate_decrease_percent"),
)
}

// Checks that the budget rate burn alert exists, has the correct attributes, and has the correct state
func testAccEnsureSuccessBudgetRateAlert(t *testing.T, burnAlert *client.BurnAlert, budgetRateWindowMinutes int, budgetRateDecreasePercent float64, pagerdutySeverity, sloID string) resource.TestCheckFunc {
return resource.ComposeAggregateTestCheckFunc(
Expand All @@ -574,6 +664,32 @@ func testAccEnsureSuccessBudgetRateAlert(t *testing.T, burnAlert *client.BurnAle
)
}

// Checks that the budget rate burn alert exists, has the correct attributes, and has the correct state
func testAccEnsureSuccessBudgetRateAlertWithWebhookRecip(t *testing.T, burnAlert *client.BurnAlert, budgetRateWindowMinutes int, budgetRateDecreasePercent float64, sloID, varValue string) resource.TestCheckFunc {
return resource.ComposeAggregateTestCheckFunc(
// Check that the burn alert exists
testAccEnsureBurnAlertExists(t, "honeycombio_burn_alert.test", burnAlert),

// Check that the burn alert has the correct attributes
testAccEnsureAttributesCorrectBudgetRate(burnAlert, budgetRateWindowMinutes, budgetRateDecreasePercent, sloID),

// Check that the burn alert has the correct values in state
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "slo_id", sloID),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "description", testBADescription),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "alert_type", "budget_rate"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "budget_rate_window_minutes", fmt.Sprintf("%d", budgetRateWindowMinutes)),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "budget_rate_decrease_percent", helper.FloatToPercentString(budgetRateDecreasePercent)),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.#", "1"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.0.notification_details.#", "1"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.0.notification_details.0.variable.#", "1"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.0.notification_details.0.variable.0.name", "severity"),
resource.TestCheckResourceAttr("honeycombio_burn_alert.test", "recipient.0.notification_details.0.variable.0.value", varValue),

// Exhaustion time attributes should not be set
resource.TestCheckNoResourceAttr("honeycombio_burn_alert.test", "exhaustion_minutes"),
)
}

func testAccEnsureBurnAlertExists(t *testing.T, name string, burnAlert *client.BurnAlert) resource.TestCheckFunc {
return func(s *terraform.State) error {
resourceState, ok := s.RootModule().Resources[name]
Expand Down Expand Up @@ -722,6 +838,13 @@ resource "honeycombio_burn_alert" "test" {
}

func testAccConfigBurnAlertDefault_basic(exhaustionMinutes int, dataset, sloID, pdseverity string) string {
tmplBody := `<<EOT
{
"name": " {{ .Name }}",
"id": " {{ .ID }}",
"description": " {{ .Description }}",
}
EOT`
return fmt.Sprintf(`
resource "honeycombio_pagerduty_recipient" "test" {
integration_key = "08b9d4cacd68933151a1ef1028b67da2"
Expand All @@ -742,7 +865,56 @@ resource "honeycombio_burn_alert" "test" {
pagerduty_severity = "%[4]s"
}
}
}`, exhaustionMinutes, dataset, sloID, pdseverity, testBADescription)
}`, exhaustionMinutes, dataset, sloID, pdseverity, testBADescription, tmplBody)
}

func testAccConfigBurnAlertExhaustionTime_basicWebhookRecipient(exhaustionMinutes int, dataset, sloID, variableValue string) string {
tmplBody := `<<EOT
{
"name": " {{ .Name }}",
"id": " {{ .ID }}",
"description": " {{ .Description }}",
}
EOT`
return fmt.Sprintf(`
resource "honeycombio_webhook_recipient" "test" {
name = "test"
url = "http://example.com"

header {
name = "Authorization"
value = "Bearer abc123"
}

variable {
name = "severity"
default_value = "critical"
}

template {
type = "exhaustion_time"
body = %[5]s
}
}

resource "honeycombio_burn_alert" "test" {
exhaustion_minutes = %[1]d

dataset = "%[2]s"
slo_id = "%[3]s"
description = "%[4]s"

recipient {
id = honeycombio_webhook_recipient.test.id

notification_details {
variable {
name = "severity"
value = "%[6]s"
}
}
}
}`, exhaustionMinutes, dataset, sloID, testBADescription, tmplBody, variableValue)
}

func testAccConfigBurnAlertDefault_validateAttributesWhenAlertTypeIsExhaustionTime(dataset, sloID string) string {
Expand Down Expand Up @@ -829,6 +1001,57 @@ resource "honeycombio_burn_alert" "test" {
}`, budgetRateWindowMinutes, helper.FloatToPercentString(budgetRateDecreasePercent), dataset, sloID, pdseverity, testBADescription)
}

func testAccConfigBurnAlertBudgetRate_basicWebhookRecipient(budgetRateWindowMinutes int, budgetRateDecreasePercent float64, dataset, sloID, variableValue string) string {
tmplBody := `<<EOT
{
"name": " {{ .Name }}",
"id": " {{ .ID }}",
"description": " {{ .Description }}",
}
EOT`
return fmt.Sprintf(`
resource "honeycombio_webhook_recipient" "test" {
name = "test"
url = "http://example.com"

header {
name = "Authorization"
value = "Bearer abc123"
}

variable {
name = "severity"
default_value = "critical"
}

template {
type = "budget_rate"
body = %[6]s
}
}

resource "honeycombio_burn_alert" "test" {
alert_type = "budget_rate"
description = "%[5]s"
budget_rate_window_minutes = %[1]d
budget_rate_decrease_percent = %[2]s

dataset = "%[3]s"
slo_id = "%[4]s"

recipient {
id = honeycombio_webhook_recipient.test.id

notification_details {
variable {
name = "severity"
value = "%[7]s"
}
}
}
}`, budgetRateWindowMinutes, helper.FloatToPercentString(budgetRateDecreasePercent), dataset, sloID, testBADescription, tmplBody, variableValue)
}

func testAccConfigBurnAlertBudgetRate_trailingZeros(dataset, sloID string) string {
return fmt.Sprintf(`
resource "honeycombio_pagerduty_recipient" "test" {
Expand Down
Loading
Loading