Skip to content

Commit

Permalink
Combine fields.yml properties when they are defined in different so…
Browse files Browse the repository at this point in the history
…urces

We define fields with the same root key across several files, this
change ensures all of them are combined in the final index template.

Fixes elastic#5075
  • Loading branch information
exekias committed Sep 1, 2017
1 parent b8fff44 commit d4a6f71
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di
- Register kubernetes `field_format` matcher and remove logger in `Encode` API {pull}4888[4888]
- Add support for `initContainers` in `add_kubernetes_metadata` processor. {issue}4825[4825]
- Fix the `/usr/bin/beatname` script to accept `-d "*"` as a parameter. {issue}5040[5040]
- Combine `fields.yml` properties when they are defined in different sources. {issue}5075[5075]

*Auditbeat*

Expand Down
4 changes: 3 additions & 1 deletion libbeat/template/field.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,9 @@ func (f *Field) text() common.MapStr {
}

if len(f.MultiFields) > 0 {
properties["fields"] = f.MultiFields.process("", f.esVersion)
fields := common.MapStr{}
f.MultiFields.process("", f.esVersion, fields)
properties["fields"] = fields
}

return properties
Expand Down
27 changes: 22 additions & 5 deletions libbeat/template/fields.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package template

import (
"errors"
"strings"

"github.com/elastic/beats/libbeat/common"
Expand All @@ -12,9 +13,7 @@ var (

type Fields []Field

func (f Fields) process(path string, esVersion common.Version) common.MapStr {
output := common.MapStr{}

func (f Fields) process(path string, esVersion common.Version, output common.MapStr) error {
for _, field := range f {

var mapping common.MapStr
Expand Down Expand Up @@ -54,7 +53,25 @@ func (f Fields) process(path string, esVersion common.Version) common.MapStr {
if field.Dynamic.value != nil {
mapping["dynamic"] = field.Dynamic.value
}
mapping["properties"] = field.Fields.process(newPath, esVersion)

// Combine properties with previous field definitions (if any)
properties := common.MapStr{}
key := generateKey(field.Name) + ".properties"
currentProperties, err := output.GetValue(key)
if err == nil {
var ok bool
properties, ok = currentProperties.(common.MapStr)
if !ok {
// This should never happen
return errors.New(key + " is expected to be a MapStr")
}
}

if err := field.Fields.process(newPath, esVersion, properties); err != nil {
return err
}
mapping["properties"] = properties

default:
mapping = field.other()
}
Expand All @@ -64,7 +81,7 @@ func (f Fields) process(path string, esVersion common.Version) common.MapStr {
}
}

return output
return nil
}

// HasKey checks if inside fields the given key exists
Expand Down
50 changes: 50 additions & 0 deletions libbeat/template/fields_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package template
import (
"testing"

"github.com/elastic/beats/libbeat/common"
"github.com/stretchr/testify/assert"
)

Expand Down Expand Up @@ -57,3 +58,52 @@ func TestHasKey(t *testing.T) {
assert.Equal(t, test.result, test.fields.HasKey(test.key))
}
}

func TestPropertiesCombine(t *testing.T) {
// Test common fields are combined even if they come from different objects
fields := Fields{
Field{
Name: "test",
Type: "group",
Fields: Fields{
Field{
Name: "one",
Type: "text",
},
},
},
Field{
Name: "test",
Type: "group",
Fields: Fields{
Field{
Name: "two",
Type: "text",
},
},
},
}

output := common.MapStr{}
version, err := common.NewVersion("6.0.0")
if err != nil {
t.Fatal(err)
}

err = fields.process("", *version, output)
if err != nil {
t.Fatal(err)
}

v1, err := output.GetValue("test.properties.one")
if err != nil {
t.Fatal(err)
}
v2, err := output.GetValue("test.properties.two")
if err != nil {
t.Fatal(err)
}

assert.Equal(t, v1, common.MapStr{"type": "text", "norms": false})
assert.Equal(t, v2, common.MapStr{"type": "text", "norms": false})
}
5 changes: 4 additions & 1 deletion libbeat/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,10 @@ func (t *Template) Load(file string) (common.MapStr, error) {
}

// Start processing at the root
properties := fields.process("", t.esVersion)
properties := common.MapStr{}
if err := fields.process("", t.esVersion, properties); err != nil {
return nil, err
}
output := t.generate(properties, dynamicTemplates)

return output, nil
Expand Down

0 comments on commit d4a6f71

Please sign in to comment.