Skip to content

Commit 4f57f44

Browse files
committed
Update export_dashboard script to export full dashboard json doc
In elastic#7239 support to export a dashboard is a added to each Beat. This is expected to be used by users. The export_dashboard script from the Beats repository is expected by the Devs and contributors which want to add new dashboards. In elastic#7224 the dashboards are modified to be stored with decoded json objects for better versioning. This change modifies the export dashboard script so it generates the same decoded output so no additional conversion is needed. Note: The export_dashboard script could need some cleanup but I didn't tackle this in this PR and leave it for later to keep the change to a minimum.
1 parent 2e1b7c8 commit 4f57f44

File tree

2 files changed

+30
-39
lines changed

2 files changed

+30
-39
lines changed

dev-tools/cmd/dashboards/export_dashboards.go

+26-35
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"strings"
1414

1515
"github.com/elastic/beats/libbeat/common"
16+
"github.com/elastic/beats/libbeat/kibana"
1617
)
1718

1819
var exportAPI = "/api/kibana/dashboards/export"
@@ -29,39 +30,6 @@ func makeURL(url, path string, params url.Values) string {
2930
return strings.Join([]string{url, path, "?", params.Encode()}, "")
3031
}
3132

32-
func ExtractIndexPattern(body []byte) ([]byte, error) {
33-
var contents common.MapStr
34-
35-
err := json.Unmarshal(body, &contents)
36-
if err != nil {
37-
return nil, err
38-
}
39-
40-
objects, ok := contents["objects"].([]interface{})
41-
if !ok {
42-
return nil, fmt.Errorf("Key objects not found or wrong type")
43-
}
44-
45-
var result []interface{}
46-
for _, obj := range objects {
47-
_type, ok := obj.(map[string]interface{})["type"].(string)
48-
if !ok {
49-
return nil, fmt.Errorf("type key not found or not string")
50-
}
51-
if _type != "index-pattern" || indexPattern {
52-
result = append(result, obj)
53-
}
54-
}
55-
contents["objects"] = result
56-
57-
newBody, err := json.MarshalIndent(contents, "", " ")
58-
if err != nil {
59-
return nil, fmt.Errorf("Error mashaling: %v", err)
60-
}
61-
62-
return newBody, nil
63-
}
64-
6533
func Export(client *http.Client, conn string, dashboard string, out string) error {
6634
params := url.Values{}
6735

@@ -90,19 +58,42 @@ func Export(client *http.Client, conn string, dashboard string, out string) erro
9058
return fmt.Errorf("HTTP GET %s fails with %s, %s", fullURL, resp.Status, body)
9159
}
9260

93-
body, err = ExtractIndexPattern(body)
61+
data, err := kibana.RemoveIndexPattern(body)
9462
if err != nil {
9563
return fmt.Errorf("fail to extract the index pattern: %v", err)
9664
}
9765

98-
err = ioutil.WriteFile(out, body, 0666)
66+
objects := data["objects"].([]interface{})
67+
for _, obj := range objects {
68+
o := obj.(common.MapStr)
69+
70+
decodeValue(o, "attributes.uiStateJSON")
71+
decodeValue(o, "attributes.visState")
72+
decodeValue(o, "attributes.optionsJSON")
73+
decodeValue(o, "attributes.panelsJSON")
74+
decodeValue(o, "attributes.kibanaSavedObjectMeta.searchSourceJSON")
75+
}
9976

77+
data["objects"] = objects
78+
err = ioutil.WriteFile(out, []byte(data.StringToPrint()), 0666)
10079
if !quiet {
10180
fmt.Printf("The dashboard %s was exported under the %s file\n", dashboard, out)
10281
}
10382
return err
10483
}
10584

85+
func decodeValue(data common.MapStr, key string) {
86+
v, err := data.GetValue(key)
87+
if err != nil {
88+
return
89+
}
90+
s := v.(string)
91+
var d common.MapStr
92+
json.Unmarshal([]byte(s), &d)
93+
94+
data.Put(key, d)
95+
}
96+
10697
func ReadManifest(file string) ([]map[string]string, error) {
10798
cfg, err := common.LoadFile(file)
10899
if err != nil {

libbeat/kibana/dashboard.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ func RemoveIndexPattern(data []byte) (common.MapStr, error) {
1313
var kbResult struct {
1414
// Has to be defined as interface instead of Type directly as it has to be assigned again
1515
// and otherwise would not contain the full content.
16-
Objects []interface{}
16+
Objects []common.MapStr
1717
}
1818

1919
var result common.MapStr
@@ -32,11 +32,11 @@ func RemoveIndexPattern(data []byte) (common.MapStr, error) {
3232
var objs []interface{}
3333

3434
for _, obj := range kbResult.Objects {
35-
t, ok := obj.(map[string]interface{})["type"].(string)
36-
if !ok {
35+
v, err := obj.GetValue("type")
36+
if err != nil {
3737
return nil, fmt.Errorf("type key not found or not string")
3838
}
39-
if t != "index-pattern" {
39+
if v != "index-pattern" {
4040
objs = append(objs, obj)
4141
}
4242
}

0 commit comments

Comments
 (0)