Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

Alerting: Add support for Unified Alerting contact points, deprecate legacy notifiers #86

Merged
merged 5 commits into from
Jun 16, 2022
Merged
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
74 changes: 74 additions & 0 deletions alerting_contact_point.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package gapi

import (
"bytes"
"encoding/json"
"fmt"
)

// ContactPoint represents a Grafana Alerting contact point.
type ContactPoint struct {
UID string `json:"uid"`
Name string `json:"name"`
Type string `json:"type"`
Settings map[string]interface{} `json:"settings"`
DisableResolveMessage bool `json:"disableResolveMessage"`
Provenance string `json:"provenance"`
}

// ContactPoints fetches all contact points.
func (c *Client) ContactPoints() ([]ContactPoint, error) {
ps := make([]ContactPoint, 0)
err := c.request("GET", "/api/v1/provisioning/contact-points", nil, nil, &ps)
if err != nil {
return nil, err
}
return ps, nil
}

// ContactPoint fetches a single contact point, identified by its UID.
func (c *Client) ContactPoint(uid string) (ContactPoint, error) {
ps, err := c.ContactPoints()
if err != nil {
return ContactPoint{}, err
}

for _, p := range ps {
if p.UID == uid {
return p, nil
}
}
return ContactPoint{}, fmt.Errorf("contact point with uid %s not found", uid)
}

// NewContactPoint creates a new contact point.
func (c *Client) NewContactPoint(p *ContactPoint) (string, error) {
req, err := json.Marshal(p)
if err != nil {
return "", err
}
result := ContactPoint{}

err = c.request("POST", "/api/v1/provisioning/contact-points", nil, bytes.NewBuffer(req), &result)
if err != nil {
return "", err
}
return result.UID, nil
}

// UpdateContactPoint replaces a contact point, identified by contact point's UID.
func (c *Client) UpdateContactPoint(p *ContactPoint) error {
uri := fmt.Sprintf("/api/v1/provisioning/contact-points/%s", p.UID)
req, err := json.Marshal(p)
if err != nil {
return err
}

return c.request("PUT", uri, nil, bytes.NewBuffer(req), nil)
}

// DeleteContactPoint deletes a contact point.
func (c *Client) DeleteContactPoint(uid string) error {
uri := fmt.Sprintf("/api/v1/provisioning/contact-points/%s", uid)
return c.request("DELETE", uri, nil, nil, nil)
}
147 changes: 147 additions & 0 deletions alerting_contact_point_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package gapi

import (
"testing"

"github.com/gobs/pretty"
)

func TestContactPoints(t *testing.T) {
t.Run("get contact points succeeds", func(t *testing.T) {
server, client := gapiTestTools(t, 200, getContactPointsJSON)
defer server.Close()

ps, err := client.ContactPoints()

if err != nil {
t.Error(err)
}
t.Log(pretty.PrettyFormat(ps))
if len(ps) != 2 {
t.Errorf("wrong number of contact points returned, got %#v", ps)
}
if ps[0].UID != "" {
t.Errorf("incorrect UID - expected %s on element %d, got %#v", "", 0, ps)
}
if ps[1].UID != "rc5r0bjnz" {
t.Errorf("incorrect UID - expected %s on element %d, got %#v", "rc5r0bjnz", 0, ps)
}
})

t.Run("get contact point succeeds", func(t *testing.T) {
server, client := gapiTestTools(t, 200, getContactPointsJSON)
defer server.Close()

p, err := client.ContactPoint("rc5r0bjnz")

if err != nil {
t.Error(err)
}
t.Log(pretty.PrettyFormat(p))
if p.UID != "rc5r0bjnz" {
t.Errorf("incorrect UID - expected %s got %#v", "rc5r0bjnz", p)
}
})

t.Run("get non-existent contact point fails", func(t *testing.T) {
server, client := gapiTestTools(t, 200, getContactPointsJSON)
defer server.Close()

p, err := client.ContactPoint("does not exist")

if err == nil {
t.Errorf("expected error but got nil")
t.Log(pretty.PrettyFormat(p))
}
})

t.Run("create contact point succeeds", func(t *testing.T) {
server, client := gapiTestTools(t, 201, writeContactPointJSON)
defer server.Close()
p := createContactPoint()

uid, err := client.NewContactPoint(&p)

if err != nil {
t.Error(err)
}
if uid != "rc5r0bjnz" {
t.Errorf("unexpected UID returned, got %s", uid)
}
})

t.Run("update contact point succeeds", func(t *testing.T) {
server, client := gapiTestTools(t, 200, writeContactPointJSON)
defer server.Close()
p := createContactPoint()
p.UID = "on7otbj7k"

err := client.UpdateContactPoint(&p)

if err != nil {
t.Error(err)
}
})

t.Run("delete contact point succeeds", func(t *testing.T) {
server, client := gapiTestTools(t, 204, "")
defer server.Close()

err := client.DeleteContactPoint("rc5r0bjnz")

if err != nil {
t.Error(err)
}
})
}

func createContactPoint() ContactPoint {
return ContactPoint{
Name: "slack-receiver-123",
Type: "slack",
DisableResolveMessage: false,
Settings: map[string]interface{}{
"recipient": "@zxcv",
"token": "test-token",
"url": "https://test-url",
},
}
}

const getContactPointsJSON = `
[
{
"uid": "",
"name": "default-email-receiver",
"type": "email",
"disableResolveMessage": false,
"settings": {
"addresses": "<[email protected]>"
}
},
{
"uid": "rc5r0bjnz",
"name": "slack-receiver-1",
"type": "slack",
"disableResolveMessage": false,
"settings": {
"recipient": "@foo",
"token": "[REDACTED]",
"url": "[REDACTED]"
}
}
]`

const writeContactPointJSON = `
{
"uid": "rc5r0bjnz",
"name": "slack-receiver-1",
"type": "slack",
"disableResolveMessage": false,
"settings": {
"recipient": "@foo",
"token": "[REDACTED]",
"url": "[REDACTED]"
}
}
`
6 changes: 6 additions & 0 deletions alertnotification.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
)

// AlertNotification represents a Grafana alert notification.
// Deprecated: Grafana Legacy Alerting is deprecated as of 9.0 and will be removed in the future. Use ContactPoint instead.
type AlertNotification struct {
ID int64 `json:"id,omitempty"`
UID string `json:"uid"`
Expand All @@ -22,6 +23,7 @@ type AlertNotification struct {
}

// AlertNotifications fetches and returns Grafana alert notifications.
// Deprecated: Grafana Legacy Alerting is deprecated as of 9.0 and will be removed in the future. Use ContactPoints instead.
func (c *Client) AlertNotifications() ([]AlertNotification, error) {
alertnotifications := make([]AlertNotification, 0)

Expand All @@ -34,6 +36,7 @@ func (c *Client) AlertNotifications() ([]AlertNotification, error) {
}

// AlertNotification fetches and returns a Grafana alert notification.
// Deprecated: Grafana Legacy Alerting is deprecated as of 9.0 and will be removed in the future. Use ContactPoint instead.
func (c *Client) AlertNotification(id int64) (*AlertNotification, error) {
path := fmt.Sprintf("/api/alert-notifications/%d", id)
result := &AlertNotification{}
Expand All @@ -46,6 +49,7 @@ func (c *Client) AlertNotification(id int64) (*AlertNotification, error) {
}

// NewAlertNotification creates a new Grafana alert notification.
// Deprecated: Grafana Legacy Alerting is deprecated as of 9.0 and will be removed in the future. Use NewContactPoint instead.
func (c *Client) NewAlertNotification(a *AlertNotification) (int64, error) {
data, err := json.Marshal(a)
if err != nil {
Expand All @@ -64,6 +68,7 @@ func (c *Client) NewAlertNotification(a *AlertNotification) (int64, error) {
}

// UpdateAlertNotification updates a Grafana alert notification.
// Deprecated: Grafana Legacy Alerting is deprecated as of 9.0 and will be removed in the future. Use UpdateContactPoint instead.
func (c *Client) UpdateAlertNotification(a *AlertNotification) error {
path := fmt.Sprintf("/api/alert-notifications/%d", a.ID)
data, err := json.Marshal(a)
Expand All @@ -76,6 +81,7 @@ func (c *Client) UpdateAlertNotification(a *AlertNotification) error {
}

// DeleteAlertNotification deletes a Grafana alert notification.
// Deprecated: Grafana Legacy Alerting is deprecated as of 9.0 and will be removed in the future. Use DeleteContactPoint instead.
func (c *Client) DeleteAlertNotification(id int64) error {
path := fmt.Sprintf("/api/alert-notifications/%d", id)

Expand Down