Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

Commit

Permalink
feat: add json_configuration to support any type of dashboard widget
Browse files Browse the repository at this point in the history
  • Loading branch information
suzuki-shunsuke committed Jan 15, 2020
1 parent 8aaf02f commit ff70236
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 24 deletions.
26 changes: 5 additions & 21 deletions terraform/docs/dashboard_widget.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,6 @@
* [Example](https://github.com/suzuki-shunsuke/go-graylog/blob/master/terraform/example/v0.12/dashboard.tf)
* [Source code](https://github.com/suzuki-shunsuke/go-graylog/blob/master/terraform/graylog/resource_dashboard_widget.go)

```hcl
resource "graylog_dashboard_widget" "test" {
description = "Stream search result count"
dashboard_id = "5b6586000000000000000000"
type = "STREAM_SEARCH_RESULT_COUNT"
stream_search_result_count_configuration {
timerange {
type = "relative"
range = 300
}
stream_id = "5b3983000000000000000000"
query = ""
}
cache_time = 10
}
```

## Supported types

* STREAM_SEARCH_RESULT_COUNT
Expand All @@ -29,11 +12,12 @@ resource "graylog_dashboard_widget" "test" {
* FIELD_CHART
* STATS_COUNT

## Unsupported types
## `json_configuration`

From v10.0.0, the attribute `json_configuration` is added to support any type of dashboard widget.
`json_configuration` should be JSON string.

* STACKED_CHART
* SEARCH_RESULT_COUNT
* etc
Please see the [Example](https://github.com/suzuki-shunsuke/go-graylog/blob/master/terraform/example/v0.12/dashboard.tf).

## Common required arguments

Expand Down
25 changes: 25 additions & 0 deletions terraform/example/v0.12/dashboard.tf
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,28 @@ resource "graylog_dashboard_widget_positions" "test" {
width = 2
}
}

resource "graylog_dashboard_widget" "stacked_chart" {
description = "stacked chart"
dashboard_id = graylog_dashboard.test.id
type = "STACKED_CHART"
cache_time = 10
json_configuration = <<EOF
{
"interval": "hour",
"timerange": {
"type": "relative",
"range": 86400
},
"renderer": "bar",
"interpolation": "linear",
"series": [
{
"query": "",
"field": "AccessMask",
"statistical_function": "count"
}
]
}
EOF
}
50 changes: 47 additions & 3 deletions terraform/graylog/resource_dashboard_widget.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,15 @@ package graylog

import (
"context"
"encoding/json"
"errors"
"fmt"

"github.com/hashicorp/terraform/helper/schema"
"github.com/suzuki-shunsuke/go-jsoneq/jsoneq"
"github.com/suzuki-shunsuke/go-ptr"

"github.com/suzuki-shunsuke/go-graylog/v9"
"github.com/suzuki-shunsuke/go-ptr"
)

func resourceDashboardWidget() *schema.Resource {
Expand Down Expand Up @@ -48,6 +51,13 @@ func resourceDashboardWidget() *schema.Resource {
Computed: true,
},

"json_configuration": {
Type: schema.TypeString,
Optional: true,
DiffSuppressFunc: schemaDiffSuppressJSONString,
ValidateFunc: wrapValidateFunc(validateFuncDashboardWidgetJSONConfiguration),
},

"quick_values_configuration": {
Type: schema.TypeList,
Optional: true,
Expand Down Expand Up @@ -286,6 +296,18 @@ func resourceDashboardWidget() *schema.Resource {
}
}

func validateFuncDashboardWidgetJSONConfiguration(v interface{}, k string) error {
c, err := jsoneq.ConvertByte([]byte(v.(string)))
if err != nil {
return fmt.Errorf("'json_configuration' must be a JSON string: %w", err)
}
_, ok := c.(map[string]interface{})
if !ok {
return errors.New("'json_configuration' should be a JSON string which represents object")
}
return nil
}

func timeRangeSchema() *schema.Schema {
return &schema.Schema{
Type: schema.TypeList,
Expand Down Expand Up @@ -428,7 +450,22 @@ func newDashboardWidget(d *schema.ResourceData) (*graylog.Widget, string, error)
Relative: cfg["relative"].(int),
}
default:
return nil, "", errors.New("unsupported type: " + t)
v, ok := d.GetOk("json_configuration")
if !ok {
return nil, "", fmt.Errorf("for unknown type '%s', 'json_configuration' is required", t)
}
c, err := jsoneq.ConvertByte([]byte(v.(string)))
if err != nil {
return nil, "", fmt.Errorf("failed to parse the 'json_configuration'. 'json_configuration' must be a JSON string '%s': %w", v.(string), err)
}
fields, ok := c.(map[string]interface{})
if !ok {
return nil, "", errors.New("'json_configuration' should be a JSON string which represents object")
}
config = &graylog.WidgetConfigUnknownType{
T: t,
Fields: fields,
}
}
return &graylog.Widget{
Description: d.Get("description").(string),
Expand Down Expand Up @@ -598,7 +635,14 @@ func resourceDashboardWidgetRead(d *schema.ResourceData, m interface{}) error {
return err
}
default:
return errors.New("unsupported type: " + widget.Type())
w := widget.Config.(*graylog.WidgetConfigUnknownType)
b, err := json.Marshal(w.Fields)
if err != nil {
return fmt.Errorf("failed to marshal fields: %w", err)
}
if err := d.Set("json_configuration", string(b)); err != nil {
return err
}
}
return setStrToRD(d, "creator_user_id", widget.CreatorUserID)
}
Expand Down

0 comments on commit ff70236

Please sign in to comment.