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 (elastic#5077) (elastic#5079)

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
(cherry picked from commit caaa4ca)
  • Loading branch information
exekias authored and andrewkroh committed Sep 1, 2017
1 parent 972c913 commit ab16749
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ https://github.com/elastic/beats/compare/v6.0.0-beta2...master[Check the HEAD di
*Affecting all Beats*

- 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 @@ -125,7 +125,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
4 changes: 2 additions & 2 deletions libbeat/template/field_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package template
import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/elastic/beats/libbeat/common"

"github.com/stretchr/testify/assert"
)

func TestField(t *testing.T) {
Expand Down
28 changes: 22 additions & 6 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 @@ -50,9 +49,26 @@ func (f Fields) process(path string, esVersion common.Version) common.MapStr {
} else {
newPath = path + "." + field.Name
}
mapping = common.MapStr{
"properties": field.Fields.process(newPath, esVersion),
mapping = common.MapStr{}

// 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 @@ -62,7 +78,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
51 changes: 51 additions & 0 deletions libbeat/template/fields_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"testing"

"github.com/stretchr/testify/assert"

"github.com/elastic/beats/libbeat/common"
)

func TestHasKey(t *testing.T) {
Expand Down Expand Up @@ -57,3 +59,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 ab16749

Please sign in to comment.