Skip to content

Commit 7080a13

Browse files
authored
Merge pull request #165 from SumoLogic/vishal-fix-topology-label-map
2 parents f8d0b99 + af6a99f commit 7080a13

File tree

3 files changed

+111
-21
lines changed

3 files changed

+111
-21
lines changed

sumologic/resource_sumologic_dashboard.go

Lines changed: 52 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -62,20 +62,29 @@ func resourceSumologicDashboard() *schema.Resource {
6262
Type: schema.TypeString,
6363
Optional: true,
6464
},
65-
// FIXME: topology_label_map doesn't work. Don't use it!
6665
"topology_label_map": {
6766
Type: schema.TypeList,
6867
Optional: true,
6968
MaxItems: 1,
7069
Elem: &schema.Resource{
7170
Schema: map[string]*schema.Schema{
7271
"data": {
73-
Type: schema.TypeMap,
72+
Type: schema.TypeList,
7473
Required: true,
75-
Elem: &schema.Schema{
76-
Type: schema.TypeList,
77-
Elem: &schema.Schema{
78-
Type: schema.TypeString,
74+
Elem: &schema.Resource{
75+
Schema: map[string]*schema.Schema{
76+
"label": {
77+
Type: schema.TypeString,
78+
Required: true,
79+
},
80+
"values": {
81+
Type: schema.TypeList,
82+
Required: true,
83+
MinItems: 1,
84+
Elem: &schema.Schema{
85+
Type: schema.TypeString,
86+
},
87+
},
7988
},
8089
},
8190
},
@@ -939,11 +948,17 @@ func getTimeRangeBoundary(tfRangeBoundary map[string]interface{}) interface{} {
939948
}
940949

941950
func getTopologyLabel(tfTopologyLabel map[string]interface{}) *TopologyLabel {
942-
// data is a map from string to list of strings
943-
if val, ok := tfTopologyLabel["data"].(map[string]interface{}); ok {
951+
if items := tfTopologyLabel["data"].([]interface{}); len(items) == 1 {
944952
labelMap := make(map[string][]string)
945-
for k, v := range val {
946-
labelMap[k] = v.([]string)
953+
for _, item := range items {
954+
dataItem := item.(map[string]interface{})
955+
key := dataItem["label"].(string)
956+
itemValues := dataItem["values"].([]interface{})
957+
values := make([]string, len(itemValues))
958+
for i := range itemValues {
959+
values[i] = itemValues[i].(string)
960+
}
961+
labelMap[key] = values
947962
}
948963
return &TopologyLabel{
949964
Data: labelMap,
@@ -1093,6 +1108,11 @@ func setDashboard(d *schema.ResourceData, dashboard *Dashboard) error {
10931108
return err
10941109
}
10951110

1111+
topologyLabel := getTerraformTopologyLabel(dashboard.TopologyLabelMap)
1112+
if err := d.Set("topology_label_map", topologyLabel); err != nil {
1113+
return err
1114+
}
1115+
10961116
timeRange := getTerraformTimeRange(dashboard.TimeRange.(map[string]interface{}))
10971117
if err := d.Set("time_range", timeRange); err != nil {
10981118
return err
@@ -1122,6 +1142,7 @@ func setDashboard(d *schema.ResourceData, dashboard *Dashboard) error {
11221142
log.Printf("title: %+v\n", d.Get("title"))
11231143
log.Printf("description: %+v\n", d.Get("description"))
11241144
log.Printf("folder_id: %+v\n", d.Get("folder_id"))
1145+
log.Printf("topology_label_map: %+v\n", d.Get("topology_label_map"))
11251146
log.Printf("time_range: %+v\n", d.Get("time_range"))
11261147
log.Printf("panel: %+v\n", d.Get("panel"))
11271148
log.Printf("layout: %+v\n", d.Get("layout"))
@@ -1139,6 +1160,27 @@ func makeTerraformObject() TerraformObject {
11391160
return terraformObject
11401161
}
11411162

1163+
func getTerraformTopologyLabel(topologyLabel *TopologyLabel) []map[string]interface{} {
1164+
// API returns an empty data map if we don't set topologyLabelMap.
1165+
if len(topologyLabel.Data) == 0 {
1166+
return nil
1167+
}
1168+
1169+
tfTopologyLabel := make([]map[string]interface{}, 0)
1170+
tfTopologyLabel = append(tfTopologyLabel, make(map[string]interface{}))
1171+
1172+
data := topologyLabel.Data
1173+
tfDataItems := make([]map[string]interface{}, 0)
1174+
for label, values := range data {
1175+
tfDataItem := make(map[string]interface{})
1176+
tfDataItem["label"] = label
1177+
tfDataItem["values"] = values
1178+
tfDataItems = append(tfDataItems, tfDataItem)
1179+
}
1180+
tfTopologyLabel[0]["data"] = tfDataItems
1181+
return tfTopologyLabel
1182+
}
1183+
11421184
func getTerraformTimeRange(timeRange map[string]interface{}) []map[string]interface{} {
11431185
tfTimeRange := []map[string]interface{}{}
11441186
tfTimeRange = append(tfTimeRange, make(map[string]interface{}))

sumologic/resource_sumologic_dashboard_test.go

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ func TestAccSumologicDashboard_create(t *testing.T) {
4141
description := "Test dashboard description"
4242
theme := "Dark"
4343
refreshInterval := 30
44+
topologyLabel := "service"
45+
topologyLabelValue := "collection-proxy"
4446
literalRangeName := "today"
4547
textPanel := TextPanel{
4648
Key: "text-panel-001",
@@ -74,8 +76,8 @@ func TestAccSumologicDashboard_create(t *testing.T) {
7476
CheckDestroy: testAccCheckDashboardDestroy(dashboard),
7577
Steps: []resource.TestStep{
7678
{
77-
Config: dashboardCreateConfig(title, description, theme, refreshInterval, literalRangeName,
78-
textPanel, layout, variable),
79+
Config: dashboardCreateConfig(title, description, theme, refreshInterval,
80+
topologyLabel, topologyLabelValue, literalRangeName, textPanel, layout, variable),
7981
Check: resource.ComposeTestCheckFunc(
8082
testAccCheckDashboardExists("sumologic_dashboard.tf_crud_test", &dashboard, t),
8183
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
@@ -86,6 +88,10 @@ func TestAccSumologicDashboard_create(t *testing.T) {
8688
"refresh_interval", strconv.FormatInt(int64(refreshInterval), 10)),
8789
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
8890
"theme", theme),
91+
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
92+
"topology_label_map.0.data.0.label", topologyLabel),
93+
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
94+
"topology_label_map.0.data.0.values.0", topologyLabelValue),
8995
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
9096
"time_range.#", "1"),
9197
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
@@ -118,6 +124,8 @@ func TestAccSumologicDashboard_update(t *testing.T) {
118124
description := "Test dashboard description"
119125
theme := "Dark"
120126
refreshInterval := 30
127+
topologyLabel := "service"
128+
topologyLabelValue := "collection-proxy"
121129
literalRangeName := "today"
122130
textPanel := TextPanel{
123131
Key: "text-panel-001",
@@ -147,6 +155,7 @@ func TestAccSumologicDashboard_update(t *testing.T) {
147155
// updated config
148156
newTheme := "Light"
149157
newRefreshInterval := 60
158+
newTopologyLabelValue := "collection-cluster"
150159
newLiteralRangeName := "week"
151160
searchPanel := SumoSearchPanel{
152161
Key: "search-panel-001",
@@ -197,8 +206,8 @@ func TestAccSumologicDashboard_update(t *testing.T) {
197206
CheckDestroy: testAccCheckDashboardDestroy(dashboard),
198207
Steps: []resource.TestStep{
199208
{
200-
Config: dashboardCreateConfig(title, description, theme, refreshInterval, literalRangeName,
201-
textPanel, layout, csvVariable),
209+
Config: dashboardCreateConfig(title, description, theme, refreshInterval,
210+
topologyLabel, topologyLabelValue, literalRangeName, textPanel, layout, csvVariable),
202211
Check: resource.ComposeTestCheckFunc(
203212
testAccCheckDashboardExists("sumologic_dashboard.tf_crud_test", &dashboard, t),
204213
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
@@ -207,6 +216,8 @@ func TestAccSumologicDashboard_update(t *testing.T) {
207216
"refresh_interval", strconv.FormatInt(int64(refreshInterval), 10)),
208217
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
209218
"theme", theme),
219+
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
220+
"topology_label_map.0.data.0.values.0", topologyLabelValue),
210221
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
211222
"time_range.0.begin_bounded_time_range.0.from.0.literal_time_range.0.range_name",
212223
literalRangeName),
@@ -225,8 +236,9 @@ func TestAccSumologicDashboard_update(t *testing.T) {
225236
),
226237
},
227238
{
228-
Config: dashboardUpdateConfig(title, description, newTheme, newRefreshInterval, newLiteralRangeName,
229-
textPanel, searchPanel, newLayout, newVariables),
239+
Config: dashboardUpdateConfig(title, description, newTheme, newRefreshInterval,
240+
topologyLabel, newTopologyLabelValue, newLiteralRangeName, textPanel, searchPanel,
241+
newLayout, newVariables),
230242
Check: resource.ComposeTestCheckFunc(
231243
testAccCheckDashboardExists("sumologic_dashboard.tf_crud_test", &dashboard, t),
232244
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
@@ -235,6 +247,8 @@ func TestAccSumologicDashboard_update(t *testing.T) {
235247
"refresh_interval", strconv.FormatInt(int64(newRefreshInterval), 10)),
236248
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
237249
"theme", newTheme),
250+
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
251+
"topology_label_map.0.data.0.values.0", newTopologyLabelValue),
238252
resource.TestCheckResourceAttr("sumologic_dashboard.tf_crud_test",
239253
"time_range.0.begin_bounded_time_range.0.from.0.literal_time_range.0.range_name",
240254
newLiteralRangeName),
@@ -377,7 +391,8 @@ func dashboardImportConfig(title string) string {
377391
}
378392

379393
func dashboardCreateConfig(title string, description string, theme string, refreshInterval int,
380-
rangeName string, textPanel TextPanel, layout GridLayout, variable Variable) string {
394+
topologyLabel string, topologyLabelValue string, rangeName string, textPanel TextPanel,
395+
layout GridLayout, variable Variable) string {
381396

382397
return fmt.Sprintf(`
383398
data "sumologic_personal_folder" "personalFolder" {}
@@ -387,6 +402,12 @@ func dashboardCreateConfig(title string, description string, theme string, refre
387402
folder_id = data.sumologic_personal_folder.personalFolder.id
388403
refresh_interval = %d
389404
theme = "%s"
405+
topology_label_map {
406+
data {
407+
label = "%s"
408+
values = ["%s"]
409+
}
410+
}
390411
time_range {
391412
begin_bounded_time_range {
392413
from {
@@ -427,15 +448,16 @@ func dashboardCreateConfig(title string, description string, theme string, refre
427448
hide_from_ui = false
428449
}
429450
}`,
430-
title, description, refreshInterval, theme, rangeName, textPanel.Key, textPanel.Title, textPanel.Text,
451+
title, description, refreshInterval, theme, topologyLabel, topologyLabelValue, rangeName,
452+
textPanel.Key, textPanel.Title, textPanel.Text,
431453
layout.LayoutStructures[0].Key, variable.Name, variable.DisplayName, variable.DefaultValue,
432454
variable.SourceDefinition.(CsvVariableSourceDefinition).Values,
433455
)
434456
}
435457

436458
func dashboardUpdateConfig(title string, description string, theme string, refreshInterval int,
437-
rangeName string, textPanel TextPanel, searchPanel SumoSearchPanel, layout GridLayout,
438-
variables []Variable) string {
459+
topologyLabel string, topologyLabelValue string, rangeName string, textPanel TextPanel,
460+
searchPanel SumoSearchPanel, layout GridLayout, variables []Variable) string {
439461

440462
loqQuerySourceDef := variables[1].SourceDefinition.(LogQueryVariableSourceDefinition)
441463
csvSourceDef := variables[0].SourceDefinition.(CsvVariableSourceDefinition)
@@ -448,6 +470,12 @@ func dashboardUpdateConfig(title string, description string, theme string, refre
448470
folder_id = data.sumologic_personal_folder.personalFolder.id
449471
refresh_interval = %d
450472
theme = "%s"
473+
topology_label_map {
474+
data {
475+
label = "%s"
476+
values = ["%s"]
477+
}
478+
}
451479
time_range {
452480
begin_bounded_time_range {
453481
from {
@@ -530,7 +558,7 @@ func dashboardUpdateConfig(title string, description string, theme string, refre
530558
hide_from_ui = false
531559
}
532560
}`,
533-
title, description, refreshInterval, theme, rangeName,
561+
title, description, refreshInterval, theme, topologyLabel, topologyLabelValue, rangeName,
534562
textPanel.Key, textPanel.Title, textPanel.Text,
535563
searchPanel.Key, searchPanel.Title, searchPanel.Description, searchPanel.Queries[0].QueryString,
536564
searchPanel.Queries[0].QueryKey,

website/docs/r/dashboard.html.markdown

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ resource "sumologic_dashboard" "api-dashboard" {
2929
}
3030
}
3131
32+
topology_label_map {
33+
data {
34+
label = "cluster"
35+
values = ["api-prod"]
36+
}
37+
data {
38+
label = "namespace"
39+
values = ["default"]
40+
}
41+
}
42+
3243
## text panel
3344
panel {
3445
text_panel {
@@ -263,6 +274,9 @@ The following arguments are supported:
263274
personal folder.
264275
- `refresh_interval` - (Optional) Interval of time (in seconds) to automatically refresh the dashboard.
265276
- `theme` - (Optional) Theme of the dashboard.
277+
- `topology_label_map` - (Block List, Max: 1, Optional) Topology labels for the dashboard. See
278+
[topology label map schema](#schema-for-topology_label_map)
279+
for details.
266280
- `time_range` - (Block List, Max: 1, Required) Time range of the dashboard. See [time range schema](#schema-for-time_range)
267281
for details.
268282
- `panel` - (Block List, Optional) A list of panels in the dashboard. See [panel schema](#schema-for-panel) for details.
@@ -275,6 +289,12 @@ In addition to all arguments above, the following attributes are exported:
275289

276290
- `id` - The ID of the dashboard.
277291

292+
### Schema for `topology_label_map`
293+
- `data` - (Block List, Required) A list of blocks containing label and it's values.
294+
- `label` - (Required) The name of the topology label.
295+
- `values` - (Required) The values for the topology label.
296+
297+
278298
### Schema for `time_range`
279299
- `complete_literal_time_range` - (Block List, Max: 1, Optional) Literal time range. See
280300
[complete_literal_time_range schema](#schema-for-complete_literal_time_range) for details.

0 commit comments

Comments
 (0)