terraform/vendor/github.com/circonus-labs/circonus-gometrics/api/dashboard.go

400 lines
17 KiB
Go
Raw Normal View History

Circonus Provider (#12338) * Begin stubbing out the Circonus provider. * Remove all references to `reverse:secret_key`. This value is dynamically set by the service and unused by Terraform. * Update the `circonus_check` resource. Still a WIP. * Add docs for the `circonus_check` resource. Commit miss, this should have been included in the last commit. * "Fix" serializing check tags I still need to figure out how I can make them order agnostic w/o using a TypeSet. I'm worried that's what I'm going to have to do. * Spike a quick circonus_broker data source. * Convert tags to a Set so the order does not matter. * Add a `circonus_account` data source. * Correctly spell account. Pointed out by: @postwait * Add the `circonus_contact_group` resource. * Push descriptions into their own file in order to reduce the busyness of the schema when reviewing code. * Rename `circonus_broker` and `broker` to `circonus_collector` and `collector`, respectively. Change made with concent by Circonus to reduce confusion (@postwait, @maier, and several others). * Use upstream contsants where available. * Import the latest circonus-gometrics. * Move to using a Set of collectors vs a list attached to a single attribute. * Rename "cid" to "id" in the circonus_account data source and elsewhere where possible. * Inject a tag automatically. Update gometrics. * Checkpoint `circonus_metric` resource. * Enable provider-level auto-tagging. This is disabled by default. * Rearrange metric. This is an experimental "style" of a provider. We'll see. That moment. When you think you've gone off the rails on a mad scientist experiment but like the outcome and think you may be onto something but haven't proven it to yourself or anyone else yet? That. That exact feeling of semi-confidence while being alone in the wilderness. Please let this not be the Terraform provider equivalent of DJB's C style of coding. We'll know in another resource or two if this was a horrible mistake or not. * Begin moving `resource_circonus_check` over to the new world order/structure: Much of this is WIP and incomplete, but here is the new supported structure: ``` variable "used_metric_name" { default = "_usage`0`_used" } resource "circonus_check" "usage" { # collectors = ["${var.collectors}"] collector { id = "${var.collectors[0]}" } name = "${var.check_name}" notes = "${var.notes}" json { url = "https://${var.target}/account/current" http_headers = { "Accept" = "application/json" "X-Circonus-App-Name" = "TerraformCheck" "X-Circonus-Auth-Token" = "${var.api_token}" } } stream { name = "${circonus_metric.used.name}" tags = "${circonus_metric.used.tags}" type = "${circonus_metric.used.type}" } tags = { source = "circonus" } } resource "circonus_metric" "used" { name = "${var.used_metric_name}" tags = { source = "circonus" } type = "numeric" } ``` * Document the `circonus_metric` resource. * Updated `circonus_check` docs. * If a port was present, automatically set it in the Config. * Alpha sort the check parameters now that they've been renamed. * Fix a handful of panics as a result of the schema changing. * Move back to a `TypeSet` for tags. After a stint with `TypeMap`, move back to `TypeSet`. A set of strings seems to match the API the best. The `map` type was convenient because it reduced the amount of boilerplate, but you loose out on other things. For instance, tags come in the form of `category:value`, so naturally it seems like you could use a map, but you can't without severe loss of functionality because assigning two values to the same category is common. And you can't normalize map input or suppress the output correctly (this was eventually what broke the camel's back). I tried an experiment of normalizing the input to be `category:value` as the key in the map and a value of `""`, but... seee diff suppress. In this case, simple is good. While here bring some cleanups to _Metric since that was my initial testing target. * Rename `providerConfig` to `_ProviderConfig` * Checkpoint the `json` check type. * Fix a few residual issues re: missing descriptions. * Rename `validateRegexp` to `_ValidateRegexp` * Use tags as real sets, not just a slice of strings. * Move the DiffSuppressFunc for tags down to the Elem. * Fix up unit tests to chase the updated, default hasher function being used. * Remove `Computed` attribute from `TypeSet` objects. This fixes a pile of issues re: update that I was having. * Rename functions. `GetStringOk` -> `GetStringOK` `GetSetAsListOk` -> `GetSetAsListOK` `GetIntOk` -> `GetIntOK` * Various small cleanups and comments rolled into a single commit. * Add a `postgresql` check type for the `circonus_check` resource. * Rename various validator functions to be _CapitalCase vs capitalCase. * Err... finish the validator renames. * Add `GetFloat64()` support. * Add `icmp_ping` check type support. * Catch up to the _API*Attr renames. Deliberately left out of the previous commit in order to create a clean example of what is required to add a new check type to the `circonus_check` resource. * Clarify when the `target` attribute is required for the `postgresql` check type. * Correctly pull the metric ID attribute from the right location. * Add a circonus_stream_group resource (a.k.a. a Circonus "metric cluster") * Add support for the [`caql`](https://login.circonus.com/user/docs/caql_reference) check type. * Add support for the `http` check type. * `s/SSL/TLS/g` * Add support for `tcp` check types. * Enumerate the available metrics that are supported for each check type. * Add [`cloudwatch`](https://login.circonus.com/user/docs/Data/CheckTypes/CloudWatch) check type support. * Add a `circonus_trigger` resource (a.k.a Circonus Ruleset). * Rename a handful of functions to make it clear in the function name the direction of flow for information moving through the provider. TL;DR: Replace `parse` and `read` with "foo to bar"-like names. * Fix the attribute name used in a validator. Absent != After. * Set the minimum `absent` predicate to 70s per testing. * Fix the regression tests for circonus_trigger now that absent has a 70s min * Fix up the `tcp` check to require a `host` attribute. Fix tests. It's clear I didn't run these before committing/pushing the `tcp` check last time. * Fix `circonus_check` for `cloudwatch` checks. * Rename `parsePerCheckTypeConfig()` to `_CheckConfigToAPI` to be consistent with other function names. grep(1)ability of code++ * Slack buttons as an integer are string encoded. * Fix updates for `circonus_contact`. * Fix the out parameters for contact groups. * Move to using `_CastSchemaToTF()` where appropriate. * Fix circonus_contact_group. Updates work as expected now. * Use `_StateSet()` in place of `d.Set()` everywhere. * Make a quick pass over the collector datasource to modernize its style * Quick pass for items identified by `golint`. * Fix up collectors * Fix the `json` check type. Reconcile possible sources of drift. Update now works as expected. * Normalize trigger durations to seconds. * Improve the robustness of the state handling for the `circonus_contact_group` resource. * I'm torn on this, but sort the contact groups in the notify list. This does mean that if the first contact group in the list has a higher lexical sort order the plan won't converge until the offending resource is tainted and recreated. But there's also some sorting happening elsewhere, so.... sort and taint for now and this will need to be revisited in the future. * Add support for the `httptrap` check type. * Remove empty units from the state file. * Metric clusters can return a 404. Detect this accordingly in its respective Exists handler. * Add a `circonus_graph` resource. * Fix a handful of bugs in the graph provider. * Re-enable the necessary `ConflictsWith` definitions and normalize attribute names. * Objects that have been deleted via the UI return a 404. Handle in Exists(). * Teach `circonus_graph`'s Stack set to accept nil values. * Set `ForceNew: true` for a graph's name. * Chase various API fixes required to make `circonus_graph` work as expected. * Fix up the handling of sub-1 zoom resolutions for graphs. * Add the `check_by_collector` out parameter to the `circonus_check` resource. * Improve validation of line vs area graphs. Fix graph_style. * Fix up the `logarithmic` graph axis option. * Resolve various trivial `go vet` issues. * Add a stream_group out parameter. * Remove incorrectly applied `Optional` attributes to the `circonus_account` resource. * Remove various `Optional` attributes from the `circonus_collector` data source. * Centralize the common need to suppress leading and trailing whitespace into `suppressWhitespace`. * Sync up with upstream vendor fixes for circonus_graph. * Update the checksum value for the http check. * Chase `circonus_graph`'s underlying `line_style` API object change from `string` to `*string`. * Clean up tests to use a generic terraform regression testing account. * Add support for the MySQL to the `circonus_check` resource. * Begin stubbing out the Circonus provider. * Remove all references to `reverse:secret_key`. This value is dynamically set by the service and unused by Terraform. * Update the `circonus_check` resource. Still a WIP. * Add docs for the `circonus_check` resource. Commit miss, this should have been included in the last commit. * "Fix" serializing check tags I still need to figure out how I can make them order agnostic w/o using a TypeSet. I'm worried that's what I'm going to have to do. * Spike a quick circonus_broker data source. * Convert tags to a Set so the order does not matter. * Add a `circonus_account` data source. * Correctly spell account. Pointed out by: @postwait * Add the `circonus_contact_group` resource. * Push descriptions into their own file in order to reduce the busyness of the schema when reviewing code. * Rename `circonus_broker` and `broker` to `circonus_collector` and `collector`, respectively. Change made with concent by Circonus to reduce confusion (@postwait, @maier, and several others). * Use upstream contsants where available. * Import the latest circonus-gometrics. * Move to using a Set of collectors vs a list attached to a single attribute. * Rename "cid" to "id" in the circonus_account data source and elsewhere where possible. * Inject a tag automatically. Update gometrics. * Checkpoint `circonus_metric` resource. * Enable provider-level auto-tagging. This is disabled by default. * Rearrange metric. This is an experimental "style" of a provider. We'll see. That moment. When you think you've gone off the rails on a mad scientist experiment but like the outcome and think you may be onto something but haven't proven it to yourself or anyone else yet? That. That exact feeling of semi-confidence while being alone in the wilderness. Please let this not be the Terraform provider equivalent of DJB's C style of coding. We'll know in another resource or two if this was a horrible mistake or not. * Begin moving `resource_circonus_check` over to the new world order/structure: Much of this is WIP and incomplete, but here is the new supported structure: ``` variable "used_metric_name" { default = "_usage`0`_used" } resource "circonus_check" "usage" { # collectors = ["${var.collectors}"] collector { id = "${var.collectors[0]}" } name = "${var.check_name}" notes = "${var.notes}" json { url = "https://${var.target}/account/current" http_headers = { "Accept" = "application/json" "X-Circonus-App-Name" = "TerraformCheck" "X-Circonus-Auth-Token" = "${var.api_token}" } } stream { name = "${circonus_metric.used.name}" tags = "${circonus_metric.used.tags}" type = "${circonus_metric.used.type}" } tags = { source = "circonus" } } resource "circonus_metric" "used" { name = "${var.used_metric_name}" tags = { source = "circonus" } type = "numeric" } ``` * Document the `circonus_metric` resource. * Updated `circonus_check` docs. * If a port was present, automatically set it in the Config. * Alpha sort the check parameters now that they've been renamed. * Fix a handful of panics as a result of the schema changing. * Move back to a `TypeSet` for tags. After a stint with `TypeMap`, move back to `TypeSet`. A set of strings seems to match the API the best. The `map` type was convenient because it reduced the amount of boilerplate, but you loose out on other things. For instance, tags come in the form of `category:value`, so naturally it seems like you could use a map, but you can't without severe loss of functionality because assigning two values to the same category is common. And you can't normalize map input or suppress the output correctly (this was eventually what broke the camel's back). I tried an experiment of normalizing the input to be `category:value` as the key in the map and a value of `""`, but... seee diff suppress. In this case, simple is good. While here bring some cleanups to _Metric since that was my initial testing target. * Rename `providerConfig` to `_ProviderConfig` * Checkpoint the `json` check type. * Fix a few residual issues re: missing descriptions. * Rename `validateRegexp` to `_ValidateRegexp` * Use tags as real sets, not just a slice of strings. * Move the DiffSuppressFunc for tags down to the Elem. * Fix up unit tests to chase the updated, default hasher function being used. * Remove `Computed` attribute from `TypeSet` objects. This fixes a pile of issues re: update that I was having. * Rename functions. `GetStringOk` -> `GetStringOK` `GetSetAsListOk` -> `GetSetAsListOK` `GetIntOk` -> `GetIntOK` * Various small cleanups and comments rolled into a single commit. * Add a `postgresql` check type for the `circonus_check` resource. * Rename various validator functions to be _CapitalCase vs capitalCase. * Err... finish the validator renames. * Add `GetFloat64()` support. * Add `icmp_ping` check type support. * Catch up to the _API*Attr renames. Deliberately left out of the previous commit in order to create a clean example of what is required to add a new check type to the `circonus_check` resource. * Clarify when the `target` attribute is required for the `postgresql` check type. * Correctly pull the metric ID attribute from the right location. * Add a circonus_stream_group resource (a.k.a. a Circonus "metric cluster") * Add support for the [`caql`](https://login.circonus.com/user/docs/caql_reference) check type. * Add support for the `http` check type. * `s/SSL/TLS/g` * Add support for `tcp` check types. * Enumerate the available metrics that are supported for each check type. * Add [`cloudwatch`](https://login.circonus.com/user/docs/Data/CheckTypes/CloudWatch) check type support. * Add a `circonus_trigger` resource (a.k.a Circonus Ruleset). * Rename a handful of functions to make it clear in the function name the direction of flow for information moving through the provider. TL;DR: Replace `parse` and `read` with "foo to bar"-like names. * Fix the attribute name used in a validator. Absent != After. * Set the minimum `absent` predicate to 70s per testing. * Fix the regression tests for circonus_trigger now that absent has a 70s min * Fix up the `tcp` check to require a `host` attribute. Fix tests. It's clear I didn't run these before committing/pushing the `tcp` check last time. * Fix `circonus_check` for `cloudwatch` checks. * Rename `parsePerCheckTypeConfig()` to `_CheckConfigToAPI` to be consistent with other function names. grep(1)ability of code++ * Slack buttons as an integer are string encoded. * Fix updates for `circonus_contact`. * Fix the out parameters for contact groups. * Move to using `_CastSchemaToTF()` where appropriate. * Fix circonus_contact_group. Updates work as expected now. * Use `_StateSet()` in place of `d.Set()` everywhere. * Make a quick pass over the collector datasource to modernize its style * Quick pass for items identified by `golint`. * Fix up collectors * Fix the `json` check type. Reconcile possible sources of drift. Update now works as expected. * Normalize trigger durations to seconds. * Improve the robustness of the state handling for the `circonus_contact_group` resource. * I'm torn on this, but sort the contact groups in the notify list. This does mean that if the first contact group in the list has a higher lexical sort order the plan won't converge until the offending resource is tainted and recreated. But there's also some sorting happening elsewhere, so.... sort and taint for now and this will need to be revisited in the future. * Add support for the `httptrap` check type. * Remove empty units from the state file. * Metric clusters can return a 404. Detect this accordingly in its respective Exists handler. * Add a `circonus_graph` resource. * Fix a handful of bugs in the graph provider. * Re-enable the necessary `ConflictsWith` definitions and normalize attribute names. * Objects that have been deleted via the UI return a 404. Handle in Exists(). * Teach `circonus_graph`'s Stack set to accept nil values. * Set `ForceNew: true` for a graph's name. * Chase various API fixes required to make `circonus_graph` work as expected. * Fix up the handling of sub-1 zoom resolutions for graphs. * Add the `check_by_collector` out parameter to the `circonus_check` resource. * Improve validation of line vs area graphs. Fix graph_style. * Fix up the `logarithmic` graph axis option. * Resolve various trivial `go vet` issues. * Add a stream_group out parameter. * Remove incorrectly applied `Optional` attributes to the `circonus_account` resource. * Remove various `Optional` attributes from the `circonus_collector` data source. * Centralize the common need to suppress leading and trailing whitespace into `suppressWhitespace`. * Sync up with upstream vendor fixes for circonus_graph. * Update the checksum value for the http check. * Chase `circonus_graph`'s underlying `line_style` API object change from `string` to `*string`. * Clean up tests to use a generic terraform regression testing account. * Rename all identifiers that began with a `_` and replace with a corresponding lowercase glyph. * Remove stale comment in types. * Move the calls to `ResourceData`'s `SetId()` calls to be first in the list so that no resources are lost in the event of a `panic()`. * Remove `stateSet` from the `circonus_trigger` resource. * Remove `stateSet` from the `circonus_stream_group` resource. * Remove `schemaSet` from the `circonus_graph` resource. * Remove `stateSet` from the `circonus_contact` resource. * Remove `stateSet` from the `circonus_metric` resource. * Remove `stateSet` from the `circonus_account` data source. * Remove `stateSet` from the `circonus_collector` data source. * Remove stray `stateSet` call from the `circonus_contact` resource. This is an odd artifact to find... I'm completely unsure as to why it was there to begin with but am mostly certain it's a bug and needs to be removed. * Remove `stateSet` from the `circonus_check` resource. * Remove the `stateSet` helper function. All call sites have been converted to return errors vs `panic()`'ing at runtime. * Remove a pile of unused functions and type definitions. * Remove the last of the `attrReader` interface. * Remove an unused `Sprintf` call. * Update `circonus-gometrics` and remove unused files. * Document what `convertToHelperSchema()` does. Rename `castSchemaToTF` to `convertToHelperSchema`. Change the function parameter ordering so the `map` of attribute descriptions: this is much easier to maintain when the description map is first when creating schema inline. * Move descriptions into their respective source files. * Remove all instances of `panic()`. In the case of software bugs, log an error. Never `panic()` and always return a value. * Rename `stream_group` to `metric_cluster`. * Rename triggers to rule sets * Rename `stream` to `metric`. * Chase the `stream` -> `metric` change into the docs. * Remove some unused test functions. * Add the now required `color` attribute for graphing a `metric_cluster`. * Add a missing description to silence a warning. * Add `id` as a selector for the account data source. * Futureproof testing: Randomize all asset names to prevent any possible resource conflicts. This isn't a necessary change for our current build and regression testing, but *just in case* we have a radical change to our testing framework in the future, make all resource names fully random. * Rename various values to match the Circonus docs. * s/alarm/alert/g * Ensure ruleset criteria can not be empty.
2017-03-10 21:19:17 +01:00
// Copyright 2016 Circonus, Inc. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Dashboard API support - Fetch, Create, Update, Delete, and Search
// See: https://login.circonus.com/resources/api/calls/dashboard
package api
import (
"encoding/json"
"fmt"
"net/url"
"regexp"
"github.com/circonus-labs/circonus-gometrics/api/config"
)
// DashboardGridLayout defines layout
type DashboardGridLayout struct {
Height uint `json:"height"`
Width uint `json:"width"`
}
// DashboardAccessConfig defines access config
type DashboardAccessConfig struct {
BlackDash bool `json:"black_dash,omitempty"`
Enabled bool `json:"enabled,omitempty"`
Fullscreen bool `json:"fullscreen,omitempty"`
FullscreenHideTitle bool `json:"fullscreen_hide_title,omitempty"`
Nickname string `json:"nickname,omitempty"`
ScaleText bool `json:"scale_text,omitempty"`
SharedID string `json:"shared_id,omitempty"`
TextSize uint `json:"text_size,omitempty"`
}
// DashboardOptions defines options
type DashboardOptions struct {
AccessConfigs []DashboardAccessConfig `json:"access_configs,omitempty"`
FullscreenHideTitle bool `json:"fullscreen_hide_title,omitempty"`
HideGrid bool `json:"hide_grid,omitempty"`
Linkages [][]string `json:"linkages,omitempty"`
ScaleText bool `json:"scale_text,omitempty"`
TextSize uint `json:"text_size,omitempty"`
}
// ChartTextWidgetDatapoint defines datapoints for charts
type ChartTextWidgetDatapoint struct {
AccountID string `json:"account_id,omitempty"` // metric cluster, metric
CheckID uint `json:"_check_id,omitempty"` // metric
ClusterID uint `json:"cluster_id,omitempty"` // metric cluster
ClusterTitle string `json:"_cluster_title,omitempty"` // metric cluster
Label string `json:"label,omitempty"` // metric
Label2 string `json:"_label,omitempty"` // metric cluster
Metric string `json:"metric,omitempty"` // metric
MetricType string `json:"_metric_type,omitempty"` // metric
NumericOnly bool `json:"numeric_only,omitempty"` // metric cluster
}
// ChartWidgetDefinitionLegend defines chart widget definition legend
type ChartWidgetDefinitionLegend struct {
Show bool `json:"show,omitempty"`
Type string `json:"type,omitempty"`
}
// ChartWidgetWedgeLabels defines chart widget wedge labels
type ChartWidgetWedgeLabels struct {
OnChart bool `json:"on_chart,omitempty"`
ToolTips bool `json:"tooltips,omitempty"`
}
// ChartWidgetWedgeValues defines chart widget wedge values
type ChartWidgetWedgeValues struct {
Angle string `json:"angle,omitempty"`
Color string `json:"color,omitempty"`
Show bool `json:"show,omitempty"`
}
// ChartWidgtDefinition defines chart widget definition
type ChartWidgtDefinition struct {
Datasource string `json:"datasource,omitempty"`
Derive string `json:"derive,omitempty"`
DisableAutoformat bool `json:"disable_autoformat,omitempty"`
Formula string `json:"formula,omitempty"`
Legend ChartWidgetDefinitionLegend `json:"legend,omitempty"`
Period uint `json:"period,omitempty"`
PopOnHover bool `json:"pop_onhover,omitempty"`
WedgeLabels ChartWidgetWedgeLabels `json:"wedge_labels,omitempty"`
WedgeValues ChartWidgetWedgeValues `json:"wedge_values,omitempty"`
}
// ForecastGaugeWidgetThresholds defines forecast widget thresholds
type ForecastGaugeWidgetThresholds struct {
Colors []string `json:"colors,omitempty"` // forecasts, gauges
Flip bool `json:"flip,omitempty"` // gauges
Values []string `json:"values,omitempty"` // forecasts, gauges
}
// StatusWidgetAgentStatusSettings defines agent status settings
type StatusWidgetAgentStatusSettings struct {
Search string `json:"search,omitempty"`
ShowAgentTypes string `json:"show_agent_types,omitempty"`
ShowContact bool `json:"show_contact,omitempty"`
ShowFeeds bool `json:"show_feeds,omitempty"`
ShowSetup bool `json:"show_setup,omitempty"`
ShowSkew bool `json:"show_skew,omitempty"`
ShowUpdates bool `json:"show_updates,omitempty"`
}
// StatusWidgetHostStatusSettings defines host status settings
type StatusWidgetHostStatusSettings struct {
LayoutStyle string `json:"layout_style,omitempty"`
Search string `json:"search,omitempty"`
SortBy string `json:"sort_by,omitempty"`
TagFilterSet []string `json:"tag_filter_set,omitempty"`
}
// DashboardWidgetSettings defines settings specific to widget
type DashboardWidgetSettings struct {
AccountID string `json:"account_id,omitempty"` // alerts, clusters, gauges, graphs, lists, status
Acknowledged string `json:"acknowledged,omitempty"` // alerts
AgentStatusSettings StatusWidgetAgentStatusSettings `json:"agent_status_settings,omitempty"` // status
Algorithm string `json:"algorithm,omitempty"` // clusters
Autoformat bool `json:"autoformat,omitempty"` // text
BodyFormat string `json:"body_format,omitempty"` // text
ChartType string `json:"chart_type,omitempty"` // charts
CheckUUID string `json:"check_uuid,omitempty"` // gauges
Cleared string `json:"cleared,omitempty"` // alerts
ClusterID uint `json:"cluster_id,omitempty"` // clusters
ClusterName string `json:"cluster_name,omitempty"` // clusters
ContactGroups []uint `json:"contact_groups,omitempty"` // alerts
ContentType string `json:"content_type,omitempty"` // status
Datapoints []ChartTextWidgetDatapoint `json:"datapoints,omitempty"` // charts, text
DateWindow string `json:"date_window,omitempty"` // graphs
Definition ChartWidgtDefinition `json:"definition,omitempty"` // charts
Dependents string `json:"dependents,omitempty"` // alerts
DisableAutoformat bool `json:"disable_autoformat,omitempty"` // gauges
Display string `json:"display,omitempty"` // alerts
Format string `json:"format,omitempty"` // forecasts
Formula string `json:"formula,omitempty"` // gauges
GraphUUID string `json:"graph_id,omitempty"` // graphs
HideXAxis bool `json:"hide_xaxis,omitempty"` // graphs
HideYAxis bool `json:"hide_yaxis,omitempty"` // graphs
HostStatusSettings StatusWidgetHostStatusSettings `json:"host_status_settings,omitempty"` // status
KeyInline bool `json:"key_inline,omitempty"` // graphs
KeyLoc string `json:"key_loc,omitempty"` // graphs
KeySize uint `json:"key_size,omitempty"` // graphs
KeyWrap bool `json:"key_wrap,omitempty"` // graphs
Label string `json:"label,omitempty"` // graphs
Layout string `json:"layout,omitempty"` // clusters
Limit uint `json:"limit,omitempty"` // lists
Maintenance string `json:"maintenance,omitempty"` // alerts
Markup string `json:"markup,omitempty"` // html
MetricDisplayName string `json:"metric_display_name,omitempty"` // gauges
MetricName string `json:"metric_name,omitempty"` // gauges
MinAge string `json:"min_age,omitempty"` // alerts
OffHours []uint `json:"off_hours,omitempty"` // alerts
OverlaySetID string `json:"overlay_set_id,omitempty"` // graphs
Period uint `json:"period,omitempty"` // gauges, text, graphs
RangeHigh int `json:"range_high,omitempty"` // gauges
RangeLow int `json:"range_low,omitempty"` // gauges
Realtime bool `json:"realtime,omitempty"` // graphs
ResourceLimit string `json:"resource_limit,omitempty"` // forecasts
ResourceUsage string `json:"resource_usage,omitempty"` // forecasts
Search string `json:"search,omitempty"` // alerts, lists
Severity string `json:"severity,omitempty"` // alerts
ShowFlags bool `json:"show_flags,omitempty"` // graphs
Size string `json:"size,omitempty"` // clusters
TagFilterSet []string `json:"tag_filter_set,omitempty"` // alerts
Threshold float32 `json:"threshold,omitempty"` // clusters
Thresholds ForecastGaugeWidgetThresholds `json:"thresholds,omitempty"` // forecasts, gauges
TimeWindow string `json:"time_window,omitempty"` // alerts
Title string `json:"title,omitempty"` // alerts, charts, forecasts, gauges, html
TitleFormat string `json:"title_format,omitempty"` // text
Trend string `json:"trend,omitempty"` // forecasts
Type string `json:"type,omitempty"` // gauges, lists
UseDefault bool `json:"use_default,omitempty"` // text
ValueType string `json:"value_type,omitempty"` // gauges, text
WeekDays []string `json:"weekdays,omitempty"` // alerts
}
// DashboardWidget defines widget
type DashboardWidget struct {
Active bool `json:"active"`
Height uint `json:"height"`
Name string `json:"name"`
Origin string `json:"origin"`
Settings DashboardWidgetSettings `json:"settings"`
Type string `json:"type"`
WidgetID string `json:"widget_id"`
Width uint `json:"width"`
}
// Dashboard defines a dashboard. See https://login.circonus.com/resources/api/calls/dashboard for more information.
type Dashboard struct {
AccountDefault bool `json:"account_default"`
Active bool `json:"_active,omitempty"`
CID string `json:"_cid,omitempty"`
Created uint `json:"_created,omitempty"`
CreatedBy string `json:"_created_by,omitempty"`
GridLayout DashboardGridLayout `json:"grid_layout"`
LastModified uint `json:"_last_modified,omitempty"`
Options DashboardOptions `json:"options"`
Shared bool `json:"shared"`
Title string `json:"title"`
UUID string `json:"_dashboard_uuid,omitempty"`
Widgets []DashboardWidget `json:"widgets"`
}
// NewDashboard returns a new Dashboard (with defaults, if applicable)
func NewDashboard() *Dashboard {
return &Dashboard{}
}
// FetchDashboard retrieves dashboard with passed cid.
func (a *API) FetchDashboard(cid CIDType) (*Dashboard, error) {
if cid == nil || *cid == "" {
return nil, fmt.Errorf("Invalid dashboard CID [none]")
}
dashboardCID := string(*cid)
matched, err := regexp.MatchString(config.DashboardCIDRegex, dashboardCID)
if err != nil {
return nil, err
}
if !matched {
return nil, fmt.Errorf("Invalid dashboard CID [%s]", dashboardCID)
}
result, err := a.Get(string(*cid))
if err != nil {
return nil, err
}
if a.Debug {
a.Log.Printf("[DEBUG] fetch dashboard, received JSON: %s", string(result))
}
dashboard := new(Dashboard)
if err := json.Unmarshal(result, dashboard); err != nil {
return nil, err
}
return dashboard, nil
}
// FetchDashboards retrieves all dashboards available to the API Token.
func (a *API) FetchDashboards() (*[]Dashboard, error) {
result, err := a.Get(config.DashboardPrefix)
if err != nil {
return nil, err
}
var dashboards []Dashboard
if err := json.Unmarshal(result, &dashboards); err != nil {
return nil, err
}
return &dashboards, nil
}
// UpdateDashboard updates passed dashboard.
func (a *API) UpdateDashboard(cfg *Dashboard) (*Dashboard, error) {
if cfg == nil {
return nil, fmt.Errorf("Invalid dashboard config [nil]")
}
dashboardCID := string(cfg.CID)
matched, err := regexp.MatchString(config.DashboardCIDRegex, dashboardCID)
if err != nil {
return nil, err
}
if !matched {
return nil, fmt.Errorf("Invalid dashboard CID [%s]", dashboardCID)
}
jsonCfg, err := json.Marshal(cfg)
if err != nil {
return nil, err
}
if a.Debug {
a.Log.Printf("[DEBUG] update dashboard, sending JSON: %s", string(jsonCfg))
}
result, err := a.Put(dashboardCID, jsonCfg)
if err != nil {
return nil, err
}
dashboard := &Dashboard{}
if err := json.Unmarshal(result, dashboard); err != nil {
return nil, err
}
return dashboard, nil
}
// CreateDashboard creates a new dashboard.
func (a *API) CreateDashboard(cfg *Dashboard) (*Dashboard, error) {
if cfg == nil {
return nil, fmt.Errorf("Invalid dashboard config [nil]")
}
jsonCfg, err := json.Marshal(cfg)
if err != nil {
return nil, err
}
if a.Debug {
a.Log.Printf("[DEBUG] create dashboard, sending JSON: %s", string(jsonCfg))
}
result, err := a.Post(config.DashboardPrefix, jsonCfg)
if err != nil {
return nil, err
}
dashboard := &Dashboard{}
if err := json.Unmarshal(result, dashboard); err != nil {
return nil, err
}
return dashboard, nil
}
// DeleteDashboard deletes passed dashboard.
func (a *API) DeleteDashboard(cfg *Dashboard) (bool, error) {
if cfg == nil {
return false, fmt.Errorf("Invalid dashboard config [nil]")
}
return a.DeleteDashboardByCID(CIDType(&cfg.CID))
}
// DeleteDashboardByCID deletes dashboard with passed cid.
func (a *API) DeleteDashboardByCID(cid CIDType) (bool, error) {
if cid == nil || *cid == "" {
return false, fmt.Errorf("Invalid dashboard CID [none]")
}
dashboardCID := string(*cid)
matched, err := regexp.MatchString(config.DashboardCIDRegex, dashboardCID)
if err != nil {
return false, err
}
if !matched {
return false, fmt.Errorf("Invalid dashboard CID [%s]", dashboardCID)
}
_, err = a.Delete(dashboardCID)
if err != nil {
return false, err
}
return true, nil
}
// SearchDashboards returns dashboards matching the specified
// search query and/or filter. If nil is passed for both parameters
// all dashboards will be returned.
func (a *API) SearchDashboards(searchCriteria *SearchQueryType, filterCriteria *SearchFilterType) (*[]Dashboard, error) {
q := url.Values{}
if searchCriteria != nil && *searchCriteria != "" {
q.Set("search", string(*searchCriteria))
}
if filterCriteria != nil && len(*filterCriteria) > 0 {
for filter, criteria := range *filterCriteria {
for _, val := range criteria {
q.Add(filter, val)
}
}
}
if q.Encode() == "" {
return a.FetchDashboards()
}
reqURL := url.URL{
Path: config.DashboardPrefix,
RawQuery: q.Encode(),
}
result, err := a.Get(reqURL.String())
if err != nil {
return nil, fmt.Errorf("[ERROR] API call error %+v", err)
}
var dashboards []Dashboard
if err := json.Unmarshal(result, &dashboards); err != nil {
return nil, err
}
return &dashboards, nil
}