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

libbeat/template: duplicate entries in fields.yml leads to repeated dynamic templates #23240

Merged
merged 3 commits into from
Feb 6, 2021
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
34 changes: 29 additions & 5 deletions libbeat/template/processor.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ type Processor struct {
EsVersion common.Version
Migration bool
ElasticLicensed bool

// dynamicTemplatesMap records which dynamic templates have been added, to prevent duplicates.
dynamicTemplatesMap map[dynamicTemplateKey]common.MapStr
// dynamicTemplates records the dynamic templates in the order they were added.
dynamicTemplates []common.MapStr
}

var (
Expand Down Expand Up @@ -420,7 +425,7 @@ func (p *Processor) object(f *mapping.Field) common.MapStr {
if len(otParams) > 1 {
path = fmt.Sprintf("%s_%s", path, matchingType)
}
addDynamicTemplate(path, pathMatch, dynProperties, matchingType)
p.addDynamicTemplate(path, pathMatch, dynProperties, matchingType)
}

properties := getDefaultProperties(f)
Expand All @@ -436,17 +441,36 @@ func (p *Processor) object(f *mapping.Field) common.MapStr {
return properties
}

func addDynamicTemplate(path string, pathMatch string, properties common.MapStr, matchType string) {
template := common.MapStr{
type dynamicTemplateKey struct {
path string
pathMatch string
matchType string
}

func (p *Processor) addDynamicTemplate(path string, pathMatch string, properties common.MapStr, matchType string) {
key := dynamicTemplateKey{
path: path,
pathMatch: pathMatch,
matchType: matchType,
}
if p.dynamicTemplatesMap == nil {
p.dynamicTemplatesMap = make(map[dynamicTemplateKey]common.MapStr)
} else {
if _, ok := p.dynamicTemplatesMap[key]; ok {
// Dynamic template already added.
return
}
}
dynamicTemplate := common.MapStr{
// Set the path of the field as name
path: common.MapStr{
"mapping": properties,
"match_mapping_type": matchType,
"path_match": pathMatch,
},
}

dynamicTemplates = append(dynamicTemplates, template)
p.dynamicTemplatesMap[key] = dynamicTemplate
p.dynamicTemplates = append(p.dynamicTemplates, dynamicTemplate)
}

func getDefaultProperties(f *mapping.Field) common.MapStr {
Expand Down
6 changes: 3 additions & 3 deletions libbeat/template/processor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,6 @@ func TestProcessor(t *testing.T) {
}

func TestDynamicTemplates(t *testing.T) {
p := &Processor{}
tests := []struct {
field mapping.Field
expected []common.MapStr
Expand Down Expand Up @@ -493,9 +492,10 @@ func TestDynamicTemplates(t *testing.T) {
}

for _, test := range tests {
dynamicTemplates = nil
p := &Processor{}
p.object(&test.field)
assert.Equal(t, test.expected, dynamicTemplates)
p.object(&test.field) // should not be added twice
assert.Equal(t, test.expected, p.dynamicTemplates)
}
}

Expand Down
22 changes: 9 additions & 13 deletions libbeat/template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,6 @@ var (
defaultNumberOfRoutingShards = 30
defaultMaxDocvalueFieldsSearch = 200

// Array to store dynamicTemplate parts in
dynamicTemplates []common.MapStr

defaultFields []string
)

Expand Down Expand Up @@ -147,7 +144,6 @@ func (t *Template) load(fields mapping.Fields) (common.MapStr, error) {
t.Lock()
defer t.Unlock()

dynamicTemplates = nil
defaultFields = nil

var err error
Expand All @@ -164,7 +160,8 @@ func (t *Template) load(fields mapping.Fields) (common.MapStr, error) {
if err := processor.Process(fields, nil, properties); err != nil {
return nil, err
}
output := t.Generate(properties, dynamicTemplates)

output := t.Generate(properties, processor.dynamicTemplates)

return output, nil
}
Expand Down Expand Up @@ -255,17 +252,16 @@ func (t *Template) GetPattern() string {
func (t *Template) Generate(properties common.MapStr, dynamicTemplates []common.MapStr) common.MapStr {
switch t.templateType {
case IndexTemplateLegacy:
return t.generateLegacy(properties)
return t.generateLegacy(properties, dynamicTemplates)
case IndexTemplateComponent:
return t.generateComponent(properties)
return t.generateComponent(properties, dynamicTemplates)
case IndexTemplateIndex:
return t.generateIndex(properties)
default:
return t.generateIndex(properties, dynamicTemplates)
}
return nil
}

func (t *Template) generateLegacy(properties common.MapStr) common.MapStr {
func (t *Template) generateLegacy(properties common.MapStr, dynamicTemplates []common.MapStr) common.MapStr {
keyPattern, patterns := buildPatternSettings(t.esVersion, t.GetPattern())
return common.MapStr{
keyPattern: patterns,
Expand All @@ -284,7 +280,7 @@ func (t *Template) generateLegacy(properties common.MapStr) common.MapStr {
}
}

func (t *Template) generateComponent(properties common.MapStr) common.MapStr {
func (t *Template) generateComponent(properties common.MapStr, dynamicTemplates []common.MapStr) common.MapStr {
return common.MapStr{
"template": common.MapStr{
"mappings": buildMappings(
Expand All @@ -302,8 +298,8 @@ func (t *Template) generateComponent(properties common.MapStr) common.MapStr {
}
}

func (t *Template) generateIndex(properties common.MapStr) common.MapStr {
tmpl := t.generateComponent(properties)
func (t *Template) generateIndex(properties common.MapStr, dynamicTemplates []common.MapStr) common.MapStr {
tmpl := t.generateComponent(properties, dynamicTemplates)
tmpl["priority"] = t.priority
keyPattern, patterns := buildPatternSettings(t.esVersion, t.GetPattern())
tmpl[keyPattern] = patterns
Expand Down