Skip to content

Commit

Permalink
Alerting: Add MQTT notifications receiver
Browse files Browse the repository at this point in the history
  • Loading branch information
alexander-akhmetov committed Aug 3, 2024
1 parent a41e72a commit d5ebbb8
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 0 deletions.
24 changes: 24 additions & 0 deletions docs/resources/contact_point.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ resource "grafana_contact_point" "my_contact_point" {
- `googlechat` (Block Set) A contact point that sends notifications to Google Chat. (see [below for nested schema](#nestedblock--googlechat))
- `kafka` (Block Set) A contact point that publishes notifications to Apache Kafka topics. (see [below for nested schema](#nestedblock--kafka))
- `line` (Block Set) A contact point that sends notifications to LINE.me. (see [below for nested schema](#nestedblock--line))
- `mqtt` (Block Set) A contact point that sends notifications to an MQTT broker. (see [below for nested schema](#nestedblock--mqtt))
- `oncall` (Block Set) A contact point that sends notifications to Grafana On-Call. (see [below for nested schema](#nestedblock--oncall))
- `opsgenie` (Block Set) A contact point that sends notifications to OpsGenie. (see [below for nested schema](#nestedblock--opsgenie))
- `org_id` (String) The Organization ID. If not set, the Org ID defined in the provider block will be used.
Expand Down Expand Up @@ -212,6 +213,29 @@ Read-Only:
- `uid` (String) The UID of the contact point.


<a id="nestedblock--mqtt"></a>
### Nested Schema for `mqtt`

Required:

- `broker_url` (String) The URL of the MQTT broker.
- `topic` (String) The topic to publish messages to.

Optional:

- `client_id` (String) The client ID to use when connecting to the broker.
- `disable_resolve_message` (Boolean) Whether to disable sending resolve messages. Defaults to `false`.
- `insecure_skip_verify` (Boolean) Whether to skip verification of the server's certificate chain and host name. Defaults to `false`.
- `message_format` (String) The format of the message to send. Supported values are `json` and `text`.
- `password` (String, Sensitive) The password to use when connecting to the broker.
- `settings` (Map of String, Sensitive) Additional custom properties to attach to the notifier. Defaults to `map[]`.
- `username` (String) The username to use when connecting to the broker.

Read-Only:

- `uid` (String) The UID of the contact point.


<a id="nestedblock--oncall"></a>
### Nested Schema for `oncall`

Expand Down
10 changes: 10 additions & 0 deletions examples/resources/grafana_contact_point/_acc_receiver_types.tf
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,16 @@ resource "grafana_contact_point" "receiver_types" {
description = "description"
}

mqtt {
broker_url = "tcp://localhost:1883"
topic = "grafana/alerts"
client_id = "client_id"
message_format = "json"
username = "username"
password = "password"
insecure_skip_verify = false
}

opsgenie {
url = "http://opsgenie-api"
api_key = "token"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ var (
googleChatNotifier{},
kafkaNotifier{},
lineNotifier{},
mqttNotifier{},
oncallNotifier{},
opsGenieNotifier{},
pagerDutyNotifier{},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -619,6 +619,105 @@ func (o lineNotifier) unpack(raw interface{}, name string) *models.EmbeddedConta
}
}

type mqttNotifier struct{}

var _ notifier = (*mqttNotifier)(nil)

func (o mqttNotifier) meta() notifierMeta {
return notifierMeta{
field: "mqtt",
typeStr: "mqtt",
desc: "A contact point that sends notifications to an MQTT broker.",
secureFields: []string{"password"},
}
}

func (o mqttNotifier) schema() *schema.Resource {
r := commonNotifierResource()
r.Schema["broker_url"] = &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "The URL of the MQTT broker.",
}
r.Schema["topic"] = &schema.Schema{
Type: schema.TypeString,
Required: true,
Description: "The topic to publish messages to.",
}
r.Schema["client_id"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "The client ID to use when connecting to the broker.",
}
r.Schema["message_format"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
ValidateFunc: validation.StringInSlice([]string{"json", "text"}, false),
Description: "The format of the message to send. Supported values are `json` and `text`.",
}
r.Schema["username"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "The username to use when connecting to the broker.",
}
r.Schema["password"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
Sensitive: true,
Description: "The password to use when connecting to the broker.",
}
r.Schema["insecure_skip_verify"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Whether to skip verification of the server's certificate chain and host name.",
}
return r
}

func (o mqttNotifier) pack(p *models.EmbeddedContactPoint, data *schema.ResourceData) (interface{}, error) {
notifier := packCommonNotifierFields(p)
settings := p.Settings.(map[string]interface{})

packNotifierStringField(&settings, &notifier, "brokerUrl", "broker_url")
packNotifierStringField(&settings, &notifier, "topic", "topic")
packNotifierStringField(&settings, &notifier, "clientId", "client_id")
packNotifierStringField(&settings, &notifier, "messageFormat", "message_format")
packNotifierStringField(&settings, &notifier, "username", "username")
if v, ok := settings["insecureSkipVerify"]; ok && v != nil {
notifier["insecure_skip_verify"] = v.(bool)
delete(settings, "insecureSkipVerify")
}

packSecureFields(notifier, getNotifierConfigFromStateWithUID(data, o, p.UID), o.meta().secureFields)

notifier["settings"] = packSettings(p)
return notifier, nil
}

func (o mqttNotifier) unpack(raw interface{}, name string) *models.EmbeddedContactPoint {
json := raw.(map[string]interface{})
uid, disableResolve, settings := unpackCommonNotifierFields(json)

unpackNotifierStringField(&json, &settings, "broker_url", "brokerUrl")
unpackNotifierStringField(&json, &settings, "topic", "topic")
unpackNotifierStringField(&json, &settings, "client_id", "clientId")
unpackNotifierStringField(&json, &settings, "message_format", "messageFormat")
unpackNotifierStringField(&json, &settings, "username", "username")
unpackNotifierStringField(&json, &settings, "password", "password")
if v, ok := json["insecure_skip_verify"]; ok && v != nil {
settings["insecureSkipVerify"] = v.(bool)
}

return &models.EmbeddedContactPoint{
UID: uid,
Name: name,
Type: common.Ref(o.meta().typeStr),
DisableResolveMessage: disableResolve,
Settings: settings,
}
}

type oncallNotifier struct {
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,15 @@ func TestAccContactPoint_notifiers(t *testing.T) {
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "line.0.token", "token"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "line.0.title", "title"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "line.0.description", "description"),
// mqtt
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.#", "1"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.broker_url", "*broker_url"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.topic", "*topic"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.client_id", "client_id"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.message_format", "json"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.username", "username"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.password", "password"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "mqtt.0.insecure_skip_verify", "true"),
// opsgenie
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "opsgenie.#", "1"),
resource.TestCheckResourceAttr("grafana_contact_point.receiver_types", "opsgenie.0.url", "http://opsgenie-api"),
Expand Down

0 comments on commit d5ebbb8

Please sign in to comment.