Skip to content

Commit

Permalink
feat(webhook recipient): notification variables (#594)
Browse files Browse the repository at this point in the history
This adds the notification variable functionality to custom webhooks.
  • Loading branch information
brookesargent authored Jan 7, 2025
1 parent 1b80562 commit f8d71e5
Show file tree
Hide file tree
Showing 10 changed files with 1,025 additions and 14 deletions.
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
2 changes: 1 addition & 1 deletion docs/data-sources/recipient.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,4 @@ In addition to all arguments above, the following attributes are exported:
* `secret` - (Sensitive) The webhook recipient's secret -- if of type `webhook`.
* `url` - The webhook recipient's URL - if of type `webhook`, `msteams` or `msteams_workflow`.
* `integration_key` - (Sensitive) The PagerDuty recipient's integration key -- if of type `pagerduty`.
* `integration_name` - The PagerDuty recipient's inregration name -- if of type `pagerduty`.
* `integration_name` - The PagerDuty recipient's integration name -- if of type `pagerduty`.
45 changes: 44 additions & 1 deletion docs/resources/burn_alert.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,47 @@ resource "honeycombio_burn_alert" "example_alert" {
}
```

### Example - Exhaustion Time Burn Alert with Webhook Recipient and Notification Variable
```hcl
variable "dataset" {
type = string
}
variable "slo_id" {
type = string
}
data "honeycombio_recipient" "custom_webhook" {
type = "webhook"
detail_filter {
name = "name"
value = "My Custom Webhook"
}
}
resource "honeycombio_burn_alert" "example_alert" {
exhaustion_minutes = 60
description = "Burn alert description"
dataset = var.dataset
slo_id = var.slo_id
dataset = var.dataset
slo_id = var.slo_id
recipient {
id = data.honeycombio_recipient.custom_webhook.id
notification_details {
variable {
name = "severity"
value = "info"
}
}
}
}
```


## Argument Reference

Expand Down Expand Up @@ -130,7 +171,9 @@ Each burn alert configuration may have one or more `recipient` blocks, which eac
* `type` - (Optional) The type of the recipient, allowed types are `email`, `pagerduty`, `msteams`, `slack` and `webhook`. Should not be used in combination with `id`.
* `target` - (Optional) Target of the recipient, this has another meaning depending on the type of recipient (see the table below). Should not be used in combination with `id`.
* `id` - (Optional) The ID of an already existing recipient. Should not be used in combination with `type` and `target`.
* `notification_details` - (Optional) a block of additional details to send along with the notification. The only supported option currently is `pagerduty_severity` which has a default value of `critical` but can be set to one of `info`, `warning`, `error`, or `critical` and must be used in combination with a PagerDuty recipient.
* `notification_details` - (Optional) a block of additional details to send along with the notification. Supported details are described below.
* `pagerduty_severity` - (Optional) Indicates the severity of an alert and has a default value of `critical` but can be set to one of `info`, `warning`, `error`, or `critical` and must be used in combination with a PagerDuty recipient.
* `variable` - (Optional) Up to 10 configuration blocks with a `name` and a `value` to override the default variable value. Must be used in combination with a Webhook recipient that already has a variable with the same name configured.

| Type | Target |
|-----------|---------------------|
Expand Down
73 changes: 70 additions & 3 deletions docs/resources/trigger.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ variable "dataset" {
type = string
}
data "honeycombio_recipient" "pd-prod" {
data "honeycombio_recipient" "pd_prod" {
type = "pagerduty"
detail_filter {
Expand Down Expand Up @@ -97,7 +97,7 @@ resource "honeycombio_trigger" "example" {
}
recipient {
id = data.honeycombio_recipient.pd-prod.id
id = data.honeycombio_recipient.pd_prod.id
notification_details {
pagerduty_severity = "warning"
Expand All @@ -116,6 +116,71 @@ resource "honeycombio_trigger" "example" {
}
}
```
### Example - Example with Webhook Recipient and Notification Variable
```hcl
variable "dataset" {
type = string
}
data "honeycombio_recipient" "custom_webhook" {
type = "webhook"
detail_filter {
name = "name"
value = "My Custom Webhook"
}
}
data "honeycombio_query_specification" "example" {
calculation {
op = "AVG"
column = "duration_ms"
}
filter {
column = "trace.parent_id"
op = "does-not-exist"
}
}
resource "honeycombio_trigger" "example" {
name = "Requests are slower than usual"
description = "Average duration of all requests for the last 10 minutes."
query_json = data.honeycombio_query_specification.example.json
dataset = var.dataset
frequency = 600 // in seconds, 10 minutes
threshold {
op = ">"
value = 1000
exceeded_limit = 3
}
recipient {
id = data.honeycombio_recipient.custom_webhook.id
notification_details {
variable {
name = "severity"
value = "info"
}
}
}
evaluation_schedule {
start_time = "13:00"
end_time = "21:00"
days_of_week = [
"monday",
"wednesday",
"friday"
]
}
}
```

## Argument Reference

Expand Down Expand Up @@ -166,7 +231,9 @@ Cannot not be used in combination with `id`.
* `target` - (Optional) Target of the trigger recipient, this has another meaning depending on the type of recipient (see the table below).
Cannot not be used in combination with `id`.
* `id` - (Optional) The ID of an already existing recipient. Cannot not be used in combination with `type` and `target`.
* `notification_details` - (Optional) a block of additional details to send along with the notification. The only supported option currently is `pagerduty_severity` which has a default value of `critical` but can be set to one of `info`, `warning`, `error`, or `critical` and must be used in combination with a PagerDuty recipient.
* `notification_details` - (Optional) a block of additional details to send along with the notification.
* `pagerduty_severity` - (Optional) Indicates the severity of an alert and has a default value of `critical` but can be set to one of `info`, `warning`, `error`, or `critical` and must be used in combination with a PagerDuty recipient.
* `variable` - (Optional) Up to 10 configuration blocks with a `name` and a `value` to override the default variable value. Must be used in combination with a Webhook recipient that already has a variable with the same name configured.

Type | Target
----------|-------------------------
Expand Down
51 changes: 51 additions & 0 deletions internal/helper/validation/valid_notification_variables.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package validation

import (
"context"

"github.com/hashicorp/terraform-plugin-framework/path"
"github.com/hashicorp/terraform-plugin-framework/schema/validator"

"github.com/honeycombio/terraform-provider-honeycombio/internal/models"
)

var _ validator.Set = notificationVariablesValidator{}

type notificationVariablesValidator struct{}

func (v notificationVariablesValidator) Description(_ context.Context) string {
return "value must be a valid set of webhook variables"
}

func (v notificationVariablesValidator) MarkdownDescription(ctx context.Context) string {
return v.Description(ctx)
}

func (v notificationVariablesValidator) ValidateSet(ctx context.Context, request validator.SetRequest, response *validator.SetResponse) {
if request.ConfigValue.IsNull() || request.ConfigValue.IsUnknown() {
return
}

// variable names cannot be duplicated
var variables []models.NotificationVariableModel
response.Diagnostics.Append(request.ConfigValue.ElementsAs(ctx, &variables, false)...)

duplicateMap := make(map[string]bool)
for i, v := range variables {
name := v.Name.ValueString()
if duplicateMap[name] {
response.Diagnostics.AddAttributeError(
path.Root("variable").AtListIndex(i).AtName("name"),
"Conflicting configuration arguments",
"cannot have more than one \"variable\" with the same \"name\"",
)
}
duplicateMap[name] = true
}
}

// ValidNotificationVariables determines if the provided recipient notification variables are valid.
// Today this means no variable names are duplicated.
func ValidNotificationVariables() validator.Set {
return notificationVariablesValidator{}
}
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,
}
Loading

0 comments on commit f8d71e5

Please sign in to comment.