1
0
mirror of https://github.com/taigrr/wtf synced 2025-01-18 04:03:14 -08:00

Add initial datadog widget

This commit is contained in:
Sean Smith 2018-08-18 17:32:18 -04:00
parent 816a3d4194
commit 07ee35b0ca
46 changed files with 16566 additions and 0 deletions

17
Gopkg.lock generated
View File

@ -73,6 +73,14 @@
pruneopts = "UT"
revision = "5f41b7c9d92de5d74bf32f4486375c7547bc8a3c"
[[projects]]
digest = "1:2209584c0f7c9b68c23374e659357ab546e1b70eec2761f03280f69a8fd23d77"
name = "github.com/cenkalti/backoff"
packages = ["."]
pruneopts = "UT"
revision = "2ea60e5f094469f9e65adb9cd103795b73ae743e"
version = "v2.0.0"
[[projects]]
branch = "master"
digest = "1:710109527a119c813d4fac773712dd92f449ed7c2f7b81f49822f94d290c8f72"
@ -247,6 +255,14 @@
pruneopts = "UT"
revision = "7c9c2852e8f9e69a80bff4f4f1fe4cdd15eeba19"
[[projects]]
branch = "master"
digest = "1:f6f2814b88ad3dd5ca45e1e9a7a0caba1ddb1bfaf1c4173ebd991d854e1669eb"
name = "github.com/zorkian/go-datadog-api"
packages = ["."]
pruneopts = "UT"
revision = "d7b8b10db6a7eb1c1c2424b10a795a1662e80c9a"
[[projects]]
branch = "master"
digest = "1:d6b719875cf8091fbab38527d81d34e71f4521b9ee9ccfbd4a32cff2ac5af96e"
@ -348,6 +364,7 @@
"github.com/stretchr/testify/assert",
"github.com/xanzy/go-gitlab",
"github.com/yfronto/newrelic",
"github.com/zorkian/go-datadog-api",
"golang.org/x/oauth2",
"golang.org/x/oauth2/google",
"google.golang.org/api/calendar/v3",

View File

@ -92,3 +92,8 @@
[prune]
go-tests = true
unused-packages = true
[[constraint]]
branch = "master"
name = "github.com/zorkian/go-datadog-api"

View File

@ -0,0 +1,59 @@
---
title: "Datadog"
date: 2018-08-18T00:00:00Z
draft: false
weight: 160
---
<img class="screenshot" src="/imgs/modules/newrelic.png" width="640" height="189" alt="newrelic screenshot" />
Connects to the Datadog API and displays alerting modules
## Source Code
```bash
wtf/datadog/
```
## Configuration
```yaml
datadog:
apiKey: "<yourapikey>"
applicationKey: "<yourapplicationkey>"
enabled: true
position:
top: 4
left: 3
height: 1
width: 2
monitors:
tags:
- "team:ops"
```
### Attributes
`apiKey` <br />
Value: Your <a href="https://docs.datadoghq.com/api/?lang=python#overview">Datadog API</a> key.
`applicationKey` <br />
The integer ID of the New Relic application you wish to report on. <br/>
Value: Your <a href="https://docs.datadoghq.com/api/?lang=python#overview">Datadog Application</a> key.
`monitors` <br />
Configuration for the monitors functionality.
`tags` <br />
Array of tags you want to query monitors by.
`enabled` <br />
Determines whether or not this module is executed and if its data displayed onscreen. <br />
Values: `true`, `false`.
`position` <br />
Defines where in the grid this module's widget will be displayed. <br />
`refreshInterval` <br />
How often, in seconds, this module will update its data. <br />
Values: A positive integer, `0..n`.

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

34
datadog/client.go Normal file
View File

@ -0,0 +1,34 @@
package datadog
import (
"os"
"github.com/senorprogrammer/wtf/wtf"
datadog "github.com/zorkian/go-datadog-api"
)
// Monitors returns a list of newrelic monitors
func Monitors() ([]datadog.Monitor, error) {
client := datadog.NewClient(apiKey(), applicationKey())
monitors, err := client.GetMonitorsByTags(wtf.ToStrs(wtf.Config.UList("wtf.mods.datadog.monitors.tags")))
if err != nil {
return nil, err
}
return monitors, nil
}
func apiKey() string {
return wtf.Config.UString(
"wtf.mods.datadog.apiKey",
os.Getenv("WTF_DATADOG_API_KEY"),
)
}
func applicationKey() string {
return wtf.Config.UString(
"wtf.mods.datadog.applicationKey",
os.Getenv("WTF_DATADOG_APPLICATION_KEY"),
)
}

73
datadog/widget.go Normal file
View File

@ -0,0 +1,73 @@
package datadog
import (
"fmt"
"github.com/senorprogrammer/wtf/wtf"
datadog "github.com/zorkian/go-datadog-api"
)
type Widget struct {
wtf.TextWidget
}
func NewWidget() *Widget {
widget := Widget{
TextWidget: wtf.NewTextWidget("Datadog", "datadog", false),
}
return &widget
}
/* -------------------- Exported Functions -------------------- */
func (widget *Widget) Refresh() {
monitors, monitorErr := Monitors()
widget.UpdateRefreshedAt()
widget.View.SetTitle(widget.ContextualTitle(fmt.Sprintf("%s", widget.Name)))
widget.View.Clear()
var content string
if monitorErr != nil {
widget.View.SetWrap(true)
content = monitorErr.Error()
} else {
widget.View.SetWrap(false)
content = widget.contentFrom(monitors)
}
widget.View.SetText(content)
}
/* -------------------- Unexported Functions -------------------- */
func (widget *Widget) contentFrom(monitors []datadog.Monitor) string {
var str string
triggeredMonitors := []datadog.Monitor{}
for _, monitor := range monitors {
state := *monitor.OverallState
switch state {
case "Alert":
triggeredMonitors = append(triggeredMonitors, monitor)
}
}
if len(triggeredMonitors) > 0 {
str = str + fmt.Sprintf(
" %s\n",
"[red]Triggered Monitors[white]",
)
for _, triggeredMonitor := range triggeredMonitors {
str = str + fmt.Sprintf("[red] %s\n", *triggeredMonitor.Name)
}
} else {
str = str + fmt.Sprintf(
" %s\n",
"[green]No Triggered Monitors[white]",
)
}
return str
}

View File

@ -20,6 +20,7 @@ import (
"github.com/senorprogrammer/wtf/cryptoexchanges/bittrex"
"github.com/senorprogrammer/wtf/cryptoexchanges/blockfolio"
"github.com/senorprogrammer/wtf/cryptoexchanges/cryptolive"
"github.com/senorprogrammer/wtf/datadog"
"github.com/senorprogrammer/wtf/flags"
"github.com/senorprogrammer/wtf/gcal"
"github.com/senorprogrammer/wtf/gerrit"
@ -195,6 +196,8 @@ func addWidget(app *tview.Application, pages *tview.Pages, widgetName string) {
widgets = append(widgets, cmdrunner.NewWidget())
case "cryptolive":
widgets = append(widgets, cryptolive.NewWidget())
case "datadog":
widgets = append(widgets, datadog.NewWidget())
case "gcal":
widgets = append(widgets, gcal.NewWidget())
case "gerrit":

22
vendor/github.com/cenkalti/backoff/.gitignore generated vendored Normal file
View File

@ -0,0 +1,22 @@
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
*.so
# Folders
_obj
_test
# Architecture specific extensions/prefixes
*.[568vq]
[568vq].out
*.cgo1.go
*.cgo2.c
_cgo_defun.c
_cgo_gotypes.go
_cgo_export.*
_testmain.go
*.exe

10
vendor/github.com/cenkalti/backoff/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,10 @@
language: go
go:
- 1.3.3
- 1.x
- tip
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -service=travis-ci

20
vendor/github.com/cenkalti/backoff/LICENSE generated vendored Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2014 Cenk Altı
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

30
vendor/github.com/cenkalti/backoff/README.md generated vendored Normal file
View File

@ -0,0 +1,30 @@
# Exponential Backoff [![GoDoc][godoc image]][godoc] [![Build Status][travis image]][travis] [![Coverage Status][coveralls image]][coveralls]
This is a Go port of the exponential backoff algorithm from [Google's HTTP Client Library for Java][google-http-java-client].
[Exponential backoff][exponential backoff wiki]
is an algorithm that uses feedback to multiplicatively decrease the rate of some process,
in order to gradually find an acceptable rate.
The retries exponentially increase and stop increasing when a certain threshold is met.
## Usage
See https://godoc.org/github.com/cenkalti/backoff#pkg-examples
## Contributing
* I would like to keep this library as small as possible.
* Please don't send a PR without opening an issue and discussing it first.
* If proposed change is not a common use case, I will probably not accept it.
[godoc]: https://godoc.org/github.com/cenkalti/backoff
[godoc image]: https://godoc.org/github.com/cenkalti/backoff?status.png
[travis]: https://travis-ci.org/cenkalti/backoff
[travis image]: https://travis-ci.org/cenkalti/backoff.png?branch=master
[coveralls]: https://coveralls.io/github/cenkalti/backoff?branch=master
[coveralls image]: https://coveralls.io/repos/github/cenkalti/backoff/badge.svg?branch=master
[google-http-java-client]: https://github.com/google/google-http-java-client
[exponential backoff wiki]: http://en.wikipedia.org/wiki/Exponential_backoff
[advanced example]: https://godoc.org/github.com/cenkalti/backoff#example_

66
vendor/github.com/cenkalti/backoff/backoff.go generated vendored Normal file
View File

@ -0,0 +1,66 @@
// Package backoff implements backoff algorithms for retrying operations.
//
// Use Retry function for retrying operations that may fail.
// If Retry does not meet your needs,
// copy/paste the function into your project and modify as you wish.
//
// There is also Ticker type similar to time.Ticker.
// You can use it if you need to work with channels.
//
// See Examples section below for usage examples.
package backoff
import "time"
// BackOff is a backoff policy for retrying an operation.
type BackOff interface {
// NextBackOff returns the duration to wait before retrying the operation,
// or backoff. Stop to indicate that no more retries should be made.
//
// Example usage:
//
// duration := backoff.NextBackOff();
// if (duration == backoff.Stop) {
// // Do not retry operation.
// } else {
// // Sleep for duration and retry operation.
// }
//
NextBackOff() time.Duration
// Reset to initial state.
Reset()
}
// Stop indicates that no more retries should be made for use in NextBackOff().
const Stop time.Duration = -1
// ZeroBackOff is a fixed backoff policy whose backoff time is always zero,
// meaning that the operation is retried immediately without waiting, indefinitely.
type ZeroBackOff struct{}
func (b *ZeroBackOff) Reset() {}
func (b *ZeroBackOff) NextBackOff() time.Duration { return 0 }
// StopBackOff is a fixed backoff policy that always returns backoff.Stop for
// NextBackOff(), meaning that the operation should never be retried.
type StopBackOff struct{}
func (b *StopBackOff) Reset() {}
func (b *StopBackOff) NextBackOff() time.Duration { return Stop }
// ConstantBackOff is a backoff policy that always returns the same backoff delay.
// This is in contrast to an exponential backoff policy,
// which returns a delay that grows longer as you call NextBackOff() over and over again.
type ConstantBackOff struct {
Interval time.Duration
}
func (b *ConstantBackOff) Reset() {}
func (b *ConstantBackOff) NextBackOff() time.Duration { return b.Interval }
func NewConstantBackOff(d time.Duration) *ConstantBackOff {
return &ConstantBackOff{Interval: d}
}

60
vendor/github.com/cenkalti/backoff/context.go generated vendored Normal file
View File

@ -0,0 +1,60 @@
package backoff
import (
"time"
"golang.org/x/net/context"
)
// BackOffContext is a backoff policy that stops retrying after the context
// is canceled.
type BackOffContext interface {
BackOff
Context() context.Context
}
type backOffContext struct {
BackOff
ctx context.Context
}
// WithContext returns a BackOffContext with context ctx
//
// ctx must not be nil
func WithContext(b BackOff, ctx context.Context) BackOffContext {
if ctx == nil {
panic("nil context")
}
if b, ok := b.(*backOffContext); ok {
return &backOffContext{
BackOff: b.BackOff,
ctx: ctx,
}
}
return &backOffContext{
BackOff: b,
ctx: ctx,
}
}
func ensureContext(b BackOff) BackOffContext {
if cb, ok := b.(BackOffContext); ok {
return cb
}
return WithContext(b, context.Background())
}
func (b *backOffContext) Context() context.Context {
return b.ctx
}
func (b *backOffContext) NextBackOff() time.Duration {
select {
case <-b.Context().Done():
return Stop
default:
return b.BackOff.NextBackOff()
}
}

158
vendor/github.com/cenkalti/backoff/exponential.go generated vendored Normal file
View File

@ -0,0 +1,158 @@
package backoff
import (
"math/rand"
"time"
)
/*
ExponentialBackOff is a backoff implementation that increases the backoff
period for each retry attempt using a randomization function that grows exponentially.
NextBackOff() is calculated using the following formula:
randomized interval =
RetryInterval * (random value in range [1 - RandomizationFactor, 1 + RandomizationFactor])
In other words NextBackOff() will range between the randomization factor
percentage below and above the retry interval.
For example, given the following parameters:
RetryInterval = 2
RandomizationFactor = 0.5
Multiplier = 2
the actual backoff period used in the next retry attempt will range between 1 and 3 seconds,
multiplied by the exponential, that is, between 2 and 6 seconds.
Note: MaxInterval caps the RetryInterval and not the randomized interval.
If the time elapsed since an ExponentialBackOff instance is created goes past the
MaxElapsedTime, then the method NextBackOff() starts returning backoff.Stop.
The elapsed time can be reset by calling Reset().
Example: Given the following default arguments, for 10 tries the sequence will be,
and assuming we go over the MaxElapsedTime on the 10th try:
Request # RetryInterval (seconds) Randomized Interval (seconds)
1 0.5 [0.25, 0.75]
2 0.75 [0.375, 1.125]
3 1.125 [0.562, 1.687]
4 1.687 [0.8435, 2.53]
5 2.53 [1.265, 3.795]
6 3.795 [1.897, 5.692]
7 5.692 [2.846, 8.538]
8 8.538 [4.269, 12.807]
9 12.807 [6.403, 19.210]
10 19.210 backoff.Stop
Note: Implementation is not thread-safe.
*/
type ExponentialBackOff struct {
InitialInterval time.Duration
RandomizationFactor float64
Multiplier float64
MaxInterval time.Duration
// After MaxElapsedTime the ExponentialBackOff stops.
// It never stops if MaxElapsedTime == 0.
MaxElapsedTime time.Duration
Clock Clock
currentInterval time.Duration
startTime time.Time
random *rand.Rand
}
// Clock is an interface that returns current time for BackOff.
type Clock interface {
Now() time.Time
}
// Default values for ExponentialBackOff.
const (
DefaultInitialInterval = 500 * time.Millisecond
DefaultRandomizationFactor = 0.5
DefaultMultiplier = 1.5
DefaultMaxInterval = 60 * time.Second
DefaultMaxElapsedTime = 15 * time.Minute
)
// NewExponentialBackOff creates an instance of ExponentialBackOff using default values.
func NewExponentialBackOff() *ExponentialBackOff {
b := &ExponentialBackOff{
InitialInterval: DefaultInitialInterval,
RandomizationFactor: DefaultRandomizationFactor,
Multiplier: DefaultMultiplier,
MaxInterval: DefaultMaxInterval,
MaxElapsedTime: DefaultMaxElapsedTime,
Clock: SystemClock,
random: rand.New(rand.NewSource(time.Now().UnixNano())),
}
b.Reset()
return b
}
type systemClock struct{}
func (t systemClock) Now() time.Time {
return time.Now()
}
// SystemClock implements Clock interface that uses time.Now().
var SystemClock = systemClock{}
// Reset the interval back to the initial retry interval and restarts the timer.
func (b *ExponentialBackOff) Reset() {
b.currentInterval = b.InitialInterval
b.startTime = b.Clock.Now()
}
// NextBackOff calculates the next backoff interval using the formula:
// Randomized interval = RetryInterval +/- (RandomizationFactor * RetryInterval)
func (b *ExponentialBackOff) NextBackOff() time.Duration {
// Make sure we have not gone over the maximum elapsed time.
if b.MaxElapsedTime != 0 && b.GetElapsedTime() > b.MaxElapsedTime {
return Stop
}
defer b.incrementCurrentInterval()
if b.random == nil {
b.random = rand.New(rand.NewSource(time.Now().UnixNano()))
}
return getRandomValueFromInterval(b.RandomizationFactor, b.random.Float64(), b.currentInterval)
}
// GetElapsedTime returns the elapsed time since an ExponentialBackOff instance
// is created and is reset when Reset() is called.
//
// The elapsed time is computed using time.Now().UnixNano(). It is
// safe to call even while the backoff policy is used by a running
// ticker.
func (b *ExponentialBackOff) GetElapsedTime() time.Duration {
return b.Clock.Now().Sub(b.startTime)
}
// Increments the current interval by multiplying it with the multiplier.
func (b *ExponentialBackOff) incrementCurrentInterval() {
// Check for overflow, if overflow is detected set the current interval to the max interval.
if float64(b.currentInterval) >= float64(b.MaxInterval)/b.Multiplier {
b.currentInterval = b.MaxInterval
} else {
b.currentInterval = time.Duration(float64(b.currentInterval) * b.Multiplier)
}
}
// Returns a random value from the following interval:
// [randomizationFactor * currentInterval, randomizationFactor * currentInterval].
func getRandomValueFromInterval(randomizationFactor, random float64, currentInterval time.Duration) time.Duration {
var delta = randomizationFactor * float64(currentInterval)
var minInterval = float64(currentInterval) - delta
var maxInterval = float64(currentInterval) + delta
// Get a random value from the range [minInterval, maxInterval].
// The formula used below has a +1 because if the minInterval is 1 and the maxInterval is 3 then
// we want a 33% chance for selecting either 1, 2 or 3.
return time.Duration(minInterval + (random * (maxInterval - minInterval + 1)))
}

78
vendor/github.com/cenkalti/backoff/retry.go generated vendored Normal file
View File

@ -0,0 +1,78 @@
package backoff
import "time"
// An Operation is executing by Retry() or RetryNotify().
// The operation will be retried using a backoff policy if it returns an error.
type Operation func() error
// Notify is a notify-on-error function. It receives an operation error and
// backoff delay if the operation failed (with an error).
//
// NOTE that if the backoff policy stated to stop retrying,
// the notify function isn't called.
type Notify func(error, time.Duration)
// Retry the operation o until it does not return error or BackOff stops.
// o is guaranteed to be run at least once.
// It is the caller's responsibility to reset b after Retry returns.
//
// If o returns a *PermanentError, the operation is not retried, and the
// wrapped error is returned.
//
// Retry sleeps the goroutine for the duration returned by BackOff after a
// failed operation returns.
func Retry(o Operation, b BackOff) error { return RetryNotify(o, b, nil) }
// RetryNotify calls notify function with the error and wait duration
// for each failed attempt before sleep.
func RetryNotify(operation Operation, b BackOff, notify Notify) error {
var err error
var next time.Duration
cb := ensureContext(b)
b.Reset()
for {
if err = operation(); err == nil {
return nil
}
if permanent, ok := err.(*PermanentError); ok {
return permanent.Err
}
if next = b.NextBackOff(); next == Stop {
return err
}
if notify != nil {
notify(err, next)
}
t := time.NewTimer(next)
select {
case <-cb.Context().Done():
t.Stop()
return err
case <-t.C:
}
}
}
// PermanentError signals that the operation should not be retried.
type PermanentError struct {
Err error
}
func (e *PermanentError) Error() string {
return e.Err.Error()
}
// Permanent wraps the given err in a *PermanentError.
func Permanent(err error) *PermanentError {
return &PermanentError{
Err: err,
}
}

84
vendor/github.com/cenkalti/backoff/ticker.go generated vendored Normal file
View File

@ -0,0 +1,84 @@
package backoff
import (
"runtime"
"sync"
"time"
)
// Ticker holds a channel that delivers `ticks' of a clock at times reported by a BackOff.
//
// Ticks will continue to arrive when the previous operation is still running,
// so operations that take a while to fail could run in quick succession.
type Ticker struct {
C <-chan time.Time
c chan time.Time
b BackOffContext
stop chan struct{}
stopOnce sync.Once
}
// NewTicker returns a new Ticker containing a channel that will send
// the time at times specified by the BackOff argument. Ticker is
// guaranteed to tick at least once. The channel is closed when Stop
// method is called or BackOff stops. It is not safe to manipulate the
// provided backoff policy (notably calling NextBackOff or Reset)
// while the ticker is running.
func NewTicker(b BackOff) *Ticker {
c := make(chan time.Time)
t := &Ticker{
C: c,
c: c,
b: ensureContext(b),
stop: make(chan struct{}),
}
t.b.Reset()
go t.run()
runtime.SetFinalizer(t, (*Ticker).Stop)
return t
}
// Stop turns off a ticker. After Stop, no more ticks will be sent.
func (t *Ticker) Stop() {
t.stopOnce.Do(func() { close(t.stop) })
}
func (t *Ticker) run() {
c := t.c
defer close(c)
// Ticker is guaranteed to tick at least once.
afterC := t.send(time.Now())
for {
if afterC == nil {
return
}
select {
case tick := <-afterC:
afterC = t.send(tick)
case <-t.stop:
t.c = nil // Prevent future ticks from being sent to the channel.
return
case <-t.b.Context().Done():
return
}
}
}
func (t *Ticker) send(tick time.Time) <-chan time.Time {
select {
case t.c <- tick:
case <-t.stop:
return nil
}
next := t.b.NextBackOff()
if next == Stop {
t.Stop()
return nil
}
return time.After(next)
}

35
vendor/github.com/cenkalti/backoff/tries.go generated vendored Normal file
View File

@ -0,0 +1,35 @@
package backoff
import "time"
/*
WithMaxRetries creates a wrapper around another BackOff, which will
return Stop if NextBackOff() has been called too many times since
the last time Reset() was called
Note: Implementation is not thread-safe.
*/
func WithMaxRetries(b BackOff, max uint64) BackOff {
return &backOffTries{delegate: b, maxTries: max}
}
type backOffTries struct {
delegate BackOff
maxTries uint64
numTries uint64
}
func (b *backOffTries) NextBackOff() time.Duration {
if b.maxTries > 0 {
if b.maxTries <= b.numTries {
return Stop
}
b.numTries++
}
return b.delegate.NextBackOff()
}
func (b *backOffTries) Reset() {
b.numTries = 0
b.delegate.Reset()
}

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

@ -0,0 +1,2 @@
*.sublime*
cmd

26
vendor/github.com/zorkian/go-datadog-api/.travis.yml generated vendored Normal file
View File

@ -0,0 +1,26 @@
language: go
go:
- "1.7"
- "1.8"
- "1.9"
- "1.10.x"
- "tip"
env:
- "PATH=/home/travis/gopath/bin:$PATH"
install:
- go get -v -t .
script:
- go get -u github.com/golang/lint/golint
- golint ./... | grep -v vendor/
- make
- scripts/check-code-generation-ran.sh
# PR's don't have access to Travis EnvVars with DDog API Keys. Skip acceptance tests on PR.
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then make testacc; fi'
matrix:
allow_failures:
- go: tip

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

@ -0,0 +1,30 @@
Copyright (c) 2013 by authors and contributors.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the <organization> nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER>
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
THE POSSIBILITY OF SUCH DAMAGE.

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

@ -0,0 +1,40 @@
TEST?=$$(go list ./... | grep -v '/go-datadog-api/vendor/')
VETARGS?=-asmdecl -atomic -bool -buildtags -copylocks -methods -nilfunc -printf -rangeloops -shift -structtags -unsafeptr
GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor)
default: test fmt
generate:
go generate
# test runs the unit tests and vets the code
test:
go test . $(TESTARGS) -v -timeout=30s -parallel=4
@$(MAKE) vet
# testacc runs acceptance tests
testacc:
go test integration/* -v $(TESTARGS) -timeout 90m
# testrace runs the race checker
testrace:
go test -race $(TEST) $(TESTARGS)
fmt:
gofmt -w $(GOFMT_FILES)
# vet runs the Go source code static analysis tool `vet` to find
# any common errors.
vet:
@go tool vet 2>/dev/null ; if [ $$? -eq 3 ]; then \
go get golang.org/x/tools/cmd/vet; \
fi
@echo "go tool vet $(VETARGS)"
@go tool vet $(VETARGS) $$(ls -d */ | grep -v vendor) ; if [ $$? -eq 1 ]; then \
echo ""; \
echo "Vet found suspicious constructs. Please check the reported constructs"; \
echo "and fix them if necessary before submitting the code for review."; \
exit 1; \
fi
.PHONY: default test testacc updatedeps vet

120
vendor/github.com/zorkian/go-datadog-api/README.md generated vendored Normal file
View File

@ -0,0 +1,120 @@
[![GoDoc](http://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/gopkg.in/zorkian/go-datadog-api.v2)
[![License](https://img.shields.io/badge/License-BSD%203--Clause-blue.svg)](https://opensource.org/licenses/BSD-3-Clause)
[![Build
status](https://travis-ci.org/zorkian/go-datadog-api.svg)](https://travis-ci.org/zorkian/go-datadog-api)
[![Go Report Card](https://goreportcard.com/badge/github.com/zorkian/go-datadog-api)](https://goreportcard.com/report/github.com/zorkian/go-datadog-api)
# Datadog API in Go
**This is the v2.0 version of the API, and has breaking changes. Use the v1.0 branch if you need
legacy code to be supported.**
A Go wrapper for the Datadog API. Use this library if you need to interact
with the Datadog system. You can post metrics with it if you want, but this library is probably
mostly used for automating dashboards/alerting and retrieving data (events, etc).
The source API documentation is here: <http://docs.datadoghq.com/api/>
## Installation
To use the default branch, include it in your code like:
```go
import "github.com/zorkian/go-datadog-api"
```
Or, if you need to control which version to use, import using [gopkg.in](http://labix.org/gopkg.in). Like so:
```go
import "gopkg.in/zorkian/go-datadog-api.v2"
```
Using go get:
```bash
go get gopkg.in/zorkian/go-datadog-api.v2
```
## USAGE
This library uses pointers to be able to verify if values are set or not (vs the default value for the type). Like
protobuf there are helpers to enhance the API. You can decide to not use them, but you'll have to be careful handling
nil pointers.
Using the client:
```go
client := datadog.NewClient("api key", "application key")
dash, err := client.GetDashboard(*datadog.Int(10880))
if err != nil {
log.Fatalf("fatal: %s\n", err)
}
log.Printf("dashboard %d: %s\n", dash.GetId(), dash.GetTitle())
```
An example using datadog.String(), which allocates a pointer for you:
```go
m := datadog.Monitor{
Name: datadog.String("Monitor other things"),
Creator: &datadog.Creator{
Name: datadog.String("Joe Creator"),
},
}
```
An example using the SetXx, HasXx, GetXx and GetXxOk accessors:
```go
m := datadog.Monitor{}
m.SetName("Monitor all the things")
m.SetMessage("Electromagnetic energy loss")
// Use HasMessage(), to verify we have interest in the message.
// Using GetMessage() always safe as it returns the actual or, if never set, default value for that type.
if m.HasMessage() {
fmt.Printf("Found message %s\n", m.GetMessage())
}
// Alternatively, use GetMessageOk(), it returns a tuple with the (default) value and a boolean expressing
// if it was set at all:
if v, ok := m.GetMessageOk(); ok {
fmt.Printf("Found message %s\n", v)
}
```
Check out the Godoc link for the available API methods and, if you can't find the one you need,
let us know (or patches welcome)!
## DOCUMENTATION
Please see: <https://godoc.org/gopkg.in/zorkian/go-datadog-api.v2>
## BUGS/PROBLEMS/CONTRIBUTING
There are certainly some, but presently no known major bugs. If you do
find something that doesn't work as expected, please file an issue on
Github:
<https://github.com/zorkian/go-datadog-api/issues>
Thanks in advance! And, as always, patches welcome!
## DEVELOPMENT
### Running tests
* Run tests tests with `make test`.
* 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
in your environment variables.
*Warning: the integrations tests will create and remove real resources in your Datadog account.*
### Regenerating code
Accessors `HasXx`, `GetXx`, `GetOkXx` and `SetXx` are generated for each struct field type type that contains pointers.
When structs are updated a contributor has to regenerate these using `go generate` and commit these changes.
Optionally there is a make target for the generation:
```bash
make generate
```
## COPYRIGHT AND LICENSE
Please see the LICENSE file for the included license information.
Copyright 2013-2017 by authors and contributors.

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

@ -0,0 +1,82 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import (
"fmt"
)
// Alert represents the data of an alert: a query that can fire and send a
// message to the users.
type Alert struct {
Id *int `json:"id,omitempty"`
Creator *int `json:"creator,omitempty"`
Query *string `json:"query,omitempty"`
Name *string `json:"name,omitempty"`
Message *string `json:"message,omitempty"`
Silenced *bool `json:"silenced,omitempty"`
NotifyNoData *bool `json:"notify_no_data,omitempty"`
State *string `json:"state,omitempty"`
}
// reqAlerts receives a slice of all alerts.
type reqAlerts struct {
Alerts []Alert `json:"alerts,omitempty"`
}
// 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.
func (client *Client) CreateAlert(alert *Alert) (*Alert, error) {
var out Alert
if err := client.doJsonRequest("POST", "/v1/alert", alert, &out); err != nil {
return nil, err
}
return &out, nil
}
// UpdateAlert takes an alert that was previously retrieved through some method
// and sends it back to the server.
func (client *Client) UpdateAlert(alert *Alert) error {
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/alert/%d", alert.Id),
alert, nil)
}
// GetAlert retrieves an alert by identifier.
func (client *Client) GetAlert(id int) (*Alert, error) {
var out Alert
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/alert/%d", id), nil, &out); err != nil {
return nil, err
}
return &out, nil
}
// DeleteAlert removes an alert from the system.
func (client *Client) DeleteAlert(id int) error {
return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/alert/%d", id),
nil, nil)
}
// GetAlerts returns a slice of all alerts.
func (client *Client) GetAlerts() ([]Alert, error) {
var out reqAlerts
if err := client.doJsonRequest("GET", "/v1/alert", nil, &out); err != nil {
return nil, err
}
return out.Alerts, nil
}
// MuteAlerts turns off alerting notifications.
func (client *Client) MuteAlerts() error {
return client.doJsonRequest("POST", "/v1/mute_alerts", nil, nil)
}
// UnmuteAlerts turns on alerting notifications.
func (client *Client) UnmuteAlerts() error {
return client.doJsonRequest("POST", "/v1/unmute_alerts", nil, nil)
}

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,omitempty"`
HostName *string `json:"host_name,omitempty"`
Status *Status `json:"status,omitempty"`
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)
}

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

@ -0,0 +1,100 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import (
"encoding/json"
"io/ioutil"
"net/http"
"os"
"time"
)
// 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, baseUrl string
//The Http Client that is used to make requests
HttpClient *http.Client
RetryTimeout time.Duration
}
// 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 {
baseUrl := os.Getenv("DATADOG_HOST")
if baseUrl == "" {
baseUrl = "https://app.datadoghq.com"
}
return &Client{
apiKey: apiKey,
appKey: appKey,
baseUrl: baseUrl,
HttpClient: http.DefaultClient,
RetryTimeout: time.Duration(60 * time.Second),
}
}
// SetKeys changes the value of apiKey and appKey.
func (c *Client) SetKeys(apiKey, appKey string) {
c.apiKey = apiKey
c.appKey = appKey
}
// SetBaseUrl changes the value of baseUrl.
func (c *Client) SetBaseUrl(baseUrl string) {
c.baseUrl = baseUrl
}
// GetBaseUrl returns the baseUrl.
func (c *Client) GetBaseUrl() string {
return c.baseUrl
}
// Validate checks if the API and application keys are valid.
func (client *Client) Validate() (bool, error) {
var out valid
var resp *http.Response
uri, err := client.uriForAPI("/v1/validate")
if err != nil {
return false, err
}
req, err := http.NewRequest("GET", uri, nil)
if err != nil {
return false, err
}
resp, err = client.doRequestWithRetries(req, client.RetryTimeout)
if err != nil {
return false, err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return false, err
}
if err = json.Unmarshal(body, &out); err != nil {
return false, err
}
return out.IsValid, nil
}

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

@ -0,0 +1,72 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import (
"fmt"
)
// Comment is a special form of event that appears in a stream.
type Comment struct {
Id *int `json:"id,omitempty"`
RelatedId *int `json:"related_event_id,omitempty"`
Handle *string `json:"handle,omitempty"`
Message *string `json:"message,omitempty"`
Resource *string `json:"resource,omitempty"`
Url *string `json:"url,omitempty"`
}
// reqComment is the container for receiving commenst.
type reqComment struct {
Comment *Comment `json:"comment,omitempty"`
}
// CreateComment adds a new comment to the system.
func (client *Client) CreateComment(handle, message string) (*Comment, error) {
var out reqComment
comment := Comment{Message: String(message)}
if len(handle) > 0 {
comment.Handle = String(handle)
}
if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
return nil, err
}
return out.Comment, nil
}
// CreateRelatedComment adds a new comment, but lets you specify the related
// identifier for the comment.
func (client *Client) CreateRelatedComment(handle, message string,
relid int) (*Comment, error) {
var out reqComment
comment := Comment{Message: String(message), RelatedId: Int(relid)}
if len(handle) > 0 {
comment.Handle = String(handle)
}
if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
return nil, err
}
return out.Comment, nil
}
// EditComment changes the message and possibly handle of a particular comment.
func (client *Client) EditComment(id int, handle, message string) error {
comment := Comment{Message: String(message)}
if len(handle) > 0 {
comment.Handle = String(handle)
}
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/comments/%d", id),
&comment, nil)
}
// DeleteComment does exactly what you expect.
func (client *Client) DeleteComment(id int) error {
return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/comments/%d", id),
nil, nil)
}

View File

@ -0,0 +1,137 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2018 by authors and contributors.
*/
package datadog
import (
"fmt"
)
const (
DashboardListItemCustomTimeboard = "custom_timeboard"
DashboardListItemCustomScreenboard = "custom_screenboard"
DashboardListItemIntegerationTimeboard = "integration_timeboard"
DashboardListItemIntegrationScreenboard = "integration_screenboard"
DashboardListItemHostTimeboard = "host_timeboard"
)
// DashboardList represents a dashboard list.
type DashboardList struct {
Id *int `json:"id,omitempty"`
Name *string `json:"name,omitempty"`
DashboardCount *int `json:"dashboard_count,omitempty"`
}
// DashboardListItem represents a single dashboard in a dashboard list.
type DashboardListItem struct {
Id *int `json:"id,omitempty"`
Type *string `json:"type,omitempty"`
}
type reqDashboardListItems struct {
Dashboards []DashboardListItem `json:"dashboards,omitempty"`
}
type reqAddedDashboardListItems struct {
Dashboards []DashboardListItem `json:"added_dashboards_to_list,omitempty"`
}
type reqDeletedDashboardListItems struct {
Dashboards []DashboardListItem `json:"deleted_dashboards_from_list,omitempty"`
}
type reqUpdateDashboardList struct {
Name string `json:"name,omitempty"`
}
type reqGetDashboardLists struct {
DashboardLists []DashboardList `json:"dashboard_lists,omitempty"`
}
// GetDashboardList returns a single dashboard list created on this account.
func (client *Client) GetDashboardList(id int) (*DashboardList, error) {
var out DashboardList
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/dashboard/lists/manual/%d", id), nil, &out); err != nil {
return nil, err
}
return &out, nil
}
// GetDashboardLists returns a list of all dashboard lists created on this account.
func (client *Client) GetDashboardLists() ([]DashboardList, error) {
var out reqGetDashboardLists
if err := client.doJsonRequest("GET", "/v1/dashboard/lists/manual", nil, &out); err != nil {
return nil, err
}
return out.DashboardLists, nil
}
// CreateDashboardList returns a single dashboard list created on this account.
func (client *Client) CreateDashboardList(list *DashboardList) (*DashboardList, error) {
var out DashboardList
if err := client.doJsonRequest("POST", "/v1/dashboard/lists/manual", list, &out); err != nil {
return nil, err
}
return &out, nil
}
// UpdateDashboardList returns a single dashboard list created on this account.
func (client *Client) UpdateDashboardList(list *DashboardList) error {
req := reqUpdateDashboardList{list.GetName()}
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/dashboard/lists/manual/%d", *list.Id), req, nil)
}
// DeleteDashboardList deletes a dashboard list by the identifier.
func (client *Client) DeleteDashboardList(id int) error {
return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/dashboard/lists/manual/%d", id), nil, nil)
}
// GetDashboardListItems fetches the dashboard list's dashboard definitions.
func (client *Client) GetDashboardListItems(id int) ([]DashboardListItem, error) {
var out reqDashboardListItems
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/dashboard/lists/manual/%d/dashboards", id), nil, &out); err != nil {
return nil, err
}
return out.Dashboards, nil
}
// AddDashboardListItems adds dashboards to an existing dashboard list.
//
// Any items already in the list are ignored (not added twice).
func (client *Client) AddDashboardListItems(dashboardListId int, items []DashboardListItem) ([]DashboardListItem, error) {
req := reqDashboardListItems{items}
var out reqAddedDashboardListItems
if err := client.doJsonRequest("POST", fmt.Sprintf("/v1/dashboard/lists/manual/%d/dashboards", dashboardListId), req, &out); err != nil {
return nil, err
}
return out.Dashboards, nil
}
// UpdateDashboardListItems updates dashboards of an existing dashboard list.
//
// This will set the list of dashboards to contain only the items in items.
func (client *Client) UpdateDashboardListItems(dashboardListId int, items []DashboardListItem) ([]DashboardListItem, error) {
req := reqDashboardListItems{items}
var out reqDashboardListItems
if err := client.doJsonRequest("PUT", fmt.Sprintf("/v1/dashboard/lists/manual/%d/dashboards", dashboardListId), req, &out); err != nil {
return nil, err
}
return out.Dashboards, nil
}
// DeleteDashboardListItems deletes dashboards from an existing dashboard list.
//
// Deletes any dashboards in the list of items from the dashboard list.
func (client *Client) DeleteDashboardListItems(dashboardListId int, items []DashboardListItem) ([]DashboardListItem, error) {
req := reqDashboardListItems{items}
var out reqDeletedDashboardListItems
if err := client.doJsonRequest("DELETE", fmt.Sprintf("/v1/dashboard/lists/manual/%d/dashboards", dashboardListId), req, &out); err != nil {
return nil, err
}
return out.Dashboards, nil
}

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

@ -0,0 +1,182 @@
/*
* 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"
)
// GraphDefinitionRequestStyle represents the graph style attributes
type GraphDefinitionRequestStyle struct {
Palette *string `json:"palette,omitempty"`
Width *string `json:"width,omitempty"`
Type *string `json:"type,omitempty"`
}
// GraphDefinitionRequest represents the requests passed into each graph.
type GraphDefinitionRequest struct {
Query *string `json:"q,omitempty"`
Stacked *bool `json:"stacked,omitempty"`
Aggregator *string `json:"aggregator,omitempty"`
ConditionalFormats []DashboardConditionalFormat `json:"conditional_formats,omitempty"`
Type *string `json:"type,omitempty"`
Style *GraphDefinitionRequestStyle `json:"style,omitempty"`
// For change type graphs
ChangeType *string `json:"change_type,omitempty"`
OrderDirection *string `json:"order_dir,omitempty"`
CompareTo *string `json:"compare_to,omitempty"`
IncreaseGood *bool `json:"increase_good,omitempty"`
OrderBy *string `json:"order_by,omitempty"`
ExtraCol *string `json:"extra_col,omitempty"`
}
type GraphDefinitionMarker struct {
Type *string `json:"type,omitempty"`
Value *string `json:"value,omitempty"`
Label *string `json:"label,omitempty"`
Val *json.Number `json:"val,omitempty"`
Min *json.Number `json:"min,omitempty"`
Max *json.Number `json:"max,omitempty"`
}
type GraphEvent struct {
Query *string `json:"q,omitempty"`
}
type Yaxis struct {
Min *float64 `json:"min,omitempty"`
Max *float64 `json:"max,omitempty"`
Scale *string `json:"scale,omitempty"`
}
type Style struct {
Palette *string `json:"palette,omitempty"`
PaletteFlip *bool `json:"paletteFlip,omitempty"`
}
type GraphDefinition struct {
Viz *string `json:"viz,omitempty"`
Requests []GraphDefinitionRequest `json:"requests,omitempty"`
Events []GraphEvent `json:"events,omitempty"`
Markers []GraphDefinitionMarker `json:"markers,omitempty"`
// For timeseries type graphs
Yaxis Yaxis `json:"yaxis,omitempty"`
// For query value type graphs
Autoscale *bool `json:"autoscale,omitempty"`
TextAlign *string `json:"text_align,omitempty"`
Precision *string `json:"precision,omitempty"`
CustomUnit *string `json:"custom_unit,omitempty"`
// For hostname type graphs
Style *Style `json:"Style,omitempty"`
Groups []string `json:"group,omitempty"`
IncludeNoMetricHosts *bool `json:"noMetricHosts,omitempty"`
Scopes []string `json:"scope,omitempty"`
IncludeUngroupedHosts *bool `json:"noGroupHosts,omitempty"`
}
// Graph represents a graph that might exist on a dashboard.
type Graph struct {
Title *string `json:"title,omitempty"`
Definition *GraphDefinition `json:"definition"`
}
// Template variable represents a template variable that might exist on a dashboard
type TemplateVariable struct {
Name *string `json:"name,omitempty"`
Prefix *string `json:"prefix,omitempty"`
Default *string `json:"default,omitempty"`
}
// Dashboard represents a user created dashboard. This is the full dashboard
// struct when we load a dashboard in detail.
type Dashboard struct {
Id *int `json:"id,omitempty"`
Description *string `json:"description,omitempty"`
Title *string `json:"title,omitempty"`
Graphs []Graph `json:"graphs,omitempty"`
TemplateVariables []TemplateVariable `json:"template_variables,omitempty"`
ReadOnly *bool `json:"read_only,omitempty"`
}
// DashboardLite represents a user created dashboard. This is the mini
// struct when we load the summaries.
type DashboardLite struct {
Id *int `json:"id,string,omitempty"` // TODO: Remove ',string'.
Resource *string `json:"resource,omitempty"`
Description *string `json:"description,omitempty"`
Title *string `json:"title,omitempty"`
}
// reqGetDashboards from /api/v1/dash
type reqGetDashboards struct {
Dashboards []DashboardLite `json:"dashes,omitempty"`
}
// reqGetDashboard from /api/v1/dash/:dashboard_id
type reqGetDashboard struct {
Resource *string `json:"resource,omitempty"`
Url *string `json:"url,omitempty"`
Dashboard *Dashboard `json:"dash,omitempty"`
}
type DashboardConditionalFormat struct {
Palette *string `json:"palette,omitempty"`
Comparator *string `json:"comparator,omitempty"`
CustomBgColor *string `json:"custom_bg_color,omitempty"`
Value *json.Number `json:"value,omitempty"`
Inverted *bool `json:"invert,omitempty"`
CustomFgColor *string `json:"custom_fg_color,omitempty"`
CustomImageUrl *string `json:"custom_image,omitempty"`
}
// GetDashboard returns a single dashboard created on this account.
func (client *Client) GetDashboard(id int) (*Dashboard, error) {
var out reqGetDashboard
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/dash/%d", id), nil, &out); err != nil {
return nil, err
}
return out.Dashboard, nil
}
// GetDashboards returns a list of all dashboards created on this account.
func (client *Client) GetDashboards() ([]DashboardLite, error) {
var out reqGetDashboards
if err := client.doJsonRequest("GET", "/v1/dash", nil, &out); err != nil {
return nil, err
}
return out.Dashboards, nil
}
// DeleteDashboard deletes a dashboard by the identifier.
func (client *Client) DeleteDashboard(id int) error {
return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/dash/%d", id), nil, nil)
}
// CreateDashboard creates a new dashboard when given a Dashboard struct. Note
// that the Id, Resource, Url and similar elements are not used in creation.
func (client *Client) CreateDashboard(dash *Dashboard) (*Dashboard, error) {
var out reqGetDashboard
if err := client.doJsonRequest("POST", "/v1/dash", dash, &out); err != nil {
return nil, err
}
return out.Dashboard, nil
}
// 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.
func (client *Client) UpdateDashboard(dash *Dashboard) error {
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/dash/%d", *dash.Id),
dash, nil)
}

File diff suppressed because it is too large Load Diff

81
vendor/github.com/zorkian/go-datadog-api/downtimes.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 (
"fmt"
)
type Recurrence struct {
Period *int `json:"period,omitempty"`
Type *string `json:"type,omitempty"`
UntilDate *int `json:"until_date,omitempty"`
UntilOccurrences *int `json:"until_occurrences,omitempty"`
WeekDays []string `json:"week_days,omitempty"`
}
type Downtime struct {
Active *bool `json:"active,omitempty"`
Canceled *int `json:"canceled,omitempty"`
Disabled *bool `json:"disabled,omitempty"`
End *int `json:"end,omitempty"`
Id *int `json:"id,omitempty"`
MonitorId *int `json:"monitor_id,omitempty"`
Message *string `json:"message,omitempty"`
Recurrence *Recurrence `json:"recurrence,omitempty"`
Scope []string `json:"scope,omitempty"`
Start *int `json:"start,omitempty"`
}
// reqDowntimes retrieves a slice of all Downtimes.
type reqDowntimes struct {
Downtimes []Downtime `json:"downtimes,omitempty"`
}
// CreateDowntime adds a new downtme to the system. This returns a pointer
// to a Downtime so you can pass that to UpdateDowntime or CancelDowntime
// later if needed.
func (client *Client) CreateDowntime(downtime *Downtime) (*Downtime, error) {
var out Downtime
if err := client.doJsonRequest("POST", "/v1/downtime", downtime, &out); err != nil {
return nil, err
}
return &out, nil
}
// UpdateDowntime takes a downtime that was previously retrieved through some method
// and sends it back to the server.
func (client *Client) UpdateDowntime(downtime *Downtime) error {
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/downtime/%d", *downtime.Id),
downtime, nil)
}
// Getdowntime retrieves an downtime by identifier.
func (client *Client) GetDowntime(id int) (*Downtime, error) {
var out Downtime
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/downtime/%d", id), nil, &out); err != nil {
return nil, err
}
return &out, nil
}
// DeleteDowntime removes an downtime from the system.
func (client *Client) DeleteDowntime(id int) error {
return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/downtime/%d", id),
nil, nil)
}
// GetDowntimes returns a slice of all downtimes.
func (client *Client) GetDowntimes() ([]Downtime, error) {
var out reqDowntimes
if err := client.doJsonRequest("GET", "/v1/downtime", nil, &out.Downtimes); err != nil {
return nil, err
}
return out.Downtimes, nil
}

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

@ -0,0 +1,87 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import (
"fmt"
"net/url"
"strconv"
)
// Event is a single event. If this is being used to post an event, then not
// all fields will be filled out.
type Event struct {
Id *int `json:"id,omitempty"`
Title *string `json:"title,omitempty"`
Text *string `json:"text,omitempty"`
Time *int `json:"date_happened,omitempty"` // UNIX time.
Priority *string `json:"priority,omitempty"`
AlertType *string `json:"alert_type,omitempty"`
Host *string `json:"host,omitempty"`
Aggregation *string `json:"aggregation_key,omitempty"`
SourceType *string `json:"source_type_name,omitempty"`
Tags []string `json:"tags,omitempty"`
Url *string `json:"url,omitempty"`
Resource *string `json:"resource,omitempty"`
EventType *string `json:"event_type,omitempty"`
}
// reqGetEvent is the container for receiving a single event.
type reqGetEvent struct {
Event *Event `json:"event,omitempty"`
}
// reqGetEvents is for returning many events.
type reqGetEvents struct {
Events []Event `json:"events,omitempty"`
}
// PostEvent takes as input an event and then posts it to the server.
func (client *Client) PostEvent(event *Event) (*Event, error) {
var out reqGetEvent
if err := client.doJsonRequest("POST", "/v1/events", event, &out); err != nil {
return nil, err
}
return out.Event, nil
}
// GetEvent gets a single event given an identifier.
func (client *Client) GetEvent(id int) (*Event, error) {
var out reqGetEvent
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/events/%d", id), nil, &out); err != nil {
return nil, err
}
return out.Event, nil
}
// QueryEvents returns a slice of events from the query stream.
func (client *Client) GetEvents(start, end int,
priority, sources, tags string) ([]Event, error) {
// Since this is a GET request, we need to build a query string.
vals := url.Values{}
vals.Add("start", strconv.Itoa(start))
vals.Add("end", strconv.Itoa(end))
if priority != "" {
vals.Add("priority", priority)
}
if sources != "" {
vals.Add("sources", sources)
}
if tags != "" {
vals.Add("tags", tags)
}
// Now the request and response.
var out reqGetEvents
if err := client.doJsonRequest("GET",
fmt.Sprintf("/v1/events?%s", vals.Encode()), nil, &out); err != nil {
return nil, err
}
return out.Events, nil
}

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

@ -0,0 +1,3 @@
package datadog
//go:generate go run cmd/tools/gen-accessors.go -v

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

@ -0,0 +1,67 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2017 by authors and contributors.
*/
package datadog
import "encoding/json"
// Bool is a helper routine that allocates a new bool value
// to store v and returns a pointer to it.
func Bool(v bool) *bool { return &v }
// GetBool is a helper routine that returns a boolean representing
// if a value was set, and if so, dereferences the pointer to it.
func GetBool(v *bool) (bool, bool) {
if v != nil {
return *v, true
}
return false, false
}
// Int is a helper routine that allocates a new int value
// to store v and returns a pointer to it.
func Int(v int) *int { return &v }
// GetInt is a helper routine that returns a boolean representing
// if a value was set, and if so, dereferences the pointer to it.
func GetIntOk(v *int) (int, bool) {
if v != nil {
return *v, true
}
return 0, false
}
// String is a helper routine that allocates a new string value
// to store v and returns a pointer to it.
func String(v string) *string { return &v }
// GetString is a helper routine that returns a boolean representing
// if a value was set, and if so, dereferences the pointer to it.
func GetStringOk(v *string) (string, bool) {
if v != nil {
return *v, true
}
return "", false
}
// JsonNumber is a helper routine that allocates a new string value
// to store v and returns a pointer to it.
func JsonNumber(v json.Number) *json.Number { return &v }
// GetJsonNumber is a helper routine that returns a boolean representing
// if a value was set, and if so, dereferences the pointer to it.
func GetJsonNumberOk(v *json.Number) (json.Number, bool) {
if v != nil {
return *v, true
}
return "", false
}

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

@ -0,0 +1,33 @@
package datadog
type HostActionResp struct {
Action string `json:"action"`
Hostname string `json:"hostname"`
Message string `json:"message,omitempty"`
}
type HostActionMute struct {
Message *string `json:"message,omitempty"`
EndTime *string `json:"end,omitempty"`
Override *bool `json:"override,omitempty"`
}
// MuteHost mutes all monitors for the given host
func (client *Client) MuteHost(host string, action *HostActionMute) (*HostActionResp, error) {
var out HostActionResp
uri := "/v1/host/" + host + "/mute"
if err := client.doJsonRequest("POST", uri, action, &out); err != nil {
return nil, err
}
return &out, nil
}
// UnmuteHost unmutes all monitors for the given host
func (client *Client) UnmuteHost(host string) (*HostActionResp, error) {
var out HostActionResp
uri := "/v1/host/" + host + "/unmute"
if err := client.doJsonRequest("POST", uri, nil, &out); err != nil {
return nil, err
}
return &out, nil
}

View File

@ -0,0 +1,178 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2018 by authors and contributors.
*/
package datadog
/*
PagerDuty Integration
*/
type servicePD struct {
ServiceName *string `json:"service_name"`
ServiceKey *string `json:"service_key"`
}
type integrationPD struct {
Services []servicePD `json:"services"`
Subdomain *string `json:"subdomain"`
Schedules []string `json:"schedules"`
APIToken *string `json:"api_token"`
}
// ServicePDRequest defines the Services struct that is part of the IntegrationPDRequest.
type ServicePDRequest struct {
ServiceName *string `json:"service_name"`
ServiceKey *string `json:"service_key"`
}
// IntegrationPDRequest defines the request payload for
// creating & updating Datadog-PagerDuty integration.
type IntegrationPDRequest struct {
Services []ServicePDRequest `json:"services,omitempty"`
Subdomain *string `json:"subdomain,omitempty"`
Schedules []string `json:"schedules,omitempty"`
APIToken *string `json:"api_token,omitempty"`
RunCheck *bool `json:"run_check,omitempty"`
}
// CreateIntegrationPD creates new PagerDuty Integrations.
// Use this if you want to setup the integration for the first time
// or to add more services/schedules.
func (client *Client) CreateIntegrationPD(pdIntegration *IntegrationPDRequest) error {
return client.doJsonRequest("POST", "/v1/integration/pagerduty", pdIntegration, nil)
}
// UpdateIntegrationPD updates the PagerDuty Integration.
// This will replace the existing values with the new values.
func (client *Client) UpdateIntegrationPD(pdIntegration *IntegrationPDRequest) error {
return client.doJsonRequest("PUT", "/v1/integration/pagerduty", pdIntegration, nil)
}
// GetIntegrationPD gets all the PagerDuty Integrations from the system.
func (client *Client) GetIntegrationPD() (*integrationPD, error) {
var out integrationPD
if err := client.doJsonRequest("GET", "/v1/integration/pagerduty", nil, &out); err != nil {
return nil, err
}
return &out, nil
}
// DeleteIntegrationPD removes the PagerDuty Integration from the system.
func (client *Client) DeleteIntegrationPD() error {
return client.doJsonRequest("DELETE", "/v1/integration/pagerduty", nil, nil)
}
/*
Slack Integration
*/
// ServiceHookSlackRequest defines the ServiceHooks struct that is part of the IntegrationSlackRequest.
type ServiceHookSlackRequest struct {
Account *string `json:"account"`
Url *string `json:"url"`
}
// ChannelSlackRequest defines the Channels struct that is part of the IntegrationSlackRequest.
type ChannelSlackRequest struct {
ChannelName *string `json:"channel_name"`
TransferAllUserComments *bool `json:"transfer_all_user_comments,omitempty,string"`
Account *string `json:"account"`
}
// IntegrationSlackRequest defines the request payload for
// creating & updating Datadog-Slack integration.
type IntegrationSlackRequest struct {
ServiceHooks []ServiceHookSlackRequest `json:"service_hooks,omitempty"`
Channels []ChannelSlackRequest `json:"channels,omitempty"`
RunCheck *bool `json:"run_check,omitempty,string"`
}
// CreateIntegrationSlack creates new Slack Integrations.
// Use this if you want to setup the integration for the first time
// or to add more channels.
func (client *Client) CreateIntegrationSlack(slackIntegration *IntegrationSlackRequest) error {
return client.doJsonRequest("POST", "/v1/integration/slack", slackIntegration, nil)
}
// UpdateIntegrationSlack updates the Slack Integration.
// This will replace the existing values with the new values.
func (client *Client) UpdateIntegrationSlack(slackIntegration *IntegrationSlackRequest) error {
return client.doJsonRequest("PUT", "/v1/integration/slack", slackIntegration, nil)
}
// GetIntegrationSlack gets all the Slack Integrations from the system.
func (client *Client) GetIntegrationSlack() (*IntegrationSlackRequest, error) {
var out IntegrationSlackRequest
if err := client.doJsonRequest("GET", "/v1/integration/slack", nil, &out); err != nil {
return nil, err
}
return &out, nil
}
// DeleteIntegrationSlack removes the Slack Integration from the system.
func (client *Client) DeleteIntegrationSlack() error {
return client.doJsonRequest("DELETE", "/v1/integration/slack", nil, nil)
}
/*
AWS Integration
*/
// IntegrationAWSAccount defines the request payload for
// creating & updating Datadog-AWS integration.
type IntegrationAWSAccount struct {
AccountID *string `json:"account_id"`
RoleName *string `json:"role_name"`
FilterTags []string `json:"filter_tags"`
HostTags []string `json:"host_tags"`
AccountSpecificNamespaceRules map[string]bool `json:"account_specific_namespace_rules"`
}
// IntegrationAWSAccountCreateResponse defines the response payload for
// creating & updating Datadog-AWS integration.
type IntegrationAWSAccountCreateResponse struct {
ExternalID string `json:"external_id"`
}
type IntegrationAWSAccountGetResponse struct {
Accounts []IntegrationAWSAccount `json:"accounts"`
}
type IntegrationAWSAccountDeleteRequest struct {
AccountID *string `json:"account_id"`
RoleName *string `json:"role_name"`
}
// CreateIntegrationAWS adds a new AWS Account in the AWS Integrations.
// Use this if you want to setup the integration for the first time
// or to add more accounts.
func (client *Client) CreateIntegrationAWS(awsAccount *IntegrationAWSAccount) (*IntegrationAWSAccountCreateResponse, error) {
var out IntegrationAWSAccountCreateResponse
if err := client.doJsonRequest("POST", "/v1/integration/aws", awsAccount, &out); err != nil {
return nil, err
}
return &out, nil
}
// GetIntegrationAWS gets all the AWS Accounts in the AWS Integrations from Datadog.
func (client *Client) GetIntegrationAWS() (*[]IntegrationAWSAccount, error) {
var response IntegrationAWSAccountGetResponse
if err := client.doJsonRequest("GET", "/v1/integration/aws", nil, &response); err != nil {
return nil, err
}
return &response.Accounts, nil
}
// DeleteIntegrationAWS removes a specific AWS Account from the AWS Integration.
func (client *Client) DeleteIntegrationAWS(awsAccount *IntegrationAWSAccountDeleteRequest) error {
return client.doJsonRequest("DELETE", "/v1/integration/aws", awsAccount, nil)
}

View File

@ -0,0 +1,39 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import "fmt"
// MetricMetadata allows you to edit fields of a metric's metadata.
type MetricMetadata struct {
Type *string `json:"type,omitempty"`
Description *string `json:"description,omitempty"`
ShortName *string `json:"short_name,omitempty"`
Unit *string `json:"unit,omitempty"`
PerUnit *string `json:"per_unit,omitempty"`
StatsdInterval *int `json:"statsd_interval,omitempty"`
}
// ViewMetricMetadata allows you to get metadata about a specific metric.
func (client *Client) ViewMetricMetadata(mn string) (*MetricMetadata, error) {
var out MetricMetadata
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/metrics/%s", mn), nil, &out); err != nil {
return nil, err
}
return &out, nil
}
// EditMetricMetadata edits the metadata for the given metric.
func (client *Client) EditMetricMetadata(mn string, mm *MetricMetadata) (*MetricMetadata, error) {
var out MetricMetadata
if err := client.doJsonRequest("PUT", fmt.Sprintf("/v1/metrics/%s", mn), mm, &out); err != nil {
return nil, err
}
return &out, nil
}

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

@ -0,0 +1,177 @@
/*
* 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"
"net/url"
"strconv"
"strings"
)
type ThresholdCount struct {
Ok *json.Number `json:"ok,omitempty"`
Critical *json.Number `json:"critical,omitempty"`
Warning *json.Number `json:"warning,omitempty"`
Unknown *json.Number `json:"unknown,omitempty"`
CriticalRecovery *json.Number `json:"critical_recovery,omitempty"`
WarningRecovery *json.Number `json:"warning_recovery,omitempty"`
}
type NoDataTimeframe int
func (tf *NoDataTimeframe) UnmarshalJSON(data []byte) error {
s := string(data)
if s == "false" || s == "null" {
*tf = 0
} else {
i, err := strconv.ParseInt(s, 10, 32)
if err != nil {
return err
}
*tf = NoDataTimeframe(i)
}
return nil
}
type Options struct {
NoDataTimeframe NoDataTimeframe `json:"no_data_timeframe,omitempty"`
NotifyAudit *bool `json:"notify_audit,omitempty"`
NotifyNoData *bool `json:"notify_no_data,omitempty"`
RenotifyInterval *int `json:"renotify_interval,omitempty"`
NewHostDelay *int `json:"new_host_delay,omitempty"`
EvaluationDelay *int `json:"evaluation_delay,omitempty"`
Silenced map[string]int `json:"silenced,omitempty"`
TimeoutH *int `json:"timeout_h,omitempty"`
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"`
}
// 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"`
Name *string `json:"name,omitempty"`
Message *string `json:"message,omitempty"`
OverallState *string `json:"overall_state,omitempty"`
Tags []string `json:"tags"`
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 a
// monitor so you can pass that to UpdateMonitor later if needed
func (client *Client) CreateMonitor(monitor *Monitor) (*Monitor, error) {
var out Monitor
// TODO: is this more pretty of frowned upon?
if err := client.doJsonRequest("POST", "/v1/monitor", monitor, &out); err != nil {
return nil, err
}
return &out, nil
}
// UpdateMonitor takes a monitor that was previously retrieved through some method
// and sends it back to the server
func (client *Client) UpdateMonitor(monitor *Monitor) error {
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/monitor/%d", *monitor.Id),
monitor, nil)
}
// GetMonitor retrieves a monitor by identifier
func (client *Client) GetMonitor(id int) (*Monitor, error) {
var out Monitor
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/monitor/%d", id), nil, &out); err != nil {
return nil, err
}
return &out, nil
}
// GetMonitor retrieves monitors by name
func (self *Client) GetMonitorsByName(name string) ([]Monitor, error) {
var out reqMonitors
query, err := url.ParseQuery(fmt.Sprintf("name=%v", name))
if err != nil {
return nil, err
}
err = self.doJsonRequest("GET", fmt.Sprintf("/v1/monitor?%v", query.Encode()), nil, &out.Monitors)
if err != nil {
return nil, err
}
return out.Monitors, nil
}
// GetMonitor retrieves monitors by a slice of tags
func (self *Client) GetMonitorsByTags(tags []string) ([]Monitor, error) {
var out reqMonitors
query, err := url.ParseQuery(fmt.Sprintf("monitor_tags=%v", strings.Join(tags, ",")))
if err != nil {
return nil, err
}
err = self.doJsonRequest("GET", fmt.Sprintf("/v1/monitor?%v", query.Encode()), nil, &out.Monitors)
if err != nil {
return nil, err
}
return out.Monitors, nil
}
// DeleteMonitor removes a monitor from the system
func (client *Client) DeleteMonitor(id int) error {
return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/monitor/%d", id),
nil, nil)
}
// GetMonitors returns a slice of all monitors
func (client *Client) GetMonitors() ([]Monitor, error) {
var out reqMonitors
if err := client.doJsonRequest("GET", "/v1/monitor", nil, &out.Monitors); err != nil {
return nil, err
}
return out.Monitors, nil
}
// MuteMonitors turns off monitoring notifications
func (client *Client) MuteMonitors() error {
return client.doJsonRequest("POST", "/v1/monitor/mute_all", nil, nil)
}
// UnmuteMonitors turns on monitoring notifications
func (client *Client) UnmuteMonitors() error {
return client.doJsonRequest("POST", "/v1/monitor/unmute_all", nil, nil)
}
// MuteMonitor turns off monitoring notifications for a monitor
func (client *Client) MuteMonitor(id int) error {
return client.doJsonRequest("POST", fmt.Sprintf("/v1/monitor/%d/mute", id), nil, nil)
}
// UnmuteMonitor turns on monitoring notifications for a monitor
func (client *Client) UnmuteMonitor(id int) error {
return client.doJsonRequest("POST", fmt.Sprintf("/v1/monitor/%d/unmute", id), nil, nil)
}

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

@ -0,0 +1,194 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"net/url"
"strings"
"time"
"github.com/cenkalti/backoff"
)
// uriForAPI is to be called with something like "/v1/events" and it will give
// the proper request URI to be posted to.
func (client *Client) uriForAPI(api string) (string, error) {
apiBase, err := url.Parse(client.baseUrl + "/api" + api)
if err != nil {
return "", err
}
q := apiBase.Query()
q.Add("api_key", client.apiKey)
q.Add("application_key", client.appKey)
apiBase.RawQuery = q.Encode()
return apiBase.String(), nil
}
// redactError removes api and application keys from error strings
func (client *Client) redactError(err error) error {
if err == nil {
return nil
}
errString := err.Error()
if len(client.apiKey) > 0 {
errString = strings.Replace(errString, client.apiKey, "redacted", -1)
}
if len(client.appKey) > 0 {
errString = strings.Replace(errString, client.appKey, "redacted", -1)
}
// Return original error if no replacements were made to keep the original,
// probably more useful error type information.
if errString == err.Error() {
return err
}
return fmt.Errorf("%s", errString)
}
// doJsonRequest is the simplest type of request: a method on a URI that
// returns some JSON result which we unmarshal into the passed interface. It
// wraps doJsonRequestUnredacted to redact api and application keys from
// errors.
func (client *Client) doJsonRequest(method, api string,
reqbody, out interface{}) error {
if err := client.doJsonRequestUnredacted(method, api, reqbody, out); err != nil {
return client.redactError(err)
}
return nil
}
// doJsonRequestUnredacted is the simplest type of request: a method on a URI that returns
// some JSON result which we unmarshal into the passed interface.
func (client *Client) doJsonRequestUnredacted(method, api string,
reqbody, out interface{}) error {
req, err := client.createRequest(method, api, reqbody)
if err != nil {
return err
}
// Perform the request and retry it if it's not a POST or PUT request
var resp *http.Response
if method == "POST" || method == "PUT" {
resp, err = client.HttpClient.Do(req)
} else {
resp, err = client.doRequestWithRetries(req, client.RetryTimeout)
}
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode < 200 || resp.StatusCode > 299 {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
return fmt.Errorf("API error %s: %s", resp.Status, body)
}
// If they don't care about the body, then we don't care to give them one,
// so bail out because we're done.
if out == nil {
// read the response body so http conn can be reused immediately
io.Copy(ioutil.Discard, resp.Body)
return nil
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return err
}
// If we got no body, by default let's just make an empty JSON dict. This
// saves us some work in other parts of the code.
if len(body) == 0 {
body = []byte{'{', '}'}
}
return json.Unmarshal(body, &out)
}
// doRequestWithRetries performs an HTTP request repeatedly for maxTime or until
// no error and no acceptable HTTP response code was returned.
func (client *Client) doRequestWithRetries(req *http.Request, maxTime time.Duration) (*http.Response, error) {
var (
err error
resp *http.Response
bo = backoff.NewExponentialBackOff()
body []byte
)
bo.MaxElapsedTime = maxTime
// Save the body for retries
if req.Body != nil {
body, err = ioutil.ReadAll(req.Body)
if err != nil {
return resp, err
}
}
operation := func() error {
if body != nil {
r := bytes.NewReader(body)
req.Body = ioutil.NopCloser(r)
}
resp, err = client.HttpClient.Do(req)
if err != nil {
return err
}
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
// 2xx all done
return nil
} else if resp.StatusCode >= 400 && resp.StatusCode < 500 {
// 4xx are not retryable
return nil
}
return fmt.Errorf("Received HTTP status code %d", resp.StatusCode)
}
err = backoff.Retry(operation, bo)
return resp, err
}
func (client *Client) createRequest(method, api string, reqbody interface{}) (*http.Request, error) {
// Handle the body if they gave us one.
var bodyReader io.Reader
if method != "GET" && reqbody != nil {
bjson, err := json.Marshal(reqbody)
if err != nil {
return nil, err
}
bodyReader = bytes.NewReader(bjson)
}
apiUrlStr, err := client.uriForAPI(api)
if err != nil {
return nil, err
}
req, err := http.NewRequest(method, apiUrlStr, bodyReader)
if err != nil {
return nil, err
}
if bodyReader != nil {
req.Header.Add("Content-Type", "application/json")
}
return req, nil
}

View File

@ -0,0 +1,287 @@
package datadog
type TextSize struct {
Size *int
Auto *bool
}
type TileDef struct {
Events []TileDefEvent `json:"events,omitempty"`
Markers []TimeseriesMarker `json:"markers,omitempty"`
Requests []TimeseriesRequest `json:"requests,omitempty"`
Viz *string `json:"viz,omitempty"`
}
type TimeseriesRequest struct {
Query *string `json:"q,omitempty"`
Type *string `json:"type,omitempty"`
ConditionalFormats []ConditionalFormat `json:"conditional_formats,omitempty"`
Style *TimeseriesRequestStyle `json:"style,omitempty"`
}
type TimeseriesRequestStyle struct {
Palette *string `json:"palette,omitempty"`
}
type TimeseriesMarker struct {
Label *string `json:"label,omitempty"`
Type *string `json:"type,omitempty"`
Value *string `json:"value,omitempty"`
}
type TileDefEvent struct {
Query *string `json:"q"`
}
type AlertValueWidget struct {
TitleSize *int `json:"title_size,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TextAlign *string `json:"text_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Precision *int `json:"precision,omitempty"`
AlertId *int `json:"alert_id,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
AddTimeframe *bool `json:"add_timeframe,omitempty"`
Y *int `json:"y,omitempty"`
X *int `json:"x,omitempty"`
TextSize *string `json:"text_size,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
Type *string `json:"type,omitempty"`
Unit *string `json:"unit,omitempty"`
}
type ChangeWidget struct {
TitleSize *int `json:"title_size,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"y,omitempty"`
Y *int `json:"x,omitempty"`
Aggregator *string `json:"aggregator,omitempty"`
TileDef *TileDef `json:"tile_def,omitempty"`
}
type GraphWidget struct {
TitleSize *int `json:"title_size,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"y,omitempty"`
Y *int `json:"x,omitempty"`
Type *string `json:"type,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
LegendSize *int `json:"legend_size,omitempty"`
Legend *bool `json:"legend,omitempty"`
TileDef *TileDef `json:"tile_def,omitempty"`
}
type EventTimelineWidget struct {
TitleSize *int `json:"title_size,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"y,omitempty"`
Y *int `json:"x,omitempty"`
Type *string `json:"type,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
Query *string `json:"query,omitempty"`
}
type AlertGraphWidget struct {
TitleSize *int `json:"title_size,omitempty"`
VizType *string `json:"timeseries,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"y,omitempty"`
Y *int `json:"x,omitempty"`
AlertId *int `json:"alert_id,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
Type *string `json:"type,omitempty"`
AddTimeframe *bool `json:"add_timeframe,omitempty"`
}
type HostMapWidget struct {
TitleSize *int `json:"title_size,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"y,omitempty"`
Y *int `json:"x,omitempty"`
Query *string `json:"query,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
LegendSize *int `json:"legend_size,omitempty"`
Type *string `json:"type,omitempty"`
Legend *bool `json:"legend,omitempty"`
TileDef *TileDef `json:"tile_def,omitempty"`
}
type CheckStatusWidget struct {
TitleSize *int `json:"title_size,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TextAlign *string `json:"text_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"y,omitempty"`
Y *int `json:"x,omitempty"`
Tags *string `json:"tags,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
TextSize *string `json:"text_size,omitempty"`
Type *string `json:"type,omitempty"`
Check *string `json:"check,omitempty"`
Group *string `json:"group,omitempty"`
Grouping *string `json:"grouping,omitempty"`
}
type IFrameWidget struct {
TitleSize *int `json:"title_size,omitempty"`
Title *bool `json:"title,omitempty"`
Url *string `json:"url,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Height *int `json:"height,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"y,omitempty"`
Y *int `json:"x,omitempty"`
Type *string `json:"type,omitempty"`
}
type NoteWidget struct {
TitleSize *int `json:"title_size,omitempty"`
Title *bool `json:"title,omitempty"`
RefreshEvery *int `json:"refresh_every,omitempty"`
TickPos *string `json:"tick_pos,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TickEdge *string `json:"tick_edge,omitempty"`
TextAlign *string `json:"text_align,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Height *int `json:"height,omitempty"`
Color *string `json:"bgcolor,omitempty"`
Html *string `json:"html,omitempty"`
Y *int `json:"y,omitempty"`
X *int `json:"x,omitempty"`
FontSize *int `json:"font_size,omitempty"`
Tick *bool `json:"tick,omitempty"`
Note *string `json:"type,omitempty"`
Width *int `json:"width,omitempty"`
AutoRefresh *bool `json:"auto_refresh,omitempty"`
}
type TimeseriesWidget struct {
Height *int `json:"height,omitempty"`
Legend *bool `json:"legend,omitempty"`
TileDef *TileDef `json:"tile_def,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleSize *TextSize `json:"title_size,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Type *string `json:"type,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"x,omitempty"`
Y *int `json:"y,omitempty"`
}
type QueryValueWidget struct {
Timeframe *string `json:"timeframe,omitempty"`
TimeframeAggregator *string `json:"aggr,omitempty"`
Aggregator *string `json:"aggregator,omitempty"`
CalcFunc *string `json:"calc_func,omitempty"`
ConditionalFormats []ConditionalFormat `json:"conditional_formats,omitempty"`
Height *int `json:"height,omitempty"`
IsValidQuery *bool `json:"is_valid_query,omitempty,omitempty"`
Metric *string `json:"metric,omitempty"`
MetricType *string `json:"metric_type,omitempty"`
Precision *int `json:"precision,omitempty"`
Query *string `json:"query,omitempty"`
ResultCalcFunc *string `json:"res_calc_func,omitempty"`
Tags []string `json:"tags,omitempty"`
TextAlign *string `json:"text_align,omitempty"`
TextSize *TextSize `json:"text_size,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleSize *TextSize `json:"title_size,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Type *string `json:"type,omitempty"`
Unit *string `json:"auto,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"x,omitempty"`
Y *int `json:"y,omitempty"`
}
type ConditionalFormat struct {
Color *string `json:"color,omitempty"`
Comparator *string `json:"comparator,omitempty"`
Inverted *bool `json:"invert,omitempty"`
Value *int `json:"value,omitempty"`
}
type ToplistWidget struct {
Height *int `json:"height,omitempty"`
Legend *bool `json:"legend,omitempty"`
LegendSize *int `json:"legend_size,omitempty"`
TileDef *TileDef `json:"tile_def,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleSize *TextSize `json:"title_size,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Type *string `json:"type,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"x,omitempty"`
Y *int `json:"y,omitempty"`
}
type EventStreamWidget struct {
EventSize *string `json:"event_size,omitempty"`
Height *int `json:"height,omitempty"`
Query *string `json:"query,omitempty"`
Timeframe *string `json:"timeframe,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleSize *TextSize `json:"title_size,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Type *string `json:"type,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"x,omitempty"`
Y *int `json:"y,omitempty"`
}
type FreeTextWidget struct {
Color *string `json:"color,omitempty"`
FontSize *string `json:"font_size,omitempty"`
Height *int `json:"height,omitempty"`
Text *string `json:"text,omitempty"`
TextAlign *string `json:"text_align,omitempty"`
Type *string `json:"type,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"x,omitempty"`
Y *int `json:"y,omitempty"`
}
type ImageWidget struct {
Height *int `json:"height,omitempty"`
Sizing *string `json:"sizing,omitempty"`
Title *bool `json:"title,omitempty"`
TitleAlign *string `json:"title_align,omitempty"`
TitleSize *TextSize `json:"title_size,omitempty"`
TitleText *string `json:"title_text,omitempty"`
Type *string `json:"type,omitempty"`
Url *string `json:"url,omitempty"`
Width *int `json:"width,omitempty"`
X *int `json:"x,omitempty"`
Y *int `json:"y,omitempty"`
}

View File

@ -0,0 +1,116 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import (
"fmt"
)
// Screenboard represents a user created screenboard. This is the full screenboard
// struct when we load a screenboard in detail.
type Screenboard struct {
Id *int `json:"id,omitempty"`
Title *string `json:"board_title,omitempty"`
Height *string `json:"height,omitempty"`
Width *string `json:"width,omitempty"`
Shared *bool `json:"shared,omitempty"`
Templated *bool `json:"templated,omitempty"`
TemplateVariables []TemplateVariable `json:"template_variables,omitempty"`
Widgets []Widget `json:"widgets"`
ReadOnly *bool `json:"read_only,omitempty"`
}
//type Widget struct {
type Widget struct {
Default *string `json:"default,omitempty"`
Name *string `json:"name,omitempty"`
Prefix *string `json:"prefix,omitempty"`
TimeseriesWidget *TimeseriesWidget `json:"timeseries,omitempty"`
QueryValueWidget *QueryValueWidget `json:"query_value,omitempty"`
EventStreamWidget *EventStreamWidget `json:"event_stream,omitempty"`
FreeTextWidget *FreeTextWidget `json:"free_text,omitempty"`
ToplistWidget *ToplistWidget `json:"toplist,omitempty"`
ImageWidget *ImageWidget `json:"image,omitempty"`
ChangeWidget *ChangeWidget `json:"change,omitempty"`
GraphWidget *GraphWidget `json:"graph,omitempty"`
EventTimelineWidget *EventTimelineWidget `json:"event_timeline,omitempty"`
AlertValueWidget *AlertValueWidget `json:"alert_value,omitempty"`
AlertGraphWidget *AlertGraphWidget `json:"alert_graph,omitempty"`
HostMapWidget *HostMapWidget `json:"hostmap,omitempty"`
CheckStatusWidget *CheckStatusWidget `json:"check_status,omitempty"`
IFrameWidget *IFrameWidget `json:"iframe,omitempty"`
NoteWidget *NoteWidget `json:"frame,omitempty"`
}
// ScreenboardLite represents a user created screenboard. This is the mini
// struct when we load the summaries.
type ScreenboardLite struct {
Id *int `json:"id,omitempty"`
Resource *string `json:"resource,omitempty"`
Title *string `json:"title,omitempty"`
}
// reqGetScreenboards from /api/v1/screen
type reqGetScreenboards struct {
Screenboards []*ScreenboardLite `json:"screenboards,omitempty"`
}
// GetScreenboard returns a single screenboard created on this account.
func (client *Client) GetScreenboard(id int) (*Screenboard, error) {
out := &Screenboard{}
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/screen/%d", id), nil, out); err != nil {
return nil, err
}
return out, nil
}
// GetScreenboards returns a list of all screenboards created on this account.
func (client *Client) GetScreenboards() ([]*ScreenboardLite, error) {
var out reqGetScreenboards
if err := client.doJsonRequest("GET", "/v1/screen", nil, &out); err != nil {
return nil, err
}
return out.Screenboards, nil
}
// DeleteScreenboard deletes a screenboard by the identifier.
func (client *Client) DeleteScreenboard(id int) error {
return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/screen/%d", id), nil, nil)
}
// CreateScreenboard creates a new screenboard when given a Screenboard struct. Note
// that the Id, Resource, Url and similar elements are not used in creation.
func (client *Client) CreateScreenboard(board *Screenboard) (*Screenboard, error) {
out := &Screenboard{}
if err := client.doJsonRequest("POST", "/v1/screen", board, out); err != nil {
return nil, err
}
return out, nil
}
// 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.
func (client *Client) UpdateScreenboard(board *Screenboard) error {
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/screen/%d", *board.Id), board, nil)
}
type ScreenShareResponse struct {
BoardId int `json:"board_id"`
PublicUrl string `json:"public_url"`
}
// ShareScreenboard shares an existing screenboard, it takes and updates ScreenShareResponse
func (client *Client) ShareScreenboard(id int, response *ScreenShareResponse) error {
return client.doJsonRequest("POST", fmt.Sprintf("/v1/screen/share/%d", id), nil, response)
}
// RevokeScreenboard revokes a currently shared screenboard
func (client *Client) RevokeScreenboard(id int) error {
return client.doJsonRequest("DELETE", fmt.Sprintf("/v1/screen/share/%d", id), nil, nil)
}

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

@ -0,0 +1,35 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
// reqSearch is the container for receiving search results.
type reqSearch struct {
Results struct {
Hosts []string `json:"hosts,omitempty"`
Metrics []string `json:"metrics,omitempty"`
} `json:"results"`
}
// SearchHosts searches through the hosts facet, returning matching hostnames.
func (client *Client) SearchHosts(search string) ([]string, error) {
var out reqSearch
if err := client.doJsonRequest("GET", "/v1/search?q=hosts:"+search, nil, &out); err != nil {
return nil, err
}
return out.Results.Hosts, nil
}
// SearchMetrics searches through the metrics facet, returning matching ones.
func (client *Client) SearchMetrics(search string) ([]string, error) {
var out reqSearch
if err := client.doJsonRequest("GET", "/v1/search?q=metrics:"+search, nil, &out); err != nil {
return nil, err
}
return out.Results.Metrics, nil
}

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

@ -0,0 +1,91 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
import (
"net/url"
"strconv"
)
// DataPoint is a tuple of [UNIX timestamp, value]. This has to use floats
// because the value could be non-integer.
type DataPoint [2]*float64
// Metric represents a collection of data points that we might send or receive
// on one single metric line.
type Metric struct {
Metric *string `json:"metric,omitempty"`
Points []DataPoint `json:"points,omitempty"`
Type *string `json:"type,omitempty"`
Host *string `json:"host,omitempty"`
Tags []string `json:"tags,omitempty"`
Unit *string `json:"unit,omitempty"`
}
// Unit represents a unit definition that we might receive when query for timeseries data.
type Unit struct {
Family string `json:"family"`
ScaleFactor float32 `json:"scale_factor"`
Name string `json:"name"`
ShortName string `json:"short_name"`
Plural string `json:"plural"`
Id int `json:"id"`
}
// A Series is characterized by 2 units as: x per y
// One or both could be missing
type UnitPair []*Unit
// Series represents a collection of data points we get when we query for timeseries data
type Series struct {
Metric *string `json:"metric,omitempty"`
DisplayName *string `json:"display_name,omitempty"`
Points []DataPoint `json:"pointlist,omitempty"`
Start *float64 `json:"start,omitempty"`
End *float64 `json:"end,omitempty"`
Interval *int `json:"interval,omitempty"`
Aggr *string `json:"aggr,omitempty"`
Length *int `json:"length,omitempty"`
Scope *string `json:"scope,omitempty"`
Expression *string `json:"expression,omitempty"`
Units *UnitPair `json:"unit,omitempty"`
}
// reqPostSeries from /api/v1/series
type reqPostSeries struct {
Series []Metric `json:"series,omitempty"`
}
// reqMetrics is the container for receiving metric results.
type reqMetrics struct {
Series []Series `json:"series,omitempty"`
}
// PostMetrics takes as input a slice of metrics and then posts them up to the
// server for posting data.
func (client *Client) PostMetrics(series []Metric) error {
return client.doJsonRequest("POST", "/v1/series",
reqPostSeries{Series: series}, nil)
}
// QueryMetrics takes as input from, to (seconds from Unix Epoch) and query string and then requests
// timeseries data for that time peried
func (client *Client) QueryMetrics(from, to int64, query string) ([]Series, error) {
v := url.Values{}
v.Add("from", strconv.FormatInt(from, 10))
v.Add("to", strconv.FormatInt(to, 10))
v.Add("query", query)
var out reqMetrics
err := client.doJsonRequest("GET", "/v1/query?"+v.Encode(), nil, &out)
if err != nil {
return nil, err
}
return out.Series, nil
}

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

@ -0,0 +1,45 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2016 by authors and contributors.
*/
package datadog
import (
"fmt"
"net/url"
"time"
)
func (client *Client) doSnapshotRequest(values url.Values) (string, error) {
out := struct {
SnapshotURL string `json:"snapshot_url,omitempty"`
}{}
if err := client.doJsonRequest("GET", "/v1/graph/snapshot?"+values.Encode(), nil, &out); err != nil {
return "", err
}
return out.SnapshotURL, nil
}
// Snapshot creates an image from a graph and returns the URL of the image.
func (client *Client) Snapshot(query string, start, end time.Time, eventQuery string) (string, error) {
options := map[string]string{"metric_query": query, "event_query": eventQuery}
return client.SnapshotGeneric(options, start, end)
}
// Generic function for snapshots, use map[string]string to create url.Values() instead of pre-defined params
func (client *Client) SnapshotGeneric(options map[string]string, start, end time.Time) (string, error) {
v := url.Values{}
v.Add("start", fmt.Sprintf("%d", start.Unix()))
v.Add("end", fmt.Sprintf("%d", end.Unix()))
for opt, val := range options {
v.Add(opt, val)
}
return client.doSnapshotRequest(v)
}

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

@ -0,0 +1,93 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
// TagMap is used to receive the format given to us by the API.
type TagMap map[string][]string
// reqGetTags is the container for receiving tags.
type reqGetTags struct {
Tags *TagMap `json:"tags,omitempty"`
}
// regGetHostTags is for receiving a slice of tags.
type reqGetHostTags struct {
Tags []string `json:"tags,omitempty"`
}
// GetTags returns a map of tags.
func (client *Client) GetTags(source string) (TagMap, error) {
var out reqGetTags
uri := "/v1/tags/hosts"
if source != "" {
uri += "?source=" + source
}
if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
return nil, err
}
return *out.Tags, nil
}
// GetHostTags returns a slice of tags for a given host and source.
func (client *Client) GetHostTags(host, source string) ([]string, error) {
var out reqGetHostTags
uri := "/v1/tags/hosts/" + host
if source != "" {
uri += "?source=" + source
}
if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
return nil, err
}
return out.Tags, nil
}
// GetHostTagsBySource is a different way of viewing the tags. It returns a map
// of source:[tag,tag].
func (client *Client) GetHostTagsBySource(host, source string) (TagMap, error) {
var out reqGetTags
uri := "/v1/tags/hosts/" + host + "?by_source=true"
if source != "" {
uri += "&source=" + source
}
if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
return nil, err
}
return *out.Tags, nil
}
// AddTagsToHost does exactly what it says on the tin. Given a list of tags,
// add them to the host. The source is optionally specified, and defaults to
// "users" as per the API documentation.
func (client *Client) AddTagsToHost(host, source string, tags []string) error {
uri := "/v1/tags/hosts/" + host
if source != "" {
uri += "?source=" + source
}
return client.doJsonRequest("POST", uri, reqGetHostTags{Tags: tags}, nil)
}
// UpdateHostTags overwrites existing tags for a host, allowing you to specify
// a new set of tags for the given source. This defaults to "users".
func (client *Client) UpdateHostTags(host, source string, tags []string) error {
uri := "/v1/tags/hosts/" + host
if source != "" {
uri += "?source=" + source
}
return client.doJsonRequest("PUT", uri, reqGetHostTags{Tags: tags}, nil)
}
// RemoveHostTags removes all tags from a host for the given source. If none is
// given, the API defaults to "users".
func (client *Client) RemoveHostTags(host, source string) error {
uri := "/v1/tags/hosts/" + host
if source != "" {
uri += "?source=" + source
}
return client.doJsonRequest("DELETE", uri, nil, nil)
}

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

@ -0,0 +1,95 @@
/*
* Datadog API for Go
*
* Please see the included LICENSE file for licensing information.
*
* Copyright 2013 by authors and contributors.
*/
package datadog
type User struct {
Handle *string `json:"handle,omitempty"`
Email *string `json:"email,omitempty"`
Name *string `json:"name,omitempty"`
Role *string `json:"role,omitempty"`
AccessRole *string `json:"access_role,omitempty"`
Verified *bool `json:"verified,omitempty"`
Disabled *bool `json:"disabled,omitempty"`
// DEPRECATED: IsAdmin is deprecated and will be removed in the next major
// revision. For more info on why it is being removed, see discussion on
// https://github.com/zorkian/go-datadog-api/issues/126.
IsAdmin *bool `json:"is_admin,omitempty"`
}
// reqInviteUsers contains email addresses to send invitations to.
type reqInviteUsers struct {
Emails []string `json:"emails,omitempty"`
}
// InviteUsers takes a slice of email addresses and sends invitations to them.
func (client *Client) InviteUsers(emails []string) error {
return client.doJsonRequest("POST", "/v1/invite_users",
reqInviteUsers{Emails: emails}, nil)
}
// CreateUser creates an user account for an email address
func (self *Client) CreateUser(handle, name *string) (*User, error) {
in := struct {
Handle *string `json:"handle"`
Name *string `json:"name"`
}{
Handle: handle,
Name: name,
}
out := struct {
*User `json:"user"`
}{}
if err := self.doJsonRequest("POST", "/v1/user", in, &out); err != nil {
return nil, err
}
return out.User, nil
}
// internal type to retrieve users from the api
type usersData struct {
Users []User `json:"users,omitempty"`
}
// GetUsers returns all user, or an error if not found
func (client *Client) GetUsers() (users []User, err error) {
var udata usersData
uri := "/v1/user"
err = client.doJsonRequest("GET", uri, nil, &udata)
users = udata.Users
return
}
// internal type to retrieve single user from the api
type userData struct {
User User `json:"user"`
}
// GetUser returns the user that match a handle, or an error if not found
func (client *Client) GetUser(handle string) (user User, err error) {
var udata userData
uri := "/v1/user/" + handle
err = client.doJsonRequest("GET", uri, nil, &udata)
user = udata.User
return
}
// UpdateUser updates a user with the content of `user`,
// and returns an error if the update failed
func (client *Client) UpdateUser(user User) error {
uri := "/v1/user/" + *user.Handle
return client.doJsonRequest("PUT", uri, user, nil)
}
// DeleteUser deletes a user and returns an error if deletion failed
func (client *Client) DeleteUser(handle string) error {
uri := "/v1/user/" + handle
return client.doJsonRequest("DELETE", uri, nil, nil)
}