provider/datadog: Upgrade to Datadog API v2 (#12098)
* provider/datadog: Pulls v2 and removes v1 of library go-datadog-api. See https://github.com/zorkian/go-datadog-api/issues/56 for context. * Fixes bug in backoff implementation that decreased performance significantly. * Uses pointers for field types, providing support of distinguishing between if a value is set, or the default value for that type is effective. * provider/datadog: Convert provider to use v2 of go-datadog-api. * provider/datadog: Update vendored library. * provider/datadog: Update dashboard resource to reflect API updates.
This commit is contained in:
parent
6d5feaf526
commit
2310316666
|
@ -3,7 +3,7 @@ package datadog
|
||||||
import (
|
import (
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/zorkian/go-datadog-api"
|
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config holds API and APP keys to authenticate to Datadog.
|
// Config holds API and APP keys to authenticate to Datadog.
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/zorkian/go-datadog-api"
|
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func resourceDatadogMonitor() *schema.Resource {
|
func resourceDatadogMonitor() *schema.Resource {
|
||||||
|
@ -137,18 +137,18 @@ func buildMonitorStruct(d *schema.ResourceData) *datadog.Monitor {
|
||||||
var thresholds datadog.ThresholdCount
|
var thresholds datadog.ThresholdCount
|
||||||
|
|
||||||
if r, ok := d.GetOk("thresholds.ok"); ok {
|
if r, ok := d.GetOk("thresholds.ok"); ok {
|
||||||
thresholds.Ok = json.Number(r.(string))
|
thresholds.SetOk(json.Number(r.(string)))
|
||||||
}
|
}
|
||||||
if r, ok := d.GetOk("thresholds.warning"); ok {
|
if r, ok := d.GetOk("thresholds.warning"); ok {
|
||||||
thresholds.Warning = json.Number(r.(string))
|
thresholds.SetWarning(json.Number(r.(string)))
|
||||||
}
|
}
|
||||||
if r, ok := d.GetOk("thresholds.critical"); ok {
|
if r, ok := d.GetOk("thresholds.critical"); ok {
|
||||||
thresholds.Critical = json.Number(r.(string))
|
thresholds.SetCritical(json.Number(r.(string)))
|
||||||
}
|
}
|
||||||
|
|
||||||
o := datadog.Options{
|
o := datadog.Options{
|
||||||
Thresholds: thresholds,
|
Thresholds: &thresholds,
|
||||||
NotifyNoData: d.Get("notify_no_data").(bool),
|
NotifyNoData: datadog.Bool(d.Get("notify_no_data").(bool)),
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("silenced"); ok {
|
if attr, ok := d.GetOk("silenced"); ok {
|
||||||
s := make(map[string]int)
|
s := make(map[string]int)
|
||||||
|
@ -159,42 +159,42 @@ func buildMonitorStruct(d *schema.ResourceData) *datadog.Monitor {
|
||||||
o.Silenced = s
|
o.Silenced = s
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("notify_no_data"); ok {
|
if attr, ok := d.GetOk("notify_no_data"); ok {
|
||||||
o.NotifyNoData = attr.(bool)
|
o.SetNotifyNoData(attr.(bool))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("new_host_delay"); ok {
|
if attr, ok := d.GetOk("new_host_delay"); ok {
|
||||||
o.NewHostDelay = datadog.Int(attr.(int))
|
o.SetNewHostDelay(attr.(int))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("no_data_timeframe"); ok {
|
if attr, ok := d.GetOk("no_data_timeframe"); ok {
|
||||||
o.NoDataTimeframe = datadog.NoDataTimeframe(attr.(int))
|
o.NoDataTimeframe = datadog.NoDataTimeframe(attr.(int))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("renotify_interval"); ok {
|
if attr, ok := d.GetOk("renotify_interval"); ok {
|
||||||
o.RenotifyInterval = attr.(int)
|
o.SetRenotifyInterval(attr.(int))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("notify_audit"); ok {
|
if attr, ok := d.GetOk("notify_audit"); ok {
|
||||||
o.NotifyAudit = attr.(bool)
|
o.SetNotifyAudit(attr.(bool))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("timeout_h"); ok {
|
if attr, ok := d.GetOk("timeout_h"); ok {
|
||||||
o.TimeoutH = attr.(int)
|
o.SetTimeoutH(attr.(int))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("escalation_message"); ok {
|
if attr, ok := d.GetOk("escalation_message"); ok {
|
||||||
o.EscalationMessage = attr.(string)
|
o.SetEscalationMessage(attr.(string))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("include_tags"); ok {
|
if attr, ok := d.GetOk("include_tags"); ok {
|
||||||
o.IncludeTags = attr.(bool)
|
o.SetIncludeTags(attr.(bool))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("require_full_window"); ok {
|
if attr, ok := d.GetOk("require_full_window"); ok {
|
||||||
o.RequireFullWindow = attr.(bool)
|
o.SetRequireFullWindow(attr.(bool))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("locked"); ok {
|
if attr, ok := d.GetOk("locked"); ok {
|
||||||
o.Locked = attr.(bool)
|
o.SetLocked(attr.(bool))
|
||||||
}
|
}
|
||||||
|
|
||||||
m := datadog.Monitor{
|
m := datadog.Monitor{
|
||||||
Type: d.Get("type").(string),
|
Type: datadog.String(d.Get("type").(string)),
|
||||||
Query: d.Get("query").(string),
|
Query: datadog.String(d.Get("query").(string)),
|
||||||
Name: d.Get("name").(string),
|
Name: datadog.String(d.Get("name").(string)),
|
||||||
Message: d.Get("message").(string),
|
Message: datadog.String(d.Get("message").(string)),
|
||||||
Options: o,
|
Options: &o,
|
||||||
}
|
}
|
||||||
|
|
||||||
if attr, ok := d.GetOk("tags"); ok {
|
if attr, ok := d.GetOk("tags"); ok {
|
||||||
|
@ -238,7 +238,7 @@ func resourceDatadogMonitorCreate(d *schema.ResourceData, meta interface{}) erro
|
||||||
return fmt.Errorf("error updating monitor: %s", err.Error())
|
return fmt.Errorf("error updating monitor: %s", err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
d.SetId(strconv.Itoa(m.Id))
|
d.SetId(strconv.Itoa(m.GetId()))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -258,9 +258,9 @@ func resourceDatadogMonitorRead(d *schema.ResourceData, meta interface{}) error
|
||||||
|
|
||||||
thresholds := make(map[string]string)
|
thresholds := make(map[string]string)
|
||||||
for k, v := range map[string]json.Number{
|
for k, v := range map[string]json.Number{
|
||||||
"ok": m.Options.Thresholds.Ok,
|
"ok": m.Options.Thresholds.GetOk(),
|
||||||
"warning": m.Options.Thresholds.Warning,
|
"warning": m.Options.Thresholds.GetWarning(),
|
||||||
"critical": m.Options.Thresholds.Critical,
|
"critical": m.Options.Thresholds.GetCritical(),
|
||||||
} {
|
} {
|
||||||
s := v.String()
|
s := v.String()
|
||||||
if s != "" {
|
if s != "" {
|
||||||
|
@ -274,24 +274,24 @@ func resourceDatadogMonitorRead(d *schema.ResourceData, meta interface{}) error
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("[DEBUG] monitor: %v", m)
|
log.Printf("[DEBUG] monitor: %v", m)
|
||||||
d.Set("name", m.Name)
|
d.Set("name", m.GetName())
|
||||||
d.Set("message", m.Message)
|
d.Set("message", m.GetMessage())
|
||||||
d.Set("query", m.Query)
|
d.Set("query", m.GetQuery())
|
||||||
d.Set("type", m.Type)
|
d.Set("type", m.GetType())
|
||||||
d.Set("thresholds", thresholds)
|
d.Set("thresholds", thresholds)
|
||||||
|
|
||||||
d.Set("new_host_delay", m.Options.NewHostDelay)
|
d.Set("new_host_delay", m.Options.GetNewHostDelay())
|
||||||
d.Set("notify_no_data", m.Options.NotifyNoData)
|
d.Set("notify_no_data", m.Options.GetNotifyNoData())
|
||||||
d.Set("no_data_timeframe", m.Options.NoDataTimeframe)
|
d.Set("no_data_timeframe", m.Options.NoDataTimeframe)
|
||||||
d.Set("renotify_interval", m.Options.RenotifyInterval)
|
d.Set("renotify_interval", m.Options.GetRenotifyInterval())
|
||||||
d.Set("notify_audit", m.Options.NotifyAudit)
|
d.Set("notify_audit", m.Options.GetNotifyAudit())
|
||||||
d.Set("timeout_h", m.Options.TimeoutH)
|
d.Set("timeout_h", m.Options.GetTimeoutH())
|
||||||
d.Set("escalation_message", m.Options.EscalationMessage)
|
d.Set("escalation_message", m.Options.GetEscalationMessage())
|
||||||
d.Set("silenced", m.Options.Silenced)
|
d.Set("silenced", m.Options.Silenced)
|
||||||
d.Set("include_tags", m.Options.IncludeTags)
|
d.Set("include_tags", m.Options.GetIncludeTags())
|
||||||
d.Set("tags", tags)
|
d.Set("tags", tags)
|
||||||
d.Set("require_full_window", m.Options.RequireFullWindow)
|
d.Set("require_full_window", m.Options.GetRequireFullWindow()) // TODO Is this one of those options that we neeed to check?
|
||||||
d.Set("locked", m.Options.Locked)
|
d.Set("locked", m.Options.GetLocked())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -306,15 +306,15 @@ func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Id = i
|
m.Id = datadog.Int(i)
|
||||||
if attr, ok := d.GetOk("name"); ok {
|
if attr, ok := d.GetOk("name"); ok {
|
||||||
m.Name = attr.(string)
|
m.SetName(attr.(string))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("message"); ok {
|
if attr, ok := d.GetOk("message"); ok {
|
||||||
m.Message = attr.(string)
|
m.SetMessage(attr.(string))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("query"); ok {
|
if attr, ok := d.GetOk("query"); ok {
|
||||||
m.Query = attr.(string)
|
m.SetQuery(attr.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if attr, ok := d.GetOk("tags"); ok {
|
if attr, ok := d.GetOk("tags"); ok {
|
||||||
|
@ -326,41 +326,42 @@ func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) erro
|
||||||
}
|
}
|
||||||
|
|
||||||
o := datadog.Options{
|
o := datadog.Options{
|
||||||
NotifyNoData: d.Get("notify_no_data").(bool),
|
NotifyNoData: datadog.Bool(d.Get("notify_no_data").(bool)),
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("thresholds"); ok {
|
if attr, ok := d.GetOk("thresholds"); ok {
|
||||||
thresholds := attr.(map[string]interface{})
|
thresholds := attr.(map[string]interface{})
|
||||||
|
o.Thresholds = &datadog.ThresholdCount{} // TODO: This is a little annoying..
|
||||||
if thresholds["ok"] != nil {
|
if thresholds["ok"] != nil {
|
||||||
o.Thresholds.Ok = json.Number(thresholds["ok"].(string))
|
o.Thresholds.SetOk(json.Number(thresholds["ok"].(string)))
|
||||||
}
|
}
|
||||||
if thresholds["warning"] != nil {
|
if thresholds["warning"] != nil {
|
||||||
o.Thresholds.Warning = json.Number(thresholds["warning"].(string))
|
o.Thresholds.SetWarning(json.Number(thresholds["warning"].(string)))
|
||||||
}
|
}
|
||||||
if thresholds["critical"] != nil {
|
if thresholds["critical"] != nil {
|
||||||
o.Thresholds.Critical = json.Number(thresholds["critical"].(string))
|
o.Thresholds.SetCritical(json.Number(thresholds["critical"].(string)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if attr, ok := d.GetOk("notify_no_data"); ok {
|
if attr, ok := d.GetOk("notify_no_data"); ok {
|
||||||
o.NotifyNoData = attr.(bool)
|
o.SetNotifyNoData(attr.(bool))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("new_host_delay"); ok {
|
if attr, ok := d.GetOk("new_host_delay"); ok {
|
||||||
o.NewHostDelay = datadog.Int(attr.(int))
|
o.SetNewHostDelay(attr.(int))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("no_data_timeframe"); ok {
|
if attr, ok := d.GetOk("no_data_timeframe"); ok {
|
||||||
o.NoDataTimeframe = datadog.NoDataTimeframe(attr.(int))
|
o.NoDataTimeframe = datadog.NoDataTimeframe(attr.(int))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("renotify_interval"); ok {
|
if attr, ok := d.GetOk("renotify_interval"); ok {
|
||||||
o.RenotifyInterval = attr.(int)
|
o.SetRenotifyInterval(attr.(int))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("notify_audit"); ok {
|
if attr, ok := d.GetOk("notify_audit"); ok {
|
||||||
o.NotifyAudit = attr.(bool)
|
o.SetNotifyAudit(attr.(bool))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("timeout_h"); ok {
|
if attr, ok := d.GetOk("timeout_h"); ok {
|
||||||
o.TimeoutH = attr.(int)
|
o.SetTimeoutH(attr.(int))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("escalation_message"); ok {
|
if attr, ok := d.GetOk("escalation_message"); ok {
|
||||||
o.EscalationMessage = attr.(string)
|
o.SetEscalationMessage(attr.(string))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("silenced"); ok {
|
if attr, ok := d.GetOk("silenced"); ok {
|
||||||
// TODO: this is not very defensive, test if we can fail non int input
|
// TODO: this is not very defensive, test if we can fail non int input
|
||||||
|
@ -371,16 +372,16 @@ func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) erro
|
||||||
o.Silenced = s
|
o.Silenced = s
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("include_tags"); ok {
|
if attr, ok := d.GetOk("include_tags"); ok {
|
||||||
o.IncludeTags = attr.(bool)
|
o.SetIncludeTags(attr.(bool))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("require_full_window"); ok {
|
if attr, ok := d.GetOk("require_full_window"); ok {
|
||||||
o.RequireFullWindow = attr.(bool)
|
o.SetRequireFullWindow(attr.(bool))
|
||||||
}
|
}
|
||||||
if attr, ok := d.GetOk("locked"); ok {
|
if attr, ok := d.GetOk("locked"); ok {
|
||||||
o.Locked = attr.(bool)
|
o.SetLocked(attr.(bool))
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Options = o
|
m.Options = &o
|
||||||
|
|
||||||
if err = client.UpdateMonitor(m); err != nil {
|
if err = client.UpdateMonitor(m); err != nil {
|
||||||
return fmt.Errorf("error updating monitor: %s", err.Error())
|
return fmt.Errorf("error updating monitor: %s", err.Error())
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/zorkian/go-datadog-api"
|
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAccDatadogMonitor_Basic(t *testing.T) {
|
func TestAccDatadogMonitor_Basic(t *testing.T) {
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/schema"
|
"github.com/hashicorp/terraform/helper/schema"
|
||||||
"github.com/zorkian/go-datadog-api"
|
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
func resourceDatadogTimeboard() *schema.Resource {
|
func resourceDatadogTimeboard() *schema.Resource {
|
||||||
|
@ -273,23 +273,23 @@ func appendConditionalFormats(datadogRequest *datadog.GraphDefinitionRequest, te
|
||||||
for _, t_ := range *terraformFormats {
|
for _, t_ := range *terraformFormats {
|
||||||
t := t_.(map[string]interface{})
|
t := t_.(map[string]interface{})
|
||||||
d := datadog.DashboardConditionalFormat{
|
d := datadog.DashboardConditionalFormat{
|
||||||
Comparator: t["comparator"].(string),
|
Comparator: datadog.String(t["comparator"].(string)),
|
||||||
}
|
}
|
||||||
|
|
||||||
if palette, ok := t["palette"]; ok {
|
if v, ok := t["palette"]; ok {
|
||||||
d.Palette = palette.(string)
|
d.SetPalette(v.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if customBgColor, ok := t["custom_bg_color"]; ok {
|
if v, ok := t["custom_bg_color"]; ok {
|
||||||
d.CustomBgColor = customBgColor.(string)
|
d.SetCustomBgColor(v.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if customFgColor, ok := t["custom_fg_color"]; ok {
|
if v, ok := t["custom_fg_color"]; ok {
|
||||||
d.CustomFgColor = customFgColor.(string)
|
d.SetCustomFgColor(v.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if value, ok := t["value"]; ok {
|
if v, ok := t["value"]; ok {
|
||||||
d.Value = json.Number(value.(string))
|
d.SetValue(json.Number(v.(string)))
|
||||||
}
|
}
|
||||||
|
|
||||||
datadogRequest.ConditionalFormats = append(datadogRequest.ConditionalFormats, d)
|
datadogRequest.ConditionalFormats = append(datadogRequest.ConditionalFormats, d)
|
||||||
|
@ -301,9 +301,10 @@ func buildTemplateVariables(terraformTemplateVariables *[]interface{}) *[]datado
|
||||||
for i, t_ := range *terraformTemplateVariables {
|
for i, t_ := range *terraformTemplateVariables {
|
||||||
t := t_.(map[string]interface{})
|
t := t_.(map[string]interface{})
|
||||||
datadogTemplateVariables[i] = datadog.TemplateVariable{
|
datadogTemplateVariables[i] = datadog.TemplateVariable{
|
||||||
Name: t["name"].(string),
|
Name: datadog.String(t["name"].(string)),
|
||||||
Prefix: t["prefix"].(string),
|
Prefix: datadog.String(t["prefix"].(string)),
|
||||||
Default: t["default"].(string)}
|
Default: datadog.String(t["default"].(string)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return &datadogTemplateVariables
|
return &datadogTemplateVariables
|
||||||
}
|
}
|
||||||
|
@ -312,58 +313,55 @@ func appendRequests(datadogGraph *datadog.Graph, terraformRequests *[]interface{
|
||||||
for _, t_ := range *terraformRequests {
|
for _, t_ := range *terraformRequests {
|
||||||
t := t_.(map[string]interface{})
|
t := t_.(map[string]interface{})
|
||||||
d := datadog.GraphDefinitionRequest{
|
d := datadog.GraphDefinitionRequest{
|
||||||
Query: t["q"].(string),
|
Query: datadog.String(t["q"].(string)),
|
||||||
Type: t["type"].(string),
|
Type: datadog.String(t["type"].(string)),
|
||||||
Aggregator: t["aggregator"].(string),
|
Aggregator: datadog.String(t["aggregator"].(string)),
|
||||||
}
|
}
|
||||||
if stacked, ok := t["stacked"]; ok {
|
if stacked, ok := t["stacked"]; ok {
|
||||||
d.Stacked = stacked.(bool)
|
d.SetStacked(stacked.(bool))
|
||||||
}
|
}
|
||||||
if style, ok := t["style"]; ok {
|
if style, ok := t["style"]; ok {
|
||||||
s, _ := style.(map[string]interface{})
|
s, _ := style.(map[string]interface{})
|
||||||
|
|
||||||
style := &datadog.GraphDefinitionRequestStyle{}
|
style := datadog.GraphDefinitionRequestStyle{}
|
||||||
|
|
||||||
if palette_, ok := s["palette"]; ok {
|
if v, ok := s["palette"]; ok {
|
||||||
palette := palette_.(string)
|
style.SetPalette(v.(string))
|
||||||
style.Palette = &palette
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if width, ok := s["width"]; ok {
|
if v, ok := s["width"]; ok {
|
||||||
width := width.(string)
|
style.SetWidth(v.(string))
|
||||||
style.Width = &width
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if type_, ok := s["type"]; ok {
|
if v, ok := s["type"]; ok {
|
||||||
style_type := type_.(string)
|
style.SetType(v.(string))
|
||||||
style.Type = &style_type
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d.Style = style
|
d.SetStyle(style)
|
||||||
}
|
}
|
||||||
|
|
||||||
if changeType, ok := t["change_type"]; ok {
|
if v, ok := t["change_type"]; ok {
|
||||||
d.ChangeType = changeType.(string)
|
d.SetChangeType(v.(string))
|
||||||
}
|
}
|
||||||
if compareTo, ok := t["compare_to"]; ok {
|
if v, ok := t["compare_to"]; ok {
|
||||||
d.CompareTo = compareTo.(string)
|
d.SetCompareTo(v.(string))
|
||||||
}
|
}
|
||||||
if increaseGood, ok := t["increase_good"]; ok {
|
if v, ok := t["increase_good"]; ok {
|
||||||
d.IncreaseGood = increaseGood.(bool)
|
d.SetIncreaseGood(v.(bool))
|
||||||
}
|
}
|
||||||
if orderBy, ok := t["order_by"]; ok {
|
if v, ok := t["order_by"]; ok {
|
||||||
d.OrderBy = orderBy.(string)
|
d.SetOrderBy(v.(string))
|
||||||
}
|
}
|
||||||
if extraCol, ok := t["extra_col"]; ok {
|
if v, ok := t["extra_col"]; ok {
|
||||||
d.ExtraCol = extraCol.(string)
|
d.SetExtraCol(v.(string))
|
||||||
}
|
}
|
||||||
if orderDirection, ok := t["order_direction"]; ok {
|
if v, ok := t["order_direction"]; ok {
|
||||||
d.OrderDirection = orderDirection.(string)
|
d.SetOrderDirection(v.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if terraformConditionalFormats, ok := t["conditional_format"]; ok {
|
if v, ok := t["conditional_format"]; ok {
|
||||||
formats := terraformConditionalFormats.([]interface{})
|
v_ := v.([]interface{})
|
||||||
appendConditionalFormats(&d, &formats)
|
appendConditionalFormats(&d, &v_)
|
||||||
}
|
}
|
||||||
|
|
||||||
datadogGraph.Definition.Requests = append(datadogGraph.Definition.Requests, d)
|
datadogGraph.Definition.Requests = append(datadogGraph.Definition.Requests, d)
|
||||||
|
@ -372,12 +370,9 @@ func appendRequests(datadogGraph *datadog.Graph, terraformRequests *[]interface{
|
||||||
|
|
||||||
func appendEvents(datadogGraph *datadog.Graph, terraformEvents *[]interface{}) {
|
func appendEvents(datadogGraph *datadog.Graph, terraformEvents *[]interface{}) {
|
||||||
for _, t_ := range *terraformEvents {
|
for _, t_ := range *terraformEvents {
|
||||||
d := struct {
|
datadogGraph.Definition.Events = append(datadogGraph.Definition.Events, datadog.GraphEvent{
|
||||||
Query string `json:"q"`
|
Query: datadog.String(t_.(string)),
|
||||||
}{
|
})
|
||||||
t_.(string),
|
|
||||||
}
|
|
||||||
datadogGraph.Definition.Events = append(datadogGraph.Definition.Events, d)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -385,11 +380,11 @@ func appendMarkers(datadogGraph *datadog.Graph, terraformMarkers *[]interface{})
|
||||||
for _, t_ := range *terraformMarkers {
|
for _, t_ := range *terraformMarkers {
|
||||||
t := t_.(map[string]interface{})
|
t := t_.(map[string]interface{})
|
||||||
d := datadog.GraphDefinitionMarker{
|
d := datadog.GraphDefinitionMarker{
|
||||||
Type: t["type"].(string),
|
Type: datadog.String(t["type"].(string)),
|
||||||
Value: t["value"].(string),
|
Value: datadog.String(t["value"].(string)),
|
||||||
}
|
}
|
||||||
if label, ok := t["label"]; ok {
|
if v, ok := t["label"]; ok {
|
||||||
d.Label = label.(string)
|
d.SetLabel(v.(string))
|
||||||
}
|
}
|
||||||
datadogGraph.Definition.Markers = append(datadogGraph.Definition.Markers, d)
|
datadogGraph.Definition.Markers = append(datadogGraph.Definition.Markers, d)
|
||||||
}
|
}
|
||||||
|
@ -399,90 +394,90 @@ func buildGraphs(terraformGraphs *[]interface{}) *[]datadog.Graph {
|
||||||
datadogGraphs := make([]datadog.Graph, len(*terraformGraphs))
|
datadogGraphs := make([]datadog.Graph, len(*terraformGraphs))
|
||||||
for i, t_ := range *terraformGraphs {
|
for i, t_ := range *terraformGraphs {
|
||||||
t := t_.(map[string]interface{})
|
t := t_.(map[string]interface{})
|
||||||
datadogGraphs[i] = datadog.Graph{Title: t["title"].(string)}
|
|
||||||
|
datadogGraphs[i] = datadog.Graph{
|
||||||
|
Title: datadog.String(t["title"].(string)),
|
||||||
|
}
|
||||||
|
|
||||||
d := &datadogGraphs[i]
|
d := &datadogGraphs[i]
|
||||||
d.Definition.Viz = t["viz"].(string)
|
d.Definition = &datadog.GraphDefinition{}
|
||||||
|
d.Definition.SetViz(t["viz"].(string))
|
||||||
|
|
||||||
if yaxis_, ok := t["yaxis"]; ok {
|
if v, ok := t["yaxis"]; ok {
|
||||||
yaxis := yaxis_.(map[string]interface{})
|
yaxis := v.(map[string]interface{})
|
||||||
if min_, ok := yaxis["min"]; ok {
|
if v, ok := yaxis["min"]; ok {
|
||||||
min, _ := strconv.ParseFloat(min_.(string), 64)
|
min, _ := strconv.ParseFloat(v.(string), 64)
|
||||||
d.Definition.Yaxis.Min = &min
|
d.Definition.Yaxis.SetMin(min)
|
||||||
}
|
}
|
||||||
if max_, ok := yaxis["max"]; ok {
|
if v, ok := yaxis["max"]; ok {
|
||||||
max, _ := strconv.ParseFloat(max_.(string), 64)
|
max, _ := strconv.ParseFloat(v.(string), 64)
|
||||||
d.Definition.Yaxis.Max = &max
|
d.Definition.Yaxis.SetMax(max)
|
||||||
}
|
}
|
||||||
if scale_, ok := yaxis["scale"]; ok {
|
if v, ok := yaxis["scale"]; ok {
|
||||||
scale := scale_.(string)
|
d.Definition.Yaxis.SetScale(v.(string))
|
||||||
d.Definition.Yaxis.Scale = &scale
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if autoscale, ok := t["autoscale"]; ok {
|
if v, ok := t["autoscale"]; ok {
|
||||||
d.Definition.Autoscale = autoscale.(bool)
|
d.Definition.SetAutoscale(v.(bool))
|
||||||
}
|
}
|
||||||
|
|
||||||
if textAlign, ok := t["text_align"]; ok {
|
if v, ok := t["text_align"]; ok {
|
||||||
d.Definition.TextAlign = textAlign.(string)
|
d.Definition.SetTextAlign(v.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if precision, ok := t["precision"]; ok {
|
if precision, ok := t["precision"]; ok {
|
||||||
d.Definition.Precision = precision.(string)
|
d.Definition.SetPrecision(precision.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if customUnit, ok := t["custom_unit"]; ok {
|
if v, ok := t["custom_unit"]; ok {
|
||||||
d.Definition.CustomUnit = customUnit.(string)
|
d.Definition.SetCustomUnit(v.(string))
|
||||||
}
|
}
|
||||||
|
|
||||||
if style, ok := t["style"]; ok {
|
if style, ok := t["style"]; ok {
|
||||||
s := style.(map[string]interface{})
|
s := style.(map[string]interface{})
|
||||||
|
|
||||||
style := struct {
|
gs := datadog.Style{}
|
||||||
Palette *string `json:"palette,omitempty"`
|
|
||||||
PaletteFlip *bool `json:"paletteFlip,omitempty"`
|
|
||||||
}{}
|
|
||||||
|
|
||||||
if palette_, ok := s["palette"]; ok {
|
if v, ok := s["palette"]; ok {
|
||||||
palette := palette_.(string)
|
gs.SetPalette(v.(string))
|
||||||
style.Palette = &palette
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if paletteFlip_, ok := s["palette_flip"]; ok {
|
if v, ok := s["palette_flip"]; ok {
|
||||||
paletteFlip, _ := strconv.ParseBool(paletteFlip_.(string))
|
pf, _ := strconv.ParseBool(v.(string))
|
||||||
style.PaletteFlip = &paletteFlip
|
gs.SetPaletteFlip(pf)
|
||||||
}
|
}
|
||||||
d.Definition.Style = &style
|
d.Definition.SetStyle(gs)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if groups, ok := t["group"]; ok {
|
if v, ok := t["group"]; ok {
|
||||||
for _, g := range groups.(*schema.Set).List() {
|
for _, g := range v.(*schema.Set).List() {
|
||||||
d.Definition.Groups = append(d.Definition.Groups, g.(string))
|
d.Definition.Groups = append(d.Definition.Groups, g.(string))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if includeNoMetricHosts, ok := t["include_no_metric_hosts"]; ok {
|
if includeNoMetricHosts, ok := t["include_no_metric_hosts"]; ok {
|
||||||
d.Definition.IncludeNoMetricHosts = includeNoMetricHosts.(bool)
|
d.Definition.SetIncludeNoMetricHosts(includeNoMetricHosts.(bool))
|
||||||
}
|
}
|
||||||
|
|
||||||
if scopes, ok := t["scope"]; ok {
|
if v, ok := t["scope"]; ok {
|
||||||
for _, s := range scopes.(*schema.Set).List() {
|
for _, s := range v.(*schema.Set).List() {
|
||||||
d.Definition.Scopes = append(d.Definition.Groups, s.(string))
|
d.Definition.Scopes = append(d.Definition.Groups, s.(string))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if includeUngroupedHosts, ok := t["include_ungrouped_hosts"]; ok {
|
if v, ok := t["include_ungrouped_hosts"]; ok {
|
||||||
d.Definition.IncludeUngroupedHosts = includeUngroupedHosts.(bool)
|
d.Definition.SetIncludeUngroupedHosts(v.(bool))
|
||||||
}
|
}
|
||||||
terraformMarkers := t["marker"].([]interface{})
|
v := t["marker"].([]interface{})
|
||||||
appendMarkers(d, &terraformMarkers)
|
appendMarkers(d, &v)
|
||||||
|
|
||||||
terraformEvents := t["events"].(*schema.Set).List()
|
v = t["events"].(*schema.Set).List()
|
||||||
appendEvents(d, &terraformEvents)
|
appendEvents(d, &v)
|
||||||
|
|
||||||
terraformRequests := t["request"].([]interface{})
|
v = t["request"].([]interface{})
|
||||||
appendRequests(d, &terraformRequests)
|
appendRequests(d, &v)
|
||||||
}
|
}
|
||||||
return &datadogGraphs
|
return &datadogGraphs
|
||||||
}
|
}
|
||||||
|
@ -499,10 +494,10 @@ func buildTimeboard(d *schema.ResourceData) (*datadog.Dashboard, error) {
|
||||||
terraformGraphs := d.Get("graph").([]interface{})
|
terraformGraphs := d.Get("graph").([]interface{})
|
||||||
terraformTemplateVariables := d.Get("template_variable").([]interface{})
|
terraformTemplateVariables := d.Get("template_variable").([]interface{})
|
||||||
return &datadog.Dashboard{
|
return &datadog.Dashboard{
|
||||||
Id: id,
|
Id: datadog.Int(id),
|
||||||
Title: d.Get("title").(string),
|
Title: datadog.String(d.Get("title").(string)),
|
||||||
Description: d.Get("description").(string),
|
Description: datadog.String(d.Get("description").(string)),
|
||||||
ReadOnly: d.Get("read_only").(bool),
|
ReadOnly: datadog.Bool(d.Get("read_only").(bool)),
|
||||||
Graphs: *buildGraphs(&terraformGraphs),
|
Graphs: *buildGraphs(&terraformGraphs),
|
||||||
TemplateVariables: *buildTemplateVariables(&terraformTemplateVariables),
|
TemplateVariables: *buildTemplateVariables(&terraformTemplateVariables),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -517,7 +512,7 @@ func resourceDatadogTimeboardCreate(d *schema.ResourceData, meta interface{}) er
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create timeboard using Datadog API: %s", err.Error())
|
return fmt.Errorf("Failed to create timeboard using Datadog API: %s", err.Error())
|
||||||
}
|
}
|
||||||
d.SetId(strconv.Itoa(timeboard.Id))
|
d.SetId(strconv.Itoa(timeboard.GetId()))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -535,19 +530,19 @@ func resourceDatadogTimeboardUpdate(d *schema.ResourceData, meta interface{}) er
|
||||||
func appendTerraformGraphRequests(datadogRequests []datadog.GraphDefinitionRequest, requests *[]map[string]interface{}) {
|
func appendTerraformGraphRequests(datadogRequests []datadog.GraphDefinitionRequest, requests *[]map[string]interface{}) {
|
||||||
for _, datadogRequest := range datadogRequests {
|
for _, datadogRequest := range datadogRequests {
|
||||||
request := map[string]interface{}{}
|
request := map[string]interface{}{}
|
||||||
request["q"] = datadogRequest.Query
|
request["q"] = datadogRequest.GetQuery()
|
||||||
request["stacked"] = datadogRequest.Stacked
|
request["stacked"] = datadogRequest.GetStacked()
|
||||||
request["type"] = datadogRequest.Type
|
request["type"] = datadogRequest.GetType()
|
||||||
if datadogRequest.Style != nil {
|
if v, ok := datadogRequest.GetStyleOk(); ok {
|
||||||
style := map[string]string{}
|
style := map[string]string{}
|
||||||
if datadogRequest.Style.Palette != nil {
|
if v, ok := v.GetPaletteOk(); ok {
|
||||||
style["palette"] = *datadogRequest.Style.Palette
|
style["palette"] = v
|
||||||
}
|
}
|
||||||
if datadogRequest.Style.Type != nil {
|
if v, ok := v.GetTypeOk(); ok {
|
||||||
style["type"] = *datadogRequest.Style.Type
|
style["type"] = v
|
||||||
}
|
}
|
||||||
if datadogRequest.Style.Width != nil {
|
if v, ok := v.GetWidthOk(); ok {
|
||||||
style["width"] = *datadogRequest.Style.Width
|
style["width"] = v
|
||||||
}
|
}
|
||||||
request["style"] = style
|
request["style"] = style
|
||||||
}
|
}
|
||||||
|
@ -563,12 +558,12 @@ func appendTerraformGraphRequests(datadogRequests []datadog.GraphDefinitionReque
|
||||||
conditionalFormats = append(conditionalFormats, conditionalFormat)
|
conditionalFormats = append(conditionalFormats, conditionalFormat)
|
||||||
}
|
}
|
||||||
request["conditional_format"] = conditionalFormats
|
request["conditional_format"] = conditionalFormats
|
||||||
request["change_type"] = datadogRequest.ChangeType
|
request["change_type"] = datadogRequest.GetChangeType()
|
||||||
request["order_direction"] = datadogRequest.OrderDirection
|
request["order_direction"] = datadogRequest.GetOrderDirection()
|
||||||
request["compare_to"] = datadogRequest.CompareTo
|
request["compare_to"] = datadogRequest.GetCompareTo()
|
||||||
request["increase_good"] = datadogRequest.IncreaseGood
|
request["increase_good"] = datadogRequest.GetIncreaseGood()
|
||||||
request["order_by"] = datadogRequest.OrderBy
|
request["order_by"] = datadogRequest.GetOrderBy()
|
||||||
request["extra_col"] = datadogRequest.ExtraCol
|
request["extra_col"] = datadogRequest.GetExtraCol()
|
||||||
|
|
||||||
*requests = append(*requests, request)
|
*requests = append(*requests, request)
|
||||||
}
|
}
|
||||||
|
@ -576,12 +571,12 @@ func appendTerraformGraphRequests(datadogRequests []datadog.GraphDefinitionReque
|
||||||
|
|
||||||
func buildTerraformGraph(datadog_graph datadog.Graph) map[string]interface{} {
|
func buildTerraformGraph(datadog_graph datadog.Graph) map[string]interface{} {
|
||||||
graph := map[string]interface{}{}
|
graph := map[string]interface{}{}
|
||||||
graph["title"] = datadog_graph.Title
|
graph["title"] = datadog_graph.GetTitle()
|
||||||
|
|
||||||
definition := datadog_graph.Definition
|
definition := datadog_graph.Definition
|
||||||
graph["viz"] = definition.Viz
|
graph["viz"] = definition.GetViz()
|
||||||
|
|
||||||
events := []string{}
|
events := []*string{}
|
||||||
for _, datadog_event := range definition.Events {
|
for _, datadog_event := range definition.Events {
|
||||||
events = append(events, datadog_event.Query)
|
events = append(events, datadog_event.Query)
|
||||||
}
|
}
|
||||||
|
@ -600,16 +595,16 @@ func buildTerraformGraph(datadog_graph datadog.Graph) map[string]interface{} {
|
||||||
|
|
||||||
yaxis := map[string]string{}
|
yaxis := map[string]string{}
|
||||||
|
|
||||||
if definition.Yaxis.Min != nil {
|
if v, ok := definition.Yaxis.GetMinOk(); ok {
|
||||||
yaxis["min"] = strconv.FormatFloat(*definition.Yaxis.Min, 'f', -1, 64)
|
yaxis["min"] = strconv.FormatFloat(v, 'f', -1, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
if definition.Yaxis.Max != nil {
|
if v, ok := definition.Yaxis.GetMaxOk(); ok {
|
||||||
yaxis["max"] = strconv.FormatFloat(*definition.Yaxis.Max, 'f', -1, 64)
|
yaxis["max"] = strconv.FormatFloat(v, 'f', -1, 64)
|
||||||
}
|
}
|
||||||
|
|
||||||
if definition.Yaxis.Scale != nil {
|
if v, ok := definition.Yaxis.GetScaleOk(); ok {
|
||||||
yaxis["scale"] = *definition.Yaxis.Scale
|
yaxis["scale"] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
graph["yaxis"] = yaxis
|
graph["yaxis"] = yaxis
|
||||||
|
@ -619,13 +614,13 @@ func buildTerraformGraph(datadog_graph datadog.Graph) map[string]interface{} {
|
||||||
graph["precision"] = definition.Precision
|
graph["precision"] = definition.Precision
|
||||||
graph["custom_unit"] = definition.CustomUnit
|
graph["custom_unit"] = definition.CustomUnit
|
||||||
|
|
||||||
if definition.Style != nil {
|
if v, ok := definition.GetStyleOk(); ok {
|
||||||
style := map[string]string{}
|
style := map[string]string{}
|
||||||
if definition.Style.Palette != nil {
|
if v, ok := v.GetPaletteOk(); ok {
|
||||||
style["palette"] = *definition.Style.Palette
|
style["palette"] = v
|
||||||
}
|
}
|
||||||
if definition.Style.PaletteFlip != nil {
|
if v, ok := v.GetPaletteFlipOk(); ok {
|
||||||
style["palette_flip"] = strconv.FormatBool(*definition.Style.PaletteFlip)
|
style["palette_flip"] = strconv.FormatBool(v)
|
||||||
}
|
}
|
||||||
graph["style"] = style
|
graph["style"] = style
|
||||||
}
|
}
|
||||||
|
@ -651,8 +646,8 @@ func resourceDatadogTimeboardRead(d *schema.ResourceData, meta interface{}) erro
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("[DEBUG] timeboard: %v", timeboard)
|
log.Printf("[DEBUG] timeboard: %v", timeboard)
|
||||||
d.Set("title", timeboard.Title)
|
d.Set("title", timeboard.GetTitle())
|
||||||
d.Set("description", timeboard.Description)
|
d.Set("description", timeboard.GetDescription())
|
||||||
|
|
||||||
graphs := []map[string]interface{}{}
|
graphs := []map[string]interface{}{}
|
||||||
for _, datadog_graph := range timeboard.Graphs {
|
for _, datadog_graph := range timeboard.Graphs {
|
||||||
|
@ -660,9 +655,9 @@ func resourceDatadogTimeboardRead(d *schema.ResourceData, meta interface{}) erro
|
||||||
}
|
}
|
||||||
d.Set("graph", graphs)
|
d.Set("graph", graphs)
|
||||||
|
|
||||||
templateVariables := []map[string]string{}
|
templateVariables := []map[string]*string{}
|
||||||
for _, templateVariable := range timeboard.TemplateVariables {
|
for _, templateVariable := range timeboard.TemplateVariables {
|
||||||
tv := map[string]string{
|
tv := map[string]*string{
|
||||||
"name": templateVariable.Name,
|
"name": templateVariable.Name,
|
||||||
"prefix": templateVariable.Prefix,
|
"prefix": templateVariable.Prefix,
|
||||||
"default": templateVariable.Default,
|
"default": templateVariable.Default,
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/helper/resource"
|
"github.com/hashicorp/terraform/helper/resource"
|
||||||
"github.com/hashicorp/terraform/terraform"
|
"github.com/hashicorp/terraform/terraform"
|
||||||
"github.com/zorkian/go-datadog-api"
|
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
const config1 = `
|
const config1 = `
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
[![GoDoc](http://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/zorkian/go-datadog-api)
|
|
||||||
[![Build
|
|
||||||
status](https://travis-ci.org/zorkian/go-datadog-api.svg)](https://travis-ci.org/zorkian/go-datadog-api)
|
|
||||||
|
|
||||||
# Datadog API in Go
|
|
||||||
|
|
||||||
Hi!
|
|
||||||
|
|
||||||
This is a Go wrapper for the Datadog API. You should 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/>
|
|
||||||
|
|
||||||
|
|
||||||
## USAGE
|
|
||||||
|
|
||||||
To use this project, include it in your code like:
|
|
||||||
|
|
||||||
``` go
|
|
||||||
import "github.com/zorkian/go-datadog-api"
|
|
||||||
```
|
|
||||||
|
|
||||||
Then, you can work with it:
|
|
||||||
|
|
||||||
``` go
|
|
||||||
client := datadog.NewClient("api key", "application key")
|
|
||||||
|
|
||||||
dash, err := client.GetDashboard(10880)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("fatal: %s\n", err)
|
|
||||||
}
|
|
||||||
log.Printf("dashboard %d: %s\n", dash.Id, dash.Title)
|
|
||||||
```
|
|
||||||
|
|
||||||
That's all; it's pretty easy to use. 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: <http://godoc.org/github.com/zorkian/go-datadog-api>
|
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|
||||||
* 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.*
|
|
||||||
|
|
||||||
## COPYRIGHT AND LICENSE
|
|
||||||
|
|
||||||
Please see the LICENSE file for the included license information.
|
|
||||||
|
|
||||||
Copyright 2013 by authors and contributors.
|
|
|
@ -1,15 +0,0 @@
|
||||||
package datadog
|
|
||||||
|
|
||||||
// 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 GetInt(v *int) (int, bool) {
|
|
||||||
if v != nil {
|
|
||||||
return *v, true
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0, false
|
|
||||||
}
|
|
|
@ -1,172 +0,0 @@
|
||||||
/*
|
|
||||||
* 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"`
|
|
||||||
Stacked bool `json:"stacked"`
|
|
||||||
Aggregator string `json:"aggregator"`
|
|
||||||
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"`
|
|
||||||
Value string `json:"value"`
|
|
||||||
Label string `json:"label,omitempty"`
|
|
||||||
Val json.Number `json:"val,omitempty"`
|
|
||||||
Min json.Number `json:"min,omitempty"`
|
|
||||||
Max json.Number `json:"max,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Graph represents a graph that might exist on a dashboard.
|
|
||||||
type Graph struct {
|
|
||||||
Title string `json:"title"`
|
|
||||||
Definition struct {
|
|
||||||
Viz string `json:"viz"`
|
|
||||||
Requests []GraphDefinitionRequest `json:"requests"`
|
|
||||||
Events []struct {
|
|
||||||
Query string `json:"q"`
|
|
||||||
} `json:"events"`
|
|
||||||
Markers []GraphDefinitionMarker `json:"markers,omitempty"`
|
|
||||||
|
|
||||||
// For timeseries type graphs
|
|
||||||
Yaxis struct {
|
|
||||||
Min *float64 `json:"min,omitempty"`
|
|
||||||
Max *float64 `json:"max,omitempty"`
|
|
||||||
Scale *string `json:"scale,omitempty"`
|
|
||||||
} `json:"yaxis,omitempty"`
|
|
||||||
|
|
||||||
// For query value type graphs
|
|
||||||
Autoscale bool `json:"austoscale,omitempty"`
|
|
||||||
TextAlign string `json:"text_align,omitempty"`
|
|
||||||
Precision string `json:"precision,omitempty"`
|
|
||||||
CustomUnit string `json:"custom_unit,omitempty"`
|
|
||||||
|
|
||||||
// For hostnamp type graphs
|
|
||||||
Style *struct {
|
|
||||||
Palette *string `json:"palette,omitempty"`
|
|
||||||
PaletteFlip *bool `json:"paletteFlip,omitempty"`
|
|
||||||
}
|
|
||||||
Groups []string `json:"group,omitempty"`
|
|
||||||
IncludeNoMetricHosts bool `json:"noMetricHosts,omitempty"`
|
|
||||||
Scopes []string `json:"scope,omitempty"`
|
|
||||||
IncludeUngroupedHosts bool `json:"noGroupHosts,omitempty"`
|
|
||||||
} `json:"definition"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// Template variable represents a template variable that might exist on a dashboard
|
|
||||||
type TemplateVariable struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Prefix string `json:"prefix"`
|
|
||||||
Default string `json:"default"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
Graphs []Graph `json:"graphs"`
|
|
||||||
TemplateVariables []TemplateVariable `json:"template_variables,omitempty"`
|
|
||||||
ReadOnly bool `json:"read_only"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// DashboardLite represents a user created dashboard. This is the mini
|
|
||||||
// struct when we load the summaries.
|
|
||||||
type DashboardLite struct {
|
|
||||||
Id int `json:"id,string"` // TODO: Remove ',string'.
|
|
||||||
Resource string `json:"resource"`
|
|
||||||
Description string `json:"description"`
|
|
||||||
Title string `json:"title"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// reqGetDashboards from /api/v1/dash
|
|
||||||
type reqGetDashboards struct {
|
|
||||||
Dashboards []DashboardLite `json:"dashes"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// reqGetDashboard from /api/v1/dash/:dashboard_id
|
|
||||||
type reqGetDashboard struct {
|
|
||||||
Resource string `json:"resource"`
|
|
||||||
Url string `json:"url"`
|
|
||||||
Dashboard Dashboard `json:"dash"`
|
|
||||||
}
|
|
||||||
|
|
||||||
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"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
package datadog
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RateLimit struct {
|
|
||||||
Limit int
|
|
||||||
Period time.Duration
|
|
||||||
Remaining int
|
|
||||||
Reset time.Duration
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RateLimit) Error() string {
|
|
||||||
return fmt.Sprintf("Rate limiting: Limit %d, Period %d, Remaining %d, Reset in %d", r.Limit, r.Period, r.Remaining, r.Reset)
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRateLimit(limit, period, remaining, reset int) *RateLimit {
|
|
||||||
return &RateLimit{
|
|
||||||
Limit: limit,
|
|
||||||
Period: time.Duration(period) * time.Second,
|
|
||||||
Remaining: remaining,
|
|
||||||
Reset: time.Duration(reset) * time.Second,
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,287 +0,0 @@
|
||||||
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"`
|
|
||||||
}
|
|
|
@ -4,6 +4,9 @@ GOFMT_FILES?=$$(find . -name '*.go' | grep -v vendor)
|
||||||
|
|
||||||
default: test fmt
|
default: test fmt
|
||||||
|
|
||||||
|
generate:
|
||||||
|
go generate
|
||||||
|
|
||||||
# test runs the unit tests and vets the code
|
# test runs the unit tests and vets the code
|
||||||
test:
|
test:
|
||||||
go test . $(TESTARGS) -v -timeout=30s -parallel=4
|
go test . $(TESTARGS) -v -timeout=30s -parallel=4
|
|
@ -0,0 +1,118 @@
|
||||||
|
[![GoDoc](http://img.shields.io/badge/godoc-reference-blue.svg)](https://godoc.org/gopkg.in/zorkian/go-datadog-api.v2)
|
||||||
|
[![Build
|
||||||
|
status](https://travis-ci.org/zorkian/go-datadog-api.svg)](https://travis-ci.org/zorkian/go-datadog-api)
|
||||||
|
|
||||||
|
# Datadog API in Go
|
||||||
|
|
||||||
|
**This is the v2.0 version of the API, and has breaking changes. Use the main or 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 2017 by authors and contributors.
|
|
@ -15,14 +15,14 @@ import (
|
||||||
// Alert represents the data of an alert: a query that can fire and send a
|
// Alert represents the data of an alert: a query that can fire and send a
|
||||||
// message to the users.
|
// message to the users.
|
||||||
type Alert struct {
|
type Alert struct {
|
||||||
Id int `json:"id,omitempty"`
|
Id *int `json:"id,omitempty"`
|
||||||
Creator int `json:"creator,omitempty"`
|
Creator *int `json:"creator,omitempty"`
|
||||||
Query string `json:"query,omitempty"`
|
Query *string `json:"query,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Message string `json:"message,omitempty"`
|
Message *string `json:"message,omitempty"`
|
||||||
Silenced bool `json:"silenced,omitempty"`
|
Silenced *bool `json:"silenced,omitempty"`
|
||||||
NotifyNoData bool `json:"notify_no_data,omitempty"`
|
NotifyNoData *bool `json:"notify_no_data,omitempty"`
|
||||||
State string `json:"state,omitempty"`
|
State *string `json:"state,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqAlerts receives a slice of all alerts.
|
// reqAlerts receives a slice of all alerts.
|
|
@ -1,11 +1,11 @@
|
||||||
package datadog
|
package datadog
|
||||||
|
|
||||||
type Check struct {
|
type Check struct {
|
||||||
Check string `json:"check"`
|
Check *string `json:"check,omitempty"`
|
||||||
HostName string `json:"host_name"`
|
HostName *string `json:"host_name,omitempty"`
|
||||||
Status Status `json:"status"`
|
Status *Status `json:"status,omitempty"`
|
||||||
Timestamp string `json:"timestamp,omitempty"`
|
Timestamp *string `json:"timestamp,omitempty"`
|
||||||
Message string `json:"message,omitempty"`
|
Message *string `json:"message,omitempty"`
|
||||||
Tags []string `json:"tags,omitempty"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,6 +44,12 @@ func NewClient(apiKey, appKey string) *Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetKeys changes the value of apiKey and appKey.
|
||||||
|
func (c *Client) SetKeys(apiKey, appKey string) {
|
||||||
|
c.apiKey = apiKey
|
||||||
|
c.appKey = appKey
|
||||||
|
}
|
||||||
|
|
||||||
// Validate checks if the API and application keys are valid.
|
// Validate checks if the API and application keys are valid.
|
||||||
func (client *Client) Validate() (bool, error) {
|
func (client *Client) Validate() (bool, error) {
|
||||||
var bodyreader io.Reader
|
var bodyreader io.Reader
|
|
@ -14,27 +14,27 @@ import (
|
||||||
|
|
||||||
// Comment is a special form of event that appears in a stream.
|
// Comment is a special form of event that appears in a stream.
|
||||||
type Comment struct {
|
type Comment struct {
|
||||||
Id int `json:"id"`
|
Id *int `json:"id,omitempty"`
|
||||||
RelatedId int `json:"related_event_id"`
|
RelatedId *int `json:"related_event_id,omitempty"`
|
||||||
Handle string `json:"handle"`
|
Handle *string `json:"handle,omitempty"`
|
||||||
Message string `json:"message"`
|
Message *string `json:"message,omitempty"`
|
||||||
Resource string `json:"resource"`
|
Resource *string `json:"resource,omitempty"`
|
||||||
Url string `json:"url"`
|
Url *string `json:"url,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqComment is the container for receiving commenst.
|
// reqComment is the container for receiving commenst.
|
||||||
type reqComment struct {
|
type reqComment struct {
|
||||||
Comment Comment `json:"comment"`
|
Comment *Comment `json:"comment,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateComment adds a new comment to the system.
|
// CreateComment adds a new comment to the system.
|
||||||
func (client *Client) CreateComment(handle, message string) (*Comment, error) {
|
func (client *Client) CreateComment(handle, message string) (*Comment, error) {
|
||||||
var out reqComment
|
var out reqComment
|
||||||
comment := Comment{Handle: handle, Message: message}
|
comment := Comment{Handle: String(handle), Message: String(message)}
|
||||||
if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
|
if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &out.Comment, nil
|
return out.Comment, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateRelatedComment adds a new comment, but lets you specify the related
|
// CreateRelatedComment adds a new comment, but lets you specify the related
|
||||||
|
@ -42,16 +42,16 @@ func (client *Client) CreateComment(handle, message string) (*Comment, error) {
|
||||||
func (client *Client) CreateRelatedComment(handle, message string,
|
func (client *Client) CreateRelatedComment(handle, message string,
|
||||||
relid int) (*Comment, error) {
|
relid int) (*Comment, error) {
|
||||||
var out reqComment
|
var out reqComment
|
||||||
comment := Comment{Handle: handle, Message: message, RelatedId: relid}
|
comment := Comment{Handle: String(handle), Message: String(message), RelatedId: Int(relid)}
|
||||||
if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
|
if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &out.Comment, nil
|
return out.Comment, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// EditComment changes the message and possibly handle of a particular comment.
|
// EditComment changes the message and possibly handle of a particular comment.
|
||||||
func (client *Client) EditComment(id int, handle, message string) error {
|
func (client *Client) EditComment(id int, handle, message string) error {
|
||||||
comment := Comment{Handle: handle, Message: message}
|
comment := Comment{Handle: String(handle), Message: String(message)}
|
||||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/comments/%d", id),
|
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/comments/%d", id),
|
||||||
&comment, nil)
|
&comment, nil)
|
||||||
}
|
}
|
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* 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:"austoscale,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"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
@ -13,23 +13,23 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Recurrence struct {
|
type Recurrence struct {
|
||||||
Period int `json:"period,omitempty"`
|
Period *int `json:"period,omitempty"`
|
||||||
Type string `json:"type,omitempty"`
|
Type *string `json:"type,omitempty"`
|
||||||
UntilDate int `json:"until_date,omitempty"`
|
UntilDate *int `json:"until_date,omitempty"`
|
||||||
UntilOccurrences int `json:"until_occurrences,omitempty"`
|
UntilOccurrences *int `json:"until_occurrences,omitempty"`
|
||||||
WeekDays []string `json:"week_days,omitempty"`
|
WeekDays []string `json:"week_days,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Downtime struct {
|
type Downtime struct {
|
||||||
Active bool `json:"active,omitempty"`
|
Active *bool `json:"active,omitempty"`
|
||||||
Canceled int `json:"canceled,omitempty"`
|
Canceled *int `json:"canceled,omitempty"`
|
||||||
Disabled bool `json:"disabled,omitempty"`
|
Disabled *bool `json:"disabled,omitempty"`
|
||||||
End int `json:"end,omitempty"`
|
End *int `json:"end,omitempty"`
|
||||||
Id int `json:"id,omitempty"`
|
Id *int `json:"id,omitempty"`
|
||||||
Message string `json:"message,omitempty"`
|
Message *string `json:"message,omitempty"`
|
||||||
Recurrence *Recurrence `json:"recurrence,omitempty"`
|
Recurrence *Recurrence `json:"recurrence,omitempty"`
|
||||||
Scope []string `json:"scope,omitempty"`
|
Scope []string `json:"scope,omitempty"`
|
||||||
Start int `json:"start,omitempty"`
|
Start *int `json:"start,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqDowntimes retrieves a slice of all Downtimes.
|
// reqDowntimes retrieves a slice of all Downtimes.
|
||||||
|
@ -51,7 +51,7 @@ func (client *Client) CreateDowntime(downtime *Downtime) (*Downtime, error) {
|
||||||
// UpdateDowntime takes a downtime that was previously retrieved through some method
|
// UpdateDowntime takes a downtime that was previously retrieved through some method
|
||||||
// and sends it back to the server.
|
// and sends it back to the server.
|
||||||
func (client *Client) UpdateDowntime(downtime *Downtime) error {
|
func (client *Client) UpdateDowntime(downtime *Downtime) error {
|
||||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/downtime/%d", downtime.Id),
|
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/downtime/%d", *downtime.Id),
|
||||||
downtime, nil)
|
downtime, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,24 +17,24 @@ import (
|
||||||
// Event is a single event. If this is being used to post an event, then not
|
// Event is a single event. If this is being used to post an event, then not
|
||||||
// all fields will be filled out.
|
// all fields will be filled out.
|
||||||
type Event struct {
|
type Event struct {
|
||||||
Id int `json:"id,omitempty"`
|
Id *int `json:"id,omitempty"`
|
||||||
Title string `json:"title,omitempty"`
|
Title *string `json:"title,omitempty"`
|
||||||
Text string `json:"text,omitempty"`
|
Text *string `json:"text,omitempty"`
|
||||||
Time int `json:"date_happened,omitempty"` // UNIX time.
|
Time *int `json:"date_happened,omitempty"` // UNIX time.
|
||||||
Priority string `json:"priority,omitempty"`
|
Priority *string `json:"priority,omitempty"`
|
||||||
AlertType string `json:"alert_type,omitempty"`
|
AlertType *string `json:"alert_type,omitempty"`
|
||||||
Host string `json:"host,omitempty"`
|
Host *string `json:"host,omitempty"`
|
||||||
Aggregation string `json:"aggregation_key,omitempty"`
|
Aggregation *string `json:"aggregation_key,omitempty"`
|
||||||
SourceType string `json:"source_type_name,omitempty"`
|
SourceType *string `json:"source_type_name,omitempty"`
|
||||||
Tags []string `json:"tags,omitempty"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
Url string `json:"url,omitempty"`
|
Url *string `json:"url,omitempty"`
|
||||||
Resource string `json:"resource,omitempty"`
|
Resource *string `json:"resource,omitempty"`
|
||||||
EventType string `json:"event_type,omitempty"`
|
EventType *string `json:"event_type,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqGetEvent is the container for receiving a single event.
|
// reqGetEvent is the container for receiving a single event.
|
||||||
type reqGetEvent struct {
|
type reqGetEvent struct {
|
||||||
Event Event `json:"event,omitempty"`
|
Event *Event `json:"event,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqGetEvents is for returning many events.
|
// reqGetEvents is for returning many events.
|
||||||
|
@ -48,7 +48,7 @@ func (client *Client) PostEvent(event *Event) (*Event, error) {
|
||||||
if err := client.doJsonRequest("POST", "/v1/events", event, &out); err != nil {
|
if err := client.doJsonRequest("POST", "/v1/events", event, &out); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &out.Event, nil
|
return out.Event, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetEvent gets a single event given an identifier.
|
// GetEvent gets a single event given an identifier.
|
||||||
|
@ -57,7 +57,7 @@ func (client *Client) GetEvent(id int) (*Event, error) {
|
||||||
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/events/%d", id), nil, &out); err != nil {
|
if err := client.doJsonRequest("GET", fmt.Sprintf("/v1/events/%d", id), nil, &out); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &out.Event, nil
|
return out.Event, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// QueryEvents returns a slice of events from the query stream.
|
// QueryEvents returns a slice of events from the query stream.
|
|
@ -0,0 +1,3 @@
|
||||||
|
package datadog
|
||||||
|
|
||||||
|
//go:generate go run cmd/tools/gen-accessors.go -v
|
|
@ -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
|
||||||
|
}
|
|
@ -17,9 +17,9 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type ThresholdCount struct {
|
type ThresholdCount struct {
|
||||||
Ok json.Number `json:"ok,omitempty"`
|
Ok *json.Number `json:"ok,omitempty"`
|
||||||
Critical json.Number `json:"critical,omitempty"`
|
Critical *json.Number `json:"critical,omitempty"`
|
||||||
Warning json.Number `json:"warning,omitempty"`
|
Warning *json.Number `json:"warning,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type NoDataTimeframe int
|
type NoDataTimeframe int
|
||||||
|
@ -40,38 +40,38 @@ func (tf *NoDataTimeframe) UnmarshalJSON(data []byte) error {
|
||||||
|
|
||||||
type Options struct {
|
type Options struct {
|
||||||
NoDataTimeframe NoDataTimeframe `json:"no_data_timeframe,omitempty"`
|
NoDataTimeframe NoDataTimeframe `json:"no_data_timeframe,omitempty"`
|
||||||
NotifyAudit bool `json:"notify_audit,omitempty"`
|
NotifyAudit *bool `json:"notify_audit,omitempty"`
|
||||||
NotifyNoData bool `json:"notify_no_data,omitempty"`
|
NotifyNoData *bool `json:"notify_no_data,omitempty"`
|
||||||
|
RenotifyInterval *int `json:"renotify_interval,omitempty"`
|
||||||
NewHostDelay *int `json:"new_host_delay,omitempty"`
|
NewHostDelay *int `json:"new_host_delay,omitempty"`
|
||||||
RenotifyInterval int `json:"renotify_interval,omitempty"`
|
|
||||||
Silenced map[string]int `json:"silenced,omitempty"`
|
Silenced map[string]int `json:"silenced,omitempty"`
|
||||||
TimeoutH int `json:"timeout_h,omitempty"`
|
TimeoutH *int `json:"timeout_h,omitempty"`
|
||||||
EscalationMessage string `json:"escalation_message,omitempty"`
|
EscalationMessage *string `json:"escalation_message,omitempty"`
|
||||||
Thresholds ThresholdCount `json:"thresholds,omitempty"`
|
Thresholds *ThresholdCount `json:"thresholds,omitempty"`
|
||||||
IncludeTags bool `json:"include_tags,omitempty"`
|
IncludeTags *bool `json:"include_tags,omitempty"`
|
||||||
RequireFullWindow bool `json:"require_full_window,omitempty"`
|
RequireFullWindow *bool `json:"require_full_window,omitempty"`
|
||||||
Locked bool `json:"locked,omitempty"`
|
Locked *bool `json:"locked,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Monitor allows watching a metric or check that you care about,
|
// Monitor allows watching a metric or check that you care about,
|
||||||
// notifying your team when some defined threshold is exceeded
|
// notifying your team when some defined threshold is exceeded
|
||||||
type Monitor struct {
|
type Monitor struct {
|
||||||
Creator Creator `json:"creator,omitempty"`
|
Creator *Creator `json:"creator,omitempty"`
|
||||||
Id int `json:"id,omitempty"`
|
Id *int `json:"id,omitempty"`
|
||||||
Type string `json:"type,omitempty"`
|
Type *string `json:"type,omitempty"`
|
||||||
Query string `json:"query,omitempty"`
|
Query *string `json:"query,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Message string `json:"message,omitempty"`
|
Message *string `json:"message,omitempty"`
|
||||||
Tags []string `json:"tags,omitempty"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
Options Options `json:"options,omitempty"`
|
Options *Options `json:"options,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creator contains the creator of the monitor
|
// Creator contains the creator of the monitor
|
||||||
type Creator struct {
|
type Creator struct {
|
||||||
Email string `json:"email,omitempty"`
|
Email *string `json:"email,omitempty"`
|
||||||
Handle string `json:"handle,omitempty"`
|
Handle *string `json:"handle,omitempty"`
|
||||||
Id int `json:"id,omitempty"`
|
Id *int `json:"id,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqMonitors receives a slice of all monitors
|
// reqMonitors receives a slice of all monitors
|
||||||
|
@ -93,7 +93,7 @@ func (client *Client) CreateMonitor(monitor *Monitor) (*Monitor, error) {
|
||||||
// UpdateMonitor takes a monitor that was previously retrieved through some method
|
// UpdateMonitor takes a monitor that was previously retrieved through some method
|
||||||
// and sends it back to the server
|
// and sends it back to the server
|
||||||
func (client *Client) UpdateMonitor(monitor *Monitor) error {
|
func (client *Client) UpdateMonitor(monitor *Monitor) error {
|
||||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/monitor/%d", monitor.Id),
|
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/monitor/%d", *monitor.Id),
|
||||||
monitor, nil)
|
monitor, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,26 +11,17 @@ package datadog
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cenkalti/backoff"
|
"github.com/cenkalti/backoff"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
|
||||||
RateLimitHeader = "X-RateLimit-Limit"
|
|
||||||
RatePeriodHeader = "X-RateLimit-Period"
|
|
||||||
RateRemainingHeader = "X-RateLimit-Remaining"
|
|
||||||
RateResetHeader = "X-RateLimit-Reset"
|
|
||||||
)
|
|
||||||
|
|
||||||
// uriForAPI is to be called with something like "/v1/events" and it will give
|
// uriForAPI is to be called with something like "/v1/events" and it will give
|
||||||
// the proper request URI to be posted to.
|
// the proper request URI to be posted to.
|
||||||
func (client *Client) uriForAPI(api string) string {
|
func (client *Client) uriForAPI(api string) string {
|
||||||
|
@ -69,9 +60,9 @@ func (client *Client) doJsonRequest(method, api string,
|
||||||
req.Header.Add("Content-Type", "application/json")
|
req.Header.Add("Content-Type", "application/json")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Perform the request and retry it if it's not a POST request
|
// Perform the request and retry it if it's not a POST or PUT request
|
||||||
var resp *http.Response
|
var resp *http.Response
|
||||||
if method == "POST" {
|
if method == "POST" || method == "PUT" {
|
||||||
resp, err = client.HttpClient.Do(req)
|
resp, err = client.HttpClient.Do(req)
|
||||||
} else {
|
} else {
|
||||||
resp, err = client.doRequestWithRetries(req, client.RetryTimeout)
|
resp, err = client.doRequestWithRetries(req, client.RetryTimeout)
|
||||||
|
@ -81,12 +72,6 @@ func (client *Client) doJsonRequest(method, api string,
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
|
||||||
if err := client.getRateLimit(resp); err != nil {
|
|
||||||
if err.(*RateLimit).Remaining == 0 {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||||
body, err := ioutil.ReadAll(resp.Body)
|
body, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -118,54 +103,35 @@ func (client *Client) doJsonRequest(method, api string,
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (client *Client) getRateLimit(response *http.Response) error {
|
|
||||||
|
|
||||||
ratelimit := response.Header.Get(RateLimitHeader)
|
|
||||||
if ratelimit == "" {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rateperiod := response.Header.Get(RatePeriodHeader)
|
|
||||||
rateremaining := response.Header.Get(RateRemainingHeader)
|
|
||||||
ratereset := response.Header.Get(RateResetHeader)
|
|
||||||
|
|
||||||
limit, _ := strconv.Atoi(ratelimit)
|
|
||||||
period, _ := strconv.Atoi(rateperiod)
|
|
||||||
remaining, _ := strconv.Atoi(rateremaining)
|
|
||||||
reset, _ := strconv.Atoi(ratereset)
|
|
||||||
|
|
||||||
ratelimiterror := NewRateLimit(limit, period, remaining, reset)
|
|
||||||
|
|
||||||
return error(ratelimiterror)
|
|
||||||
}
|
|
||||||
|
|
||||||
// doRequestWithRetries performs an HTTP request repeatedly for maxTime or until
|
// doRequestWithRetries performs an HTTP request repeatedly for maxTime or until
|
||||||
// no error and no HTTP response code higher than 299 is returned.
|
// no error and no acceptable HTTP response code was returned.
|
||||||
func (client *Client) doRequestWithRetries(req *http.Request, maxTime time.Duration) (*http.Response, error) {
|
func (client *Client) doRequestWithRetries(req *http.Request, maxTime time.Duration) (*http.Response, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
resp *http.Response
|
resp *http.Response
|
||||||
bo = backoff.NewExponentialBackOff()
|
bo = backoff.NewExponentialBackOff()
|
||||||
)
|
)
|
||||||
|
|
||||||
bo.MaxElapsedTime = maxTime
|
bo.MaxElapsedTime = maxTime
|
||||||
|
|
||||||
err = backoff.Retry(func() error {
|
operation := func() error {
|
||||||
resp, err = client.HttpClient.Do(req)
|
resp, err = client.HttpClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := client.getRateLimit(resp); err != nil {
|
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||||
if err.(*RateLimit).Remaining == 0 {
|
// 2xx all done
|
||||||
return err
|
return nil
|
||||||
}
|
} else if resp.StatusCode >= 400 && resp.StatusCode < 500 {
|
||||||
|
// 4xx are not retryable
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
return fmt.Errorf("Received HTTP status code %d", resp.StatusCode)
|
||||||
return errors.New("API error: " + resp.Status)
|
|
||||||
}
|
}
|
||||||
return nil
|
|
||||||
}, bo)
|
err = backoff.Retry(operation, bo)
|
||||||
|
|
||||||
return resp, err
|
return resp, err
|
||||||
}
|
}
|
|
@ -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"`
|
||||||
|
}
|
|
@ -15,50 +15,50 @@ import (
|
||||||
// Screenboard represents a user created screenboard. This is the full screenboard
|
// Screenboard represents a user created screenboard. This is the full screenboard
|
||||||
// struct when we load a screenboard in detail.
|
// struct when we load a screenboard in detail.
|
||||||
type Screenboard struct {
|
type Screenboard struct {
|
||||||
Id int `json:"id,omitempty"`
|
Id *int `json:"id,omitempty"`
|
||||||
Title string `json:"board_title,omitempty"`
|
Title *string `json:"board_title,omitempty"`
|
||||||
Height string `json:"height,omitempty"`
|
Height *string `json:"height,omitempty"`
|
||||||
Width string `json:"width,omitempty"`
|
Width *string `json:"width,omitempty"`
|
||||||
Shared bool `json:"shared,omitempty"`
|
Shared *bool `json:"shared,omitempty"`
|
||||||
Templated bool `json:"templated,omitempty"`
|
Templated *bool `json:"templated,omitempty"`
|
||||||
TemplateVariables []TemplateVariable `json:"template_variables,omitempty"`
|
TemplateVariables []TemplateVariable `json:"template_variables,omitempty"`
|
||||||
Widgets []Widget `json:"widgets,omitempty"`
|
Widgets []Widget `json:"widgets,omitempty"`
|
||||||
ReadOnly bool `json:"read_only,omitempty"`
|
ReadOnly *bool `json:"read_only,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//type Widget struct {
|
//type Widget struct {
|
||||||
type Widget struct {
|
type Widget struct {
|
||||||
Default string `json:"default,omitempty"`
|
Default *string `json:"default,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Prefix string `json:"prefix,omitempty"`
|
Prefix *string `json:"prefix,omitempty"`
|
||||||
TimeseriesWidget TimeseriesWidget `json:"timeseries,omitempty"`
|
TimeseriesWidget *TimeseriesWidget `json:"timeseries,omitempty"`
|
||||||
QueryValueWidget QueryValueWidget `json:"query_value,omitempty"`
|
QueryValueWidget *QueryValueWidget `json:"query_value,omitempty"`
|
||||||
EventStreamWidget EventStreamWidget `json:"event_stream,omitempty"`
|
EventStreamWidget *EventStreamWidget `json:"event_stream,omitempty"`
|
||||||
FreeTextWidget FreeTextWidget `json:"free_text,omitempty"`
|
FreeTextWidget *FreeTextWidget `json:"free_text,omitempty"`
|
||||||
ToplistWidget ToplistWidget `json:"toplist,omitempty"`
|
ToplistWidget *ToplistWidget `json:"toplist,omitempty"`
|
||||||
ImageWidget ImageWidget `json:"image,omitempty"`
|
ImageWidget *ImageWidget `json:"image,omitempty"`
|
||||||
ChangeWidget ChangeWidget `json:"change,omitempty"`
|
ChangeWidget *ChangeWidget `json:"change,omitempty"`
|
||||||
GraphWidget GraphWidget `json:"graph,omitempty"`
|
GraphWidget *GraphWidget `json:"graph,omitempty"`
|
||||||
EventTimelineWidget EventTimelineWidget `json:"event_timeline,omitempty"`
|
EventTimelineWidget *EventTimelineWidget `json:"event_timeline,omitempty"`
|
||||||
AlertValueWidget AlertValueWidget `json:"alert_value,omitempty"`
|
AlertValueWidget *AlertValueWidget `json:"alert_value,omitempty"`
|
||||||
AlertGraphWidget AlertGraphWidget `json:"alert_graph,omitempty"`
|
AlertGraphWidget *AlertGraphWidget `json:"alert_graph,omitempty"`
|
||||||
HostMapWidget HostMapWidget `json:"hostmap,omitempty"`
|
HostMapWidget *HostMapWidget `json:"hostmap,omitempty"`
|
||||||
CheckStatusWidget CheckStatusWidget `json:"check_status,omitempty"`
|
CheckStatusWidget *CheckStatusWidget `json:"check_status,omitempty"`
|
||||||
IFrameWidget IFrameWidget `json:"iframe,omitempty"`
|
IFrameWidget *IFrameWidget `json:"iframe,omitempty"`
|
||||||
NoteWidget NoteWidget `json:"frame,omitempty"`
|
NoteWidget *NoteWidget `json:"frame,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ScreenboardLite represents a user created screenboard. This is the mini
|
// ScreenboardLite represents a user created screenboard. This is the mini
|
||||||
// struct when we load the summaries.
|
// struct when we load the summaries.
|
||||||
type ScreenboardLite struct {
|
type ScreenboardLite struct {
|
||||||
Id int `json:"id,omitempty"`
|
Id *int `json:"id,omitempty"`
|
||||||
Resource string `json:"resource,omitempty"`
|
Resource *string `json:"resource,omitempty"`
|
||||||
Title string `json:"title,omitempty"`
|
Title *string `json:"title,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqGetScreenboards from /api/v1/screen
|
// reqGetScreenboards from /api/v1/screen
|
||||||
type reqGetScreenboards struct {
|
type reqGetScreenboards struct {
|
||||||
Screenboards []*ScreenboardLite `json:"screenboards"`
|
Screenboards []*ScreenboardLite `json:"screenboards,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetScreenboard returns a single screenboard created on this account.
|
// GetScreenboard returns a single screenboard created on this account.
|
||||||
|
@ -97,7 +97,7 @@ func (client *Client) CreateScreenboard(board *Screenboard) (*Screenboard, error
|
||||||
// UpdateScreenboard in essence takes a Screenboard struct and persists it back to
|
// UpdateScreenboard in essence takes a Screenboard struct and persists it back to
|
||||||
// the server. Use this if you've updated your local and need to push it back.
|
// the server. Use this if you've updated your local and need to push it back.
|
||||||
func (client *Client) UpdateScreenboard(board *Screenboard) error {
|
func (client *Client) UpdateScreenboard(board *Screenboard) error {
|
||||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/screen/%d", board.Id), board, nil)
|
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/screen/%d", *board.Id), board, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ScreenShareResponse struct {
|
type ScreenShareResponse struct {
|
|
@ -17,25 +17,26 @@ type DataPoint [2]float64
|
||||||
// Metric represents a collection of data points that we might send or receive
|
// Metric represents a collection of data points that we might send or receive
|
||||||
// on one single metric line.
|
// on one single metric line.
|
||||||
type Metric struct {
|
type Metric struct {
|
||||||
Metric string `json:"metric,omitempty"`
|
Metric *string `json:"metric,omitempty"`
|
||||||
Points []DataPoint `json:"points,omitempty"`
|
Points []DataPoint `json:"points,omitempty"`
|
||||||
Type string `json:"type,omitempty"`
|
Type *string `json:"type,omitempty"`
|
||||||
Host string `json:"host,omitempty"`
|
Host *string `json:"host,omitempty"`
|
||||||
Tags []string `json:"tags,omitempty"`
|
Tags []string `json:"tags,omitempty"`
|
||||||
|
Unit *string `json:"unit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Series represents a collection of data points we get when we query for timeseries data
|
// Series represents a collection of data points we get when we query for timeseries data
|
||||||
type Series struct {
|
type Series struct {
|
||||||
Metric string `json:"metric,omitempty"`
|
Metric *string `json:"metric,omitempty"`
|
||||||
DisplayName string `json:"display_name,omitempty"`
|
DisplayName *string `json:"display_name,omitempty"`
|
||||||
Points []DataPoint `json:"pointlist,omitempty"`
|
Points []DataPoint `json:"pointlist,omitempty"`
|
||||||
Start float64 `json:"start,omitempty"`
|
Start *float64 `json:"start,omitempty"`
|
||||||
End float64 `json:"end,omitempty"`
|
End *float64 `json:"end,omitempty"`
|
||||||
Interval int `json:"interval,omitempty"`
|
Interval *int `json:"interval,omitempty"`
|
||||||
Aggr string `json:"aggr,omitempty"`
|
Aggr *string `json:"aggr,omitempty"`
|
||||||
Length int `json:"length,omitempty"`
|
Length *int `json:"length,omitempty"`
|
||||||
Scope string `json:"scope,omitempty"`
|
Scope *string `json:"scope,omitempty"`
|
||||||
Expression string `json:"expression,omitempty"`
|
Expression *string `json:"expression,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqPostSeries from /api/v1/series
|
// reqPostSeries from /api/v1/series
|
|
@ -23,7 +23,7 @@ func (client *Client) Snapshot(query string, start, end time.Time, eventQuery st
|
||||||
v.Add("event_query", eventQuery)
|
v.Add("event_query", eventQuery)
|
||||||
|
|
||||||
out := struct {
|
out := struct {
|
||||||
SnapshotURL string `json:"snapshot_url"`
|
SnapshotURL string `json:"snapshot_url,omitempty"`
|
||||||
}{}
|
}{}
|
||||||
if err := client.doJsonRequest("GET", "/v1/graph/snapshot?"+v.Encode(), nil, &out); err != nil {
|
if err := client.doJsonRequest("GET", "/v1/graph/snapshot?"+v.Encode(), nil, &out); err != nil {
|
||||||
return "", err
|
return "", err
|
|
@ -13,7 +13,7 @@ type TagMap map[string][]string
|
||||||
|
|
||||||
// reqGetTags is the container for receiving tags.
|
// reqGetTags is the container for receiving tags.
|
||||||
type reqGetTags struct {
|
type reqGetTags struct {
|
||||||
Tags TagMap `json:"tags,omitempty"`
|
Tags *TagMap `json:"tags,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// regGetHostTags is for receiving a slice of tags.
|
// regGetHostTags is for receiving a slice of tags.
|
||||||
|
@ -31,7 +31,7 @@ func (client *Client) GetTags(source string) (TagMap, error) {
|
||||||
if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
|
if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return out.Tags, nil
|
return *out.Tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetHostTags returns a slice of tags for a given host and source.
|
// GetHostTags returns a slice of tags for a given host and source.
|
||||||
|
@ -58,11 +58,11 @@ func (client *Client) GetHostTagsBySource(host, source string) (TagMap, error) {
|
||||||
if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
|
if err := client.doJsonRequest("GET", uri, nil, &out); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return out.Tags, nil
|
return *out.Tags, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddTagsToHost does exactly what it says on the tin. Given a list of tags,
|
// AddTagsToHost does exactly what it says on the tin. Given a list of tags,
|
||||||
// add them to the host. The source is optionally specificed, and defaults to
|
// add them to the host. The source is optionally specified, and defaults to
|
||||||
// "users" as per the API documentation.
|
// "users" as per the API documentation.
|
||||||
func (client *Client) AddTagsToHost(host, source string, tags []string) error {
|
func (client *Client) AddTagsToHost(host, source string, tags []string) error {
|
||||||
uri := "/v1/tags/hosts/" + host
|
uri := "/v1/tags/hosts/" + host
|
|
@ -9,13 +9,13 @@
|
||||||
package datadog
|
package datadog
|
||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
Handle string `json:"handle,omitempty"`
|
Handle *string `json:"handle,omitempty"`
|
||||||
Email string `json:"email,omitempty"`
|
Email *string `json:"email,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name *string `json:"name,omitempty"`
|
||||||
Role string `json:"role,omitempty"`
|
Role *string `json:"role,omitempty"`
|
||||||
IsAdmin bool `json:"is_admin,omitempty"`
|
IsAdmin *bool `json:"is_admin,omitempty"`
|
||||||
Verified bool `json:"verified,omitempty"`
|
Verified *bool `json:"verified,omitempty"`
|
||||||
Disabled bool `json:"disabled,omitempty"`
|
Disabled *bool `json:"disabled,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// reqInviteUsers contains email addresses to send invitations to.
|
// reqInviteUsers contains email addresses to send invitations to.
|
||||||
|
@ -30,10 +30,10 @@ func (client *Client) InviteUsers(emails []string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateUser creates an user account for an email address
|
// CreateUser creates an user account for an email address
|
||||||
func (self *Client) CreateUser(handle, name string) (*User, error) {
|
func (self *Client) CreateUser(handle, name *string) (*User, error) {
|
||||||
in := struct {
|
in := struct {
|
||||||
Handle string `json:"handle"`
|
Handle *string `json:"handle"`
|
||||||
Name string `json:"name"`
|
Name *string `json:"name"`
|
||||||
}{
|
}{
|
||||||
Handle: handle,
|
Handle: handle,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -50,7 +50,7 @@ func (self *Client) CreateUser(handle, name string) (*User, error) {
|
||||||
|
|
||||||
// internal type to retrieve users from the api
|
// internal type to retrieve users from the api
|
||||||
type usersData struct {
|
type usersData struct {
|
||||||
Users []User `json:"users"`
|
Users []User `json:"users,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUsers returns all user, or an error if not found
|
// GetUsers returns all user, or an error if not found
|
||||||
|
@ -79,7 +79,7 @@ func (client *Client) GetUser(handle string) (user User, err error) {
|
||||||
// UpdateUser updates a user with the content of `user`,
|
// UpdateUser updates a user with the content of `user`,
|
||||||
// and returns an error if the update failed
|
// and returns an error if the update failed
|
||||||
func (client *Client) UpdateUser(user User) error {
|
func (client *Client) UpdateUser(user User) error {
|
||||||
uri := "/v1/user/" + user.Handle
|
uri := "/v1/user/" + *user.Handle
|
||||||
return client.doJsonRequest("PUT", uri, user, nil)
|
return client.doJsonRequest("PUT", uri, user, nil)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2155,18 +2155,18 @@
|
||||||
"path": "github.com/maximilien/softlayer-go/softlayer",
|
"path": "github.com/maximilien/softlayer-go/softlayer",
|
||||||
"revision": "85659debe44fab5792fc92cf755c04b115b9dc19"
|
"revision": "85659debe44fab5792fc92cf755c04b115b9dc19"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"checksumSHA1": "OUZ1FFXyKs+Cfg9M9rmXqqweQck=",
|
|
||||||
"path": "github.com/miekg/dns",
|
|
||||||
"revision": "db96a2b759cdef4f11a34506a42eb8d1290c598e",
|
|
||||||
"revisionTime": "2016-07-26T03:20:27Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"checksumSHA1": "GSum+utW01N3KeMdvAPnsW0TemM=",
|
"checksumSHA1": "GSum+utW01N3KeMdvAPnsW0TemM=",
|
||||||
"path": "github.com/michaelklishin/rabbit-hole",
|
"path": "github.com/michaelklishin/rabbit-hole",
|
||||||
"revision": "88550829bcdcf614361c73459c903578eb44074e",
|
"revision": "88550829bcdcf614361c73459c903578eb44074e",
|
||||||
"revisionTime": "2016-07-06T11:10:56Z"
|
"revisionTime": "2016-07-06T11:10:56Z"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "OUZ1FFXyKs+Cfg9M9rmXqqweQck=",
|
||||||
|
"path": "github.com/miekg/dns",
|
||||||
|
"revision": "db96a2b759cdef4f11a34506a42eb8d1290c598e",
|
||||||
|
"revisionTime": "2016-07-26T03:20:27Z"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"checksumSHA1": "7niW29CvYceZ6zbia6b/LT+yD/M=",
|
"checksumSHA1": "7niW29CvYceZ6zbia6b/LT+yD/M=",
|
||||||
"path": "github.com/mitchellh/cli",
|
"path": "github.com/mitchellh/cli",
|
||||||
|
@ -2664,12 +2664,6 @@
|
||||||
"path": "github.com/ziutek/mymysql/thrsafe",
|
"path": "github.com/ziutek/mymysql/thrsafe",
|
||||||
"revision": "75ce5fbba34b1912a3641adbd58cf317d7315821"
|
"revision": "75ce5fbba34b1912a3641adbd58cf317d7315821"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"checksumSHA1": "uynUzdKeOsfi7flpYWFx835Nafo=",
|
|
||||||
"path": "github.com/zorkian/go-datadog-api",
|
|
||||||
"revision": "6308094e4aca46eb16a227b50be29772242bf3aa",
|
|
||||||
"revisionTime": "2017-02-02T00:47:50Z"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"checksumSHA1": "9x64JhJGo6z8TS0Q33cGcR64kjA=",
|
"checksumSHA1": "9x64JhJGo6z8TS0Q33cGcR64kjA=",
|
||||||
"path": "golang.org/x/crypto/curve25519",
|
"path": "golang.org/x/crypto/curve25519",
|
||||||
|
@ -3003,6 +2997,12 @@
|
||||||
"path": "gopkg.in/yaml.v2",
|
"path": "gopkg.in/yaml.v2",
|
||||||
"revision": "a5b47d31c556af34a302ce5d659e6fea44d90de0",
|
"revision": "a5b47d31c556af34a302ce5d659e6fea44d90de0",
|
||||||
"revisionTime": "2016-09-28T15:37:09Z"
|
"revisionTime": "2016-09-28T15:37:09Z"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"checksumSHA1": "OcJdNALtPXoFOieAZjznhm7ufuU=",
|
||||||
|
"path": "gopkg.in/zorkian/go-datadog-api.v2",
|
||||||
|
"revision": "f005bb24262365e93726b94d89e6cd8a26a7455e",
|
||||||
|
"revisionTime": "2017-02-20T05:26:33Z"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"rootPath": "github.com/hashicorp/terraform"
|
"rootPath": "github.com/hashicorp/terraform"
|
||||||
|
|
Loading…
Reference in New Issue