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 (
|
||||
"log"
|
||||
|
||||
"github.com/zorkian/go-datadog-api"
|
||||
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||
)
|
||||
|
||||
// Config holds API and APP keys to authenticate to Datadog.
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/zorkian/go-datadog-api"
|
||||
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||
)
|
||||
|
||||
func resourceDatadogMonitor() *schema.Resource {
|
||||
|
@ -137,18 +137,18 @@ func buildMonitorStruct(d *schema.ResourceData) *datadog.Monitor {
|
|||
var thresholds datadog.ThresholdCount
|
||||
|
||||
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 {
|
||||
thresholds.Warning = json.Number(r.(string))
|
||||
thresholds.SetWarning(json.Number(r.(string)))
|
||||
}
|
||||
if r, ok := d.GetOk("thresholds.critical"); ok {
|
||||
thresholds.Critical = json.Number(r.(string))
|
||||
thresholds.SetCritical(json.Number(r.(string)))
|
||||
}
|
||||
|
||||
o := datadog.Options{
|
||||
Thresholds: thresholds,
|
||||
NotifyNoData: d.Get("notify_no_data").(bool),
|
||||
Thresholds: &thresholds,
|
||||
NotifyNoData: datadog.Bool(d.Get("notify_no_data").(bool)),
|
||||
}
|
||||
if attr, ok := d.GetOk("silenced"); ok {
|
||||
s := make(map[string]int)
|
||||
|
@ -159,42 +159,42 @@ func buildMonitorStruct(d *schema.ResourceData) *datadog.Monitor {
|
|||
o.Silenced = s
|
||||
}
|
||||
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 {
|
||||
o.NewHostDelay = datadog.Int(attr.(int))
|
||||
o.SetNewHostDelay(attr.(int))
|
||||
}
|
||||
if attr, ok := d.GetOk("no_data_timeframe"); ok {
|
||||
o.NoDataTimeframe = datadog.NoDataTimeframe(attr.(int))
|
||||
}
|
||||
if attr, ok := d.GetOk("renotify_interval"); ok {
|
||||
o.RenotifyInterval = attr.(int)
|
||||
o.SetRenotifyInterval(attr.(int))
|
||||
}
|
||||
if attr, ok := d.GetOk("notify_audit"); ok {
|
||||
o.NotifyAudit = attr.(bool)
|
||||
o.SetNotifyAudit(attr.(bool))
|
||||
}
|
||||
if attr, ok := d.GetOk("timeout_h"); ok {
|
||||
o.TimeoutH = attr.(int)
|
||||
o.SetTimeoutH(attr.(int))
|
||||
}
|
||||
if attr, ok := d.GetOk("escalation_message"); ok {
|
||||
o.EscalationMessage = attr.(string)
|
||||
o.SetEscalationMessage(attr.(string))
|
||||
}
|
||||
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 {
|
||||
o.RequireFullWindow = attr.(bool)
|
||||
o.SetRequireFullWindow(attr.(bool))
|
||||
}
|
||||
if attr, ok := d.GetOk("locked"); ok {
|
||||
o.Locked = attr.(bool)
|
||||
o.SetLocked(attr.(bool))
|
||||
}
|
||||
|
||||
m := datadog.Monitor{
|
||||
Type: d.Get("type").(string),
|
||||
Query: d.Get("query").(string),
|
||||
Name: d.Get("name").(string),
|
||||
Message: d.Get("message").(string),
|
||||
Options: o,
|
||||
Type: datadog.String(d.Get("type").(string)),
|
||||
Query: datadog.String(d.Get("query").(string)),
|
||||
Name: datadog.String(d.Get("name").(string)),
|
||||
Message: datadog.String(d.Get("message").(string)),
|
||||
Options: &o,
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(m.Id))
|
||||
d.SetId(strconv.Itoa(m.GetId()))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -258,9 +258,9 @@ func resourceDatadogMonitorRead(d *schema.ResourceData, meta interface{}) error
|
|||
|
||||
thresholds := make(map[string]string)
|
||||
for k, v := range map[string]json.Number{
|
||||
"ok": m.Options.Thresholds.Ok,
|
||||
"warning": m.Options.Thresholds.Warning,
|
||||
"critical": m.Options.Thresholds.Critical,
|
||||
"ok": m.Options.Thresholds.GetOk(),
|
||||
"warning": m.Options.Thresholds.GetWarning(),
|
||||
"critical": m.Options.Thresholds.GetCritical(),
|
||||
} {
|
||||
s := v.String()
|
||||
if s != "" {
|
||||
|
@ -274,24 +274,24 @@ func resourceDatadogMonitorRead(d *schema.ResourceData, meta interface{}) error
|
|||
}
|
||||
|
||||
log.Printf("[DEBUG] monitor: %v", m)
|
||||
d.Set("name", m.Name)
|
||||
d.Set("message", m.Message)
|
||||
d.Set("query", m.Query)
|
||||
d.Set("type", m.Type)
|
||||
d.Set("name", m.GetName())
|
||||
d.Set("message", m.GetMessage())
|
||||
d.Set("query", m.GetQuery())
|
||||
d.Set("type", m.GetType())
|
||||
d.Set("thresholds", thresholds)
|
||||
|
||||
d.Set("new_host_delay", m.Options.NewHostDelay)
|
||||
d.Set("notify_no_data", m.Options.NotifyNoData)
|
||||
d.Set("new_host_delay", m.Options.GetNewHostDelay())
|
||||
d.Set("notify_no_data", m.Options.GetNotifyNoData())
|
||||
d.Set("no_data_timeframe", m.Options.NoDataTimeframe)
|
||||
d.Set("renotify_interval", m.Options.RenotifyInterval)
|
||||
d.Set("notify_audit", m.Options.NotifyAudit)
|
||||
d.Set("timeout_h", m.Options.TimeoutH)
|
||||
d.Set("escalation_message", m.Options.EscalationMessage)
|
||||
d.Set("renotify_interval", m.Options.GetRenotifyInterval())
|
||||
d.Set("notify_audit", m.Options.GetNotifyAudit())
|
||||
d.Set("timeout_h", m.Options.GetTimeoutH())
|
||||
d.Set("escalation_message", m.Options.GetEscalationMessage())
|
||||
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("require_full_window", m.Options.RequireFullWindow)
|
||||
d.Set("locked", m.Options.Locked)
|
||||
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.GetLocked())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -306,15 +306,15 @@ func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
return err
|
||||
}
|
||||
|
||||
m.Id = i
|
||||
m.Id = datadog.Int(i)
|
||||
if attr, ok := d.GetOk("name"); ok {
|
||||
m.Name = attr.(string)
|
||||
m.SetName(attr.(string))
|
||||
}
|
||||
if attr, ok := d.GetOk("message"); ok {
|
||||
m.Message = attr.(string)
|
||||
m.SetMessage(attr.(string))
|
||||
}
|
||||
if attr, ok := d.GetOk("query"); ok {
|
||||
m.Query = attr.(string)
|
||||
m.SetQuery(attr.(string))
|
||||
}
|
||||
|
||||
if attr, ok := d.GetOk("tags"); ok {
|
||||
|
@ -326,41 +326,42 @@ func resourceDatadogMonitorUpdate(d *schema.ResourceData, meta interface{}) erro
|
|||
}
|
||||
|
||||
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 {
|
||||
thresholds := attr.(map[string]interface{})
|
||||
o.Thresholds = &datadog.ThresholdCount{} // TODO: This is a little annoying..
|
||||
if thresholds["ok"] != nil {
|
||||
o.Thresholds.Ok = json.Number(thresholds["ok"].(string))
|
||||
o.Thresholds.SetOk(json.Number(thresholds["ok"].(string)))
|
||||
}
|
||||
if thresholds["warning"] != nil {
|
||||
o.Thresholds.Warning = json.Number(thresholds["warning"].(string))
|
||||
o.Thresholds.SetWarning(json.Number(thresholds["warning"].(string)))
|
||||
}
|
||||
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 {
|
||||
o.NotifyNoData = attr.(bool)
|
||||
o.SetNotifyNoData(attr.(bool))
|
||||
}
|
||||
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 {
|
||||
o.NoDataTimeframe = datadog.NoDataTimeframe(attr.(int))
|
||||
}
|
||||
if attr, ok := d.GetOk("renotify_interval"); ok {
|
||||
o.RenotifyInterval = attr.(int)
|
||||
o.SetRenotifyInterval(attr.(int))
|
||||
}
|
||||
if attr, ok := d.GetOk("notify_audit"); ok {
|
||||
o.NotifyAudit = attr.(bool)
|
||||
o.SetNotifyAudit(attr.(bool))
|
||||
}
|
||||
if attr, ok := d.GetOk("timeout_h"); ok {
|
||||
o.TimeoutH = attr.(int)
|
||||
o.SetTimeoutH(attr.(int))
|
||||
}
|
||||
if attr, ok := d.GetOk("escalation_message"); ok {
|
||||
o.EscalationMessage = attr.(string)
|
||||
o.SetEscalationMessage(attr.(string))
|
||||
}
|
||||
if attr, ok := d.GetOk("silenced"); ok {
|
||||
// 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
|
||||
}
|
||||
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 {
|
||||
o.RequireFullWindow = attr.(bool)
|
||||
o.SetRequireFullWindow(attr.(bool))
|
||||
}
|
||||
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 {
|
||||
return fmt.Errorf("error updating monitor: %s", err.Error())
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/zorkian/go-datadog-api"
|
||||
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||
)
|
||||
|
||||
func TestAccDatadogMonitor_Basic(t *testing.T) {
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/zorkian/go-datadog-api"
|
||||
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||
)
|
||||
|
||||
func resourceDatadogTimeboard() *schema.Resource {
|
||||
|
@ -273,23 +273,23 @@ func appendConditionalFormats(datadogRequest *datadog.GraphDefinitionRequest, te
|
|||
for _, t_ := range *terraformFormats {
|
||||
t := t_.(map[string]interface{})
|
||||
d := datadog.DashboardConditionalFormat{
|
||||
Comparator: t["comparator"].(string),
|
||||
Comparator: datadog.String(t["comparator"].(string)),
|
||||
}
|
||||
|
||||
if palette, ok := t["palette"]; ok {
|
||||
d.Palette = palette.(string)
|
||||
if v, ok := t["palette"]; ok {
|
||||
d.SetPalette(v.(string))
|
||||
}
|
||||
|
||||
if customBgColor, ok := t["custom_bg_color"]; ok {
|
||||
d.CustomBgColor = customBgColor.(string)
|
||||
if v, ok := t["custom_bg_color"]; ok {
|
||||
d.SetCustomBgColor(v.(string))
|
||||
}
|
||||
|
||||
if customFgColor, ok := t["custom_fg_color"]; ok {
|
||||
d.CustomFgColor = customFgColor.(string)
|
||||
if v, ok := t["custom_fg_color"]; ok {
|
||||
d.SetCustomFgColor(v.(string))
|
||||
}
|
||||
|
||||
if value, ok := t["value"]; ok {
|
||||
d.Value = json.Number(value.(string))
|
||||
if v, ok := t["value"]; ok {
|
||||
d.SetValue(json.Number(v.(string)))
|
||||
}
|
||||
|
||||
datadogRequest.ConditionalFormats = append(datadogRequest.ConditionalFormats, d)
|
||||
|
@ -301,9 +301,10 @@ func buildTemplateVariables(terraformTemplateVariables *[]interface{}) *[]datado
|
|||
for i, t_ := range *terraformTemplateVariables {
|
||||
t := t_.(map[string]interface{})
|
||||
datadogTemplateVariables[i] = datadog.TemplateVariable{
|
||||
Name: t["name"].(string),
|
||||
Prefix: t["prefix"].(string),
|
||||
Default: t["default"].(string)}
|
||||
Name: datadog.String(t["name"].(string)),
|
||||
Prefix: datadog.String(t["prefix"].(string)),
|
||||
Default: datadog.String(t["default"].(string)),
|
||||
}
|
||||
}
|
||||
return &datadogTemplateVariables
|
||||
}
|
||||
|
@ -312,58 +313,55 @@ func appendRequests(datadogGraph *datadog.Graph, terraformRequests *[]interface{
|
|||
for _, t_ := range *terraformRequests {
|
||||
t := t_.(map[string]interface{})
|
||||
d := datadog.GraphDefinitionRequest{
|
||||
Query: t["q"].(string),
|
||||
Type: t["type"].(string),
|
||||
Aggregator: t["aggregator"].(string),
|
||||
Query: datadog.String(t["q"].(string)),
|
||||
Type: datadog.String(t["type"].(string)),
|
||||
Aggregator: datadog.String(t["aggregator"].(string)),
|
||||
}
|
||||
if stacked, ok := t["stacked"]; ok {
|
||||
d.Stacked = stacked.(bool)
|
||||
d.SetStacked(stacked.(bool))
|
||||
}
|
||||
if style, ok := t["style"]; ok {
|
||||
s, _ := style.(map[string]interface{})
|
||||
|
||||
style := &datadog.GraphDefinitionRequestStyle{}
|
||||
style := datadog.GraphDefinitionRequestStyle{}
|
||||
|
||||
if palette_, ok := s["palette"]; ok {
|
||||
palette := palette_.(string)
|
||||
style.Palette = &palette
|
||||
if v, ok := s["palette"]; ok {
|
||||
style.SetPalette(v.(string))
|
||||
}
|
||||
|
||||
if width, ok := s["width"]; ok {
|
||||
width := width.(string)
|
||||
style.Width = &width
|
||||
if v, ok := s["width"]; ok {
|
||||
style.SetWidth(v.(string))
|
||||
}
|
||||
|
||||
if type_, ok := s["type"]; ok {
|
||||
style_type := type_.(string)
|
||||
style.Type = &style_type
|
||||
if v, ok := s["type"]; ok {
|
||||
style.SetType(v.(string))
|
||||
}
|
||||
|
||||
d.Style = style
|
||||
d.SetStyle(style)
|
||||
}
|
||||
|
||||
if changeType, ok := t["change_type"]; ok {
|
||||
d.ChangeType = changeType.(string)
|
||||
if v, ok := t["change_type"]; ok {
|
||||
d.SetChangeType(v.(string))
|
||||
}
|
||||
if compareTo, ok := t["compare_to"]; ok {
|
||||
d.CompareTo = compareTo.(string)
|
||||
if v, ok := t["compare_to"]; ok {
|
||||
d.SetCompareTo(v.(string))
|
||||
}
|
||||
if increaseGood, ok := t["increase_good"]; ok {
|
||||
d.IncreaseGood = increaseGood.(bool)
|
||||
if v, ok := t["increase_good"]; ok {
|
||||
d.SetIncreaseGood(v.(bool))
|
||||
}
|
||||
if orderBy, ok := t["order_by"]; ok {
|
||||
d.OrderBy = orderBy.(string)
|
||||
if v, ok := t["order_by"]; ok {
|
||||
d.SetOrderBy(v.(string))
|
||||
}
|
||||
if extraCol, ok := t["extra_col"]; ok {
|
||||
d.ExtraCol = extraCol.(string)
|
||||
if v, ok := t["extra_col"]; ok {
|
||||
d.SetExtraCol(v.(string))
|
||||
}
|
||||
if orderDirection, ok := t["order_direction"]; ok {
|
||||
d.OrderDirection = orderDirection.(string)
|
||||
if v, ok := t["order_direction"]; ok {
|
||||
d.SetOrderDirection(v.(string))
|
||||
}
|
||||
|
||||
if terraformConditionalFormats, ok := t["conditional_format"]; ok {
|
||||
formats := terraformConditionalFormats.([]interface{})
|
||||
appendConditionalFormats(&d, &formats)
|
||||
if v, ok := t["conditional_format"]; ok {
|
||||
v_ := v.([]interface{})
|
||||
appendConditionalFormats(&d, &v_)
|
||||
}
|
||||
|
||||
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{}) {
|
||||
for _, t_ := range *terraformEvents {
|
||||
d := struct {
|
||||
Query string `json:"q"`
|
||||
}{
|
||||
t_.(string),
|
||||
}
|
||||
datadogGraph.Definition.Events = append(datadogGraph.Definition.Events, d)
|
||||
datadogGraph.Definition.Events = append(datadogGraph.Definition.Events, datadog.GraphEvent{
|
||||
Query: datadog.String(t_.(string)),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -385,11 +380,11 @@ func appendMarkers(datadogGraph *datadog.Graph, terraformMarkers *[]interface{})
|
|||
for _, t_ := range *terraformMarkers {
|
||||
t := t_.(map[string]interface{})
|
||||
d := datadog.GraphDefinitionMarker{
|
||||
Type: t["type"].(string),
|
||||
Value: t["value"].(string),
|
||||
Type: datadog.String(t["type"].(string)),
|
||||
Value: datadog.String(t["value"].(string)),
|
||||
}
|
||||
if label, ok := t["label"]; ok {
|
||||
d.Label = label.(string)
|
||||
if v, ok := t["label"]; ok {
|
||||
d.SetLabel(v.(string))
|
||||
}
|
||||
datadogGraph.Definition.Markers = append(datadogGraph.Definition.Markers, d)
|
||||
}
|
||||
|
@ -399,90 +394,90 @@ func buildGraphs(terraformGraphs *[]interface{}) *[]datadog.Graph {
|
|||
datadogGraphs := make([]datadog.Graph, len(*terraformGraphs))
|
||||
for i, t_ := range *terraformGraphs {
|
||||
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.Definition.Viz = t["viz"].(string)
|
||||
d.Definition = &datadog.GraphDefinition{}
|
||||
d.Definition.SetViz(t["viz"].(string))
|
||||
|
||||
if yaxis_, ok := t["yaxis"]; ok {
|
||||
yaxis := yaxis_.(map[string]interface{})
|
||||
if min_, ok := yaxis["min"]; ok {
|
||||
min, _ := strconv.ParseFloat(min_.(string), 64)
|
||||
d.Definition.Yaxis.Min = &min
|
||||
if v, ok := t["yaxis"]; ok {
|
||||
yaxis := v.(map[string]interface{})
|
||||
if v, ok := yaxis["min"]; ok {
|
||||
min, _ := strconv.ParseFloat(v.(string), 64)
|
||||
d.Definition.Yaxis.SetMin(min)
|
||||
}
|
||||
if max_, ok := yaxis["max"]; ok {
|
||||
max, _ := strconv.ParseFloat(max_.(string), 64)
|
||||
d.Definition.Yaxis.Max = &max
|
||||
if v, ok := yaxis["max"]; ok {
|
||||
max, _ := strconv.ParseFloat(v.(string), 64)
|
||||
d.Definition.Yaxis.SetMax(max)
|
||||
}
|
||||
if scale_, ok := yaxis["scale"]; ok {
|
||||
scale := scale_.(string)
|
||||
d.Definition.Yaxis.Scale = &scale
|
||||
if v, ok := yaxis["scale"]; ok {
|
||||
d.Definition.Yaxis.SetScale(v.(string))
|
||||
}
|
||||
}
|
||||
|
||||
if autoscale, ok := t["autoscale"]; ok {
|
||||
d.Definition.Autoscale = autoscale.(bool)
|
||||
if v, ok := t["autoscale"]; ok {
|
||||
d.Definition.SetAutoscale(v.(bool))
|
||||
}
|
||||
|
||||
if textAlign, ok := t["text_align"]; ok {
|
||||
d.Definition.TextAlign = textAlign.(string)
|
||||
if v, ok := t["text_align"]; ok {
|
||||
d.Definition.SetTextAlign(v.(string))
|
||||
}
|
||||
|
||||
if precision, ok := t["precision"]; ok {
|
||||
d.Definition.Precision = precision.(string)
|
||||
d.Definition.SetPrecision(precision.(string))
|
||||
}
|
||||
|
||||
if customUnit, ok := t["custom_unit"]; ok {
|
||||
d.Definition.CustomUnit = customUnit.(string)
|
||||
if v, ok := t["custom_unit"]; ok {
|
||||
d.Definition.SetCustomUnit(v.(string))
|
||||
}
|
||||
|
||||
if style, ok := t["style"]; ok {
|
||||
s := style.(map[string]interface{})
|
||||
|
||||
style := struct {
|
||||
Palette *string `json:"palette,omitempty"`
|
||||
PaletteFlip *bool `json:"paletteFlip,omitempty"`
|
||||
}{}
|
||||
gs := datadog.Style{}
|
||||
|
||||
if palette_, ok := s["palette"]; ok {
|
||||
palette := palette_.(string)
|
||||
style.Palette = &palette
|
||||
if v, ok := s["palette"]; ok {
|
||||
gs.SetPalette(v.(string))
|
||||
}
|
||||
|
||||
if paletteFlip_, ok := s["palette_flip"]; ok {
|
||||
paletteFlip, _ := strconv.ParseBool(paletteFlip_.(string))
|
||||
style.PaletteFlip = &paletteFlip
|
||||
if v, ok := s["palette_flip"]; ok {
|
||||
pf, _ := strconv.ParseBool(v.(string))
|
||||
gs.SetPaletteFlip(pf)
|
||||
}
|
||||
d.Definition.Style = &style
|
||||
d.Definition.SetStyle(gs)
|
||||
|
||||
}
|
||||
|
||||
if groups, ok := t["group"]; ok {
|
||||
for _, g := range groups.(*schema.Set).List() {
|
||||
if v, ok := t["group"]; ok {
|
||||
for _, g := range v.(*schema.Set).List() {
|
||||
d.Definition.Groups = append(d.Definition.Groups, g.(string))
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
for _, s := range scopes.(*schema.Set).List() {
|
||||
if v, ok := t["scope"]; ok {
|
||||
for _, s := range v.(*schema.Set).List() {
|
||||
d.Definition.Scopes = append(d.Definition.Groups, s.(string))
|
||||
}
|
||||
}
|
||||
|
||||
if includeUngroupedHosts, ok := t["include_ungrouped_hosts"]; ok {
|
||||
d.Definition.IncludeUngroupedHosts = includeUngroupedHosts.(bool)
|
||||
if v, ok := t["include_ungrouped_hosts"]; ok {
|
||||
d.Definition.SetIncludeUngroupedHosts(v.(bool))
|
||||
}
|
||||
terraformMarkers := t["marker"].([]interface{})
|
||||
appendMarkers(d, &terraformMarkers)
|
||||
v := t["marker"].([]interface{})
|
||||
appendMarkers(d, &v)
|
||||
|
||||
terraformEvents := t["events"].(*schema.Set).List()
|
||||
appendEvents(d, &terraformEvents)
|
||||
v = t["events"].(*schema.Set).List()
|
||||
appendEvents(d, &v)
|
||||
|
||||
terraformRequests := t["request"].([]interface{})
|
||||
appendRequests(d, &terraformRequests)
|
||||
v = t["request"].([]interface{})
|
||||
appendRequests(d, &v)
|
||||
}
|
||||
return &datadogGraphs
|
||||
}
|
||||
|
@ -499,10 +494,10 @@ func buildTimeboard(d *schema.ResourceData) (*datadog.Dashboard, error) {
|
|||
terraformGraphs := d.Get("graph").([]interface{})
|
||||
terraformTemplateVariables := d.Get("template_variable").([]interface{})
|
||||
return &datadog.Dashboard{
|
||||
Id: id,
|
||||
Title: d.Get("title").(string),
|
||||
Description: d.Get("description").(string),
|
||||
ReadOnly: d.Get("read_only").(bool),
|
||||
Id: datadog.Int(id),
|
||||
Title: datadog.String(d.Get("title").(string)),
|
||||
Description: datadog.String(d.Get("description").(string)),
|
||||
ReadOnly: datadog.Bool(d.Get("read_only").(bool)),
|
||||
Graphs: *buildGraphs(&terraformGraphs),
|
||||
TemplateVariables: *buildTemplateVariables(&terraformTemplateVariables),
|
||||
}, nil
|
||||
|
@ -517,7 +512,7 @@ func resourceDatadogTimeboardCreate(d *schema.ResourceData, meta interface{}) er
|
|||
if err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -535,19 +530,19 @@ func resourceDatadogTimeboardUpdate(d *schema.ResourceData, meta interface{}) er
|
|||
func appendTerraformGraphRequests(datadogRequests []datadog.GraphDefinitionRequest, requests *[]map[string]interface{}) {
|
||||
for _, datadogRequest := range datadogRequests {
|
||||
request := map[string]interface{}{}
|
||||
request["q"] = datadogRequest.Query
|
||||
request["stacked"] = datadogRequest.Stacked
|
||||
request["type"] = datadogRequest.Type
|
||||
if datadogRequest.Style != nil {
|
||||
request["q"] = datadogRequest.GetQuery()
|
||||
request["stacked"] = datadogRequest.GetStacked()
|
||||
request["type"] = datadogRequest.GetType()
|
||||
if v, ok := datadogRequest.GetStyleOk(); ok {
|
||||
style := map[string]string{}
|
||||
if datadogRequest.Style.Palette != nil {
|
||||
style["palette"] = *datadogRequest.Style.Palette
|
||||
if v, ok := v.GetPaletteOk(); ok {
|
||||
style["palette"] = v
|
||||
}
|
||||
if datadogRequest.Style.Type != nil {
|
||||
style["type"] = *datadogRequest.Style.Type
|
||||
if v, ok := v.GetTypeOk(); ok {
|
||||
style["type"] = v
|
||||
}
|
||||
if datadogRequest.Style.Width != nil {
|
||||
style["width"] = *datadogRequest.Style.Width
|
||||
if v, ok := v.GetWidthOk(); ok {
|
||||
style["width"] = v
|
||||
}
|
||||
request["style"] = style
|
||||
}
|
||||
|
@ -563,12 +558,12 @@ func appendTerraformGraphRequests(datadogRequests []datadog.GraphDefinitionReque
|
|||
conditionalFormats = append(conditionalFormats, conditionalFormat)
|
||||
}
|
||||
request["conditional_format"] = conditionalFormats
|
||||
request["change_type"] = datadogRequest.ChangeType
|
||||
request["order_direction"] = datadogRequest.OrderDirection
|
||||
request["compare_to"] = datadogRequest.CompareTo
|
||||
request["increase_good"] = datadogRequest.IncreaseGood
|
||||
request["order_by"] = datadogRequest.OrderBy
|
||||
request["extra_col"] = datadogRequest.ExtraCol
|
||||
request["change_type"] = datadogRequest.GetChangeType()
|
||||
request["order_direction"] = datadogRequest.GetOrderDirection()
|
||||
request["compare_to"] = datadogRequest.GetCompareTo()
|
||||
request["increase_good"] = datadogRequest.GetIncreaseGood()
|
||||
request["order_by"] = datadogRequest.GetOrderBy()
|
||||
request["extra_col"] = datadogRequest.GetExtraCol()
|
||||
|
||||
*requests = append(*requests, request)
|
||||
}
|
||||
|
@ -576,12 +571,12 @@ func appendTerraformGraphRequests(datadogRequests []datadog.GraphDefinitionReque
|
|||
|
||||
func buildTerraformGraph(datadog_graph datadog.Graph) map[string]interface{} {
|
||||
graph := map[string]interface{}{}
|
||||
graph["title"] = datadog_graph.Title
|
||||
graph["title"] = datadog_graph.GetTitle()
|
||||
|
||||
definition := datadog_graph.Definition
|
||||
graph["viz"] = definition.Viz
|
||||
graph["viz"] = definition.GetViz()
|
||||
|
||||
events := []string{}
|
||||
events := []*string{}
|
||||
for _, datadog_event := range definition.Events {
|
||||
events = append(events, datadog_event.Query)
|
||||
}
|
||||
|
@ -600,16 +595,16 @@ func buildTerraformGraph(datadog_graph datadog.Graph) map[string]interface{} {
|
|||
|
||||
yaxis := map[string]string{}
|
||||
|
||||
if definition.Yaxis.Min != nil {
|
||||
yaxis["min"] = strconv.FormatFloat(*definition.Yaxis.Min, 'f', -1, 64)
|
||||
if v, ok := definition.Yaxis.GetMinOk(); ok {
|
||||
yaxis["min"] = strconv.FormatFloat(v, 'f', -1, 64)
|
||||
}
|
||||
|
||||
if definition.Yaxis.Max != nil {
|
||||
yaxis["max"] = strconv.FormatFloat(*definition.Yaxis.Max, 'f', -1, 64)
|
||||
if v, ok := definition.Yaxis.GetMaxOk(); ok {
|
||||
yaxis["max"] = strconv.FormatFloat(v, 'f', -1, 64)
|
||||
}
|
||||
|
||||
if definition.Yaxis.Scale != nil {
|
||||
yaxis["scale"] = *definition.Yaxis.Scale
|
||||
if v, ok := definition.Yaxis.GetScaleOk(); ok {
|
||||
yaxis["scale"] = v
|
||||
}
|
||||
|
||||
graph["yaxis"] = yaxis
|
||||
|
@ -619,13 +614,13 @@ func buildTerraformGraph(datadog_graph datadog.Graph) map[string]interface{} {
|
|||
graph["precision"] = definition.Precision
|
||||
graph["custom_unit"] = definition.CustomUnit
|
||||
|
||||
if definition.Style != nil {
|
||||
if v, ok := definition.GetStyleOk(); ok {
|
||||
style := map[string]string{}
|
||||
if definition.Style.Palette != nil {
|
||||
style["palette"] = *definition.Style.Palette
|
||||
if v, ok := v.GetPaletteOk(); ok {
|
||||
style["palette"] = v
|
||||
}
|
||||
if definition.Style.PaletteFlip != nil {
|
||||
style["palette_flip"] = strconv.FormatBool(*definition.Style.PaletteFlip)
|
||||
if v, ok := v.GetPaletteFlipOk(); ok {
|
||||
style["palette_flip"] = strconv.FormatBool(v)
|
||||
}
|
||||
graph["style"] = style
|
||||
}
|
||||
|
@ -651,8 +646,8 @@ func resourceDatadogTimeboardRead(d *schema.ResourceData, meta interface{}) erro
|
|||
return err
|
||||
}
|
||||
log.Printf("[DEBUG] timeboard: %v", timeboard)
|
||||
d.Set("title", timeboard.Title)
|
||||
d.Set("description", timeboard.Description)
|
||||
d.Set("title", timeboard.GetTitle())
|
||||
d.Set("description", timeboard.GetDescription())
|
||||
|
||||
graphs := []map[string]interface{}{}
|
||||
for _, datadog_graph := range timeboard.Graphs {
|
||||
|
@ -660,9 +655,9 @@ func resourceDatadogTimeboardRead(d *schema.ResourceData, meta interface{}) erro
|
|||
}
|
||||
d.Set("graph", graphs)
|
||||
|
||||
templateVariables := []map[string]string{}
|
||||
templateVariables := []map[string]*string{}
|
||||
for _, templateVariable := range timeboard.TemplateVariables {
|
||||
tv := map[string]string{
|
||||
tv := map[string]*string{
|
||||
"name": templateVariable.Name,
|
||||
"prefix": templateVariable.Prefix,
|
||||
"default": templateVariable.Default,
|
||||
|
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/zorkian/go-datadog-api"
|
||||
"gopkg.in/zorkian/go-datadog-api.v2"
|
||||
)
|
||||
|
||||
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
|
||||
|
||||
generate:
|
||||
go generate
|
||||
|
||||
# test runs the unit tests and vets the code
|
||||
test:
|
||||
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
|
||||
// message to the users.
|
||||
type Alert struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Creator int `json:"creator,omitempty"`
|
||||
Query string `json:"query,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Silenced bool `json:"silenced,omitempty"`
|
||||
NotifyNoData bool `json:"notify_no_data,omitempty"`
|
||||
State string `json:"state,omitempty"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
Creator *int `json:"creator,omitempty"`
|
||||
Query *string `json:"query,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
Silenced *bool `json:"silenced,omitempty"`
|
||||
NotifyNoData *bool `json:"notify_no_data,omitempty"`
|
||||
State *string `json:"state,omitempty"`
|
||||
}
|
||||
|
||||
// reqAlerts receives a slice of all alerts.
|
|
@ -1,11 +1,11 @@
|
|||
package datadog
|
||||
|
||||
type Check struct {
|
||||
Check string `json:"check"`
|
||||
HostName string `json:"host_name"`
|
||||
Status Status `json:"status"`
|
||||
Timestamp string `json:"timestamp,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Check *string `json:"check,omitempty"`
|
||||
HostName *string `json:"host_name,omitempty"`
|
||||
Status *Status `json:"status,omitempty"`
|
||||
Timestamp *string `json:"timestamp,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
}
|
||||
|
|
@ -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.
|
||||
func (client *Client) Validate() (bool, error) {
|
||||
var bodyreader io.Reader
|
|
@ -14,27 +14,27 @@ import (
|
|||
|
||||
// Comment is a special form of event that appears in a stream.
|
||||
type Comment struct {
|
||||
Id int `json:"id"`
|
||||
RelatedId int `json:"related_event_id"`
|
||||
Handle string `json:"handle"`
|
||||
Message string `json:"message"`
|
||||
Resource string `json:"resource"`
|
||||
Url string `json:"url"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
RelatedId *int `json:"related_event_id,omitempty"`
|
||||
Handle *string `json:"handle,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
Resource *string `json:"resource,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// reqComment is the container for receiving commenst.
|
||||
type reqComment struct {
|
||||
Comment Comment `json:"comment"`
|
||||
Comment *Comment `json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
// CreateComment adds a new comment to the system.
|
||||
func (client *Client) CreateComment(handle, message string) (*Comment, error) {
|
||||
var out reqComment
|
||||
comment := Comment{Handle: handle, Message: message}
|
||||
comment := Comment{Handle: String(handle), Message: String(message)}
|
||||
if err := client.doJsonRequest("POST", "/v1/comments", &comment, &out); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out.Comment, nil
|
||||
return out.Comment, nil
|
||||
}
|
||||
|
||||
// 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,
|
||||
relid int) (*Comment, error) {
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
return &out.Comment, nil
|
||||
return out.Comment, nil
|
||||
}
|
||||
|
||||
// EditComment changes the message and possibly handle of a particular comment.
|
||||
func (client *Client) EditComment(id int, handle, message string) error {
|
||||
comment := Comment{Handle: handle, Message: message}
|
||||
comment := Comment{Handle: String(handle), Message: String(message)}
|
||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/comments/%d", id),
|
||||
&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 {
|
||||
Period int `json:"period,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
UntilDate int `json:"until_date,omitempty"`
|
||||
UntilOccurrences int `json:"until_occurrences,omitempty"`
|
||||
Period *int `json:"period,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
UntilDate *int `json:"until_date,omitempty"`
|
||||
UntilOccurrences *int `json:"until_occurrences,omitempty"`
|
||||
WeekDays []string `json:"week_days,omitempty"`
|
||||
}
|
||||
|
||||
type Downtime struct {
|
||||
Active bool `json:"active,omitempty"`
|
||||
Canceled int `json:"canceled,omitempty"`
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
End int `json:"end,omitempty"`
|
||||
Id int `json:"id,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Active *bool `json:"active,omitempty"`
|
||||
Canceled *int `json:"canceled,omitempty"`
|
||||
Disabled *bool `json:"disabled,omitempty"`
|
||||
End *int `json:"end,omitempty"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
Recurrence *Recurrence `json:"recurrence,omitempty"`
|
||||
Scope []string `json:"scope,omitempty"`
|
||||
Start int `json:"start,omitempty"`
|
||||
Start *int `json:"start,omitempty"`
|
||||
}
|
||||
|
||||
// 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
|
||||
// and sends it back to the server.
|
||||
func (client *Client) UpdateDowntime(downtime *Downtime) error {
|
||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/downtime/%d", downtime.Id),
|
||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/downtime/%d", *downtime.Id),
|
||||
downtime, nil)
|
||||
}
|
||||
|
|
@ -17,24 +17,24 @@ import (
|
|||
// Event is a single event. If this is being used to post an event, then not
|
||||
// all fields will be filled out.
|
||||
type Event struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Text string `json:"text,omitempty"`
|
||||
Time int `json:"date_happened,omitempty"` // UNIX time.
|
||||
Priority string `json:"priority,omitempty"`
|
||||
AlertType string `json:"alert_type,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Aggregation string `json:"aggregation_key,omitempty"`
|
||||
SourceType string `json:"source_type_name,omitempty"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
Text *string `json:"text,omitempty"`
|
||||
Time *int `json:"date_happened,omitempty"` // UNIX time.
|
||||
Priority *string `json:"priority,omitempty"`
|
||||
AlertType *string `json:"alert_type,omitempty"`
|
||||
Host *string `json:"host,omitempty"`
|
||||
Aggregation *string `json:"aggregation_key,omitempty"`
|
||||
SourceType *string `json:"source_type_name,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Url string `json:"url,omitempty"`
|
||||
Resource string `json:"resource,omitempty"`
|
||||
EventType string `json:"event_type,omitempty"`
|
||||
Url *string `json:"url,omitempty"`
|
||||
Resource *string `json:"resource,omitempty"`
|
||||
EventType *string `json:"event_type,omitempty"`
|
||||
}
|
||||
|
||||
// reqGetEvent is the container for receiving a single event.
|
||||
type reqGetEvent struct {
|
||||
Event Event `json:"event,omitempty"`
|
||||
Event *Event `json:"event,omitempty"`
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
return &out.Event, nil
|
||||
return out.Event, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
return &out.Event, nil
|
||||
return out.Event, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
Ok json.Number `json:"ok,omitempty"`
|
||||
Critical json.Number `json:"critical,omitempty"`
|
||||
Warning json.Number `json:"warning,omitempty"`
|
||||
Ok *json.Number `json:"ok,omitempty"`
|
||||
Critical *json.Number `json:"critical,omitempty"`
|
||||
Warning *json.Number `json:"warning,omitempty"`
|
||||
}
|
||||
|
||||
type NoDataTimeframe int
|
||||
|
@ -40,38 +40,38 @@ func (tf *NoDataTimeframe) UnmarshalJSON(data []byte) error {
|
|||
|
||||
type Options struct {
|
||||
NoDataTimeframe NoDataTimeframe `json:"no_data_timeframe,omitempty"`
|
||||
NotifyAudit bool `json:"notify_audit,omitempty"`
|
||||
NotifyNoData bool `json:"notify_no_data,omitempty"`
|
||||
NotifyAudit *bool `json:"notify_audit,omitempty"`
|
||||
NotifyNoData *bool `json:"notify_no_data,omitempty"`
|
||||
RenotifyInterval *int `json:"renotify_interval,omitempty"`
|
||||
NewHostDelay *int `json:"new_host_delay,omitempty"`
|
||||
RenotifyInterval int `json:"renotify_interval,omitempty"`
|
||||
Silenced map[string]int `json:"silenced,omitempty"`
|
||||
TimeoutH int `json:"timeout_h,omitempty"`
|
||||
EscalationMessage string `json:"escalation_message,omitempty"`
|
||||
Thresholds ThresholdCount `json:"thresholds,omitempty"`
|
||||
IncludeTags bool `json:"include_tags,omitempty"`
|
||||
RequireFullWindow bool `json:"require_full_window,omitempty"`
|
||||
Locked bool `json:"locked,omitempty"`
|
||||
TimeoutH *int `json:"timeout_h,omitempty"`
|
||||
EscalationMessage *string `json:"escalation_message,omitempty"`
|
||||
Thresholds *ThresholdCount `json:"thresholds,omitempty"`
|
||||
IncludeTags *bool `json:"include_tags,omitempty"`
|
||||
RequireFullWindow *bool `json:"require_full_window,omitempty"`
|
||||
Locked *bool `json:"locked,omitempty"`
|
||||
}
|
||||
|
||||
// Monitor allows watching a metric or check that you care about,
|
||||
// notifying your team when some defined threshold is exceeded
|
||||
type Monitor struct {
|
||||
Creator Creator `json:"creator,omitempty"`
|
||||
Id int `json:"id,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Query string `json:"query,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Creator *Creator `json:"creator,omitempty"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
Query *string `json:"query,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Message *string `json:"message,omitempty"`
|
||||
Tags []string `json:"tags,omitempty"`
|
||||
Options Options `json:"options,omitempty"`
|
||||
Options *Options `json:"options,omitempty"`
|
||||
}
|
||||
|
||||
// Creator contains the creator of the monitor
|
||||
type Creator struct {
|
||||
Email string `json:"email,omitempty"`
|
||||
Handle string `json:"handle,omitempty"`
|
||||
Id int `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Email *string `json:"email,omitempty"`
|
||||
Handle *string `json:"handle,omitempty"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// reqMonitors receives a slice of all monitors
|
||||
|
@ -93,7 +93,7 @@ func (client *Client) CreateMonitor(monitor *Monitor) (*Monitor, error) {
|
|||
// UpdateMonitor takes a monitor that was previously retrieved through some method
|
||||
// and sends it back to the server
|
||||
func (client *Client) UpdateMonitor(monitor *Monitor) error {
|
||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/monitor/%d", monitor.Id),
|
||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/monitor/%d", *monitor.Id),
|
||||
monitor, nil)
|
||||
}
|
||||
|
|
@ -11,26 +11,17 @@ package datadog
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"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
|
||||
// the proper request URI to be posted to.
|
||||
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")
|
||||
}
|
||||
|
||||
// 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
|
||||
if method == "POST" {
|
||||
if method == "POST" || method == "PUT" {
|
||||
resp, err = client.HttpClient.Do(req)
|
||||
} else {
|
||||
resp, err = client.doRequestWithRetries(req, client.RetryTimeout)
|
||||
|
@ -81,12 +72,6 @@ func (client *Client) doJsonRequest(method, api string,
|
|||
}
|
||||
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 {
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
|
@ -118,54 +103,35 @@ func (client *Client) doJsonRequest(method, api string,
|
|||
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
|
||||
// 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) {
|
||||
var (
|
||||
err error
|
||||
resp *http.Response
|
||||
bo = backoff.NewExponentialBackOff()
|
||||
)
|
||||
|
||||
bo.MaxElapsedTime = maxTime
|
||||
|
||||
err = backoff.Retry(func() error {
|
||||
operation := func() error {
|
||||
resp, err = client.HttpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := client.getRateLimit(resp); err != nil {
|
||||
if err.(*RateLimit).Remaining == 0 {
|
||||
return err
|
||||
}
|
||||
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||
// 2xx all done
|
||||
return nil
|
||||
} else if resp.StatusCode >= 400 && resp.StatusCode < 500 {
|
||||
// 4xx are not retryable
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
||||
return errors.New("API error: " + resp.Status)
|
||||
return fmt.Errorf("Received HTTP status code %d", resp.StatusCode)
|
||||
}
|
||||
return nil
|
||||
}, bo)
|
||||
|
||||
err = backoff.Retry(operation, bo)
|
||||
|
||||
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
|
||||
// struct when we load a screenboard in detail.
|
||||
type Screenboard struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Title string `json:"board_title,omitempty"`
|
||||
Height string `json:"height,omitempty"`
|
||||
Width string `json:"width,omitempty"`
|
||||
Shared bool `json:"shared,omitempty"`
|
||||
Templated bool `json:"templated,omitempty"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
Title *string `json:"board_title,omitempty"`
|
||||
Height *string `json:"height,omitempty"`
|
||||
Width *string `json:"width,omitempty"`
|
||||
Shared *bool `json:"shared,omitempty"`
|
||||
Templated *bool `json:"templated,omitempty"`
|
||||
TemplateVariables []TemplateVariable `json:"template_variables,omitempty"`
|
||||
Widgets []Widget `json:"widgets,omitempty"`
|
||||
ReadOnly bool `json:"read_only,omitempty"`
|
||||
ReadOnly *bool `json:"read_only,omitempty"`
|
||||
}
|
||||
|
||||
//type Widget struct {
|
||||
type Widget struct {
|
||||
Default string `json:"default,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Prefix string `json:"prefix,omitempty"`
|
||||
TimeseriesWidget TimeseriesWidget `json:"timeseries,omitempty"`
|
||||
QueryValueWidget QueryValueWidget `json:"query_value,omitempty"`
|
||||
EventStreamWidget EventStreamWidget `json:"event_stream,omitempty"`
|
||||
FreeTextWidget FreeTextWidget `json:"free_text,omitempty"`
|
||||
ToplistWidget ToplistWidget `json:"toplist,omitempty"`
|
||||
ImageWidget ImageWidget `json:"image,omitempty"`
|
||||
ChangeWidget ChangeWidget `json:"change,omitempty"`
|
||||
GraphWidget GraphWidget `json:"graph,omitempty"`
|
||||
EventTimelineWidget EventTimelineWidget `json:"event_timeline,omitempty"`
|
||||
AlertValueWidget AlertValueWidget `json:"alert_value,omitempty"`
|
||||
AlertGraphWidget AlertGraphWidget `json:"alert_graph,omitempty"`
|
||||
HostMapWidget HostMapWidget `json:"hostmap,omitempty"`
|
||||
CheckStatusWidget CheckStatusWidget `json:"check_status,omitempty"`
|
||||
IFrameWidget IFrameWidget `json:"iframe,omitempty"`
|
||||
NoteWidget NoteWidget `json:"frame,omitempty"`
|
||||
Default *string `json:"default,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Prefix *string `json:"prefix,omitempty"`
|
||||
TimeseriesWidget *TimeseriesWidget `json:"timeseries,omitempty"`
|
||||
QueryValueWidget *QueryValueWidget `json:"query_value,omitempty"`
|
||||
EventStreamWidget *EventStreamWidget `json:"event_stream,omitempty"`
|
||||
FreeTextWidget *FreeTextWidget `json:"free_text,omitempty"`
|
||||
ToplistWidget *ToplistWidget `json:"toplist,omitempty"`
|
||||
ImageWidget *ImageWidget `json:"image,omitempty"`
|
||||
ChangeWidget *ChangeWidget `json:"change,omitempty"`
|
||||
GraphWidget *GraphWidget `json:"graph,omitempty"`
|
||||
EventTimelineWidget *EventTimelineWidget `json:"event_timeline,omitempty"`
|
||||
AlertValueWidget *AlertValueWidget `json:"alert_value,omitempty"`
|
||||
AlertGraphWidget *AlertGraphWidget `json:"alert_graph,omitempty"`
|
||||
HostMapWidget *HostMapWidget `json:"hostmap,omitempty"`
|
||||
CheckStatusWidget *CheckStatusWidget `json:"check_status,omitempty"`
|
||||
IFrameWidget *IFrameWidget `json:"iframe,omitempty"`
|
||||
NoteWidget *NoteWidget `json:"frame,omitempty"`
|
||||
}
|
||||
|
||||
// ScreenboardLite represents a user created screenboard. This is the mini
|
||||
// struct when we load the summaries.
|
||||
type ScreenboardLite struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Resource string `json:"resource,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
Id *int `json:"id,omitempty"`
|
||||
Resource *string `json:"resource,omitempty"`
|
||||
Title *string `json:"title,omitempty"`
|
||||
}
|
||||
|
||||
// reqGetScreenboards from /api/v1/screen
|
||||
type reqGetScreenboards struct {
|
||||
Screenboards []*ScreenboardLite `json:"screenboards"`
|
||||
Screenboards []*ScreenboardLite `json:"screenboards,omitempty"`
|
||||
}
|
||||
|
||||
// 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
|
||||
// the server. Use this if you've updated your local and need to push it back.
|
||||
func (client *Client) UpdateScreenboard(board *Screenboard) error {
|
||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/screen/%d", board.Id), board, nil)
|
||||
return client.doJsonRequest("PUT", fmt.Sprintf("/v1/screen/%d", *board.Id), board, nil)
|
||||
}
|
||||
|
||||
type ScreenShareResponse struct {
|
|
@ -17,25 +17,26 @@ type DataPoint [2]float64
|
|||
// Metric represents a collection of data points that we might send or receive
|
||||
// on one single metric line.
|
||||
type Metric struct {
|
||||
Metric string `json:"metric,omitempty"`
|
||||
Metric *string `json:"metric,omitempty"`
|
||||
Points []DataPoint `json:"points,omitempty"`
|
||||
Type string `json:"type,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
Type *string `json:"type,omitempty"`
|
||||
Host *string `json:"host,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
|
||||
type Series struct {
|
||||
Metric string `json:"metric,omitempty"`
|
||||
DisplayName string `json:"display_name,omitempty"`
|
||||
Metric *string `json:"metric,omitempty"`
|
||||
DisplayName *string `json:"display_name,omitempty"`
|
||||
Points []DataPoint `json:"pointlist,omitempty"`
|
||||
Start float64 `json:"start,omitempty"`
|
||||
End float64 `json:"end,omitempty"`
|
||||
Interval int `json:"interval,omitempty"`
|
||||
Aggr string `json:"aggr,omitempty"`
|
||||
Length int `json:"length,omitempty"`
|
||||
Scope string `json:"scope,omitempty"`
|
||||
Expression string `json:"expression,omitempty"`
|
||||
Start *float64 `json:"start,omitempty"`
|
||||
End *float64 `json:"end,omitempty"`
|
||||
Interval *int `json:"interval,omitempty"`
|
||||
Aggr *string `json:"aggr,omitempty"`
|
||||
Length *int `json:"length,omitempty"`
|
||||
Scope *string `json:"scope,omitempty"`
|
||||
Expression *string `json:"expression,omitempty"`
|
||||
}
|
||||
|
||||
// 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)
|
||||
|
||||
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 {
|
||||
return "", err
|
|
@ -13,7 +13,7 @@ type TagMap map[string][]string
|
|||
|
||||
// reqGetTags is the container for receiving tags.
|
||||
type reqGetTags struct {
|
||||
Tags TagMap `json:"tags,omitempty"`
|
||||
Tags *TagMap `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// 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 {
|
||||
return nil, err
|
||||
}
|
||||
return out.Tags, nil
|
||||
return *out.Tags, nil
|
||||
}
|
||||
|
||||
// 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 {
|
||||
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,
|
||||
// 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.
|
||||
func (client *Client) AddTagsToHost(host, source string, tags []string) error {
|
||||
uri := "/v1/tags/hosts/" + host
|
|
@ -9,13 +9,13 @@
|
|||
package datadog
|
||||
|
||||
type User struct {
|
||||
Handle string `json:"handle,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Role string `json:"role,omitempty"`
|
||||
IsAdmin bool `json:"is_admin,omitempty"`
|
||||
Verified bool `json:"verified,omitempty"`
|
||||
Disabled bool `json:"disabled,omitempty"`
|
||||
Handle *string `json:"handle,omitempty"`
|
||||
Email *string `json:"email,omitempty"`
|
||||
Name *string `json:"name,omitempty"`
|
||||
Role *string `json:"role,omitempty"`
|
||||
IsAdmin *bool `json:"is_admin,omitempty"`
|
||||
Verified *bool `json:"verified,omitempty"`
|
||||
Disabled *bool `json:"disabled,omitempty"`
|
||||
}
|
||||
|
||||
// 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
|
||||
func (self *Client) CreateUser(handle, name string) (*User, error) {
|
||||
func (self *Client) CreateUser(handle, name *string) (*User, error) {
|
||||
in := struct {
|
||||
Handle string `json:"handle"`
|
||||
Name string `json:"name"`
|
||||
Handle *string `json:"handle"`
|
||||
Name *string `json:"name"`
|
||||
}{
|
||||
Handle: handle,
|
||||
Name: name,
|
||||
|
@ -50,7 +50,7 @@ func (self *Client) CreateUser(handle, name string) (*User, error) {
|
|||
|
||||
// internal type to retrieve users from the api
|
||||
type usersData struct {
|
||||
Users []User `json:"users"`
|
||||
Users []User `json:"users,omitempty"`
|
||||
}
|
||||
|
||||
// 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`,
|
||||
// and returns an error if the update failed
|
||||
func (client *Client) UpdateUser(user User) error {
|
||||
uri := "/v1/user/" + user.Handle
|
||||
uri := "/v1/user/" + *user.Handle
|
||||
return client.doJsonRequest("PUT", uri, user, nil)
|
||||
}
|
||||
|
|
@ -2155,18 +2155,18 @@
|
|||
"path": "github.com/maximilien/softlayer-go/softlayer",
|
||||
"revision": "85659debe44fab5792fc92cf755c04b115b9dc19"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "OUZ1FFXyKs+Cfg9M9rmXqqweQck=",
|
||||
"path": "github.com/miekg/dns",
|
||||
"revision": "db96a2b759cdef4f11a34506a42eb8d1290c598e",
|
||||
"revisionTime": "2016-07-26T03:20:27Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "GSum+utW01N3KeMdvAPnsW0TemM=",
|
||||
"path": "github.com/michaelklishin/rabbit-hole",
|
||||
"revision": "88550829bcdcf614361c73459c903578eb44074e",
|
||||
"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=",
|
||||
"path": "github.com/mitchellh/cli",
|
||||
|
@ -2664,12 +2664,6 @@
|
|||
"path": "github.com/ziutek/mymysql/thrsafe",
|
||||
"revision": "75ce5fbba34b1912a3641adbd58cf317d7315821"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "uynUzdKeOsfi7flpYWFx835Nafo=",
|
||||
"path": "github.com/zorkian/go-datadog-api",
|
||||
"revision": "6308094e4aca46eb16a227b50be29772242bf3aa",
|
||||
"revisionTime": "2017-02-02T00:47:50Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "9x64JhJGo6z8TS0Q33cGcR64kjA=",
|
||||
"path": "golang.org/x/crypto/curve25519",
|
||||
|
@ -3003,6 +2997,12 @@
|
|||
"path": "gopkg.in/yaml.v2",
|
||||
"revision": "a5b47d31c556af34a302ce5d659e6fea44d90de0",
|
||||
"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"
|
||||
|
|
Loading…
Reference in New Issue