diff --git a/dev-tools/cmd/dashboards/export_dashboards.go b/dev-tools/cmd/dashboards/export_dashboards.go index 4dfe8709f183..7d8121fc77d3 100644 --- a/dev-tools/cmd/dashboards/export_dashboards.go +++ b/dev-tools/cmd/dashboards/export_dashboards.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/kibana" ) var exportAPI = "/api/kibana/dashboards/export" @@ -29,39 +30,6 @@ func makeURL(url, path string, params url.Values) string { return strings.Join([]string{url, path, "?", params.Encode()}, "") } -func ExtractIndexPattern(body []byte) ([]byte, error) { - var contents common.MapStr - - err := json.Unmarshal(body, &contents) - if err != nil { - return nil, err - } - - objects, ok := contents["objects"].([]interface{}) - if !ok { - return nil, fmt.Errorf("Key objects not found or wrong type") - } - - var result []interface{} - for _, obj := range objects { - _type, ok := obj.(map[string]interface{})["type"].(string) - if !ok { - return nil, fmt.Errorf("type key not found or not string") - } - if _type != "index-pattern" || indexPattern { - result = append(result, obj) - } - } - contents["objects"] = result - - newBody, err := json.MarshalIndent(contents, "", " ") - if err != nil { - return nil, fmt.Errorf("Error mashaling: %v", err) - } - - return newBody, nil -} - func Export(client *http.Client, conn string, dashboard string, out string) error { params := url.Values{} @@ -90,19 +58,42 @@ func Export(client *http.Client, conn string, dashboard string, out string) erro return fmt.Errorf("HTTP GET %s fails with %s, %s", fullURL, resp.Status, body) } - body, err = ExtractIndexPattern(body) + data, err := kibana.RemoveIndexPattern(body) if err != nil { return fmt.Errorf("fail to extract the index pattern: %v", err) } - err = ioutil.WriteFile(out, body, 0666) + objects := data["objects"].([]interface{}) + for _, obj := range objects { + o := obj.(common.MapStr) + + decodeValue(o, "attributes.uiStateJSON") + decodeValue(o, "attributes.visState") + decodeValue(o, "attributes.optionsJSON") + decodeValue(o, "attributes.panelsJSON") + decodeValue(o, "attributes.kibanaSavedObjectMeta.searchSourceJSON") + } + data["objects"] = objects + err = ioutil.WriteFile(out, []byte(data.StringToPrint()), 0666) if !quiet { fmt.Printf("The dashboard %s was exported under the %s file\n", dashboard, out) } return err } +func decodeValue(data common.MapStr, key string) { + v, err := data.GetValue(key) + if err != nil { + return + } + s := v.(string) + var d common.MapStr + json.Unmarshal([]byte(s), &d) + + data.Put(key, d) +} + func ReadManifest(file string) ([]map[string]string, error) { cfg, err := common.LoadFile(file) if err != nil { diff --git a/libbeat/kibana/dashboard.go b/libbeat/kibana/dashboard.go index bb996b362d22..47ba251a72ab 100644 --- a/libbeat/kibana/dashboard.go +++ b/libbeat/kibana/dashboard.go @@ -13,7 +13,7 @@ func RemoveIndexPattern(data []byte) (common.MapStr, error) { var kbResult struct { // Has to be defined as interface instead of Type directly as it has to be assigned again // and otherwise would not contain the full content. - Objects []interface{} + Objects []common.MapStr } var result common.MapStr @@ -32,11 +32,11 @@ func RemoveIndexPattern(data []byte) (common.MapStr, error) { var objs []interface{} for _, obj := range kbResult.Objects { - t, ok := obj.(map[string]interface{})["type"].(string) - if !ok { + v, err := obj.GetValue("type") + if err != nil { return nil, fmt.Errorf("type key not found or not string") } - if t != "index-pattern" { + if v != "index-pattern" { objs = append(objs, obj) } }