provider/datadog 9869: Validate credentials when initialising client. (#10567)

* provider/datadog 9869: Validate credentials when initialising client.

* provider/datadog Pull in new version of go-datadog-api.

* provider/datadog Update testAccCheckDatadogMonitorConfigNoThresholds test config.
This commit is contained in:
Otto Jongerius 2016-12-08 21:17:42 +11:00 committed by Paul Stack
parent a33f36218e
commit 10d68d90dd
21 changed files with 235 additions and 208 deletions

View File

@ -13,11 +13,10 @@ type Config struct {
} }
// Client returns a new Datadog client. // Client returns a new Datadog client.
func (c *Config) Client() (*datadog.Client, error) { func (c *Config) Client() *datadog.Client {
client := datadog.NewClient(c.APIKey, c.APPKey) client := datadog.NewClient(c.APIKey, c.APPKey)
log.Printf("[INFO] Datadog Client configured ") log.Printf("[INFO] Datadog Client configured ")
return client, nil return client
} }

View File

@ -3,6 +3,7 @@ package datadog
import ( import (
"log" "log"
"errors"
"github.com/hashicorp/terraform/helper/schema" "github.com/hashicorp/terraform/helper/schema"
"github.com/hashicorp/terraform/terraform" "github.com/hashicorp/terraform/terraform"
) )
@ -39,5 +40,17 @@ func providerConfigure(d *schema.ResourceData) (interface{}, error) {
} }
log.Println("[INFO] Initializing Datadog client") log.Println("[INFO] Initializing Datadog client")
return config.Client() client := config.Client()
ok, err := client.Validate()
if err != nil {
return client, err
}
if ok == false {
return client, errors.New(`No valid credential sources found for Datadog Provider. Please see https://terraform.io/docs/providers/datadog/index.html for more information on providing credentials for the Datadog Provider`)
}
return client, nil
} }

View File

@ -78,9 +78,9 @@ func TestAccDatadogMonitor_BasicNoTreshold(t *testing.T) {
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"datadog_monitor.foo", "locked", "false"), "datadog_monitor.foo", "locked", "false"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"datadog_monitor.foo", "tags.foo", "bar"), "datadog_monitor.foo", "tags.0", "foo:bar"),
resource.TestCheckResourceAttr( resource.TestCheckResourceAttr(
"datadog_monitor.foo", "tags.bar", "baz"), "datadog_monitor.foo", "tags.1", "bar:baz"),
), ),
}, },
}, },
@ -305,10 +305,7 @@ resource "datadog_monitor" "foo" {
include_tags = true include_tags = true
require_full_window = true require_full_window = true
locked = false locked = false
tags { tags = ["foo:bar", "bar:baz"]
"foo" = "bar"
"bar" = "baz"
}
} }
` `

View File

@ -1,16 +1,8 @@
TEST?=. TEST?=$$(go list ./... | grep -v '/go-datadog-api/vendor/')
VETARGS?=-asmdecl -atomic -bool -buildtags -copylocks -methods -nilfunc -printf -rangeloops -shift -structtags -unsafeptr VETARGS?=-asmdecl -atomic -bool -buildtags -copylocks -methods -nilfunc -printf -rangeloops -shift -structtags -unsafeptr
GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor)
default: test default: test fmt
# get dependencies
updatedeps:
go list ./... \
| xargs go list -f '{{join .Deps "\n"}}' \
| grep -v go-datadog-api\
| grep -v '/internal/' \
| sort -u \
| xargs go get -f -u -v
# test runs the unit tests and vets the code # test runs the unit tests and vets the code
test: test:
@ -25,14 +17,17 @@ testacc:
testrace: testrace:
go test -race $(TEST) $(TESTARGS) go test -race $(TEST) $(TESTARGS)
fmt:
gofmt -w $(GOFMT_FILES)
# vet runs the Go source code static analysis tool `vet` to find # vet runs the Go source code static analysis tool `vet` to find
# any common errors. # any common errors.
vet: vet:
@go tool vet 2>/dev/null ; if [ $$? -eq 3 ]; then \ @go tool vet 2>/dev/null ; if [ $$? -eq 3 ]; then \
go get golang.org/x/tools/cmd/vet; \ go get golang.org/x/tools/cmd/vet; \
fi fi
@echo "go tool vet $(VETARGS) $(TEST) " @echo "go tool vet $(VETARGS)"
@go tool vet $(VETARGS) $(TEST) ; if [ $$? -eq 1 ]; then \ @go tool vet $(VETARGS) $$(ls -d */ | grep -v vendor) ; if [ $$? -eq 1 ]; then \
echo ""; \ echo ""; \
echo "Vet found suspicious constructs. Please check the reported constructs"; \ echo "Vet found suspicious constructs. Please check the reported constructs"; \
echo "and fix them if necessary before submitting the code for review."; \ echo "and fix them if necessary before submitting the code for review."; \

View File

@ -53,15 +53,13 @@ Thanks in advance! And, as always, patches welcome!
## DEVELOPMENT ## DEVELOPMENT
* Get dependencies with `make updatedeps`.
* Run tests tests with `make test`. * Run tests tests with `make test`.
* Integration tests can be run with `make testacc`. * Integration tests can be run with `make testacc`. Run specific integration tests with `make testacc TESTARGS='-run=TestCreateAndDeleteMonitor'`
The acceptance tests require _DATADOG_API_KEY_ and _DATADOG_APP_KEY_ to be available The acceptance tests require _DATADOG_API_KEY_ and _DATADOG_APP_KEY_ to be available
in your environment variables. in your environment variables.
*Warning: the integrations tests will create and remove real resources in your Datadog *Warning: the integrations tests will create and remove real resources in your Datadog account.*
account*
## COPYRIGHT AND LICENSE ## COPYRIGHT AND LICENSE

View File

@ -32,10 +32,9 @@ type reqAlerts struct {
// CreateAlert adds a new alert to the system. This returns a pointer to an // CreateAlert adds a new alert to the system. This returns a pointer to an
// Alert so you can pass that to UpdateAlert later if needed. // Alert so you can pass that to UpdateAlert later if needed.
func (self *Client) CreateAlert(alert *Alert) (*Alert, error) { func (client *Client) CreateAlert(alert *Alert) (*Alert, error) {
var out Alert var out Alert
err := self.doJsonRequest("POST", "/v1/alert", alert, &out) if err := client.doJsonRequest("POST", "/v1/alert", alert, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out, nil return &out, nil
@ -43,43 +42,41 @@ func (self *Client) CreateAlert(alert *Alert) (*Alert, error) {
// UpdateAlert takes an alert that was previously retrieved through some method // UpdateAlert takes an alert that was previously retrieved through some method
// and sends it back to the server. // and sends it back to the server.
func (self *Client) UpdateAlert(alert *Alert) error { func (client *Client) UpdateAlert(alert *Alert) error {
return self.doJsonRequest("PUT", fmt.Sprintf("/v1/alert/%d", alert.Id), return client.doJsonRequest("PUT", fmt.Sprintf("/v1/alert/%d", alert.Id),
alert, nil) alert, nil)
} }
// GetAlert retrieves an alert by identifier. // GetAlert retrieves an alert by identifier.
func (self *Client) GetAlert(id int) (*Alert, error) { func (client *Client) GetAlert(id int) (*Alert, error) {
var out Alert var out Alert
err := self.doJsonRequest("GET", fmt.Sprintf("/v1/alert/%d", id), nil, &out) if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/alert/%d", id), nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out, nil return &out, nil
} }
// DeleteAlert removes an alert from the system. // DeleteAlert removes an alert from the system.
func (self *Client) DeleteAlert(id int) error { func (client *Client) DeleteAlert(id int) error {
return self.doJsonRequest("DELETE", fmt.Sprintf("/v1/alert/%d", id), return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/alert/%d", id),
nil, nil) nil, nil)
} }
// GetAlerts returns a slice of all alerts. // GetAlerts returns a slice of all alerts.
func (self *Client) GetAlerts() ([]Alert, error) { func (client *Client) GetAlerts() ([]Alert, error) {
var out reqAlerts var out reqAlerts
err := self.doJsonRequest("GET", "/v1/alert", nil, &out) if err := client.doJsonRequest("GET", "/v1/alert", nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Alerts, nil return out.Alerts, nil
} }
// MuteAlerts turns off alerting notifications. // MuteAlerts turns off alerting notifications.
func (self *Client) MuteAlerts() error { func (client *Client) MuteAlerts() error {
return self.doJsonRequest("POST", "/v1/mute_alerts", nil, nil) return client.doJsonRequest("POST", "/v1/mute_alerts", nil, nil)
} }
// UnmuteAlerts turns on alerting notifications. // UnmuteAlerts turns on alerting notifications.
func (self *Client) UnmuteAlerts() error { func (client *Client) UnmuteAlerts() error {
return self.doJsonRequest("POST", "/v1/unmute_alerts", nil, nil) return client.doJsonRequest("POST", "/v1/unmute_alerts", nil, nil)
} }

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

@ -0,0 +1,81 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import (
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
)
// Client is the object that handles talking to the Datadog API. This maintains
// state information for a particular application connection.
type Client struct {
apiKey, appKey string
//The Http Client that is used to make requests
HttpClient *http.Client
}
// valid is the struct to unmarshal validation endpoint responses into.
type valid struct {
Errors []string `json:"errors"`
IsValid bool `json:"valid"`
}
// NewClient returns a new datadog.Client which can be used to access the API
// methods. The expected argument is the API key.
func NewClient(apiKey, appKey string) *Client {
return &Client{
apiKey: apiKey,
appKey: appKey,
HttpClient: http.DefaultClient,
}
}
// Validate checks if the API and application keys are valid.
func (client *Client) Validate() (bool, error) {
var bodyreader io.Reader
var out valid
req, err := http.NewRequest("GET", client.uriForAPI("/v1/validate"), bodyreader)
if err != nil {
return false, err
}
if bodyreader != nil {
req.Header.Add("Content-Type", "application/json")
}
var resp *http.Response
resp, err = client.HttpClient.Do(req)
if err != nil {
return false, err
}
defer resp.Body.Close()
// Only care about 200 OK or 403 which we'll unmarshal into struct valid. Everything else is of no interest to us.
if resp.StatusCode != 200 && resp.StatusCode != 403 {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
return false, fmt.Errorf("API error %s: %s", resp.Status, body)
}
body, err := ioutil.ReadAll(resp.Body)
err = json.Unmarshal(body, &out)
if err != nil {
return false, err
}
return out.IsValid, nil
}

View File

@ -28,11 +28,10 @@ type reqComment struct {
} }
// CreateComment adds a new comment to the system. // CreateComment adds a new comment to the system.
func (self *Client) CreateComment(handle, message string) (*Comment, error) { func (client *Client) CreateComment(handle, message string) (*Comment, error) {
var out reqComment var out reqComment
comment := Comment{Handle: handle, Message: message} comment := Comment{Handle: handle, Message: message}
err := self.doJsonRequest("POST", "/v1/comments", &comment, &out) if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out.Comment, nil return &out.Comment, nil
@ -40,26 +39,25 @@ func (self *Client) CreateComment(handle, message string) (*Comment, error) {
// CreateRelatedComment adds a new comment, but lets you specify the related // CreateRelatedComment adds a new comment, but lets you specify the related
// identifier for the comment. // identifier for the comment.
func (self *Client) CreateRelatedComment(handle, message string, func (client *Client) CreateRelatedComment(handle, message string,
relid int) (*Comment, error) { relid int) (*Comment, error) {
var out reqComment var out reqComment
comment := Comment{Handle: handle, Message: message, RelatedId: relid} comment := Comment{Handle: handle, Message: message, RelatedId: relid}
err := self.doJsonRequest("POST", "/v1/comments", &comment, &out) if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out.Comment, nil return &out.Comment, nil
} }
// EditComment changes the message and possibly handle of a particular comment. // EditComment changes the message and possibly handle of a particular comment.
func (self *Client) EditComment(id int, handle, message string) error { func (client *Client) EditComment(id int, handle, message string) error {
comment := Comment{Handle: handle, Message: message} comment := Comment{Handle: handle, Message: message}
return self.doJsonRequest("PUT", fmt.Sprintf("/v1/comments/%d", id), return client.doJsonRequest("PUT", fmt.Sprintf("/v1/comments/%d", id),
&comment, nil) &comment, nil)
} }
// DeleteComment does exactly what you expect. // DeleteComment does exactly what you expect.
func (self *Client) DeleteComment(id int) error { func (client *Client) DeleteComment(id int) error {
return self.doJsonRequest("DELETE", fmt.Sprintf("/v1/comments/%d", id), return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/comments/%d", id),
nil, nil) nil, nil)
} }

View File

@ -129,36 +129,33 @@ type DashboardConditionalFormat struct {
} }
// GetDashboard returns a single dashboard created on this account. // GetDashboard returns a single dashboard created on this account.
func (self *Client) GetDashboard(id int) (*Dashboard, error) { func (client *Client) GetDashboard(id int) (*Dashboard, error) {
var out reqGetDashboard var out reqGetDashboard
err := self.doJsonRequest("GET", fmt.Sprintf("/v1/dash/%d", id), nil, &out) if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/dash/%d", id), nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out.Dashboard, nil return &out.Dashboard, nil
} }
// GetDashboards returns a list of all dashboards created on this account. // GetDashboards returns a list of all dashboards created on this account.
func (self *Client) GetDashboards() ([]DashboardLite, error) { func (client *Client) GetDashboards() ([]DashboardLite, error) {
var out reqGetDashboards var out reqGetDashboards
err := self.doJsonRequest("GET", "/v1/dash", nil, &out) if err := client.doJsonRequest("GET", "/v1/dash", nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Dashboards, nil return out.Dashboards, nil
} }
// DeleteDashboard deletes a dashboard by the identifier. // DeleteDashboard deletes a dashboard by the identifier.
func (self *Client) DeleteDashboard(id int) error { func (client *Client) DeleteDashboard(id int) error {
return self.doJsonRequest("DELETE", fmt.Sprintf("/v1/dash/%d", id), nil, nil) return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/dash/%d", id), nil, nil)
} }
// CreateDashboard creates a new dashboard when given a Dashboard struct. Note // CreateDashboard creates a new dashboard when given a Dashboard struct. Note
// that the Id, Resource, Url and similar elements are not used in creation. // that the Id, Resource, Url and similar elements are not used in creation.
func (self *Client) CreateDashboard(dash *Dashboard) (*Dashboard, error) { func (client *Client) CreateDashboard(dash *Dashboard) (*Dashboard, error) {
var out reqGetDashboard var out reqGetDashboard
err := self.doJsonRequest("POST", "/v1/dash", dash, &out) if err := client.doJsonRequest("POST", "/v1/dash", dash, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out.Dashboard, nil return &out.Dashboard, nil
@ -166,7 +163,7 @@ func (self *Client) CreateDashboard(dash *Dashboard) (*Dashboard, error) {
// UpdateDashboard in essence takes a Dashboard struct and persists it back to // UpdateDashboard in essence takes a Dashboard struct and persists it back to
// the server. Use this if you've updated your local and need to push it back. // the server. Use this if you've updated your local and need to push it back.
func (self *Client) UpdateDashboard(dash *Dashboard) error { func (client *Client) UpdateDashboard(dash *Dashboard) error {
return self.doJsonRequest("PUT", fmt.Sprintf("/v1/dash/%d", dash.Id), return client.doJsonRequest("PUT", fmt.Sprintf("/v1/dash/%d", dash.Id),
dash, nil) dash, nil)
} }

View File

@ -40,10 +40,9 @@ type reqDowntimes struct {
// CreateDowntime adds a new downtme to the system. This returns a pointer // CreateDowntime adds a new downtme to the system. This returns a pointer
// to a Downtime so you can pass that to UpdateDowntime or CancelDowntime // to a Downtime so you can pass that to UpdateDowntime or CancelDowntime
// later if needed. // later if needed.
func (self *Client) CreateDowntime(downtime *Downtime) (*Downtime, error) { func (client *Client) CreateDowntime(downtime *Downtime) (*Downtime, error) {
var out Downtime var out Downtime
err := self.doJsonRequest("POST", "/v1/downtime", downtime, &out) if err := client.doJsonRequest("POST", "/v1/downtime", downtime, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out, nil return &out, nil
@ -51,32 +50,30 @@ func (self *Client) CreateDowntime(downtime *Downtime) (*Downtime, error) {
// UpdateDowntime takes a downtime that was previously retrieved through some method // UpdateDowntime takes a downtime that was previously retrieved through some method
// and sends it back to the server. // and sends it back to the server.
func (self *Client) UpdateDowntime(downtime *Downtime) error { func (client *Client) UpdateDowntime(downtime *Downtime) error {
return self.doJsonRequest("PUT", fmt.Sprintf("/v1/downtime/%d", downtime.Id), return client.doJsonRequest("PUT", fmt.Sprintf("/v1/downtime/%d", downtime.Id),
downtime, nil) downtime, nil)
} }
// Getdowntime retrieves an downtime by identifier. // Getdowntime retrieves an downtime by identifier.
func (self *Client) GetDowntime(id int) (*Downtime, error) { func (client *Client) GetDowntime(id int) (*Downtime, error) {
var out Downtime var out Downtime
err := self.doJsonRequest("GET", fmt.Sprintf("/v1/downtime/%d", id), nil, &out) if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/downtime/%d", id), nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out, nil return &out, nil
} }
// DeleteDowntime removes an downtime from the system. // DeleteDowntime removes an downtime from the system.
func (self *Client) DeleteDowntime(id int) error { func (client *Client) DeleteDowntime(id int) error {
return self.doJsonRequest("DELETE", fmt.Sprintf("/v1/downtime/%d", id), return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/downtime/%d", id),
nil, nil) nil, nil)
} }
// GetDowntimes returns a slice of all downtimes. // GetDowntimes returns a slice of all downtimes.
func (self *Client) GetDowntimes() ([]Downtime, error) { func (client *Client) GetDowntimes() ([]Downtime, error) {
var out reqDowntimes var out reqDowntimes
err := self.doJsonRequest("GET", "/v1/downtime", nil, &out.Downtimes) if err := client.doJsonRequest("GET", "/v1/downtime", nil, &out.Downtimes); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Downtimes, nil return out.Downtimes, nil

View File

@ -43,27 +43,25 @@ type reqGetEvents struct {
} }
// PostEvent takes as input an event and then posts it to the server. // PostEvent takes as input an event and then posts it to the server.
func (self *Client) PostEvent(event *Event) (*Event, error) { func (client *Client) PostEvent(event *Event) (*Event, error) {
var out reqGetEvent var out reqGetEvent
err := self.doJsonRequest("POST", "/v1/events", event, &out) if err := client.doJsonRequest("POST", "/v1/events", event, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out.Event, nil return &out.Event, nil
} }
// GetEvent gets a single event given an identifier. // GetEvent gets a single event given an identifier.
func (self *Client) GetEvent(id int) (*Event, error) { func (client *Client) GetEvent(id int) (*Event, error) {
var out reqGetEvent var out reqGetEvent
err := self.doJsonRequest("GET", fmt.Sprintf("/v1/events/%d", id), nil, &out) if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/events/%d", id), nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out.Event, nil return &out.Event, nil
} }
// QueryEvents returns a slice of events from the query stream. // QueryEvents returns a slice of events from the query stream.
func (self *Client) GetEvents(start, end int, func (client *Client) GetEvents(start, end int,
priority, sources, tags string) ([]Event, error) { priority, sources, tags string) ([]Event, error) {
// Since this is a GET request, we need to build a query string. // Since this is a GET request, we need to build a query string.
vals := url.Values{} vals := url.Values{}
@ -81,9 +79,8 @@ func (self *Client) GetEvents(start, end int,
// Now the request and response. // Now the request and response.
var out reqGetEvents var out reqGetEvents
err := self.doJsonRequest("GET", if err := client.doJsonRequest("GET",
fmt.Sprintf("/v1/events?%s", vals.Encode()), nil, &out) fmt.Sprintf("/v1/events?%s", vals.Encode()), nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Events, nil return out.Events, nil

View File

@ -1,30 +0,0 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import "net/http"
// Client is the object that handles talking to the Datadog API. This maintains
// state information for a particular application connection.
type Client struct {
apiKey, appKey string
//The Http Client that is used to make requests
HttpClient *http.Client
}
// NewClient returns a new datadog.Client which can be used to access the API
// methods. The expected argument is the API key.
func NewClient(apiKey, appKey string) *Client {
return &Client{
apiKey: apiKey,
appKey: appKey,
HttpClient: http.DefaultClient,
}
}

View File

@ -80,10 +80,10 @@ type reqMonitors struct {
// CreateMonitor adds a new monitor to the system. This returns a pointer to a // 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 // monitor so you can pass that to UpdateMonitor later if needed
func (self *Client) CreateMonitor(monitor *Monitor) (*Monitor, error) { func (client *Client) CreateMonitor(monitor *Monitor) (*Monitor, error) {
var out Monitor var out Monitor
err := self.doJsonRequest("POST", "/v1/monitor", monitor, &out) // TODO: is this more pretty of frowned upon?
if err != nil { if err := client.doJsonRequest("POST", "/v1/monitor", monitor, &out); err != nil {
return nil, err return nil, err
} }
return &out, nil return &out, nil
@ -91,16 +91,15 @@ func (self *Client) CreateMonitor(monitor *Monitor) (*Monitor, error) {
// UpdateMonitor takes a monitor that was previously retrieved through some method // UpdateMonitor takes a monitor that was previously retrieved through some method
// and sends it back to the server // and sends it back to the server
func (self *Client) UpdateMonitor(monitor *Monitor) error { func (client *Client) UpdateMonitor(monitor *Monitor) error {
return self.doJsonRequest("PUT", fmt.Sprintf("/v1/monitor/%d", monitor.Id), return client.doJsonRequest("PUT", fmt.Sprintf("/v1/monitor/%d", monitor.Id),
monitor, nil) monitor, nil)
} }
// GetMonitor retrieves a monitor by identifier // GetMonitor retrieves a monitor by identifier
func (self *Client) GetMonitor(id int) (*Monitor, error) { func (client *Client) GetMonitor(id int) (*Monitor, error) {
var out Monitor var out Monitor
err := self.doJsonRequest("GET", fmt.Sprintf("/v1/monitor/%d", id), nil, &out) if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/monitor/%d", id), nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return &out, nil return &out, nil
@ -137,37 +136,36 @@ func (self *Client) GetMonitorsByTags(tags []string) ([]Monitor, error) {
} }
// DeleteMonitor removes a monitor from the system // DeleteMonitor removes a monitor from the system
func (self *Client) DeleteMonitor(id int) error { func (client *Client) DeleteMonitor(id int) error {
return self.doJsonRequest("DELETE", fmt.Sprintf("/v1/monitor/%d", id), return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/monitor/%d", id),
nil, nil) nil, nil)
} }
// GetMonitors returns a slice of all monitors // GetMonitors returns a slice of all monitors
func (self *Client) GetMonitors() ([]Monitor, error) { func (client *Client) GetMonitors() ([]Monitor, error) {
var out reqMonitors var out reqMonitors
err := self.doJsonRequest("GET", "/v1/monitor", nil, &out.Monitors) if err := client.doJsonRequest("GET", "/v1/monitor", nil, &out.Monitors); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Monitors, nil return out.Monitors, nil
} }
// MuteMonitors turns off monitoring notifications // MuteMonitors turns off monitoring notifications
func (self *Client) MuteMonitors() error { func (client *Client) MuteMonitors() error {
return self.doJsonRequest("POST", "/v1/monitor/mute_all", nil, nil) return client.doJsonRequest("POST", "/v1/monitor/mute_all", nil, nil)
} }
// UnmuteMonitors turns on monitoring notifications // UnmuteMonitors turns on monitoring notifications
func (self *Client) UnmuteMonitors() error { func (client *Client) UnmuteMonitors() error {
return self.doJsonRequest("POST", "/v1/monitor/unmute_all", nil, nil) return client.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 { func (client *Client) MuteMonitor(id int) error {
return self.doJsonRequest("POST", fmt.Sprintf("/v1/monitor/%d/mute", id), nil, nil) return client.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 { func (client *Client) UnmuteMonitor(id int) error {
return self.doJsonRequest("POST", fmt.Sprintf("/v1/monitor/%d/unmute", id), nil, nil) return client.doJsonRequest("POST", fmt.Sprintf("/v1/monitor/%d/unmute", id), nil, nil)
} }

View File

@ -25,23 +25,23 @@ import (
// uriForAPI is to be called with something like "/v1/events" and it will give // uriForAPI is to be called with something like "/v1/events" and it will give
// the proper request URI to be posted to. // the proper request URI to be posted to.
func (self *Client) uriForAPI(api string) string { func (client *Client) uriForAPI(api string) string {
url := os.Getenv("DATADOG_HOST") url := os.Getenv("DATADOG_HOST")
if url == "" { if url == "" {
url = "https://app.datadoghq.com" url = "https://app.datadoghq.com"
} }
if strings.Index(api, "?") > -1 { if strings.Index(api, "?") > -1 {
return url + "/api" + api + "&api_key=" + return url + "/api" + api + "&api_key=" +
self.apiKey + "&application_key=" + self.appKey client.apiKey + "&application_key=" + client.appKey
} else { } else {
return url + "/api" + api + "?api_key=" + return url + "/api" + api + "?api_key=" +
self.apiKey + "&application_key=" + self.appKey client.apiKey + "&application_key=" + client.appKey
} }
} }
// doJsonRequest is the simplest type of request: a method on a URI that returns // doJsonRequest is the simplest type of request: a method on a URI that returns
// some JSON result which we unmarshal into the passed interface. // some JSON result which we unmarshal into the passed interface.
func (self *Client) doJsonRequest(method, api string, func (client *Client) doJsonRequest(method, api string,
reqbody, out interface{}) error { reqbody, out interface{}) error {
// Handle the body if they gave us one. // Handle the body if they gave us one.
var bodyreader io.Reader var bodyreader io.Reader
@ -53,7 +53,7 @@ func (self *Client) doJsonRequest(method, api string,
bodyreader = bytes.NewReader(bjson) bodyreader = bytes.NewReader(bjson)
} }
req, err := http.NewRequest(method, self.uriForAPI(api), bodyreader) req, err := http.NewRequest(method, client.uriForAPI(api), bodyreader)
if err != nil { if err != nil {
return err return err
} }
@ -64,9 +64,9 @@ func (self *Client) doJsonRequest(method, api string,
// Perform the request and retry it if it's not a POST request // Perform the request and retry it if it's not a POST request
var resp *http.Response var resp *http.Response
if method == "POST" { if method == "POST" {
resp, err = self.HttpClient.Do(req) resp, err = client.HttpClient.Do(req)
} else { } else {
resp, err = self.doRequestWithRetries(req, 60*time.Second) resp, err = client.doRequestWithRetries(req, 60*time.Second)
} }
if err != nil { if err != nil {
return err return err
@ -98,8 +98,7 @@ func (self *Client) doJsonRequest(method, api string,
body = []byte{'{', '}'} body = []byte{'{', '}'}
} }
err = json.Unmarshal(body, &out) if err := json.Unmarshal(body, &out); err != nil {
if err != nil {
return err return err
} }
return nil return nil
@ -107,7 +106,7 @@ func (self *Client) doJsonRequest(method, api string,
// doRequestWithRetries performs an HTTP request repeatedly for maxTime or until // doRequestWithRetries performs an HTTP request repeatedly for maxTime or until
// no error and no HTTP response code higher than 299 is returned. // no error and no HTTP response code higher than 299 is returned.
func (self *Client) doRequestWithRetries(req *http.Request, maxTime time.Duration) (*http.Response, error) { func (client *Client) doRequestWithRetries(req *http.Request, maxTime time.Duration) (*http.Response, error) {
var ( var (
err error err error
resp *http.Response resp *http.Response
@ -116,7 +115,7 @@ func (self *Client) doRequestWithRetries(req *http.Request, maxTime time.Duratio
bo.MaxElapsedTime = maxTime bo.MaxElapsedTime = maxTime
err = backoff.Retry(func() error { err = backoff.Retry(func() error {
resp, err = self.HttpClient.Do(req) resp, err = client.HttpClient.Do(req)
if err != nil { if err != nil {
return err return err
} }

View File

@ -62,35 +62,33 @@ type reqGetScreenboards struct {
} }
// GetScreenboard returns a single screenboard created on this account. // GetScreenboard returns a single screenboard created on this account.
func (self *Client) GetScreenboard(id int) (*Screenboard, error) { func (client *Client) GetScreenboard(id int) (*Screenboard, error) {
out := &Screenboard{} out := &Screenboard{}
err := self.doJsonRequest("GET", fmt.Sprintf("/v1/screen/%d", id), nil, out) if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/screen/%d", id), nil, out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
} }
// GetScreenboards returns a list of all screenboards created on this account. // GetScreenboards returns a list of all screenboards created on this account.
func (self *Client) GetScreenboards() ([]*ScreenboardLite, error) { func (client *Client) GetScreenboards() ([]*ScreenboardLite, error) {
var out reqGetScreenboards var out reqGetScreenboards
err := self.doJsonRequest("GET", "/v1/screen", nil, &out) if err := client.doJsonRequest("GET", "/v1/screen", nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Screenboards, nil return out.Screenboards, nil
} }
// DeleteScreenboard deletes a screenboard by the identifier. // DeleteScreenboard deletes a screenboard by the identifier.
func (self *Client) DeleteScreenboard(id int) error { func (client *Client) DeleteScreenboard(id int) error {
return self.doJsonRequest("DELETE", fmt.Sprintf("/v1/screen/%d", id), nil, nil) return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/screen/%d", id), nil, nil)
} }
// CreateScreenboard creates a new screenboard when given a Screenboard struct. Note // CreateScreenboard creates a new screenboard when given a Screenboard struct. Note
// that the Id, Resource, Url and similar elements are not used in creation. // that the Id, Resource, Url and similar elements are not used in creation.
func (self *Client) CreateScreenboard(board *Screenboard) (*Screenboard, error) { func (client *Client) CreateScreenboard(board *Screenboard) (*Screenboard, error) {
out := &Screenboard{} out := &Screenboard{}
if err := self.doJsonRequest("POST", "/v1/screen", board, out); err != nil { if err := client.doJsonRequest("POST", "/v1/screen", board, out); err != nil {
return nil, err return nil, err
} }
return out, nil return out, nil
@ -98,8 +96,8 @@ func (self *Client) CreateScreenboard(board *Screenboard) (*Screenboard, error)
// UpdateScreenboard in essence takes a Screenboard struct and persists it back to // UpdateScreenboard in essence takes a Screenboard struct and persists it back to
// the server. Use this if you've updated your local and need to push it back. // the server. Use this if you've updated your local and need to push it back.
func (self *Client) UpdateScreenboard(board *Screenboard) error { func (client *Client) UpdateScreenboard(board *Screenboard) error {
return self.doJsonRequest("PUT", fmt.Sprintf("/v1/screen/%d", board.Id), board, nil) return client.doJsonRequest("PUT", fmt.Sprintf("/v1/screen/%d", board.Id), board, nil)
} }
type ScreenShareResponse struct { type ScreenShareResponse struct {
@ -108,11 +106,11 @@ type ScreenShareResponse struct {
} }
// ShareScreenboard shares an existing screenboard, it takes and updates ScreenShareResponse // ShareScreenboard shares an existing screenboard, it takes and updates ScreenShareResponse
func (self *Client) ShareScreenboard(id int, response *ScreenShareResponse) error { func (client *Client) ShareScreenboard(id int, response *ScreenShareResponse) error {
return self.doJsonRequest("GET", fmt.Sprintf("/v1/screen/share/%d", id), nil, response) return client.doJsonRequest("GET", fmt.Sprintf("/v1/screen/share/%d", id), nil, response)
} }
// RevokeScreenboard revokes a currently shared screenboard // RevokeScreenboard revokes a currently shared screenboard
func (self *Client) RevokeScreenboard(id int) error { func (client *Client) RevokeScreenboard(id int) error {
return self.doJsonRequest("DELETE", fmt.Sprintf("/v1/screen/share/%d", id), nil, nil) return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/screen/share/%d", id), nil, nil)
} }

View File

@ -17,20 +17,18 @@ type reqSearch struct {
} }
// SearchHosts searches through the hosts facet, returning matching hostnames. // SearchHosts searches through the hosts facet, returning matching hostnames.
func (self *Client) SearchHosts(search string) ([]string, error) { func (client *Client) SearchHosts(search string) ([]string, error) {
var out reqSearch var out reqSearch
err := self.doJsonRequest("GET", "/v1/search?q=hosts:"+search, nil, &out) if err := client.doJsonRequest("GET", "/v1/search?q=hosts:"+search, nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Results.Hosts, nil return out.Results.Hosts, nil
} }
// SearchMetrics searches through the metrics facet, returning matching ones. // SearchMetrics searches through the metrics facet, returning matching ones.
func (self *Client) SearchMetrics(search string) ([]string, error) { func (client *Client) SearchMetrics(search string) ([]string, error) {
var out reqSearch var out reqSearch
err := self.doJsonRequest("GET", "/v1/search?q=metrics:"+search, nil, &out) if err := client.doJsonRequest("GET", "/v1/search?q=metrics:"+search, nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Results.Metrics, nil return out.Results.Metrics, nil

View File

@ -59,9 +59,8 @@ func (client *Client) PostMetrics(series []Metric) error {
// timeseries data for that time peried // timeseries data for that time peried
func (client *Client) QueryMetrics(from, to int64, query string) ([]Series, error) { func (client *Client) QueryMetrics(from, to int64, query string) ([]Series, error) {
var out reqMetrics var out reqMetrics
err := client.doJsonRequest("GET", "/v1/query?from="+strconv.FormatInt(from, 10)+"&to="+strconv.FormatInt(to, 10)+"&query="+query, if err := client.doJsonRequest("GET", "/v1/query?from="+strconv.FormatInt(from, 10)+"&to="+strconv.FormatInt(to, 10)+"&query="+query,
nil, &out) nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Series, nil return out.Series, nil

View File

@ -15,7 +15,7 @@ import (
) )
// Snapshot creates an image from a graph and returns the URL of the image. // Snapshot creates an image from a graph and returns the URL of the image.
func (self *Client) Snapshot(query string, start, end time.Time, eventQuery string) (string, error) { func (client *Client) Snapshot(query string, start, end time.Time, eventQuery string) (string, error) {
v := url.Values{} v := url.Values{}
v.Add("start", fmt.Sprintf("%d", start.Unix())) v.Add("start", fmt.Sprintf("%d", start.Unix()))
v.Add("end", fmt.Sprintf("%d", end.Unix())) v.Add("end", fmt.Sprintf("%d", end.Unix()))
@ -25,8 +25,7 @@ func (self *Client) Snapshot(query string, start, end time.Time, eventQuery stri
out := struct { out := struct {
SnapshotURL string `json:"snapshot_url"` SnapshotURL string `json:"snapshot_url"`
}{} }{}
err := self.doJsonRequest("GET", "/v1/graph/snapshot?"+v.Encode(), nil, &out) if err := client.doJsonRequest("GET", "/v1/graph/snapshot?"+v.Encode(), nil, &out); err != nil {
if err != nil {
return "", err return "", err
} }
return out.SnapshotURL, nil return out.SnapshotURL, nil

View File

@ -22,28 +22,26 @@ type reqGetHostTags struct {
} }
// GetTags returns a map of tags. // GetTags returns a map of tags.
func (self *Client) GetTags(source string) (TagMap, error) { func (client *Client) GetTags(source string) (TagMap, error) {
var out reqGetTags var out reqGetTags
uri := "/v1/tags/hosts" uri := "/v1/tags/hosts"
if source != "" { if source != "" {
uri += "?source=" + source uri += "?source=" + source
} }
err := self.doJsonRequest("GET", uri, nil, &out) if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Tags, nil return out.Tags, nil
} }
// GetHostTags returns a slice of tags for a given host and source. // GetHostTags returns a slice of tags for a given host and source.
func (self *Client) GetHostTags(host, source string) ([]string, error) { func (client *Client) GetHostTags(host, source string) ([]string, error) {
var out reqGetHostTags var out reqGetHostTags
uri := "/v1/tags/hosts/" + host uri := "/v1/tags/hosts/" + host
if source != "" { if source != "" {
uri += "?source=" + source uri += "?source=" + source
} }
err := self.doJsonRequest("GET", uri, nil, &out) if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Tags, nil return out.Tags, nil
@ -51,14 +49,13 @@ func (self *Client) GetHostTags(host, source string) ([]string, error) {
// GetHostTagsBySource is a different way of viewing the tags. It returns a map // GetHostTagsBySource is a different way of viewing the tags. It returns a map
// of source:[tag,tag]. // of source:[tag,tag].
func (self *Client) GetHostTagsBySource(host, source string) (TagMap, error) { func (client *Client) GetHostTagsBySource(host, source string) (TagMap, error) {
var out reqGetTags var out reqGetTags
uri := "/v1/tags/hosts/" + host + "?by_source=true" uri := "/v1/tags/hosts/" + host + "?by_source=true"
if source != "" { if source != "" {
uri += "&source=" + source uri += "&source=" + source
} }
err := self.doJsonRequest("GET", uri, nil, &out) if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
if err != nil {
return nil, err return nil, err
} }
return out.Tags, nil return out.Tags, nil
@ -67,30 +64,30 @@ func (self *Client) GetHostTagsBySource(host, source string) (TagMap, error) {
// AddTagsToHost does exactly what it says on the tin. Given a list of tags, // AddTagsToHost does exactly what it says on the tin. Given a list of tags,
// add them to the host. The source is optionally specificed, and defaults to // add them to the host. The source is optionally specificed, and defaults to
// "users" as per the API documentation. // "users" as per the API documentation.
func (self *Client) AddTagsToHost(host, source string, tags []string) error { func (client *Client) AddTagsToHost(host, source string, tags []string) error {
uri := "/v1/tags/hosts/" + host uri := "/v1/tags/hosts/" + host
if source != "" { if source != "" {
uri += "?source=" + source uri += "?source=" + source
} }
return self.doJsonRequest("POST", uri, reqGetHostTags{Tags: tags}, nil) return client.doJsonRequest("POST", uri, reqGetHostTags{Tags: tags}, nil)
} }
// UpdateHostTags overwrites existing tags for a host, allowing you to specify // UpdateHostTags overwrites existing tags for a host, allowing you to specify
// a new set of tags for the given source. This defaults to "users". // a new set of tags for the given source. This defaults to "users".
func (self *Client) UpdateHostTags(host, source string, tags []string) error { func (client *Client) UpdateHostTags(host, source string, tags []string) error {
uri := "/v1/tags/hosts/" + host uri := "/v1/tags/hosts/" + host
if source != "" { if source != "" {
uri += "?source=" + source uri += "?source=" + source
} }
return self.doJsonRequest("PUT", uri, reqGetHostTags{Tags: tags}, nil) return client.doJsonRequest("PUT", uri, reqGetHostTags{Tags: tags}, nil)
} }
// RemoveHostTags removes all tags from a host for the given source. If none is // RemoveHostTags removes all tags from a host for the given source. If none is
// given, the API defaults to "users". // given, the API defaults to "users".
func (self *Client) RemoveHostTags(host, source string) error { func (client *Client) RemoveHostTags(host, source string) error {
uri := "/v1/tags/hosts/" + host uri := "/v1/tags/hosts/" + host
if source != "" { if source != "" {
uri += "?source=" + source uri += "?source=" + source
} }
return self.doJsonRequest("DELETE", uri, nil, nil) return client.doJsonRequest("DELETE", uri, nil, nil)
} }

View File

@ -24,8 +24,8 @@ type reqInviteUsers struct {
} }
// InviteUsers takes a slice of email addresses and sends invitations to them. // InviteUsers takes a slice of email addresses and sends invitations to them.
func (self *Client) InviteUsers(emails []string) error { func (client *Client) InviteUsers(emails []string) error {
return self.doJsonRequest("POST", "/v1/invite_users", return client.doJsonRequest("POST", "/v1/invite_users",
reqInviteUsers{Emails: emails}, nil) reqInviteUsers{Emails: emails}, nil)
} }
@ -54,10 +54,10 @@ type usersData struct {
} }
// GetUsers returns all user, or an error if not found // GetUsers returns all user, or an error if not found
func (self *Client) GetUsers() (users []User, err error) { func (client *Client) GetUsers() (users []User, err error) {
var udata usersData var udata usersData
uri := "/v1/user" uri := "/v1/user"
err = self.doJsonRequest("GET", uri, nil, &udata) err = client.doJsonRequest("GET", uri, nil, &udata)
users = udata.Users users = udata.Users
return return
} }
@ -68,23 +68,23 @@ type userData struct {
} }
// GetUser returns the user that match a handle, or an error if not found // GetUser returns the user that match a handle, or an error if not found
func (self *Client) GetUser(handle string) (user User, err error) { func (client *Client) GetUser(handle string) (user User, err error) {
var udata userData var udata userData
uri := "/v1/user/" + handle uri := "/v1/user/" + handle
err = self.doJsonRequest("GET", uri, nil, &udata) err = client.doJsonRequest("GET", uri, nil, &udata)
user = udata.User user = udata.User
return return
} }
// UpdateUser updates a user with the content of `user`, // UpdateUser updates a user with the content of `user`,
// and returns an error if the update failed // and returns an error if the update failed
func (self *Client) UpdateUser(user User) error { func (client *Client) UpdateUser(user User) error {
uri := "/v1/user/" + user.Handle uri := "/v1/user/" + user.Handle
return self.doJsonRequest("PUT", uri, user, nil) return client.doJsonRequest("PUT", uri, user, nil)
} }
// DeleteUser deletes a user and returns an error if deletion failed // DeleteUser deletes a user and returns an error if deletion failed
func (self *Client) DeleteUser(handle string) error { func (client *Client) DeleteUser(handle string) error {
uri := "/v1/user/" + handle uri := "/v1/user/" + handle
return self.doJsonRequest("DELETE", uri, nil, nil) return client.doJsonRequest("DELETE", uri, nil, nil)
} }

6
vendor/vendor.json vendored
View File

@ -2316,10 +2316,10 @@
"revision": "75ce5fbba34b1912a3641adbd58cf317d7315821" "revision": "75ce5fbba34b1912a3641adbd58cf317d7315821"
}, },
{ {
"checksumSHA1": "U817qc0NaamC2zeUcZknLpnkrOw=", "checksumSHA1": "yMIu8wtilcyADHouhDllFm+kovE=",
"path": "github.com/zorkian/go-datadog-api", "path": "github.com/zorkian/go-datadog-api",
"revision": "73d5b59ca18ee5e94fb449e001ed3f724fa0634e", "revision": "a0a72fc5e4cae721b5144ba785f07f4edcf2cd47",
"revisionTime": "2016-11-30T17:19:56Z" "revisionTime": "2016-12-07T17:41:01Z"
}, },
{ {
"path": "golang.org/x/crypto/curve25519", "path": "golang.org/x/crypto/curve25519",