provider/datadog add 'require full window' and 'locked' (#6738)

* provider/datadog Update go-datadog-api.

* provider/datadog Add support for "require_full_window" and "locked".

* provider/datadog Update tests, update doco, gofmt.

* provider/datadog Add options to update resource.

* provider/datadog "require_full_window" defaults to True, "locked" to False. Use
those initial values as the starting configuration.

* provider/datadog Update notify_audit tests to use the default value for
testAccCheckDatadogMonitorConfig and a custom value for
testAccCheckDatadogMonitorConfigUpdated.

This catches a situation where the code ignores setting the option on creation,
and the update function merely asserts the default value, versus actually changing
the value.
This commit is contained in:
Otto Jongerius 2016-05-19 18:29:23 +10:00 committed by Paul Stack
parent 55583baa7e
commit dc7a7219bf
14 changed files with 1453 additions and 20 deletions

2
Godeps/Godeps.json generated
View File

@ -1360,7 +1360,7 @@
},
{
"ImportPath": "github.com/zorkian/go-datadog-api",
"Rev": "632146c79714fe4232b496087802f922c1daf96f"
"Rev": "af9919d4fd020eba6daada1cbba9310f5d7b44a8"
},
{
"ImportPath": "golang.org/x/crypto/curve25519",

View File

@ -92,6 +92,14 @@ func resourceDatadogMonitor() *schema.Resource {
Type: schema.TypeInt,
Optional: true,
},
"require_full_window": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
"locked": &schema.Schema{
Type: schema.TypeBool,
Optional: true,
},
// TODO should actually be map[string]int
"silenced": &schema.Schema{
Type: schema.TypeMap,
@ -156,6 +164,12 @@ func buildMonitorStruct(d *schema.ResourceData) *datadog.Monitor {
if attr, ok := d.GetOk("include_tags"); ok {
o.IncludeTags = attr.(bool)
}
if attr, ok := d.GetOk("require_full_window"); ok {
o.RequireFullWindow = attr.(bool)
}
if attr, ok := d.GetOk("locked"); ok {
o.Locked = attr.(bool)
}
m := datadog.Monitor{
Type: d.Get("type").(string),
@ -230,6 +244,8 @@ func resourceDatadogMonitorRead(d *schema.ResourceData, meta interface{}) error
d.Set("escalation_message", m.Options.EscalationMessage)
d.Set("silenced", m.Options.Silenced)
d.Set("include_tags", m.Options.IncludeTags)
d.Set("require_full_window", m.Options.RequireFullWindow)
d.Set("locked", m.Options.Locked)
return nil
}
@ -298,6 +314,12 @@ func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) erro
if attr, ok := d.GetOk("include_tags"); ok {
o.IncludeTags = attr.(bool)
}
if attr, ok := d.GetOk("require_full_window"); ok {
o.RequireFullWindow = attr.(bool)
}
if attr, ok := d.GetOk("locked"); ok {
o.Locked = attr.(bool)
}
m.Options = o

View File

@ -30,7 +30,7 @@ func TestAccDatadogMonitor_Basic(t *testing.T) {
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "query", "avg(last_1h):avg:aws.ec2.cpu{environment:foo,host:foo} by {host} > 2"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "notify_no_data", "false"),
"datadog_monitor.foo", "notify_no_data", "true"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "renotify_interval", "60"),
resource.TestCheckResourceAttr(
@ -39,6 +39,10 @@ func TestAccDatadogMonitor_Basic(t *testing.T) {
"datadog_monitor.foo", "thresholds.warning", "1"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "thresholds.critical", "2"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "require_full_window", "true"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "locked", "false"),
),
},
},
@ -66,7 +70,7 @@ func TestAccDatadogMonitor_Updated(t *testing.T) {
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "type", "metric alert"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "notify_no_data", "false"),
"datadog_monitor.foo", "notify_no_data", "true"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "renotify_interval", "60"),
resource.TestCheckResourceAttr(
@ -81,6 +85,10 @@ func TestAccDatadogMonitor_Updated(t *testing.T) {
"datadog_monitor.foo", "timeout_h", "60"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "include_tags", "true"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "require_full_window", "true"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "locked", "false"),
),
},
resource.TestStep{
@ -98,7 +106,7 @@ func TestAccDatadogMonitor_Updated(t *testing.T) {
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "type", "metric alert"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "notify_no_data", "true"),
"datadog_monitor.foo", "notify_no_data", "false"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "renotify_interval", "40"),
resource.TestCheckResourceAttr(
@ -115,6 +123,10 @@ func TestAccDatadogMonitor_Updated(t *testing.T) {
"datadog_monitor.foo", "include_tags", "false"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "silenced.*", "0"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "require_full_window", "false"),
resource.TestCheckResourceAttr(
"datadog_monitor.foo", "locked", "true"),
),
},
},
@ -189,12 +201,14 @@ resource "datadog_monitor" "foo" {
critical = 2
}
notify_no_data = false
notify_no_data = true
renotify_interval = 60
notify_audit = false
timeout_h = 60
include_tags = true
require_full_window = true
locked = false
}
`
@ -213,12 +227,14 @@ resource "datadog_monitor" "foo" {
critical = 3
}
notify_no_data = true
notify_no_data = false
renotify_interval = 40
escalation_message = "the situation has escalated! @pagerduty"
notify_audit = true
timeout_h = 70
include_tags = false
require_full_window = false
locked = true
silenced {
"*" = 0
}

View File

@ -1,8 +1,8 @@
language: go
go:
- 1.4
- 1.5
- 1.6
- tip
env:

25
vendor/github.com/zorkian/go-datadog-api/checks.go generated vendored Normal file
View File

@ -0,0 +1,25 @@
package datadog
type Check struct {
Check string `json:"check"`
HostName string `json:"host_name"`
Status status `json:"status"`
Timestamp string `json:"timestamp,omitempty"`
Message string `json:"message,omitempty"`
Tags []string `json:"tags,omitempty"`
}
type status int
const (
OK status = iota
WARNING
CRITICAL
UNKNOWN
)
// PostCheck posts the result of a check run to the server
func (client *Client) PostCheck(check Check) error {
return client.doJsonRequest("POST", "/v1/check_run",
check, nil)
}

View File

@ -0,0 +1,22 @@
package datadog_test
import (
"testing"
"github.com/zorkian/go-datadog-api"
)
func TestCheckStatus(T *testing.T) {
if datadog.OK != 0 {
T.Error("status OK must be 0 to satisfy Datadog's API")
}
if datadog.WARNING != 1 {
T.Error("status WARNING must be 1 to satisfy Datadog's API")
}
if datadog.CRITICAL != 2 {
T.Error("status CRITICAL must be 2 to satisfy Datadog's API")
}
if datadog.UNKNOWN != 3 {
T.Error("status UNKNOWN must be 3 to satisfy Datadog's API")
}
}

View File

@ -0,0 +1,138 @@
package integration
import (
"github.com/zorkian/go-datadog-api"
"testing"
)
func init() {
client = initTest()
}
func TestCreateAndDeleteDashboard(t *testing.T) {
expected := getTestDashboard()
// create the dashboard and compare it
actual, err := client.CreateDashboard(expected)
if err != nil {
t.Fatalf("Creating a dashboard failed when it shouldn't. (%s)", err)
}
defer cleanUpDashboard(t, actual.Id)
assertDashboardEquals(t, actual, expected)
// now try to fetch it freshly and compare it again
actual, err = client.GetDashboard(actual.Id)
if err != nil {
t.Fatalf("Retrieving a dashboard failed when it shouldn't. (%s)", err)
}
assertDashboardEquals(t, actual, expected)
}
func TestUpdateDashboard(t *testing.T) {
expected := getTestDashboard()
board, err := client.CreateDashboard(expected)
if err != nil {
t.Fatalf("Creating a dashboard failed when it shouldn't. (%s)", err)
}
defer cleanUpDashboard(t, board.Id)
board.Title = "___New-Test-Board___"
if err := client.UpdateDashboard(board); err != nil {
t.Fatalf("Updating a dashboard failed when it shouldn't: %s", err)
}
actual, err := client.GetDashboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a dashboard failed when it shouldn't: %s", err)
}
assertDashboardEquals(t, actual, board)
}
func TestGetDashboards(t *testing.T) {
boards, err := client.GetDashboards()
if err != nil {
t.Fatalf("Retrieving dashboards failed when it shouldn't: %s", err)
}
num := len(boards)
board := createTestDashboard(t)
defer cleanUpDashboard(t, board.Id)
boards, err = client.GetDashboards()
if err != nil {
t.Fatalf("Retrieving dashboards failed when it shouldn't: %s", err)
}
if num+1 != len(boards) {
t.Fatalf("Number of dashboards didn't match expected: %d != %d", len(boards), num+1)
}
}
func getTestDashboard() *datadog.Dashboard {
return &datadog.Dashboard{
Title: "___Test-Board___",
Description: "Testboard description",
TemplateVariables: []datadog.TemplateVariable{},
Graphs: createGraph(),
}
}
func createTestDashboard(t *testing.T) *datadog.Dashboard {
board := getTestDashboard()
board, err := client.CreateDashboard(board)
if err != nil {
t.Fatalf("Creating a dashboard failed when it shouldn't: %s", err)
}
return board
}
func cleanUpDashboard(t *testing.T, id int) {
if err := client.DeleteDashboard(id); err != nil {
t.Fatalf("Deleting a dashboard failed when it shouldn't. Manual cleanup needed. (%s)", err)
}
deletedBoard, err := client.GetDashboard(id)
if deletedBoard != nil {
t.Fatal("Dashboard hasn't been deleted when it should have been. Manual cleanup needed.")
}
if err == nil {
t.Fatal("Fetching deleted dashboard didn't lead to an error. Manual cleanup needed.")
}
}
type TestGraphDefintionRequests struct {
Query string `json:"q"`
Stacked bool `json:"stacked"`
}
func createGraph() []datadog.Graph {
graphDefinition := datadog.Graph{}.Definition
graphDefinition.Viz = "timeseries"
r := datadog.Graph{}.Definition.Requests
graphDefinition.Requests = append(r, TestGraphDefintionRequests{Query: "avg:system.mem.free{*}", Stacked: false})
graph := datadog.Graph{Title: "Mandatory graph", Definition: graphDefinition}
graphs := []datadog.Graph{}
graphs = append(graphs, graph)
return graphs
}
func assertDashboardEquals(t *testing.T, actual, expected *datadog.Dashboard) {
if actual.Title != expected.Title {
t.Errorf("Dashboard title does not match: %s != %s", actual.Title, expected.Title)
}
if actual.Description != expected.Description {
t.Errorf("Dashboard description does not match: %s != %s", actual.Description, expected.Description)
}
if len(actual.Graphs) != len(expected.Graphs) {
t.Errorf("Number of Dashboard graphs does not match: %d != %d", len(actual.Graphs), len(expected.Graphs))
}
if len(actual.TemplateVariables) != len(expected.TemplateVariables) {
t.Errorf("Number of Dashboard template variables does not match: %d != %d", len(actual.TemplateVariables), len(expected.TemplateVariables))
}
}

View File

@ -0,0 +1,110 @@
package integration
import (
"github.com/stretchr/testify/assert"
"github.com/zorkian/go-datadog-api"
"testing"
)
func init() {
client = initTest()
}
func TestCreateAndDeleteDowntime(t *testing.T) {
expected := getTestDowntime()
// create the downtime and compare it
actual := createTestDowntime(t)
defer cleanUpDowntime(t, actual.Id)
// Set ID of our original struct to zero we we can easily compare the results
expected.Id = actual.Id
assert.Equal(t, expected, actual)
actual, err := client.GetDowntime(actual.Id)
if err != nil {
t.Fatalf("Retrieving a downtime failed when it shouldn't: (%s)", err)
}
assert.Equal(t, expected, actual)
}
func TestUpdateDowntime(t *testing.T) {
downtime := createTestDowntime(t)
downtime.Scope = []string{"env:downtime_test", "env:downtime_test2"}
defer cleanUpDowntime(t, downtime.Id)
if err := client.UpdateDowntime(downtime); err != nil {
t.Fatalf("Updating a downtime failed when it shouldn't: %s", err)
}
actual, err := client.GetDowntime(downtime.Id)
if err != nil {
t.Fatalf("Retrieving a downtime failed when it shouldn't: %s", err)
}
assert.Equal(t, downtime, actual)
}
func TestGetDowntime(t *testing.T) {
downtimes, err := client.GetDowntimes()
if err != nil {
t.Fatalf("Retrieving downtimes failed when it shouldn't: %s", err)
}
num := len(downtimes)
downtime := createTestDowntime(t)
defer cleanUpDowntime(t, downtime.Id)
downtimes, err = client.GetDowntimes()
if err != nil {
t.Fatalf("Retrieving downtimes failed when it shouldn't: %s", err)
}
if num+1 != len(downtimes) {
t.Fatalf("Number of downtimes didn't match expected: %d != %d", len(downtimes), num+1)
}
}
func getTestDowntime() *datadog.Downtime {
r := &datadog.Recurrence{
Type: "weeks",
Period: 1,
WeekDays: []string{"Mon", "Tue", "Wed", "Thu", "Fri"},
}
return &datadog.Downtime{
Message: "Test downtime message",
Scope: []string{"env:downtime_test"},
Start: 1577836800,
End: 1577840400,
Recurrence: r,
}
}
func createTestDowntime(t *testing.T) *datadog.Downtime {
downtime := getTestDowntime()
downtime, err := client.CreateDowntime(downtime)
if err != nil {
t.Fatalf("Creating a downtime failed when it shouldn't: %s", err)
}
return downtime
}
func cleanUpDowntime(t *testing.T, id int) {
if err := client.DeleteDowntime(id); err != nil {
t.Fatalf("Deleting a downtime failed when it shouldn't. Manual cleanup needed. (%s)", err)
}
deletedDowntime, err := client.GetDowntime(id)
if deletedDowntime != nil && deletedDowntime.Canceled == 0 {
t.Fatal("Downtime hasn't been deleted when it should have been. Manual cleanup needed.")
}
if err == nil && deletedDowntime.Canceled == 0 {
t.Fatal("Fetching deleted downtime didn't lead to an error and downtime Canceled not set.")
}
}

View File

@ -0,0 +1,152 @@
package integration
import (
"github.com/stretchr/testify/assert"
"github.com/zorkian/go-datadog-api"
"testing"
)
func init() {
client = initTest()
}
func TestCreateAndDeleteMonitor(t *testing.T) {
expected := getTestMonitor()
// create the monitor and compare it
actual := createTestMonitor(t)
defer cleanUpMonitor(t, actual.Id)
// Set ID of our original struct to zero we we can easily compare the results
expected.Id = actual.Id
assert.Equal(t, expected, actual)
actual, err := client.GetMonitor(actual.Id)
if err != nil {
t.Fatalf("Retrieving a monitor failed when it shouldn't: (%s)", err)
}
assert.Equal(t, expected, actual)
}
func TestUpdateMonitor(t *testing.T) {
monitor := createTestMonitor(t)
defer cleanUpMonitor(t, monitor.Id)
monitor.Name = "___New-Test-Monitor___"
if err := client.UpdateMonitor(monitor); err != nil {
t.Fatalf("Updating a monitor failed when it shouldn't: %s", err)
}
actual, err := client.GetMonitor(monitor.Id)
if err != nil {
t.Fatalf("Retrieving a monitor failed when it shouldn't: %s", err)
}
assert.Equal(t, monitor, actual)
}
func TestGetMonitor(t *testing.T) {
monitors, err := client.GetMonitors()
if err != nil {
t.Fatalf("Retrieving monitors failed when it shouldn't: %s", err)
}
num := len(monitors)
monitor := createTestMonitor(t)
defer cleanUpMonitor(t, monitor.Id)
monitors, err = client.GetMonitors()
if err != nil {
t.Fatalf("Retrieving monitors failed when it shouldn't: %s", err)
}
if num+1 != len(monitors) {
t.Fatalf("Number of monitors didn't match expected: %d != %d", len(monitors), num+1)
}
}
func TestMuteUnmuteMonitor(t *testing.T) {
monitor := createTestMonitor(t)
defer cleanUpMonitor(t, monitor.Id)
// Mute
err := client.MuteMonitor(monitor.Id)
if err != nil {
t.Fatalf("Failed to mute monitor")
}
monitor, err = client.GetMonitor(monitor.Id)
if err != nil {
t.Fatalf("Retrieving monitors failed when it shouldn't: %s", err)
}
// Mute without options will result in monitor.Options.Silenced
// to have a key of "*" with value 0
assert.Equal(t, 0, monitor.Options.Silenced["*"])
// Unmute
err = client.UnmuteMonitor(monitor.Id)
if err != nil {
t.Fatalf("Failed to unmute monitor")
}
// Update remote state
monitor, err = client.GetMonitor(monitor.Id)
if err != nil {
t.Fatalf("Retrieving monitors failed when it shouldn't: %s", err)
}
// Assert this map is empty
assert.Equal(t, 0, len(monitor.Options.Silenced))
}
/*
Testing of global mute and unmuting has not been added for following reasons:
* Disabling and enabling of global monitoring does an @all mention which is noisy
* It exposes risk to users that run integration tests in their main account
* There is no endpoint to verify success
*/
func getTestMonitor() *datadog.Monitor {
o := datadog.Options{
NotifyNoData: true,
NoDataTimeframe: 60,
Silenced: map[string]int{},
}
return &datadog.Monitor{
Message: "Test message",
Query: "avg(last_15m):avg:system.disk.in_use{*} by {host,device} > 0.8",
Name: "Test monitor",
Options: o,
Type: "metric alert",
}
}
func createTestMonitor(t *testing.T) *datadog.Monitor {
monitor := getTestMonitor()
monitor, err := client.CreateMonitor(monitor)
if err != nil {
t.Fatalf("Creating a monitor failed when it shouldn't: %s", err)
}
return monitor
}
func cleanUpMonitor(t *testing.T, id int) {
if err := client.DeleteMonitor(id); err != nil {
t.Fatalf("Deleting a monitor failed when it shouldn't. Manual cleanup needed. (%s)", err)
}
deletedMonitor, err := client.GetMonitor(id)
if deletedMonitor != nil {
t.Fatal("Monitor hasn't been deleted when it should have been. Manual cleanup needed.")
}
if err == nil {
t.Fatal("Fetching deleted monitor didn't lead to an error.")
}
}

View File

@ -0,0 +1,766 @@
package integration
import (
"testing"
"github.com/zorkian/go-datadog-api"
)
func TestAlertValueWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.AlertValueWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.TextSize = "auto"
expected.Precision = 2
expected.AlertId = 1
expected.Type = "alert_value"
expected.Unit = "auto"
expected.AddTimeframe = false
w := datadog.Widget{AlertValueWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].AlertValueWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "text_size", actualWidget.TextSize, expected.TextSize)
assertEquals(t, "precision", actualWidget.Precision, expected.Precision)
assertEquals(t, "alert_id", actualWidget.AlertId, expected.AlertId)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "unit", actualWidget.Unit, expected.Unit)
assertEquals(t, "add_timeframe", actualWidget.AddTimeframe, expected.AddTimeframe)
}
func TestChangeWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.ChangeWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.Aggregator = "min"
expected.TileDef = datadog.TileDef{}
w := datadog.Widget{ChangeWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].ChangeWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "aggregator", actualWidget.Aggregator, expected.Aggregator)
assertTileDefEquals(t, actualWidget.TileDef, expected.TileDef)
}
func TestGraphWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.GraphWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.Timeframe = "1d"
expected.Type = "alert_graph"
expected.Legend = true
expected.LegendSize = 5
expected.TileDef = datadog.TileDef{}
w := datadog.Widget{GraphWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].GraphWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "timeframe", actualWidget.Timeframe, expected.Timeframe)
assertEquals(t, "legend", actualWidget.Legend, expected.Legend)
assertEquals(t, "legend_size", actualWidget.LegendSize, expected.LegendSize)
assertTileDefEquals(t, actualWidget.TileDef, expected.TileDef)
}
func TestEventTimelineWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.EventTimelineWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.Query = "avg:system.load.1{foo} by {bar}"
expected.Timeframe = "1d"
expected.Type = "alert_graph"
w := datadog.Widget{EventTimelineWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].EventTimelineWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "query", actualWidget.Query, expected.Query)
assertEquals(t, "timeframe", actualWidget.Timeframe, expected.Timeframe)
}
func TestAlertGraphWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.AlertGraphWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.VizType = ""
expected.Timeframe = "1d"
expected.AddTimeframe = false
expected.AlertId = 1
expected.Type = "alert_graph"
w := datadog.Widget{AlertGraphWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].AlertGraphWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "viz_type", actualWidget.VizType, expected.VizType)
assertEquals(t, "timeframe", actualWidget.Timeframe, expected.Timeframe)
assertEquals(t, "add_timeframe", actualWidget.AddTimeframe, expected.AddTimeframe)
assertEquals(t, "alert_id", actualWidget.AlertId, expected.AlertId)
}
func TestHostMapWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.HostMapWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.Type = "check_status"
expected.Query = "avg:system.load.1{foo} by {bar}"
expected.Timeframe = "1d"
expected.Legend = true
expected.LegendSize = 5
expected.TileDef = datadog.TileDef{}
w := datadog.Widget{HostMapWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].HostMapWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "query", actualWidget.Query, expected.Query)
assertEquals(t, "timeframe", actualWidget.Timeframe, expected.Timeframe)
assertEquals(t, "query", actualWidget.Query, expected.Query)
assertEquals(t, "legend", actualWidget.Legend, expected.Legend)
assertEquals(t, "legend_size", actualWidget.LegendSize, expected.LegendSize)
assertTileDefEquals(t, actualWidget.TileDef, expected.TileDef)
}
func TestCheckStatusWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.CheckStatusWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.Type = "check_status"
expected.Tags = "foo"
expected.Timeframe = "1d"
expected.Timeframe = "1d"
expected.Check = "datadog.agent.up"
expected.Group = "foo"
expected.Grouping = "check"
w := datadog.Widget{CheckStatusWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].CheckStatusWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "tags", actualWidget.Tags, expected.Tags)
assertEquals(t, "timeframe", actualWidget.Timeframe, expected.Timeframe)
assertEquals(t, "check", actualWidget.Check, expected.Check)
assertEquals(t, "group", actualWidget.Group, expected.Group)
assertEquals(t, "grouping", actualWidget.Grouping, expected.Grouping)
}
func TestIFrameWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.IFrameWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.Url = "http://www.example.com"
expected.Type = "iframe"
w := datadog.Widget{IFrameWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].IFrameWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "url", actualWidget.Url, expected.Url)
assertEquals(t, "type", actualWidget.Type, expected.Type)
}
func TestNoteWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.NoteWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.TitleText = "foo"
expected.TitleAlign = "center"
expected.TitleSize = 1
expected.Title = true
expected.Color = "green"
expected.FontSize = 5
expected.RefreshEvery = 60
expected.TickPos = "foo"
expected.TickEdge = "bar"
expected.Html = "<strong>baz</strong>"
expected.Tick = false
expected.Note = "quz"
expected.AutoRefresh = false
w := datadog.Widget{NoteWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].NoteWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "color", actualWidget.Color, expected.Color)
assertEquals(t, "front_size", actualWidget.FontSize, expected.FontSize)
assertEquals(t, "refresh_every", actualWidget.RefreshEvery, expected.RefreshEvery)
assertEquals(t, "tick_pos", actualWidget.TickPos, expected.TickPos)
assertEquals(t, "tick_edge", actualWidget.TickEdge, expected.TickEdge)
assertEquals(t, "tick", actualWidget.Tick, expected.Tick)
assertEquals(t, "html", actualWidget.Html, expected.Html)
assertEquals(t, "note", actualWidget.Note, expected.Note)
assertEquals(t, "auto_refresh", actualWidget.AutoRefresh, expected.AutoRefresh)
}
func TestToplistWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.ToplistWidget
expected.X = 1
expected.Y = 1
expected.Width = 5
expected.Height = 5
expected.Type = "toplist"
expected.TitleText = "foo"
expected.TitleSize.Auto = false
expected.TitleSize.Size = 5
expected.TitleAlign = "center"
expected.Title = false
expected.Timeframe = "5m"
expected.Legend = false
expected.LegendSize = 5
w := datadog.Widget{ToplistWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].ToplistWidget
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "legend", actualWidget.Legend, expected.Legend)
assertEquals(t, "legend_size", actualWidget.LegendSize, expected.LegendSize)
}
func TestEventSteamWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.EventStreamWidget
expected.EventSize = "1"
expected.Width = 1
expected.Height = 1
expected.X = 1
expected.Y = 1
expected.Query = "foo"
expected.Timeframe = "5w"
expected.Title = false
expected.TitleAlign = "center"
expected.TitleSize.Auto = false
expected.TitleSize.Size = 5
expected.TitleText = "bar"
expected.Type = "baz"
w := datadog.Widget{EventStreamWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].EventStreamWidget
assertEquals(t, "event_size", actualWidget.EventSize, expected.EventSize)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "query", actualWidget.Query, expected.Query)
assertEquals(t, "timeframe", actualWidget.Timeframe, expected.Timeframe)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "type", actualWidget.Type, expected.Type)
}
func TestImageWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.ImageWidget
expected.Width = 1
expected.Height = 1
expected.X = 1
expected.Y = 1
expected.Title = false
expected.TitleAlign = "center"
expected.TitleSize.Auto = false
expected.TitleSize.Size = 5
expected.TitleText = "bar"
expected.Type = "baz"
expected.Url = "qux"
expected.Sizing = "quuz"
w := datadog.Widget{ImageWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].ImageWidget
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "title_align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title_size", actualWidget.TitleSize, expected.TitleSize)
assertEquals(t, "title_text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "url", actualWidget.Url, expected.Url)
assertEquals(t, "sizing", actualWidget.Sizing, expected.Sizing)
}
func TestFreeTextWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.FreeTextWidget
expected.X = 1
expected.Y = 1
expected.Height = 10
expected.Width = 10
expected.Text = "Test"
expected.FontSize = "16"
expected.TextAlign = "center"
w := datadog.Widget{FreeTextWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].FreeTextWidget
assertEquals(t, "font-size", actualWidget.FontSize, expected.FontSize)
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "text", actualWidget.Text, expected.Text)
assertEquals(t, "text-align", actualWidget.TextAlign, expected.TextAlign)
assertEquals(t, "type", actualWidget.Type, expected.Type)
}
func TestTimeseriesWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.TimeseriesWidget
expected.X = 1
expected.Y = 1
expected.Width = 20
expected.Height = 30
expected.Title = true
expected.TitleAlign = "centre"
expected.TitleSize = datadog.TextSize{Size: 16}
expected.TitleText = "Test"
expected.Timeframe = "1m"
w := datadog.Widget{TimeseriesWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].TimeseriesWidget
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "title-align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title-size.size", actualWidget.TitleSize.Size, expected.TitleSize.Size)
assertEquals(t, "title-size.auto", actualWidget.TitleSize.Auto, expected.TitleSize.Auto)
assertEquals(t, "title-text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "timeframe", actualWidget.Timeframe, expected.Timeframe)
assertEquals(t, "legend", actualWidget.Legend, expected.Legend)
assertTileDefEquals(t, actualWidget.TileDef, expected.TileDef)
}
func TestQueryValueWidget(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
expected := datadog.Widget{}.QueryValueWidget
expected.X = 1
expected.Y = 1
expected.Width = 20
expected.Height = 30
expected.Title = true
expected.TitleAlign = "centre"
expected.TitleSize = datadog.TextSize{Size: 16}
expected.TitleText = "Test"
expected.Timeframe = "1m"
expected.TimeframeAggregator = "sum"
expected.Aggregator = "min"
expected.Query = "docker.containers.running"
expected.MetricType = "standard"
/* TODO: add test for conditional formats
"conditional_formats": [{
"comparator": ">",
"color": "white_on_red",
"custom_bg_color": null,
"value": 1,
"invert": false,
"custom_fg_color": null}],
*/
expected.IsValidQuery = true
expected.ResultCalcFunc = "raw"
expected.Aggregator = "avg"
expected.CalcFunc = "raw"
w := datadog.Widget{QueryValueWidget: expected}
board.Widgets = append(board.Widgets, w)
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed: %s", err)
}
actualWidget := actual.Widgets[0].QueryValueWidget
assertEquals(t, "height", actualWidget.Height, expected.Height)
assertEquals(t, "width", actualWidget.Width, expected.Width)
assertEquals(t, "x", actualWidget.X, expected.X)
assertEquals(t, "y", actualWidget.Y, expected.Y)
assertEquals(t, "title", actualWidget.Title, expected.Title)
assertEquals(t, "title-align", actualWidget.TitleAlign, expected.TitleAlign)
assertEquals(t, "title-size.size", actualWidget.TitleSize.Size, expected.TitleSize.Size)
assertEquals(t, "title-size.auto", actualWidget.TitleSize.Auto, expected.TitleSize.Auto)
assertEquals(t, "title-text", actualWidget.TitleText, expected.TitleText)
assertEquals(t, "type", actualWidget.Type, expected.Type)
assertEquals(t, "timeframe", actualWidget.Timeframe, expected.Timeframe)
assertEquals(t, "timeframe-aggregator", actualWidget.TimeframeAggregator, expected.TimeframeAggregator)
assertEquals(t, "aggregator", actualWidget.Aggregator, expected.Aggregator)
assertEquals(t, "query", actualWidget.Query, expected.Query)
assertEquals(t, "is_valid_query", actualWidget.IsValidQuery, expected.IsValidQuery)
assertEquals(t, "res_calc_func", actualWidget.ResultCalcFunc, expected.ResultCalcFunc)
assertEquals(t, "aggr", actualWidget.Aggregator, expected.Aggregator)
}
func assertTileDefEquals(t *testing.T, actual datadog.TileDef, expected datadog.TileDef) {
assertEquals(t, "num-events", len(actual.Events), len(expected.Events))
assertEquals(t, "num-requests", len(actual.Requests), len(expected.Requests))
assertEquals(t, "viz", actual.Viz, expected.Viz)
for i, event := range actual.Events {
assertEquals(t, "event-query", event.Query, expected.Events[i].Query)
}
for i, request := range actual.Requests {
assertEquals(t, "request-query", request.Query, expected.Requests[i].Query)
assertEquals(t, "request-type", request.Type, expected.Requests[i].Type)
}
}
func assertEquals(t *testing.T, attribute string, a, b interface{}) {
if a != b {
t.Errorf("The two %s values '%v' and '%v' are not equal", attribute, a, b)
}
}

View File

@ -0,0 +1,143 @@
package integration
import (
"github.com/zorkian/go-datadog-api"
"testing"
)
func init() {
client = initTest()
}
func TestCreateAndDeleteScreenboard(t *testing.T) {
expected := getTestScreenboard()
// create the screenboard and compare it
actual, err := client.CreateScreenboard(expected)
if err != nil {
t.Fatalf("Creating a screenboard failed when it shouldn't. (%s)", err)
}
defer cleanUpScreenboard(t, actual.Id)
assertScreenboardEquals(t, actual, expected)
// now try to fetch it freshly and compare it again
actual, err = client.GetScreenboard(actual.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed when it shouldn't. (%s)", err)
}
assertScreenboardEquals(t, actual, expected)
}
func TestShareAndRevokeScreenboard(t *testing.T) {
expected := getTestScreenboard()
// create the screenboard
actual, err := client.CreateScreenboard(expected)
if err != nil {
t.Fatalf("Creating a screenboard failed when it shouldn't: %s", err)
}
defer cleanUpScreenboard(t, actual.Id)
// share screenboard and verify it was shared
var response datadog.ScreenShareResponse
err = client.ShareScreenboard(actual.Id, &response)
if err != nil {
t.Fatalf("Failed to share screenboard: %s", err)
}
// revoke screenboard
err = client.RevokeScreenboard(actual.Id)
if err != nil {
t.Fatalf("Failed to revoke sharing of screenboard: %s", err)
}
}
func TestUpdateScreenboard(t *testing.T) {
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
board.Title = "___New-Test-Board___"
if err := client.UpdateScreenboard(board); err != nil {
t.Fatalf("Updating a screenboard failed when it shouldn't: %s", err)
}
actual, err := client.GetScreenboard(board.Id)
if err != nil {
t.Fatalf("Retrieving a screenboard failed when it shouldn't: %s", err)
}
assertScreenboardEquals(t, actual, board)
}
func TestGetScreenboards(t *testing.T) {
boards, err := client.GetScreenboards()
if err != nil {
t.Fatalf("Retrieving screenboards failed when it shouldn't: %s", err)
}
num := len(boards)
board := createTestScreenboard(t)
defer cleanUpScreenboard(t, board.Id)
boards, err = client.GetScreenboards()
if err != nil {
t.Fatalf("Retrieving screenboards failed when it shouldn't: %s", err)
}
if num+1 != len(boards) {
t.Fatalf("Number of screenboards didn't match expected: %d != %d", len(boards), num+1)
}
}
func getTestScreenboard() *datadog.Screenboard {
return &datadog.Screenboard{
Title: "___Test-Board___",
Height: "600",
Width: "800",
Widgets: []datadog.Widget{},
}
}
func createTestScreenboard(t *testing.T) *datadog.Screenboard {
board := getTestScreenboard()
board, err := client.CreateScreenboard(board)
if err != nil {
t.Fatalf("Creating a screenboard failed when it shouldn't: %s", err)
}
return board
}
func cleanUpScreenboard(t *testing.T, id int) {
if err := client.DeleteScreenboard(id); err != nil {
t.Fatalf("Deleting a screenboard failed when it shouldn't. Manual cleanup needed. (%s)", err)
}
deletedBoard, err := client.GetScreenboard(id)
if deletedBoard != nil {
t.Fatal("Screenboard hasn't been deleted when it should have been. Manual cleanup needed.")
}
if err == nil {
t.Fatal("Fetching deleted screenboard didn't lead to an error. Manual cleanup needed.")
}
}
func assertScreenboardEquals(t *testing.T, actual, expected *datadog.Screenboard) {
if actual.Title != expected.Title {
t.Errorf("Screenboard title does not match: %s != %s", actual.Title, expected.Title)
}
if actual.Width != expected.Width {
t.Errorf("Screenboard width does not match: %s != %s", actual.Width, expected.Width)
}
if actual.Height != expected.Height {
t.Errorf("Screenboard width does not match: %s != %s", actual.Height, expected.Height)
}
if len(actual.Widgets) != len(expected.Widgets) {
t.Errorf("Number of Screenboard widgets does not match: %d != %d", len(actual.Widgets), len(expected.Widgets))
}
}

View File

@ -0,0 +1,24 @@
package integration
import (
"github.com/zorkian/go-datadog-api"
"log"
"os"
)
var (
apiKey string
appKey string
client *datadog.Client
)
func initTest() *datadog.Client {
apiKey = os.Getenv("DATADOG_API_KEY")
appKey = os.Getenv("DATADOG_APP_KEY")
if apiKey == "" || appKey == "" {
log.Fatal("Please make sure to set the env variables 'DATADOG_API_KEY' and 'DATADOG_APP_KEY' before running this test")
}
return datadog.NewClient(apiKey, appKey)
}

View File

@ -29,11 +29,14 @@ type Options struct {
EscalationMessage string `json:"escalation_message,omitempty"`
Thresholds ThresholdCount `json:"thresholds,omitempty"`
IncludeTags bool `json:"include_tags,omitempty"`
RequireFullWindow bool `json:"require_full_window,omitempty"`
Locked bool `json:"locked,omitempty"`
}
//Monitors allow you to watch a metric or check that you care about,
//notifying your team when some defined threshold is exceeded.
// Monitor allows watching a metric or check that you care about,
// notifying your team when some defined threshold is exceeded
type Monitor struct {
Creator Creator `json:"creator,omitempty"`
Id int `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Query string `json:"query,omitempty"`
@ -43,13 +46,21 @@ type Monitor struct {
Options Options `json:"options,omitempty"`
}
// Creator contains the creator of the monitor
type Creator struct {
Email string `json:"email,omitempty"`
Handle string `json:"handle,omitempty"`
Id int `json:"id,omitempty"`
Name string `json:"name,omitempty"`
}
// reqMonitors receives a slice of all monitors
type reqMonitors struct {
Monitors []Monitor `json:"monitors,omitempty"`
}
// Createmonitor adds a new monitor to the system. This returns a pointer to an
// monitor so you can pass that to Updatemonitor later if needed.
// CreateMonitor adds a new monitor to the system. This returns a pointer to a
// monitor so you can pass that to UpdateMonitor later if needed
func (self *Client) CreateMonitor(monitor *Monitor) (*Monitor, error) {
var out Monitor
err := self.doJsonRequest("POST", "/v1/monitor", monitor, &out)
@ -59,14 +70,14 @@ func (self *Client) CreateMonitor(monitor *Monitor) (*Monitor, error) {
return &out, nil
}
// Updatemonitor takes an monitor that was previously retrieved through some method
// and sends it back to the server.
// UpdateMonitor takes a monitor that was previously retrieved through some method
// and sends it back to the server
func (self *Client) UpdateMonitor(monitor *Monitor) error {
return self.doJsonRequest("PUT", fmt.Sprintf("/v1/monitor/%d", monitor.Id),
monitor, nil)
}
// Getmonitor retrieves an monitor by identifier.
// GetMonitor retrieves a monitor by identifier
func (self *Client) GetMonitor(id int) (*Monitor, error) {
var out Monitor
err := self.doJsonRequest("GET", fmt.Sprintf("/v1/monitor/%d", id), nil, &out)
@ -76,13 +87,13 @@ func (self *Client) GetMonitor(id int) (*Monitor, error) {
return &out, nil
}
// Deletemonitor removes an monitor from the system.
// DeleteMonitor removes a monitor from the system
func (self *Client) DeleteMonitor(id int) error {
return self.doJsonRequest("DELETE", fmt.Sprintf("/v1/monitor/%d", id),
nil, nil)
}
// GetMonitors returns a slice of all monitors.
// GetMonitors returns a slice of all monitors
func (self *Client) GetMonitors() ([]Monitor, error) {
var out reqMonitors
err := self.doJsonRequest("GET", "/v1/monitor", nil, &out.Monitors)
@ -92,22 +103,22 @@ func (self *Client) GetMonitors() ([]Monitor, error) {
return out.Monitors, nil
}
// MuteMonitors turns off monitoring notifications.
// MuteMonitors turns off monitoring notifications
func (self *Client) MuteMonitors() error {
return self.doJsonRequest("POST", "/v1/monitor/mute_all", nil, nil)
}
// UnmuteMonitors turns on monitoring notifications.
// UnmuteMonitors turns on monitoring notifications
func (self *Client) UnmuteMonitors() error {
return self.doJsonRequest("POST", "/v1/monitor/unmute_all", nil, nil)
}
// MuteMonitor turns off monitoring notifications for a monitor.
// MuteMonitor turns off monitoring notifications for a monitor
func (self *Client) MuteMonitor(id int) error {
return self.doJsonRequest("POST", fmt.Sprintf("/v1/monitor/%d/mute", id), nil, nil)
}
// UnmuteMonitor turns on monitoring notifications for a monitor.
// UnmuteMonitor turns on monitoring notifications for a monitor
func (self *Client) UnmuteMonitor(id int) error {
return self.doJsonRequest("POST", fmt.Sprintf("/v1/monitor/%d/unmute", id), nil, nil)
}

View File

@ -74,6 +74,10 @@ The following arguments are supported:
* `include_tags` (Optional) A boolean indicating whether notifications from this monitor will automatically insert its
triggering tags into the title. Defaults to true.
* `silenced` (Optional) Each scope will be muted until the given POSIX timestamp or forever if the value is 0.
* `require_full_window` (Optional) A boolean indicating whether this monitor needs a full window of data before it's evaluated.
We highly recommend you set this to False for sparse metrics, otherwise some evaluations will be skipped.
Default: True for "on average", "at all times" and "in total" aggregation. False otherwise.
* `locked` (Optional) A boolean indicating whether changes to to this monitor should be restricted to the creator or admins. Defaults to False.
To mute the alert completely: