Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace index patterns in TSVB visualizations #7929

Merged
merged 1 commit into from
Aug 9, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ https://github.com/elastic/beats/compare/v6.4.0...master[Check the HEAD diff]
- Fix potential data loss on OS X in spool file by using fcntl with F_FULLFSYNC. {pull}7859[7859]
- Improve fsync on linux, by assuming the kernel resets error flags of failed writes. {pull}7859[7859]
- Remove unix-like permission checks on Windows, so files can be opened. {issue}7849[7849]
- Deregister pipeline loader callback when inputsRunner is stopped. {pull}[7893][7893]
- Deregister pipeline loader callback when inputsRunner is stopped. {pull}7893[7893]
- Replace index patterns in TSVB visualizations. {pull}7929[7929]

*Auditbeat*

Expand Down
5 changes: 4 additions & 1 deletion libbeat/dashboards/es_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,12 @@ func (loader ElasticsearchLoader) importVisualization(file string) error {

if loader.config.Index != "" {
if savedObject, ok := vizContent["kibanaSavedObjectMeta"].(map[string]interface{}); ok {

vizContent["kibanaSavedObjectMeta"] = ReplaceIndexInSavedObject(loader.config.Index, savedObject)
}

if visState, ok := vizContent["visState"].(string); ok {
vizContent["visState"] = ReplaceIndexInVisState(loader.config.Index, visState)
}
}

vizName := strings.TrimSuffix(filepath.Base(file), filepath.Ext(file))
Expand Down
104 changes: 76 additions & 28 deletions libbeat/dashboards/modify_json.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,24 +42,29 @@ type JSONFormat struct {
}

func ReplaceIndexInIndexPattern(index string, content common.MapStr) common.MapStr {
Copy link
Member Author

@jsoriano jsoriano Aug 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes here are not directly related, I have just reorganized the code to have less nesting levels in these functions. Result should be the same.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

++ on the cleanup.

if index == "" {
return content
}

objects, ok := content["objects"].([]interface{})
if !ok {
return content
}

// change index pattern name
for i, object := range objects {
objectMap, ok := object.(map[string]interface{})
if !ok {
continue
}

if index != "" {
// change index pattern name
if objects, ok := content["objects"].([]interface{}); ok {
for i, object := range objects {
if objectMap, ok := object.(map[string]interface{}); ok {
objectMap["id"] = index

if attributes, ok := objectMap["attributes"].(map[string]interface{}); ok {
attributes["title"] = index
objectMap["attributes"] = attributes
}
objects[i] = objectMap
}
}
content["objects"] = objects
objectMap["id"] = index
if attributes, ok := objectMap["attributes"].(map[string]interface{}); ok {
attributes["title"] = index
}
objects[i] = objectMap
}
content["objects"] = objects

return content
}
Expand Down Expand Up @@ -97,28 +102,71 @@ func ReplaceIndexInSavedObject(index string, kibanaSavedObject map[string]interf
return kibanaSavedObject
}

func ReplaceIndexInDashboardObject(index string, content common.MapStr) common.MapStr {
// ReplaceIndexInVisState replaces index appearing in visState params objects
func ReplaceIndexInVisState(index string, visStateJSON string) string {

var visState map[string]interface{}
err := json.Unmarshal([]byte(visStateJSON), &visState)
if err != nil {
logp.Err("Fail to unmarshal visState: %v", err)
return visStateJSON
}

params, ok := visState["params"].(map[string]interface{})
if !ok {
return visStateJSON
}

// Don't set it if it was not set before
if pattern, ok := params["index_pattern"].(string); !ok || len(pattern) == 0 {
return visStateJSON
}

params["index_pattern"] = index

d, err := json.Marshal(visState)
if err != nil {
logp.Err("Fail to marshal visState: %v", err)
return visStateJSON
}

return string(d)
}

// ReplaceIndexInDashboardObject replaces references to the index pattern in dashboard objects
func ReplaceIndexInDashboardObject(index string, content common.MapStr) common.MapStr {
if index == "" {
return content
}
if objects, ok := content["objects"].([]interface{}); ok {
for i, object := range objects {
if objectMap, ok := object.(map[string]interface{}); ok {
if attributes, ok := objectMap["attributes"].(map[string]interface{}); ok {

if kibanaSavedObject, ok := attributes["kibanaSavedObjectMeta"].(map[string]interface{}); ok {
objects, ok := content["objects"].([]interface{})
if !ok {
return content
}

for i, object := range objects {
objectMap, ok := object.(map[string]interface{})
if !ok {
continue
}

attributes, ok := objectMap["attributes"].(map[string]interface{})
if !ok {
continue
}

attributes["kibanaSavedObjectMeta"] = ReplaceIndexInSavedObject(index, kibanaSavedObject)
}
if kibanaSavedObject, ok := attributes["kibanaSavedObjectMeta"].(map[string]interface{}); ok {
attributes["kibanaSavedObjectMeta"] = ReplaceIndexInSavedObject(index, kibanaSavedObject)
}

objectMap["attributes"] = attributes
}
objects[i] = objectMap
}
if visState, ok := attributes["visState"].(string); ok {
attributes["visState"] = ReplaceIndexInVisState(index, visState)
}
content["objects"] = objects

objects[i] = objectMap
}
content["objects"] = objects

return content
}

Expand Down
42 changes: 42 additions & 0 deletions libbeat/dashboards/modify_json_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,45 @@ func TestReplaceStringInDashboard(t *testing.T) {
assert.Equal(t, test.expected, result)
}
}

func TestReplaceIndexInDashboardObject(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, wanted to ask for tests :-)

tests := []struct {
dashboard common.MapStr
pattern string
expected common.MapStr
}{
{
common.MapStr{"objects": []interface{}{map[string]interface{}{
"attributes": map[string]interface{}{
"kibanaSavedObjectMeta": map[string]interface{}{
"searchSourceJSON": "{\"index\":\"metricbeat-*\"}",
},
}}}},
"otherindex-*",
common.MapStr{"objects": []interface{}{map[string]interface{}{
"attributes": map[string]interface{}{
"kibanaSavedObjectMeta": map[string]interface{}{
"searchSourceJSON": "{\"index\":\"otherindex-*\"}",
},
}}}},
},
{
common.MapStr{"objects": []interface{}{map[string]interface{}{
"attributes": map[string]interface{}{
"kibanaSavedObjectMeta": map[string]interface{}{},
"visState": "{\"params\":{\"index_pattern\":\"metricbeat-*\"}}",
}}}},
"otherindex-*",
common.MapStr{"objects": []interface{}{map[string]interface{}{
"attributes": map[string]interface{}{
"kibanaSavedObjectMeta": map[string]interface{}{},
"visState": "{\"params\":{\"index_pattern\":\"otherindex-*\"}}",
}}}},
},
}

for _, test := range tests {
result := ReplaceIndexInDashboardObject(test.pattern, test.dashboard)
assert.Equal(t, test.expected, result)
}
}