diff --git a/.go-version b/.go-version
index d3de22ef..74bb9d57 100644
--- a/.go-version
+++ b/.go-version
@@ -1 +1 @@
-1.73.1
+1.73.2
diff --git a/client/metric_dashboards.go b/client/metric_dashboards.go
index bc566c49..92e8e661 100644
--- a/client/metric_dashboards.go
+++ b/client/metric_dashboards.go
@@ -15,11 +15,12 @@ type UnifiedDashboard struct {
}
type UnifiedDashboardAttributes struct {
- Name string `json:"name"`
- Description string `json:"description"`
- Charts []UnifiedChart `json:"charts"`
- Groups []UnifiedGroup `json:"groups"`
- Labels []Label `json:"labels"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ Charts []UnifiedChart `json:"charts"`
+ Groups []UnifiedGroup `json:"groups"`
+ Labels []Label `json:"labels"`
+ TemplateVariables []TemplateVariable `json:"template_variables"`
}
type UnifiedGroup struct {
@@ -63,6 +64,12 @@ type MetricGroupBy struct {
AggregationMethod string `json:"aggregation-method"`
}
+type TemplateVariable struct {
+ Name string `json:"name"`
+ DefaultValues []string `json:"default_values"`
+ SuggestionAttributeKey string `json:"suggestion_attribute_key"`
+}
+
func getUnifiedDashboardURL(project, id string, query map[string]string) string {
path := fmt.Sprintf(
"projects/%s/metric_dashboards",
@@ -95,10 +102,11 @@ func (c *Client) CreateUnifiedDashboard(
bytes, err := json.Marshal(UnifiedDashboard{
Type: dashboard.Type,
Attributes: UnifiedDashboardAttributes{
- Name: dashboard.Attributes.Name,
- Description: dashboard.Attributes.Description,
- Groups: dashboard.Attributes.Groups,
- Labels: dashboard.Attributes.Labels,
+ Name: dashboard.Attributes.Name,
+ Description: dashboard.Attributes.Description,
+ Groups: dashboard.Attributes.Groups,
+ Labels: dashboard.Attributes.Labels,
+ TemplateVariables: dashboard.Attributes.TemplateVariables,
},
})
diff --git a/docs/resources/dashboard.md b/docs/resources/dashboard.md
index bab819ac..acb4b4d2 100644
--- a/docs/resources/dashboard.md
+++ b/docs/resources/dashboard.md
@@ -20,7 +20,7 @@ resource "lightstep_dashboard" "customer_charges" {
dashboard_description = "Dashboard for customer charges metrics"
chart {
- name = "Requests by Project"
+ name = "Requests by Project for $service"
rank = 1
type = "timeseries"
@@ -28,7 +28,7 @@ resource "lightstep_dashboard" "customer_charges" {
hidden = false
query_name = "a"
display = "line"
- query_string = "metric requests | rate 10m | group_by [project_id], sum"
+ query_string = "metric requests | filter (service == $service) | rate 10m | group_by [project_id], sum"
}
}
@@ -53,6 +53,12 @@ resource "lightstep_dashboard" "customer_charges" {
label {
value = "customlabel"
}
+
+ template_variable {
+ name = "service"
+ default_values = ["adservice"]
+ suggestion_attribute_key = "service_name"
+ }
}
```
@@ -70,6 +76,7 @@ resource "lightstep_dashboard" "customer_charges" {
- `dashboard_description` (String)
- `group` (Block Set) (see [below for nested schema](#nestedblock--group))
- `label` (Block Set) Labels can be key/value pairs or standalone values. (see [below for nested schema](#nestedblock--label))
+- `template_variable` (Block Set) Variable to be used in dashboard queries for dynamically filtering telemetry data (see [below for nested schema](#nestedblock--template_variable))
### Read-Only
@@ -216,3 +223,13 @@ Required:
Optional:
- `key` (String)
+
+
+
+### Nested Schema for `template_variable`
+
+Required:
+
+- `default_values` (List of String) One or more values to set the template variable to by default (if none are provided, defaults to all possible values)
+- `name` (String) Unique (per dashboard) name for template variable, beginning with a letter or underscore and only containing letters, numbers, and underscores
+- `suggestion_attribute_key` (String) Attribute key used as source for suggested template variable values appearing in Lightstep UI
diff --git a/docs/resources/metric_dashboard.md b/docs/resources/metric_dashboard.md
index 405529ef..796ba632 100644
--- a/docs/resources/metric_dashboard.md
+++ b/docs/resources/metric_dashboard.md
@@ -92,6 +92,7 @@ resource "lightstep_metric_dashboard" "customer_charges" {
- `dashboard_description` (String)
- `group` (Block Set) (see [below for nested schema](#nestedblock--group))
- `label` (Block Set) Labels can be key/value pairs or standalone values. (see [below for nested schema](#nestedblock--label))
+- `template_variable` (Block Set) Variable to be used in dashboard queries for dynamically filtering telemetry data (see [below for nested schema](#nestedblock--template_variable))
### Read-Only
@@ -302,3 +303,13 @@ Required:
Optional:
- `key` (String)
+
+
+
+### Nested Schema for `template_variable`
+
+Required:
+
+- `default_values` (List of String) One or more values to set the template variable to by default (if none are provided, defaults to all possible values)
+- `name` (String) Unique (per dashboard) name for template variable, beginning with a letter or underscore and only containing letters, numbers, and underscores
+- `suggestion_attribute_key` (String) Attribute key used as source for suggested template variable values appearing in Lightstep UI
diff --git a/lightstep/resource_dashboard_test.go b/lightstep/resource_dashboard_test.go
index c2fa3343..1525142b 100644
--- a/lightstep/resource_dashboard_test.go
+++ b/lightstep/resource_dashboard_test.go
@@ -479,6 +479,84 @@ resource "lightstep_dashboard" "labels" {
})
}
+func TestAccDashboardWithTemplateVariables(t *testing.T) {
+ validDashboardConfigWithTemplateVariables := `
+resource "lightstep_dashboard" "test" {
+ project_name = "terraform-provider-tests"
+ dashboard_name = "Acceptance Test Dashboard with Template Variables"
+ chart {
+ name = "Chart Number One"
+ rank = 1
+ type = "timeseries"
+ query {
+ hidden = false
+ query_name = "a"
+ display = "line"
+ query_string = "metric m | filter (service == $service) | rate | group_by [], sum"
+ }
+ }
+ template_variable {
+ name = "service"
+ default_values = ["myService"]
+ suggestion_attribute_key = "service_name"
+ }
+}
+`
+
+ invalidDashboardConfigWithInvalidTemplateVariableName := `
+resource "lightstep_dashboard" "test" {
+ project_name = "terraform-provider-tests"
+ dashboard_name = "Acceptance Test Dashboard"
+ chart {
+ name = "Chart Number One"
+ rank = 1
+ type = "timeseries"
+ query {
+ hidden = false
+ query_name = "a"
+ display = "line"
+ query_string = "metric m | filter (service == $invalid-name) | rate | group_by [], sum"
+ }
+ }
+ template_variable {
+ name = "invalid-name"
+ default_values = ["myService"]
+ suggestion_attribute_key = "service_name"
+ }
+}
+`
+
+ var dashboard client.UnifiedDashboard
+ resourceName := "lightstep_dashboard.test"
+
+ resource.Test(t, resource.TestCase{
+ PreCheck: func() { testAccPreCheck(t) },
+ ProviderFactories: testAccProviderFactories,
+ CheckDestroy: testGetMetricDashboardDestroy,
+ Steps: []resource.TestStep{
+ {
+ Config: validDashboardConfigWithTemplateVariables,
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckMetricDashboardExists(resourceName, &dashboard),
+ resource.TestCheckResourceAttr(resourceName, "dashboard_name", "Acceptance Test Dashboard with Template Variables"),
+ resource.TestCheckResourceAttr(resourceName, "chart.0.query.0.query_string", "metric m | filter (service == $service) | rate | group_by [], sum"),
+ resource.TestCheckResourceAttr(resourceName, "chart.0.query.0.display", "line"),
+ resource.TestCheckResourceAttr(resourceName, "chart.0.query.0.hidden", "false"),
+ resource.TestCheckResourceAttr(resourceName, "template_variable.0.name", "service"),
+ resource.TestCheckResourceAttr(resourceName, "template_variable.0.default_values.0", "myService"),
+ resource.TestCheckResourceAttr(resourceName, "template_variable.0.suggestion_attribute_key", "service_name"),
+ ),
+ },
+ {
+ Config: invalidDashboardConfigWithInvalidTemplateVariableName,
+ Check: resource.ComposeTestCheckFunc(
+ testAccCheckMetricDashboardExists(resourceName, &dashboard)),
+ ExpectError: regexp.MustCompile("InvalidArgument"),
+ },
+ },
+ })
+}
+
func testGetMetricDashboardDestroy(s *terraform.State) error {
conn := testAccProvider.Meta().(*client.Client)
for _, r := range s.RootModule().Resources {
diff --git a/lightstep/resource_metric_dashboard.go b/lightstep/resource_metric_dashboard.go
index 488bee2f..1c4e8f33 100644
--- a/lightstep/resource_metric_dashboard.go
+++ b/lightstep/resource_metric_dashboard.go
@@ -86,6 +86,14 @@ func resourceUnifiedDashboard(chartSchemaType ChartSchemaType) *schema.Resource
},
},
},
+ "template_variable": {
+ Type: schema.TypeSet,
+ Optional: true,
+ Elem: &schema.Resource{
+ Schema: getTemplateVariableSchema(),
+ },
+ Description: "Variable to be used in dashboard queries for dynamically filtering telemetry data",
+ },
},
}
}
@@ -219,6 +227,29 @@ func getChartSchema(chartSchemaType ChartSchemaType) map[string]*schema.Schema {
}
}
+func getTemplateVariableSchema() map[string]*schema.Schema {
+ return map[string]*schema.Schema{
+ "name": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "Unique (per dashboard) name for template variable, beginning with a letter or underscore and only containing letters, numbers, and underscores",
+ },
+ "suggestion_attribute_key": {
+ Type: schema.TypeString,
+ Required: true,
+ Description: "Attribute key used as source for suggested template variable values appearing in Lightstep UI",
+ },
+ "default_values": {
+ Type: schema.TypeList,
+ Required: true,
+ Elem: &schema.Schema{
+ Type: schema.TypeString,
+ },
+ Description: "One or more values to set the template variable to by default (if none are provided, defaults to all possible values)",
+ },
+ }
+}
+
type resourceUnifiedDashboardImp struct {
chartSchemaType ChartSchemaType
}
@@ -363,11 +394,15 @@ func getUnifiedDashboardAttributesFromResource(d *schema.ResourceData) (*client.
return nil, err
}
+ templateVariableSet := d.Get("template_variable").(*schema.Set)
+ templateVariables := buildTemplateVariables(templateVariableSet.List())
+
attributes := &client.UnifiedDashboardAttributes{
- Name: d.Get("dashboard_name").(string),
- Description: d.Get("dashboard_description").(string),
- Groups: groups,
- Labels: labels,
+ Name: d.Get("dashboard_name").(string),
+ Description: d.Get("dashboard_description").(string),
+ Groups: groups,
+ Labels: labels,
+ TemplateVariables: templateVariables,
}
return attributes, nil
@@ -519,6 +554,31 @@ func buildYAxis(yAxisIn []interface{}) (*client.YAxis, error) {
return yAxis, nil
}
+func buildTemplateVariables(templateVariablesIn []interface{}) []client.TemplateVariable {
+ var newTemplateVariables []client.TemplateVariable
+ for _, tv := range templateVariablesIn {
+ tvMap := tv.(map[string]interface{})
+ name := tvMap["name"].(string)
+ suggestionAttributeKey := tvMap["suggestion_attribute_key"].(string)
+ defaultValues := buildDefaultValues(tvMap["default_values"].([]interface{}))
+
+ newTemplateVariables = append(newTemplateVariables, client.TemplateVariable{
+ Name: name,
+ DefaultValues: defaultValues,
+ SuggestionAttributeKey: suggestionAttributeKey,
+ })
+ }
+ return newTemplateVariables
+}
+
+func buildDefaultValues(valuesIn []interface{}) []string {
+ defaultValues := make([]string, 0, len(valuesIn))
+ for _, v := range valuesIn {
+ defaultValues = append(defaultValues, v.(string))
+ }
+ return defaultValues
+}
+
func (p *resourceUnifiedDashboardImp) setResourceDataFromUnifiedDashboard(project string, dash client.UnifiedDashboard, d *schema.ResourceData) error {
if err := d.Set("project_name", project); err != nil {
return fmt.Errorf("unable to set project_name resource field: %v", err)
@@ -618,6 +678,19 @@ func (p *resourceUnifiedDashboardImp) setResourceDataFromUnifiedDashboard(projec
return fmt.Errorf("unable to set labels resource field: %v", err)
}
+ var templateVariables []interface{}
+ for _, tv := range dash.Attributes.TemplateVariables {
+ templateVariable := map[string]interface{}{}
+ templateVariable["name"] = tv.Name
+ templateVariable["default_values"] = tv.DefaultValues
+ templateVariable["suggestion_attribute_key"] = tv.SuggestionAttributeKey
+
+ templateVariables = append(templateVariables, templateVariable)
+ }
+ if err := d.Set("template_variable", templateVariables); err != nil {
+ return fmt.Errorf("unable to set template variables resource field: %v", err)
+ }
+
return nil
}
diff --git a/templates/resources/dashboard.md.tmpl b/templates/resources/dashboard.md.tmpl
index 0a179434..1668c21f 100644
--- a/templates/resources/dashboard.md.tmpl
+++ b/templates/resources/dashboard.md.tmpl
@@ -20,7 +20,7 @@ resource "lightstep_dashboard" "customer_charges" {
dashboard_description = "Dashboard for customer charges metrics"
chart {
- name = "Requests by Project"
+ name = "Requests by Project for $service"
rank = 1
type = "timeseries"
@@ -28,7 +28,7 @@ resource "lightstep_dashboard" "customer_charges" {
hidden = false
query_name = "a"
display = "line"
- query_string = "metric requests | rate 10m | group_by [project_id], sum"
+ query_string = "metric requests | filter (service == $service) | rate 10m | group_by [project_id], sum"
}
}
@@ -53,6 +53,12 @@ resource "lightstep_dashboard" "customer_charges" {
label {
value = "customlabel"
}
+
+ template_variable {
+ name = "service"
+ default_values = ["adservice"]
+ suggestion_attribute_key = "service_name"
+ }
}
```