From 9f21b967b0e56730de64298e145d5b8249f8e065 Mon Sep 17 00:00:00 2001 From: Andrew Kroh Date: Thu, 31 Oct 2019 14:30:02 -0400 Subject: [PATCH] Add default_field option to fields.yml (#14341) * Add default_field option to fields.yml The number of fields in the Elasticsearch index template's `settings.index.query.default_field` option has grown over time, and is now greater than 1024 in Filebeat (Elastic licensed version). This causes queries to Elasticsearch to fail when a list of fields is not specified because there is a default limit of 1024 in Elasticsearch. This adds a new setting to fields.yml called `default_field` whose value can be true/false (defaults to true). When true the text/keyword fields are added to the `default_field` list (as was the behavior before this change). And when set to false the field is omitted from the default_field list. This adds a test for every beat to check if the default_field list contains more than 1000 fields. The limit is a little less than 1024 because `fields.*` is in the default_field list already and at query time that wildcard will be expanded and count toward the limit. Fixes #14262 * Exclude new zeek datasets from default_field list --- CHANGELOG-developer.next.asciidoc | 1 + auditbeat/main_test.go | 5 ++ filebeat/main_test.go | 5 ++ heartbeat/main_test.go | 5 ++ journalbeat/main_test.go | 6 +- libbeat/libbeat_test.go | 6 ++ libbeat/mapping/field.go | 5 +- libbeat/template/processor.go | 42 +++++---- libbeat/template/processor_test.go | 82 +++++++++++++++++- libbeat/template/template.go | 2 +- libbeat/tests/system/template/template.go | 86 +++++++++++++++++++ metricbeat/main_test.go | 5 ++ packetbeat/main_test.go | 5 ++ winlogbeat/main_test.go | 5 ++ x-pack/auditbeat/main_test.go | 5 ++ x-pack/filebeat/main_test.go | 5 ++ .../module/zeek/connection/_meta/fields.yml | 1 + .../module/zeek/dce_rpc/_meta/fields.yml | 1 + .../module/zeek/dhcp/_meta/fields.yml | 1 + .../module/zeek/dnp3/_meta/fields.yml | 1 + .../filebeat/module/zeek/dpd/_meta/fields.yml | 1 + x-pack/filebeat/module/zeek/fields.go | 2 +- .../filebeat/module/zeek/ftp/_meta/fields.yml | 1 + .../filebeat/module/zeek/irc/_meta/fields.yml | 1 + .../module/zeek/kerberos/_meta/fields.yml | 1 + .../module/zeek/modbus/_meta/fields.yml | 1 + .../module/zeek/mysql/_meta/fields.yml | 1 + .../module/zeek/ntlm/_meta/fields.yml | 1 + .../module/zeek/ocsp/_meta/fields.yml | 1 + .../filebeat/module/zeek/pe/_meta/fields.yml | 1 + .../module/zeek/radius/_meta/fields.yml | 1 + .../filebeat/module/zeek/rdp/_meta/fields.yml | 1 + .../filebeat/module/zeek/rfb/_meta/fields.yml | 1 + .../filebeat/module/zeek/sip/_meta/fields.yml | 1 + .../module/zeek/smb_cmd/_meta/fields.yml | 1 + .../module/zeek/smb_files/_meta/fields.yml | 1 + .../module/zeek/smb_mapping/_meta/fields.yml | 1 + .../module/zeek/smtp/_meta/fields.yml | 1 + .../module/zeek/snmp/_meta/fields.yml | 1 + .../module/zeek/socks/_meta/fields.yml | 1 + .../filebeat/module/zeek/ssh/_meta/fields.yml | 1 + .../filebeat/module/zeek/ssl/_meta/fields.yml | 1 + .../module/zeek/stats/_meta/fields.yml | 1 + .../module/zeek/syslog/_meta/fields.yml | 1 + .../module/zeek/tunnel/_meta/fields.yml | 1 + .../module/zeek/weird/_meta/fields.yml | 1 + .../module/zeek/x509/_meta/fields.yml | 1 + x-pack/functionbeat/main_test.go | 6 +- x-pack/heartbeat/main_test.go | 32 +++++++ x-pack/journalbeat/main_test.go | 32 +++++++ x-pack/libbeat/libbeat_test.go | 6 ++ x-pack/metricbeat/main_test.go | 5 ++ x-pack/packetbeat/cmd/root.go | 3 + x-pack/packetbeat/main_test.go | 32 +++++++ x-pack/winlogbeat/cmd/root.go | 3 + x-pack/winlogbeat/main_test.go | 32 +++++++ 56 files changed, 430 insertions(+), 23 deletions(-) create mode 100644 libbeat/tests/system/template/template.go create mode 100644 x-pack/heartbeat/main_test.go create mode 100644 x-pack/journalbeat/main_test.go create mode 100644 x-pack/packetbeat/main_test.go create mode 100644 x-pack/winlogbeat/main_test.go diff --git a/CHANGELOG-developer.next.asciidoc b/CHANGELOG-developer.next.asciidoc index aea99565b69..3510a97e842 100644 --- a/CHANGELOG-developer.next.asciidoc +++ b/CHANGELOG-developer.next.asciidoc @@ -58,3 +58,4 @@ The list below covers the major changes between 7.0.0-rc2 and master only. - Makefile included in generator copies files from beats repository using `git archive` instead of cp. {pull}13193[13193] - Strip debug symbols from binaries to reduce binary sizes. {issue}12768[12768] - Compare event by event in `testadata` framework to avoid sorting problems {pull}13747[13747] +- Added a `default_field` option to fields in fields.yml to offer a way to exclude fields from the default_field list. {issue}14262[14262] {pull}14341[14341] diff --git a/auditbeat/main_test.go b/auditbeat/main_test.go index f6540e0724d..741b334a61e 100644 --- a/auditbeat/main_test.go +++ b/auditbeat/main_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/elastic/beats/auditbeat/cmd" + "github.com/elastic/beats/libbeat/tests/system/template" ) var systemTest *bool @@ -41,3 +42,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/filebeat/main_test.go b/filebeat/main_test.go index 27db61da1b8..0079fda68ca 100644 --- a/filebeat/main_test.go +++ b/filebeat/main_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/elastic/beats/filebeat/cmd" + "github.com/elastic/beats/libbeat/tests/system/template" ) var systemTest *bool @@ -40,3 +41,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/heartbeat/main_test.go b/heartbeat/main_test.go index 11c35df0758..8303bf40983 100644 --- a/heartbeat/main_test.go +++ b/heartbeat/main_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/elastic/beats/heartbeat/cmd" + "github.com/elastic/beats/libbeat/tests/system/template" ) var systemTest *bool @@ -40,3 +41,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/journalbeat/main_test.go b/journalbeat/main_test.go index c6eb420ed2c..9059e843c86 100644 --- a/journalbeat/main_test.go +++ b/journalbeat/main_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/elastic/beats/journalbeat/cmd" + "github.com/elastic/beats/libbeat/tests/system/template" ) var systemTest *bool @@ -37,8 +38,11 @@ func init() { // Test started when the test binary is started. Only calls main. func TestSystem(t *testing.T) { - if *systemTest { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/libbeat/libbeat_test.go b/libbeat/libbeat_test.go index 7b9cc9e4ee5..a78ed01e567 100644 --- a/libbeat/libbeat_test.go +++ b/libbeat/libbeat_test.go @@ -20,6 +20,8 @@ package main import ( "flag" "testing" + + "github.com/elastic/beats/libbeat/tests/system/template" ) var systemTest *bool @@ -37,3 +39,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, "mockbeat") +} diff --git a/libbeat/mapping/field.go b/libbeat/mapping/field.go index 0dabe3f340a..dd226201a76 100644 --- a/libbeat/mapping/field.go +++ b/libbeat/mapping/field.go @@ -76,8 +76,9 @@ type Field struct { UrlTemplate []VersionizedString `config:"url_template"` OpenLinkInCurrentTab *bool `config:"open_link_in_current_tab"` - Overwrite bool `config:"overwrite"` - Path string + Overwrite bool `config:"overwrite"` + DefaultField *bool `config:"default_field"` + Path string } // ObjectTypeCfg defines type and configuration of object attributes diff --git a/libbeat/template/processor.go b/libbeat/template/processor.go index 72dae2a6eae..48593ad4317 100644 --- a/libbeat/template/processor.go +++ b/libbeat/template/processor.go @@ -38,15 +38,27 @@ var ( const scalingFactorKey = "scalingFactor" +type fieldState struct { + DefaultField bool + Path string +} + // Process recursively processes the given fields and writes the template in the given output -func (p *Processor) Process(fields mapping.Fields, path string, output common.MapStr) error { - for _, field := range fields { +func (p *Processor) Process(fields mapping.Fields, state *fieldState, output common.MapStr) error { + if state == nil { + // Set the defaults. + state = &fieldState{DefaultField: true} + } + for _, field := range fields { if field.Name == "" { continue } - field.Path = path + field.Path = state.Path + if field.DefaultField == nil { + field.DefaultField = &state.DefaultField + } var indexMapping common.MapStr switch field.Type { @@ -69,12 +81,6 @@ func (p *Processor) Process(fields mapping.Fields, path string, output common.Ma case "alias": indexMapping = p.alias(&field) case "group": - var newPath string - if path == "" { - newPath = field.Name - } else { - newPath = path + "." + field.Name - } indexMapping = common.MapStr{} if field.Dynamic.Value != nil { indexMapping["dynamic"] = field.Dynamic.Value @@ -93,7 +99,11 @@ func (p *Processor) Process(fields mapping.Fields, path string, output common.Ma } } - if err := p.Process(field.Fields, newPath, properties); err != nil { + groupState := &fieldState{Path: field.Name, DefaultField: *field.DefaultField} + if state.Path != "" { + groupState.Path = state.Path + "." + field.Name + } + if err := p.Process(field.Fields, groupState, properties); err != nil { return err } indexMapping["properties"] = properties @@ -101,9 +111,11 @@ func (p *Processor) Process(fields mapping.Fields, path string, output common.Ma indexMapping = p.other(&field) } - switch field.Type { - case "", "keyword", "text": - addToDefaultFields(&field) + if *field.DefaultField { + switch field.Type { + case "", "keyword", "text": + addToDefaultFields(&field) + } } if len(indexMapping) > 0 { @@ -207,7 +219,7 @@ func (p *Processor) keyword(f *mapping.Field) common.MapStr { if len(f.MultiFields) > 0 { fields := common.MapStr{} - p.Process(f.MultiFields, "", fields) + p.Process(f.MultiFields, nil, fields) property["fields"] = fields } @@ -243,7 +255,7 @@ func (p *Processor) text(f *mapping.Field) common.MapStr { if len(f.MultiFields) > 0 { fields := common.MapStr{} - p.Process(f.MultiFields, "", fields) + p.Process(f.MultiFields, nil, fields) properties["fields"] = fields } diff --git a/libbeat/template/processor_test.go b/libbeat/template/processor_test.go index e97bb35219e..dd316957e24 100644 --- a/libbeat/template/processor_test.go +++ b/libbeat/template/processor_test.go @@ -522,7 +522,7 @@ func TestPropertiesCombine(t *testing.T) { } p := Processor{EsVersion: *version} - err = p.Process(fields, "", output) + err = p.Process(fields, nil, output) if err != nil { t.Fatal(err) } @@ -570,7 +570,7 @@ func TestProcessNoName(t *testing.T) { } p := Processor{EsVersion: *version} - err = p.Process(fields, "", output) + err = p.Process(fields, nil, output) if err != nil { t.Fatal(err) } @@ -589,3 +589,81 @@ func TestProcessNoName(t *testing.T) { assert.Equal(t, expectedOutput, output) } + +func TestProcessDefaultField(t *testing.T) { + // NOTE: This package stores global state. It must be cleared before this test. + defaultFields = nil + + var ( + enableDefaultField = true + disableDefaultField = false + ) + + fields := mapping.Fields{ + // By default foo will be included in default_field. + mapping.Field{ + Name: "foo", + Type: "keyword", + }, + // bar is explicitly set to be included in default_field. + mapping.Field{ + Name: "bar", + Type: "keyword", + DefaultField: &enableDefaultField, + }, + // baz is explicitly set to be excluded from default_field. + mapping.Field{ + Name: "baz", + Type: "keyword", + DefaultField: &disableDefaultField, + }, + mapping.Field{ + Name: "nested", + Type: "group", + DefaultField: &enableDefaultField, + Fields: mapping.Fields{ + mapping.Field{ + Name: "bar", + Type: "keyword", + }, + }, + }, + // The nested group is disabled default_field but one of the children + // has explicitly requested to be included. + mapping.Field{ + Name: "nested", + Type: "group", + DefaultField: &disableDefaultField, + Fields: mapping.Fields{ + mapping.Field{ + Name: "foo", + Type: "keyword", + DefaultField: &enableDefaultField, + }, + mapping.Field{ + Name: "baz", + Type: "keyword", + }, + }, + }, + } + + version, err := common.NewVersion("7.0.0") + if err != nil { + t.Fatal(err) + } + + p := Processor{EsVersion: *version} + output := common.MapStr{} + if err = p.Process(fields, nil, output); err != nil { + t.Fatal(err) + } + + assert.Len(t, defaultFields, 4) + assert.Contains(t, defaultFields, + "foo", + "bar", + "nested.foo", + "nested.bar", + ) +} diff --git a/libbeat/template/template.go b/libbeat/template/template.go index ecdc38d0d5f..1bd23009927 100644 --- a/libbeat/template/template.go +++ b/libbeat/template/template.go @@ -155,7 +155,7 @@ func (t *Template) load(fields mapping.Fields) (common.MapStr, error) { // Start processing at the root properties := common.MapStr{} processor := Processor{EsVersion: t.esVersion, Migration: t.migration} - if err := processor.Process(fields, "", properties); err != nil { + if err := processor.Process(fields, nil, properties); err != nil { return nil, err } output := t.Generate(properties, dynamicTemplates) diff --git a/libbeat/tests/system/template/template.go b/libbeat/tests/system/template/template.go new file mode 100644 index 00000000000..33d690e6ad6 --- /dev/null +++ b/libbeat/tests/system/template/template.go @@ -0,0 +1,86 @@ +// Licensed to Elasticsearch B.V. under one or more contributor +// license agreements. See the NOTICE file distributed with +// this work for additional information regarding copyright +// ownership. Elasticsearch B.V. licenses this file to you under +// the Apache License, Version 2.0 (the "License"); you may +// not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + +package template + +import ( + "strings" + "testing" + + "github.com/elastic/beats/libbeat/asset" + "github.com/elastic/beats/libbeat/common" + "github.com/elastic/beats/libbeat/template" + "github.com/elastic/beats/libbeat/version" +) + +// MaxDefaultFieldLength is the limit on the number of default_field values +// allowed by the test. This is less that the 1024 limit of Elasticsearch to +// give a little room for custom fields and the expansion of `fields.*`. +const MaxDefaultFieldLength = 1000 + +// TestTemplate executes tests on the Beat's index template. +func TestTemplate(t *testing.T, beatName string) { + t.Run("default_field length", testTemplateDefaultFieldLength(beatName)) +} + +// testTemplateDefaultFieldLength constructs a template based on the embedded +// fields.yml data verifies that the length is less than 1000. +func testTemplateDefaultFieldLength(beatName string) func(*testing.T) { + return func(t *testing.T) { + // 7.0 is when default_field was introduced. + esVersion, err := common.NewVersion("7.0.0") + if err != nil { + t.Fatal(err) + } + + // Generate a template based on the embedded fields.yml data. + tmpl, err := template.New(version.GetDefaultVersion(), beatName, *esVersion, template.TemplateConfig{}, false) + if err != nil { + t.Fatal(err) + } + + fieldsBytes, err := asset.GetFields(beatName) + if err != nil { + t.Fatal("Failed to get embedded fields.yml asset data:", err) + } + + fields, err := tmpl.LoadBytes(fieldsBytes) + if err != nil { + t.Fatal("Failed to load template bytes:", err) + } + + templateMap := tmpl.Generate(fields, nil) + + v, _ := templateMap.GetValue("settings.index.query.default_field") + defaultValue, ok := v.([]string) + if !ok { + t.Fatalf("settings.index.query.default_field value has an unexpected type: %T", v) + } + + if len(defaultValue) > MaxDefaultFieldLength { + t.Fatalf("Too many fields (%d>%d) in %v index template"+ + "settings.index.query.default_field for comfort. By default "+ + "Elasticsearch has a limit of 1024 fields in a query so we need "+ + "to keep the number of fields below 1024. Adding 'default_field: "+ + "false' to fields or groups in a fields.yml can be used to "+ + "reduce the number of text/keyword fields that end up in "+ + "default_field.", + len(defaultValue), MaxDefaultFieldLength, strings.Title(beatName)) + } + t.Logf("%v template has %d fields in default_field.", strings.Title(beatName), len(defaultValue)) + } +} diff --git a/metricbeat/main_test.go b/metricbeat/main_test.go index 41f3d5634a4..8680f3b3893 100644 --- a/metricbeat/main_test.go +++ b/metricbeat/main_test.go @@ -23,6 +23,7 @@ import ( "flag" "testing" + "github.com/elastic/beats/libbeat/tests/system/template" "github.com/elastic/beats/metricbeat/cmd" ) @@ -40,3 +41,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/packetbeat/main_test.go b/packetbeat/main_test.go index 50b2af45c7c..a6c61e24924 100644 --- a/packetbeat/main_test.go +++ b/packetbeat/main_test.go @@ -23,6 +23,7 @@ import ( "flag" "testing" + "github.com/elastic/beats/libbeat/tests/system/template" "github.com/elastic/beats/packetbeat/cmd" ) @@ -40,3 +41,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/winlogbeat/main_test.go b/winlogbeat/main_test.go index 545df43f7a8..f918a07f9a3 100644 --- a/winlogbeat/main_test.go +++ b/winlogbeat/main_test.go @@ -22,6 +22,7 @@ import ( "flag" "testing" + "github.com/elastic/beats/libbeat/tests/system/template" "github.com/elastic/beats/winlogbeat/cmd" ) @@ -40,3 +41,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/x-pack/auditbeat/main_test.go b/x-pack/auditbeat/main_test.go index 1eca7b4f54d..cd5e3228c3e 100644 --- a/x-pack/auditbeat/main_test.go +++ b/x-pack/auditbeat/main_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/elastic/beats/auditbeat/cmd" + "github.com/elastic/beats/libbeat/tests/system/template" ) var systemTest *bool @@ -28,3 +29,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/x-pack/filebeat/main_test.go b/x-pack/filebeat/main_test.go index 83e01532aed..d652032181a 100644 --- a/x-pack/filebeat/main_test.go +++ b/x-pack/filebeat/main_test.go @@ -9,6 +9,7 @@ import ( "testing" "github.com/elastic/beats/filebeat/cmd" + "github.com/elastic/beats/libbeat/tests/system/template" ) var systemTest *bool @@ -25,3 +26,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/x-pack/filebeat/module/zeek/connection/_meta/fields.yml b/x-pack/filebeat/module/zeek/connection/_meta/fields.yml index d25c6b268a4..f628b178c81 100644 --- a/x-pack/filebeat/module/zeek/connection/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/connection/_meta/fields.yml @@ -1,5 +1,6 @@ - name: connection type: group + default_field: false description: > Fields exported by the Zeek Connection log fields: diff --git a/x-pack/filebeat/module/zeek/dce_rpc/_meta/fields.yml b/x-pack/filebeat/module/zeek/dce_rpc/_meta/fields.yml index 227741faadb..77316f81e8d 100644 --- a/x-pack/filebeat/module/zeek/dce_rpc/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/dce_rpc/_meta/fields.yml @@ -1,5 +1,6 @@ - name: dce_rpc type: group + default_field: false description: > Fields exported by the Zeek DCE_RPC log fields: diff --git a/x-pack/filebeat/module/zeek/dhcp/_meta/fields.yml b/x-pack/filebeat/module/zeek/dhcp/_meta/fields.yml index 71bd7a50114..d90e6088d1a 100644 --- a/x-pack/filebeat/module/zeek/dhcp/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/dhcp/_meta/fields.yml @@ -1,5 +1,6 @@ - name: dhcp type: group + default_field: false description: > Fields exported by the Zeek DHCP log fields: diff --git a/x-pack/filebeat/module/zeek/dnp3/_meta/fields.yml b/x-pack/filebeat/module/zeek/dnp3/_meta/fields.yml index 348d281317c..01c71a916eb 100644 --- a/x-pack/filebeat/module/zeek/dnp3/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/dnp3/_meta/fields.yml @@ -1,5 +1,6 @@ - name: dnp3 type: group + default_field: false description: > Fields exported by the Zeek SSH log fields: diff --git a/x-pack/filebeat/module/zeek/dpd/_meta/fields.yml b/x-pack/filebeat/module/zeek/dpd/_meta/fields.yml index 7fa392a306b..c924c27baf8 100644 --- a/x-pack/filebeat/module/zeek/dpd/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/dpd/_meta/fields.yml @@ -1,5 +1,6 @@ - name: dpd type: group + default_field: false description: > Fields exported by the Zeek DPD log fields: diff --git a/x-pack/filebeat/module/zeek/fields.go b/x-pack/filebeat/module/zeek/fields.go index fdcb0f5e409..5f6017c18a8 100644 --- a/x-pack/filebeat/module/zeek/fields.go +++ b/x-pack/filebeat/module/zeek/fields.go @@ -19,5 +19,5 @@ func init() { // AssetZeek returns asset data. // This is the base64 encoded gzipped contents of module/zeek. func AssetZeek() string { - return "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" + return "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" } diff --git a/x-pack/filebeat/module/zeek/ftp/_meta/fields.yml b/x-pack/filebeat/module/zeek/ftp/_meta/fields.yml index 05a1a2f70a6..3c36e53e301 100644 --- a/x-pack/filebeat/module/zeek/ftp/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/ftp/_meta/fields.yml @@ -1,5 +1,6 @@ - name: ftp type: group + default_field: false description: > Fields exported by the Zeek FTP log fields: diff --git a/x-pack/filebeat/module/zeek/irc/_meta/fields.yml b/x-pack/filebeat/module/zeek/irc/_meta/fields.yml index e108aa6db83..5981bea032f 100644 --- a/x-pack/filebeat/module/zeek/irc/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/irc/_meta/fields.yml @@ -1,5 +1,6 @@ - name: irc type: group + default_field: false description: > Fields exported by the Zeek IRC log fields: diff --git a/x-pack/filebeat/module/zeek/kerberos/_meta/fields.yml b/x-pack/filebeat/module/zeek/kerberos/_meta/fields.yml index 627d7a2f37a..6d247788950 100644 --- a/x-pack/filebeat/module/zeek/kerberos/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/kerberos/_meta/fields.yml @@ -1,5 +1,6 @@ - name: kerberos type: group + default_field: false description: > Fields exported by the Zeek Kerberos log fields: diff --git a/x-pack/filebeat/module/zeek/modbus/_meta/fields.yml b/x-pack/filebeat/module/zeek/modbus/_meta/fields.yml index 7ebd45dbd50..3a8e70f85d7 100644 --- a/x-pack/filebeat/module/zeek/modbus/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/modbus/_meta/fields.yml @@ -1,5 +1,6 @@ - name: modbus type: group + default_field: false description: > Fields exported by the Zeek modbus log. fields: diff --git a/x-pack/filebeat/module/zeek/mysql/_meta/fields.yml b/x-pack/filebeat/module/zeek/mysql/_meta/fields.yml index 1fbc5b79268..d779391f0d8 100644 --- a/x-pack/filebeat/module/zeek/mysql/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/mysql/_meta/fields.yml @@ -1,5 +1,6 @@ - name: mysql type: group + default_field: false description: > Fields exported by the Zeek MySQL log. fields: diff --git a/x-pack/filebeat/module/zeek/ntlm/_meta/fields.yml b/x-pack/filebeat/module/zeek/ntlm/_meta/fields.yml index c3ed94c2792..35b383c2579 100644 --- a/x-pack/filebeat/module/zeek/ntlm/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/ntlm/_meta/fields.yml @@ -1,5 +1,6 @@ - name: ntlm type: group + default_field: false description: > Fields exported by the Zeek NTLM log. fields: diff --git a/x-pack/filebeat/module/zeek/ocsp/_meta/fields.yml b/x-pack/filebeat/module/zeek/ocsp/_meta/fields.yml index b445e59a43a..4e98f4c66f2 100644 --- a/x-pack/filebeat/module/zeek/ocsp/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/ocsp/_meta/fields.yml @@ -1,5 +1,6 @@ - name: ocsp type: group + default_field: false description: | Fields exported by the Zeek OCSP log Online Certificate Status Protocol (OCSP). Only created if policy script is loaded. diff --git a/x-pack/filebeat/module/zeek/pe/_meta/fields.yml b/x-pack/filebeat/module/zeek/pe/_meta/fields.yml index c07a1c9713e..b862b77cad8 100644 --- a/x-pack/filebeat/module/zeek/pe/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/pe/_meta/fields.yml @@ -1,5 +1,6 @@ - name: pe type: group + default_field: false description: > Fields exported by the Zeek pe log. fields: diff --git a/x-pack/filebeat/module/zeek/radius/_meta/fields.yml b/x-pack/filebeat/module/zeek/radius/_meta/fields.yml index b3c8cbbd326..a71dd2f0361 100644 --- a/x-pack/filebeat/module/zeek/radius/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/radius/_meta/fields.yml @@ -1,5 +1,6 @@ - name: radius type: group + default_field: false description: > Fields exported by the Zeek Radius log. fields: diff --git a/x-pack/filebeat/module/zeek/rdp/_meta/fields.yml b/x-pack/filebeat/module/zeek/rdp/_meta/fields.yml index 14303d8f668..fc7566a3b7d 100644 --- a/x-pack/filebeat/module/zeek/rdp/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/rdp/_meta/fields.yml @@ -1,5 +1,6 @@ - name: rdp type: group + default_field: false description: > Fields exported by the Zeek RDP log. fields: diff --git a/x-pack/filebeat/module/zeek/rfb/_meta/fields.yml b/x-pack/filebeat/module/zeek/rfb/_meta/fields.yml index 7b07b854c63..16e11029736 100644 --- a/x-pack/filebeat/module/zeek/rfb/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/rfb/_meta/fields.yml @@ -1,5 +1,6 @@ - name: rfb type: group + default_field: false description: > Fields exported by the Zeek RFB log. fields: diff --git a/x-pack/filebeat/module/zeek/sip/_meta/fields.yml b/x-pack/filebeat/module/zeek/sip/_meta/fields.yml index c974eb84582..09e40c632a1 100644 --- a/x-pack/filebeat/module/zeek/sip/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/sip/_meta/fields.yml @@ -1,5 +1,6 @@ - name: sip type: group + default_field: false description: > Fields exported by the Zeek SIP log. fields: diff --git a/x-pack/filebeat/module/zeek/smb_cmd/_meta/fields.yml b/x-pack/filebeat/module/zeek/smb_cmd/_meta/fields.yml index 5e9f21c04ca..820ca0e6d69 100644 --- a/x-pack/filebeat/module/zeek/smb_cmd/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/smb_cmd/_meta/fields.yml @@ -1,5 +1,6 @@ - name: smb_cmd type: group + default_field: false description: > Fields exported by the Zeek smb_cmd log. fields: diff --git a/x-pack/filebeat/module/zeek/smb_files/_meta/fields.yml b/x-pack/filebeat/module/zeek/smb_files/_meta/fields.yml index e54570c7de8..c41211edc71 100644 --- a/x-pack/filebeat/module/zeek/smb_files/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/smb_files/_meta/fields.yml @@ -1,5 +1,6 @@ - name: smb_files type: group + default_field: false description: > Fields exported by the Zeek SMB Files log. fields: diff --git a/x-pack/filebeat/module/zeek/smb_mapping/_meta/fields.yml b/x-pack/filebeat/module/zeek/smb_mapping/_meta/fields.yml index af27ed825d8..64ffaadb848 100644 --- a/x-pack/filebeat/module/zeek/smb_mapping/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/smb_mapping/_meta/fields.yml @@ -1,5 +1,6 @@ - name: smb_mapping type: group + default_field: false description: > Fields exported by the Zeek SMB_Mapping log. fields: diff --git a/x-pack/filebeat/module/zeek/smtp/_meta/fields.yml b/x-pack/filebeat/module/zeek/smtp/_meta/fields.yml index 000718b6861..48894bf04a1 100644 --- a/x-pack/filebeat/module/zeek/smtp/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/smtp/_meta/fields.yml @@ -1,5 +1,6 @@ - name: smtp type: group + default_field: false description: > Fields exported by the Zeek SMTP log. fields: diff --git a/x-pack/filebeat/module/zeek/snmp/_meta/fields.yml b/x-pack/filebeat/module/zeek/snmp/_meta/fields.yml index 318cdd1154d..0ec5b677d24 100644 --- a/x-pack/filebeat/module/zeek/snmp/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/snmp/_meta/fields.yml @@ -1,5 +1,6 @@ - name: snmp type: group + default_field: false description: > Fields exported by the Zeek SNMP log. fields: diff --git a/x-pack/filebeat/module/zeek/socks/_meta/fields.yml b/x-pack/filebeat/module/zeek/socks/_meta/fields.yml index c7a68e0704f..31e80f4990a 100644 --- a/x-pack/filebeat/module/zeek/socks/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/socks/_meta/fields.yml @@ -1,5 +1,6 @@ - name: socks type: group + default_field: false description: > Fields exported by the Zeek SOCKS log. fields: diff --git a/x-pack/filebeat/module/zeek/ssh/_meta/fields.yml b/x-pack/filebeat/module/zeek/ssh/_meta/fields.yml index e196b5a8823..5097e8769c5 100644 --- a/x-pack/filebeat/module/zeek/ssh/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/ssh/_meta/fields.yml @@ -1,5 +1,6 @@ - name: ssh type: group + default_field: false description: > Fields exported by the Zeek SSH log. fields: diff --git a/x-pack/filebeat/module/zeek/ssl/_meta/fields.yml b/x-pack/filebeat/module/zeek/ssl/_meta/fields.yml index f956125bf65..604c9ab6f4d 100644 --- a/x-pack/filebeat/module/zeek/ssl/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/ssl/_meta/fields.yml @@ -1,5 +1,6 @@ - name: ssl type: group + default_field: false description: > Fields exported by the Zeek SSL log. fields: diff --git a/x-pack/filebeat/module/zeek/stats/_meta/fields.yml b/x-pack/filebeat/module/zeek/stats/_meta/fields.yml index b075be42dec..c043adccecc 100644 --- a/x-pack/filebeat/module/zeek/stats/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/stats/_meta/fields.yml @@ -1,5 +1,6 @@ - name: stats type: group + default_field: false description: > Fields exported by the Zeek stats log. fields: diff --git a/x-pack/filebeat/module/zeek/syslog/_meta/fields.yml b/x-pack/filebeat/module/zeek/syslog/_meta/fields.yml index 0a4530cd48e..8f5f9f0e757 100644 --- a/x-pack/filebeat/module/zeek/syslog/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/syslog/_meta/fields.yml @@ -1,5 +1,6 @@ - name: syslog type: group + default_field: false description: > Fields exported by the Zeek syslog log. fields: diff --git a/x-pack/filebeat/module/zeek/tunnel/_meta/fields.yml b/x-pack/filebeat/module/zeek/tunnel/_meta/fields.yml index 85152f404f9..bef9c6e9da8 100644 --- a/x-pack/filebeat/module/zeek/tunnel/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/tunnel/_meta/fields.yml @@ -1,5 +1,6 @@ - name: tunnel type: group + default_field: false description: > Fields exported by the Zeek SSH log. fields: diff --git a/x-pack/filebeat/module/zeek/weird/_meta/fields.yml b/x-pack/filebeat/module/zeek/weird/_meta/fields.yml index 057230dacd7..72a0791a7b2 100644 --- a/x-pack/filebeat/module/zeek/weird/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/weird/_meta/fields.yml @@ -1,5 +1,6 @@ - name: weird type: group + default_field: false description: > Fields exported by the Zeek Weird log. fields: diff --git a/x-pack/filebeat/module/zeek/x509/_meta/fields.yml b/x-pack/filebeat/module/zeek/x509/_meta/fields.yml index c8c152c46c7..bc08ad5c973 100644 --- a/x-pack/filebeat/module/zeek/x509/_meta/fields.yml +++ b/x-pack/filebeat/module/zeek/x509/_meta/fields.yml @@ -1,5 +1,6 @@ - name: x509 type: group + default_field: false description: > Fields exported by the Zeek x509 log. fields: diff --git a/x-pack/functionbeat/main_test.go b/x-pack/functionbeat/main_test.go index 1d1c2c79a21..776ea131f57 100644 --- a/x-pack/functionbeat/main_test.go +++ b/x-pack/functionbeat/main_test.go @@ -10,6 +10,7 @@ import ( "flag" "testing" + "github.com/elastic/beats/libbeat/tests/system/template" "github.com/elastic/beats/x-pack/functionbeat/manager/cmd" ) @@ -24,8 +25,11 @@ func init() { // Test started when the test binary is started. Only calls main. func TestSystem(t *testing.T) { - if *systemTest { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/x-pack/heartbeat/main_test.go b/x-pack/heartbeat/main_test.go new file mode 100644 index 00000000000..b7f6f28bbca --- /dev/null +++ b/x-pack/heartbeat/main_test.go @@ -0,0 +1,32 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. +package main + +// This file is mandatory as otherwise the heartbeat.test binary is not generated correctly. +import ( + "flag" + "testing" + + "github.com/elastic/beats/heartbeat/cmd" + "github.com/elastic/beats/libbeat/tests/system/template" +) + +var systemTest *bool + +func init() { + systemTest = flag.Bool("systemTest", false, "Set to true when running system tests") + cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("systemTest")) + cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("test.coverprofile")) +} + +// Test started when the test binary is started. Only calls main. +func TestSystem(t *testing.T) { + if *systemTest { + main() + } +} + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/x-pack/journalbeat/main_test.go b/x-pack/journalbeat/main_test.go new file mode 100644 index 00000000000..26522d0cf42 --- /dev/null +++ b/x-pack/journalbeat/main_test.go @@ -0,0 +1,32 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. +package main + +// This file is mandatory as otherwise the journalbeat.test binary is not generated correctly. +import ( + "flag" + "testing" + + "github.com/elastic/beats/journalbeat/cmd" + "github.com/elastic/beats/libbeat/tests/system/template" +) + +var systemTest *bool + +func init() { + systemTest = flag.Bool("systemTest", false, "Set to true when running system tests") + cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("systemTest")) + cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("test.coverprofile")) +} + +// Test started when the test binary is started. Only calls main. +func TestSystem(t *testing.T) { + if *systemTest { + main() + } +} + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/x-pack/libbeat/libbeat_test.go b/x-pack/libbeat/libbeat_test.go index e8dc1903dd4..22ec0442583 100644 --- a/x-pack/libbeat/libbeat_test.go +++ b/x-pack/libbeat/libbeat_test.go @@ -7,6 +7,8 @@ package main import ( "flag" "testing" + + "github.com/elastic/beats/libbeat/tests/system/template" ) var systemTest *bool @@ -24,3 +26,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, "mockbeat") +} diff --git a/x-pack/metricbeat/main_test.go b/x-pack/metricbeat/main_test.go index c022c48402c..5310cdc1239 100644 --- a/x-pack/metricbeat/main_test.go +++ b/x-pack/metricbeat/main_test.go @@ -8,6 +8,7 @@ import ( "flag" "testing" + "github.com/elastic/beats/libbeat/tests/system/template" "github.com/elastic/beats/x-pack/metricbeat/cmd" ) @@ -25,3 +26,7 @@ func TestSystem(t *testing.T) { main() } } + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/x-pack/packetbeat/cmd/root.go b/x-pack/packetbeat/cmd/root.go index 1ddfbdcfd1b..3e399023a22 100644 --- a/x-pack/packetbeat/cmd/root.go +++ b/x-pack/packetbeat/cmd/root.go @@ -9,6 +9,9 @@ import ( xpackcmd "github.com/elastic/beats/x-pack/libbeat/cmd" ) +// Name of this beat. +var Name = cmd.Name + // RootCmd to handle beats cli var RootCmd = cmd.RootCmd diff --git a/x-pack/packetbeat/main_test.go b/x-pack/packetbeat/main_test.go new file mode 100644 index 00000000000..e0026fea538 --- /dev/null +++ b/x-pack/packetbeat/main_test.go @@ -0,0 +1,32 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. +package main + +// This file is mandatory as otherwise the packetbeat.test binary is not generated correctly. +import ( + "flag" + "testing" + + "github.com/elastic/beats/libbeat/tests/system/template" + "github.com/elastic/beats/x-pack/packetbeat/cmd" +) + +var systemTest *bool + +func init() { + systemTest = flag.Bool("systemTest", false, "Set to true when running system tests") + cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("systemTest")) + cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("test.coverprofile")) +} + +// Test started when the test binary is started. Only calls main. +func TestSystem(t *testing.T) { + if *systemTest { + main() + } +} + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +} diff --git a/x-pack/winlogbeat/cmd/root.go b/x-pack/winlogbeat/cmd/root.go index b1da4f69a54..faafbac4fb3 100644 --- a/x-pack/winlogbeat/cmd/root.go +++ b/x-pack/winlogbeat/cmd/root.go @@ -9,6 +9,9 @@ import ( xpackcmd "github.com/elastic/beats/x-pack/libbeat/cmd" ) +// Name of this beat. +var Name = cmd.Name + // RootCmd to handle beats cli var RootCmd = cmd.RootCmd diff --git a/x-pack/winlogbeat/main_test.go b/x-pack/winlogbeat/main_test.go new file mode 100644 index 00000000000..9080874b5e8 --- /dev/null +++ b/x-pack/winlogbeat/main_test.go @@ -0,0 +1,32 @@ +// Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one +// or more contributor license agreements. Licensed under the Elastic License; +// you may not use this file except in compliance with the Elastic License. +package main + +// This file is mandatory as otherwise the winlogbeat.test binary is not generated correctly. +import ( + "flag" + "testing" + + "github.com/elastic/beats/libbeat/tests/system/template" + "github.com/elastic/beats/x-pack/winlogbeat/cmd" +) + +var systemTest *bool + +func init() { + systemTest = flag.Bool("systemTest", false, "Set to true when running system tests") + cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("systemTest")) + cmd.RootCmd.PersistentFlags().AddGoFlag(flag.CommandLine.Lookup("test.coverprofile")) +} + +// Test started when the test binary is started. Only calls main. +func TestSystem(t *testing.T) { + if *systemTest { + main() + } +} + +func TestTemplate(t *testing.T) { + template.TestTemplate(t, cmd.Name) +}