diff --git a/.travis.yml b/.travis.yml index 6fea7c7c133..af251cd0c43 100644 --- a/.travis.yml +++ b/.travis.yml @@ -35,7 +35,7 @@ jobs: go: $GO_VERSION stage: test - os: linux - env: TARGETS="-C x-pack/filebeat unit" + env: TARGETS="-C x-pack/filebeat testsuite" go: $GO_VERSION stage: test diff --git a/Makefile b/Makefile index 377ce751998..7005f806e44 100644 --- a/Makefile +++ b/Makefile @@ -17,13 +17,18 @@ XPACK_SUFFIX=x-pack/ # in the x-pack directory (rather than having the OSS build produce both sets # of artifacts). This will be removed once we complete the transition. PROJECTS_XPACK_PKG=x-pack/auditbeat +# PROJECTS_XPACK_MAGE is a list of Beats whose primary build logic is based in +# Mage. For compatibility with CI testing these projects support a subset of the +# makefile targets. After all Beats converge to primarily using Mage we can +# remove this and treat all sub-projects the same. +PROJECTS_XPACK_MAGE=x-pack/filebeat $(PROJECTS_XPACK_PKG) # Runs complete testsuites (unit, system, integration) for all beats with coverage and race detection. # Also it builds the docs and the generators .PHONY: testsuite testsuite: - @$(foreach var,$(PROJECTS),$(MAKE) -C $(var) testsuite || exit 1;) + @$(foreach var,$(PROJECTS) $(PROJECTS_XPACK_MAGE),$(MAKE) -C $(var) testsuite || exit 1;) .PHONY: setup-commit-hook setup-commit-hook: @@ -59,13 +64,13 @@ coverage-report: .PHONY: update update: notice - @$(foreach var,$(PROJECTS),$(MAKE) -C $(var) update || exit 1;) + @$(foreach var,$(PROJECTS) $(PROJECTS_XPACK_MAGE),$(MAKE) -C $(var) update || exit 1;) @$(MAKE) -C deploy/kubernetes all .PHONY: clean clean: @rm -rf build - @$(foreach var,$(PROJECTS),$(MAKE) -C $(var) clean || exit 1;) + @$(foreach var,$(PROJECTS) $(PROJECTS_XPACK_MAGE),$(MAKE) -C $(var) clean || exit 1;) @$(MAKE) -C generator clean @-mage -clean 2> /dev/null @@ -77,7 +82,7 @@ clean-vendor: .PHONY: check check: python-env - @$(foreach var,$(PROJECTS) dev-tools,$(MAKE) -C $(var) check || exit 1;) + @$(foreach var,$(PROJECTS) dev-tools $(PROJECTS_XPACK_MAGE),$(MAKE) -C $(var) check || exit 1;) @# Checks also python files which are not part of the beats @$(FIND) -name *.py -exec $(PYTHON_ENV)/bin/autopep8 -d --max-line-length 120 {} \; | (! grep . -q) || (echo "Code differs from autopep8's style" && false) @# Validate that all updates were committed @@ -112,7 +117,7 @@ misspell: .PHONY: fmt fmt: add-headers python-env - @$(foreach var,$(PROJECTS) dev-tools,$(MAKE) -C $(var) fmt || exit 1;) + @$(foreach var,$(PROJECTS) dev-tools $(PROJECTS_XPACK_MAGE),$(MAKE) -C $(var) fmt || exit 1;) @# Cleans also python files which are not part of the beats @$(FIND) -name "*.py" -exec $(PYTHON_ENV)/bin/autopep8 --in-place --max-line-length 120 {} \; diff --git a/dev-tools/cmd/module_fields/main.go b/dev-tools/cmd/module_fields/module_fields.go similarity index 100% rename from dev-tools/cmd/module_fields/main.go rename to dev-tools/cmd/module_fields/module_fields.go diff --git a/dev-tools/cmd/module_include_list/module_include_list.go b/dev-tools/cmd/module_include_list/module_include_list.go index db46b5e872e..e5fc651d745 100644 --- a/dev-tools/cmd/module_include_list/module_include_list.go +++ b/dev-tools/cmd/module_include_list/module_include_list.go @@ -18,6 +18,7 @@ package main import ( + "bufio" "bytes" "flag" "fmt" @@ -25,31 +26,43 @@ import ( "log" "os" "path/filepath" + "sort" "strings" "text/template" + "github.com/pkg/errors" + "github.com/elastic/beats/dev-tools/mage" "github.com/elastic/beats/licenses" ) var usageText = ` -Usage: module_include_list [flags] [module-dir] +Usage: module_include_list [flags] module_include_list generates a list.go file containing import statements for - the module and its dataset packages. The file is usually written to the - include/list.go in the Beat's root directory. + the specified imports and module directories. An import is a directory or + directory glob containing .go files. A moduleDir is a directory to search + for modules and datasets. + + Packages without .go files or without an init() method are omitted from the + generated file. The output file is written to the include/list.go in the + Beat's root directory by default. Options: `[1:] var ( - license string - pkg string - outFile string + license string + pkg string + outFile string + moduleDirs stringSliceFlag + importDirs stringSliceFlag ) func init() { flag.StringVar(&license, "license", "ASL2", "License header for generated file (ASL2 or Elastic).") flag.StringVar(&pkg, "pkg", "include", "Package name.") flag.StringVar(&outFile, "out", "include/list.go", "Output file.") + flag.Var(&moduleDirs, "moduleDir", "Directory to search for modules to include") + flag.Var(&importDirs, "import", "Directory to include") flag.Usage = usageFlag } @@ -62,19 +75,19 @@ func main() { log.Fatalf("Invalid license specifier: %v", err) } - args := flag.Args() - if len(args) != 1 { - log.Fatal("module-dir must be passed as an argument.") + if len(moduleDirs) == 0 && len(importDirs) == 0 { + log.Fatal("At least one -import or -moduleDir must be specified.") } - dir := args[0] - // Find modules and datasets. - metaDirs, err := mage.FindFiles( - filepath.Join(dir, "*/_meta"), - filepath.Join(dir, "*/*/_meta"), - ) + dirs, err := findModuleAndDatasets() if err != nil { - log.Fatalf("Failed finding modules and datasets: %v", err) + log.Fatal(err) + } + + if imports, err := findImports(); err != nil { + log.Fatal(err) + } else { + dirs = append(dirs, imports...) } // Get the current directories Go import path. @@ -85,11 +98,9 @@ func main() { // Build import paths. var imports []string - for _, metaDir := range metaDirs { - importDir := filepath.Dir(metaDir) - + for _, dir := range dirs { // Skip dirs that have no .go files. - goFiles, err := filepath.Glob(filepath.Join(importDir, "*.go")) + goFiles, err := filepath.Glob(filepath.Join(dir, "*.go")) if err != nil { log.Fatal("Failed checking for .go files in package dir: %v", err) } @@ -97,15 +108,34 @@ func main() { continue } - importDir, err = filepath.Rel(mage.CWD(), filepath.Dir(metaDir)) - if err != nil { - log.Fatal(err) + // Skip packages without an init() function because that cannot register + // anything as a side-effect of being imported (e.g. filebeat/input/file). + var foundInitMethod bool + for _, f := range goFiles { + if hasInitMethod(f) { + foundInitMethod = true + break + } + } + if !foundInitMethod { + continue + } + + importDir := dir + if filepath.IsAbs(dir) { + // Make it relative to the current package if it's absolute. + importDir, err = filepath.Rel(mage.CWD(), dir) + if err != nil { + log.Fatalf("Failure creating import for dir=%v: %v", dir, err) + } } imports = append(imports, filepath.ToSlash( filepath.Join(repo.ImportPath, importDir))) } + sort.Strings(imports) + // Populate the template. var buf bytes.Buffer err = Template.Execute(&buf, Data{ @@ -155,3 +185,61 @@ type Data struct { Package string Imports []string } + +//stringSliceFlag is a flag type that allows more than one value to be specified. +type stringSliceFlag []string + +func (f *stringSliceFlag) String() string { return strings.Join(*f, ", ") } + +func (f *stringSliceFlag) Set(value string) error { + *f = append(*f, value) + return nil +} + +// findModuleAndDatasets searches the specified moduleDirs for packages that +// should be imported. They are designated by the presence of a _meta dir. +func findModuleAndDatasets() ([]string, error) { + var dirs []string + for _, moduleDir := range moduleDirs { + // Find modules and datasets as indicated by the _meta dir. + metaDirs, err := mage.FindFiles( + filepath.Join(moduleDir, "*/_meta"), + filepath.Join(moduleDir, "*/*/_meta"), + ) + if err != nil { + return nil, errors.Wrap(err, "failed finding modules and datasets") + } + + for _, metaDir := range metaDirs { + // Strip off _meta. + dirs = append(dirs, filepath.Dir(metaDir)) + } + } + return dirs, nil +} + +// findImports expands the given import values in case they contain globs. +func findImports() ([]string, error) { + return mage.FindFiles(importDirs...) +} + +// hasInitMethod returns true if the file contains 'func init()'. +func hasInitMethod(file string) bool { + f, err := os.Open(file) + if err != nil { + log.Fatalf("failed to read from %v: %v", file, err) + } + defer f.Close() + + var initSignature = []byte("func init()") + scanner := bufio.NewScanner(f) + for scanner.Scan() { + if bytes.Contains(scanner.Bytes(), initSignature) { + return true + } + } + if err := scanner.Err(); err != nil { + log.Fatal("failed scanning %v: %v", file, err) + } + return false +} diff --git a/dev-tools/mage/common.go b/dev-tools/mage/common.go index 0e024aaaae3..57ca7c85bf6 100644 --- a/dev-tools/mage/common.go +++ b/dev-tools/mage/common.go @@ -676,6 +676,23 @@ func IsUpToDate(dst string, sources ...string) bool { return err == nil && !execute } +// OSSBeatDir returns the OSS beat directory. You can pass paths and they will +// be joined and appended to the OSS beat dir. +func OSSBeatDir(path ...string) string { + ossDir := CWD() + + // Check if we need to correct ossDir because it's in x-pack. + if parentDir := filepath.Base(filepath.Dir(ossDir)); parentDir == "x-pack" { + // If the OSS version of the beat exists. + tmp := filepath.Join(ossDir, "../..", BeatName) + if _, err := os.Stat(tmp); !os.IsNotExist(err) { + ossDir = tmp + } + } + + return filepath.Join(append([]string{ossDir}, path...)...) +} + // LibbeatDir returns the libbeat directory. You can pass paths and // they will be joined and appended to the libbeat dir. func LibbeatDir(path ...string) string { diff --git a/dev-tools/mage/config.go b/dev-tools/mage/config.go index c5766df5c09..0b4330dd63b 100644 --- a/dev-tools/mage/config.go +++ b/dev-tools/mage/config.go @@ -151,5 +151,5 @@ func GenerateModuleReferenceConfig(out string, moduleDirs ...string) error { "Modules": moduleConfigs, }) - return ioutil.WriteFile(out, []byte(config), 0644) + return ioutil.WriteFile(createDir(out), []byte(config), 0644) } diff --git a/dev-tools/mage/fields.go b/dev-tools/mage/fields.go index ef05b0be734..60716592a95 100644 --- a/dev-tools/mage/fields.go +++ b/dev-tools/mage/fields.go @@ -18,7 +18,6 @@ package mage import ( - "os" "path/filepath" "github.com/pkg/errors" @@ -33,27 +32,17 @@ import ( // moduleDirs specifies additional directories to search for modules. The // contents of each fields.yml will be included in the generated file. func GenerateFieldsYAML(moduleDirs ...string) error { - return generateFieldsYAML(OSSBeatDir(), moduleDirs...) + return generateFieldsYAML(OSSBeatDir(), "fields.yml", moduleDirs...) } -// OSSBeatDir returns the OSS beat directory. You can pass paths and they will -// be joined and appended to the OSS beat dir. -func OSSBeatDir(path ...string) string { - ossDir := CWD() - - // Check if we need to correct ossDir because it's in x-pack. - if parentDir := filepath.Base(filepath.Dir(ossDir)); parentDir == "x-pack" { - // If the OSS version of the beat exists. - tmp := filepath.Join(ossDir, "../..", BeatName) - if _, err := os.Stat(tmp); !os.IsNotExist(err) { - ossDir = tmp - } - } - - return filepath.Join(append([]string{ossDir}, path...)...) +// GenerateFieldsYAMLTo generates a YAML file containing the field definitions +// for the Beat. It's the same as GenerateFieldsYAML but with a configurable +// output file. +func GenerateFieldsYAMLTo(output string, moduleDirs ...string) error { + return generateFieldsYAML(OSSBeatDir(), output, moduleDirs...) } -func generateFieldsYAML(baseDir string, moduleDirs ...string) error { +func generateFieldsYAML(baseDir, output string, moduleDirs ...string) error { const globalFieldsCmdPath = "libbeat/scripts/cmd/global_fields/main.go" beatsDir, err := ElasticBeatsDir() @@ -65,7 +54,7 @@ func generateFieldsYAML(baseDir string, moduleDirs ...string) error { filepath.Join(beatsDir, globalFieldsCmdPath), "-es_beats_path", beatsDir, "-beat_path", baseDir, - "-out", "fields.yml", + "-out", output, ) return globalFieldsCmd(moduleDirs...) @@ -100,8 +89,8 @@ func GenerateFieldsGo(fieldsYML, out string) error { // GenerateModuleFieldsGo generates a fields.go file containing a copy of the // each module's field.yml data in a format that can be embedded in Beat's // binary. -func GenerateModuleFieldsGo() error { - const moduleFieldsCmdPath = "dev-tools/cmd/module_fields/main.go" +func GenerateModuleFieldsGo(moduleDir string) error { + const moduleFieldsCmdPath = "dev-tools/cmd/module_fields/module_fields.go" beatsDir, err := ElasticBeatsDir() if err != nil { @@ -112,7 +101,7 @@ func GenerateModuleFieldsGo() error { filepath.Join(beatsDir, moduleFieldsCmdPath), "-beat", BeatName, "-license", toLibbeatLicenseName(BeatLicense), - filepath.Join(CWD(), "module"), + filepath.Join(CWD(), moduleDir), ) return moduleFieldsCmd() @@ -121,6 +110,15 @@ func GenerateModuleFieldsGo() error { // GenerateModuleIncludeListGo generates an include/list.go file containing // a import statement for each module and dataset. func GenerateModuleIncludeListGo() error { + return GenerateIncludeListGo(nil, []string{ + filepath.Join(CWD(), "module"), + }) +} + +// GenerateIncludeListGo generates an include/list.go file containing imports +// for the packages that match the paths (or globs) in importDirs (optional) +// and moduleDirs (optional). +func GenerateIncludeListGo(importDirs []string, moduleDirs []string) error { const moduleIncludeListCmdPath = "dev-tools/cmd/module_include_list/module_include_list.go" beatsDir, err := ElasticBeatsDir() @@ -131,10 +129,17 @@ func GenerateModuleIncludeListGo() error { includeListCmd := sh.RunCmd("go", "run", filepath.Join(beatsDir, moduleIncludeListCmdPath), "-license", toLibbeatLicenseName(BeatLicense), - filepath.Join(CWD(), "module"), ) - return includeListCmd() + var args []string + for _, dir := range importDirs { + args = append(args, "-import", dir) + } + for _, dir := range moduleDirs { + args = append(args, "-moduleDir", dir) + } + + return includeListCmd(args...) } // toLibbeatLicenseName translates the license type used in packages to diff --git a/libbeat/scripts/Makefile b/libbeat/scripts/Makefile index d319410bb98..14f5d106444 100755 --- a/libbeat/scripts/Makefile +++ b/libbeat/scripts/Makefile @@ -211,14 +211,6 @@ system-tests: prepare-tests ${BEAT_NAME}.test python-env system-tests-environment: ## @testing Runs the system tests inside a virtual environment. This can be run on any docker-machine (local, remote) system-tests-environment: prepare-tests build-image ${DOCKER_COMPOSE} run -e INTEGRATION_TESTS=1 -e TESTING_ENVIRONMENT=${TESTING_ENVIRONMENT} -e DOCKER_COMPOSE_PROJECT_NAME=${DOCKER_COMPOSE_PROJECT_NAME} beat make system-tests - #This is a hack to run x-pack/filebeat module tests - @XPACKBEAT="${ES_BEATS}/x-pack/${BEAT_NAME}" ; \ - if [ -e "$$XPACKBEAT/tests/system" ] && [ "$(BEAT_NAME)" != "libbeat" ] && [ "$(BEAT_NAME)" != "auditbeat" ] && [ $(XPACK_ONLY) = false ]; then \ - $(MAKE) -C ../x-pack/${BEAT_NAME} fields; \ - ${DOCKER_COMPOSE} run -e INTEGRATION_TESTS=1 -e MODULES_PATH="../../x-pack/${BEAT_NAME}/module" -e TESTING_ENVIRONMENT=${TESTING_ENVIRONMENT} -e DOCKER_COMPOSE_PROJECT_NAME=${DOCKER_COMPOSE_PROJECT_NAME} beat make -C "$$XPACKBEAT" ${BEAT_NAME}.test system-tests ; \ - $(MAKE) -C ../x-pack/${BEAT_NAME} fix-permissions; \ - fi - .PHONY: fast-system-tests fast-system-tests: ## @testing Runs system tests without coverage reports and in parallel diff --git a/x-pack/auditbeat/magefile.go b/x-pack/auditbeat/magefile.go index 2db2e222f0b..a7a62b9d7b0 100644 --- a/x-pack/auditbeat/magefile.go +++ b/x-pack/auditbeat/magefile.go @@ -81,9 +81,14 @@ func TestPackages() error { return mage.TestPackages() } -// Fields generates a fields.yml and for each module generate a fields.go. +// Fields generates a fields.yml and for each module generates a fields.go. func Fields() { - mg.SerialDeps(fieldsYML, mage.GenerateModuleFieldsGo) + mg.SerialDeps(fieldsYML, moduleFieldsGo) +} + +// moduleFieldsGo generates a fields.go file for each module. +func moduleFieldsGo() error { + return mage.GenerateModuleFieldsGo("module") } // fieldsYML generates a fields.yml based on auditbeat + x-pack/auditbeat/modules. diff --git a/x-pack/filebeat/Makefile b/x-pack/filebeat/Makefile index 94a0a81d2b8..56633e2b3e5 100644 --- a/x-pack/filebeat/Makefile +++ b/x-pack/filebeat/Makefile @@ -1,8 +1,3 @@ -BEAT_NAME=filebeat -ES_BEATS?=../.. -XPACK_BEAT_PATH?=github.com/elastic/beats/x-pack/${BEAT_NAME} -GOPACKAGES?=$(shell go list ${BEAT_PATH}/... ${XPACK_BEAT_PATH}/... | grep -v /vendor/ | grep -v /scripts/cmd/ ) -LICENSE=Elastic +ES_BEATS ?= ../.. -# Include main filebeat Makefile -include ${ES_BEATS}/${BEAT_NAME}/Makefile +include $(ES_BEATS)/dev-tools/make/xpack.mk diff --git a/x-pack/filebeat/docker-compose.yml b/x-pack/filebeat/docker-compose.yml new file mode 100644 index 00000000000..8a4f6f4a240 --- /dev/null +++ b/x-pack/filebeat/docker-compose.yml @@ -0,0 +1,28 @@ +version: '2.1' +services: + beat: + build: ../../filebeat + depends_on: + - proxy_dep + environment: + - BEAT_STRICT_PERMS=false + - ES_HOST=elasticsearch + - ES_PORT=9200 + working_dir: /go/src/github.com/elastic/beats/x-pack/filebeat + volumes: + - ${PWD}/../..:/go/src/github.com/elastic/beats/ + - /var/run/docker.sock:/var/run/docker.sock + command: make + + # This is a proxy used to block beats until all services are healthy. + # See: https://github.com/docker/compose/issues/4369 + proxy_dep: + image: busybox + depends_on: + elasticsearch: { condition: service_healthy } + + elasticsearch: + extends: + file: ${ES_BEATS}/testing/environments/${TESTING_ENVIRONMENT}.yml + service: elasticsearch + diff --git a/x-pack/filebeat/filebeat.reference.yml b/x-pack/filebeat/filebeat.reference.yml index bb4d3c9a357..d5200432fdc 100644 --- a/x-pack/filebeat/filebeat.reference.yml +++ b/x-pack/filebeat/filebeat.reference.yml @@ -791,6 +791,12 @@ filebeat.inputs: # This option is not supported on Windows. #filebeat.registry_file_permissions: 0600 +# The timeout value that controls when registry entries are written to disk +# (flushed). When an unwritten update exceeds this value, it triggers a write to +# disk. When registry_flush is set to 0s, the registry is written to disk after +# each batch of events has been published successfully. The default value is 0s. +#filebeat.registry_flush: 0s + # By default Ingest pipelines are not updated if a pipeline with the same ID # already exists. If this option is enabled Filebeat overwrites pipelines # everytime a new Elasticsearch connection is established. diff --git a/x-pack/filebeat/include/list.go b/x-pack/filebeat/include/list.go index 33a93af0b64..718202a1769 100644 --- a/x-pack/filebeat/include/list.go +++ b/x-pack/filebeat/include/list.go @@ -2,9 +2,12 @@ // or more contributor license agreements. Licensed under the Elastic License; // you may not use this file except in compliance with the Elastic License. +// Code generated by beats/dev-tools/module_include_list/module_include_list.go - DO NOT EDIT. + package include import ( - // Include modules to register their fields.go. + // Import packages that need to register themselves. + _ "github.com/elastic/beats/x-pack/filebeat/input/netflow" _ "github.com/elastic/beats/x-pack/filebeat/module/suricata" ) diff --git a/x-pack/filebeat/input/netflow/_meta/fields.header.yml b/x-pack/filebeat/input/netflow/_meta/fields.header.yml index d8bbb2efa42..4afce171475 100644 --- a/x-pack/filebeat/input/netflow/_meta/fields.header.yml +++ b/x-pack/filebeat/input/netflow/_meta/fields.header.yml @@ -39,6 +39,6 @@ How long the exporter process has been running, in milliseconds. - name: version - type: int + type: long description: > NetFlow version used. diff --git a/x-pack/filebeat/input/netflow/_meta/fields.yml b/x-pack/filebeat/input/netflow/_meta/fields.yml index 5e9af19ac47..f2cde02956c 100644 --- a/x-pack/filebeat/input/netflow/_meta/fields.yml +++ b/x-pack/filebeat/input/netflow/_meta/fields.yml @@ -39,7 +39,7 @@ How long the exporter process has been running, in milliseconds. - name: version - type: int + type: long description: > NetFlow version used. diff --git a/x-pack/filebeat/input/netflow/fields.go b/x-pack/filebeat/input/netflow/fields.go new file mode 100644 index 00000000000..12e9168d6d3 --- /dev/null +++ b/x-pack/filebeat/input/netflow/fields.go @@ -0,0 +1,22 @@ +// 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. + +// Code generated by beats/dev-tools/cmd/asset/asset.go - DO NOT EDIT. + +package netflow + +import ( + "github.com/elastic/beats/libbeat/asset" +) + +func init() { + if err := asset.SetFields("filebeat", "netflow", Asset); err != nil { + panic(err) + } +} + +// Asset returns asset data +func Asset() string { + return "eJysXTuT5Cjy9+dTKNb5O/+d2NfcY4yz7jZujbtbY43zCISyJLYloAFVde2nvwAkFVWCahJ1GxMx1fXLTCBJ8gX9bfMC16+NAHsa5eVT01huR/jafPNvsD+P8vLNp6bpwDDNleVSfG3+9qlpmuZnDmNnmpOWU7N8s6Gia3759edf/ts4Uubzp6Y5+a999ZBvG0EniFm5H3tV8LXptZzV8kmC27scPy9fi/nFPB2X7cOV6QtcL1J30ecZ1u7ntwE8rJGnjb0GJnW3oFromvba2IGbBs4g7OdPOzHgTUltQe9Eicf/jiD/Aks7ammjYaQWusbKxg6w0W46OHMGjR2obXoQoMO3nFxB4M8RvccJi6WlXafBmLvf5efuHbHdzz8WEf/POCW4SP2y8mi4aH759av7dXOSeqLx7MUyGTlrBoQ/cg5SjVL0OJH+0xrQZ+p+3XRyok6Ov7spvQycDfGsNS048iYjmOUTGEsnlRSsoxZwgv3GJ/D67aBO6cL6ZrjPyvEnEx9Hnl4w/NT8U1486l67lJbMLdhATdMCiEbPQnDR/79bwsAfmBRdbp7OoA2X4oNkXHfiQrWZDXSJfSeZBUs6GC0lTM7C7jagZ73DKcpeqoAB4cwcjp+WVjI5Et6BsPzEE6bCDFLbPZQrwkZqDJEn4lSas73By0AtU4RJYbUcScut2eG4sNCD3iOX3Wg1FcbpB3H/oOFcnX8ie2OzgNVznNJw4m9kBNHboXiyRO+YESeZPtHEVOWW1VguvLWoHnRMAz3yHbhq+FA3eq6IgDdLBqnwkre9Isu6UUPEPLUJ3U7zddB44DX4esGVNJZMjBpLqs1BRKPWFHlbAqIj5mrIrIiz9xiosVTbCrAXvdp+yiOzNnHBp3kiXBErLR1zWp5B07cD6JuJ+dORDYoDx0yrNvaOexUVry8jbWH0REqtA5sUcV8gTHbBOJcbRd4v4FIZDZ3UyEUfjNiZjqXruuLo2EvN7TChZoUyy8/g94+cEUbfg3k3VkBB9FwAanIWyJ2T/BwQvLtu2ehhv2C26kZgAmNoD0dI+LkKPncFGW/ftZwtaGJYpTtx5Cwuwk5qNMRKtWwzzOI+QPHOk9sBoBHasSIm2eH2J2iiqejkhN2lwZMtl3A9Kazdc8hBluMBATlp2k8g7OadM7/4mLPwgJe+aOlEWXa516A8zTvW1yoq55GK1KJkTZdni0ZxRfZB4vumueMaWHI98hFT7BXijupHnxKH9gB4syDcMMkAtAO9h2Ycm3sDYCxlL8Tgxu5pJPA/HCXw41ECe6cBSeDLUQJ7hwdJ4M9HCfzlKIG/HiXw/Xc1Lme9bTpi3LYwlrj/1+CiJFM5fD3hcExrHawliMIDTyPtDaEucMwf/Bnoet7J08kAxtuV+kJ159xsY6md94v5TB3PSgQHjnTc6VY/czOUJ8IezGNVBGQ0I1bT04kzwkUHe6cukx8ytgpHlRoXb6JOGWMC5W5TjMKp8erMdPwUHJkQ9CnJE4qZW6h5tNznRDTc5DhRZmVpZif4UjjRPWZz3gg6VhrpFfQPy35czCV6hySJGP7Hfhw4Eh21tHQgmwtDu98pc/u8JrGmNJzrKaxlBXwYEyORKRotldpi3Yrc/oKvLw7cCYA36Q8C1JwJSy5RAzXlTiOT0yQFUVoq0JZDMkJLc5S3MlswEuXQfV5p76BlN8k+WMbpyuhsA6O6K5fXlwSKvz2BBe0OyqWuVo4MG6AKamFSI7VJq5edyouL49hAhXATWWwuPcyYBCBroZdkWYVqhQouwsOJMuOharkD+sptfgdVwAK/uFSKZVqLXTkzLas512EDZ0FFLeNKaOAbTPRT2d8xlNUUzNVYmAgX3JKoRI8fSTfrJch6RuDJMCIC6FGEPbbmZiuSsr2Q+siJtRKoPTKFdDtc2NoBbPjqEWwUqk/9dG2n6BjbF5aKYFHtryJijWp/lS7KC1xdGOVc9eKQYF+urRQ9LtdWKOzmtSQLYbmUpEPly2fPUCuv4uzVHa9i1NxtZXxc24MDxiqMQ1tWydYBD7KF1xkEA1xg45CUvQh5GaHrwadR0AQuXHTuEEPFhQ44694bK+lzXDhsSEZjG2oqcXFlHlkyVvQ6StpFYERcwBWm8BMS/WF8mM3io497OUvNx7HUCvdxOYPOKW4paEv3+ZRhKSqOos08+cLW60w1FPsWkYWtIvBYS0XUAB+z37gGk0d0BwoHvgkNbwqztjUq5QzwWp3PAPPbxZAtW1cu5/knwofixfDflz7vWbryzlzhEIp2Pi3tla5Yx5kcR2BWVqSp7qC43EMI8NFdegtsayVF1lIXeNTduBDCT1Zth+SW2qsl4I/tq6hw2xzyxGuR2tS4ig6pzFCJdIanDjnrvqq/pqadznvUwjvUdS2/C4HOkiPtswsVtclRq2EroXt5aqkJaonUvPd0RL8OiWigY3F/miPi750UG1zBLXeRVc4appdSg1FSOFcIBTtxDRc6jlgZQ6vyWZ/KE6N4yFmTU0UBrP4Qj717RkeEe9/yum4XsANoAbbOT9/Q77geeZu+EnhqPPJN89J+/4pvJQowpbnU3F5LBxtQbDZWTqBruW54LPsJrJYEzizFNKuQN5RFNBMqA3MnyYXrZDEgY8wjUJJZ3mxGyPXGycM1sqdnz2IN1HA1nNER7xsdxIc+ujpdjLD1qnXbRrh5X8r1+KBw8eb86VaZvl48SsOsIsZqoBNqyBN9IysJFF8HrKzTrHHS1H0hbAD2Yubic3jFGiYRTb1cVA6SC1JdxZKKvs6ADIYMGN+0iBtfvBYVRaQHPFoH7/D4WtLDLNcM4JECfgj3FPCDuAVmDPTSvlx+pWCNySqwHbV0aeh3Pu3IacvH1IHYSjkCFc9rvKF9AHPICbi400asPTLoho0IbObpVknDFdEiKj5QoCzXrlUcQ+ESCrkYCkfFxRlKymQPQKb0tSJwLjYVUlwn/sfSF5ZMSmZPjXuwBTYI/jojjkwuwj103yM2hgR+uqUvf+r+oAJnOcp+r+3ZgdvZ91jUQEEwfVUWuip02ytypiPvuL36zs3iLcaV2wzEKF6oE70G8gJ72fIahNnxt9A21ADxsS0Ol+hBwem6gdXL2spNxdsrYCWisTep2wiXbOOYv0SXx64X8JbqbO39vbXxUZV77xvWe7K1jD24im2yjvfeMKWaR8w1oxtSyzZ30HZybseEi+BP6pGLF3LS1A0TVXm8FQHvu1IRRmRNL9QR2In/MZdiUPhjI4j28pIpUS/WkLX/Bm8RYirh42IqtDVynC0Q0DrRfpHTIf8sDT9jYbEJDVsMF8o8wis87AQNtJ+/o4H30zveg7FkoGZwp3HCaUmvlwdwpciigZme9DIwwlZ5qJytmi3RVLiwmZdaqwSWll6a8NhVp+s4P6JxvJeFCuKXBzNhqr2H4jRUoxZ529o4/2JWysVuIyd84ntZc5tylJcaGJPixH2aiYxwhv0RmwOmHBNv1HHOX4JIzaWaFCHctKcoBFVroS9W1TwVEEdcPgMTFZaz4tRPisgsUC8GKc3P1J0pzvtSmhtkX9WZaztTf0CH8HW7xFfekp6ngVvdRzrzXC8DjnO4+0MM9DnfPT17C6725ssdvKJ0vKTvZ8GP9WeuhG43yA6TarWk3TFS8EGjgw+TaJKCW6njZ1Li/CM21ZygtqVjkbR8pjvYMC8QwoDckCnrV4IzFhQytInQYp58eR/zTJqldVebHRDd5HCxqvYi9cO7YOlj96nWVmG1fb/NNt9YbNCXsON7r4xa6KW+HiBh5vYjyPg3QLHXyUPXyOgrA4YoDSbVXZHJWt2Dl6RZcXz4AGdyUiOUw8PlbmaDRfNtn3LWjABXlGRUt5TSreObiA8gV/JOIV60d/qX8MLl8/iVwmEJ+kDG39rXvJ3DZSOwgyz2ivSJ/fjly3fkd24t6JqrTjsK6LtODxSexe+ZafU1/g72qfBsSPjQFoDChprggYxsRODAreh7KtV3o+/JhFYnNJFb/st2xHtNwURVp9HuySDzaFtGNtxrrUw7h4lRlPG7N3Lfn8sjSe8EBZwIPtcRVtGXRcq18tZLWauRUTdmrTZuR1z9OwVJEriK60biyFVnv/ITdO6Ex98YX+9fRqX8miuMD/n5pIv4pOpU99bGirt/5BDhvgfrvDzXRrgwljpH1dL9LnjaUbijUDz9GfzBxsYjjy7tTqyPeAXqYHoiurb5EZQOZjty0lSE8cvrhguZA2/h1lNY3xw5OLFJMvXXwQ+S2e5kH6STmJSqm2wJMY7QCUa2Os232Gi84kdNvoceO39Y5Vp5Jt4S2f4OzIZKC1kN/U6GbAvqI4WwQi7MSXhC2RbPRyKY900fsMln+gvBnOQj4uRbtY/M/eQXZ+x38J7OfWlmaAf2Pqjl7KX4dugjhVkY3oti7z3C4/8ogwObuX2GzHP13Wbo9w8cklFlZw1rHR1Z5fEUpLDwZvGvo8VgXCormuhqYFWZL8Kbq7CJGvBT6CS7ecSWjibZ8hEIn8w+0n8PNBluOsT4Busb76mdjb9KjvCcU5fkDBmTxeAsFc9fw+sMziFK54OeC7+CB5m4flwGtVT3iaDhOXht5c9doc2iBbUVXr4P0VycV3X/D96OoJ3Er7O0lMAbA+igy1zUe9KgOWgwgxxxSD/RPodP+xTq+Qp5U5NrB39PM6iRgqhBU4PZufSNrFcgQFjNy98poG+k5dASNGrhQxRoP1UIqJnb8MfJyp+Xpm9kfQrCsRT+wrybLQNTO5a27K5a6Bu/B94PN/2ooeCfbaomoC2ZqFJuIAdFiSh9mEjrstbJ1o+yjXb9oXGelSjwcv4XAAD//080Z0o=" +} diff --git a/x-pack/filebeat/magefile.go b/x-pack/filebeat/magefile.go index 3ce0bd013d7..0892a99c2fb 100644 --- a/x-pack/filebeat/magefile.go +++ b/x-pack/filebeat/magefile.go @@ -34,7 +34,7 @@ func Build() error { return mage.Build(mage.DefaultBuildArgs()) } -// GolangCrossBuild build the Beat binary inside of the golang-builder. +// GolangCrossBuild builds the Beat binary inside of the golang-builder. // Do not use directly, use crossBuild instead. func GolangCrossBuild() error { return mage.GolangCrossBuild(mage.DefaultGolangCrossBuildArgs()) @@ -45,9 +45,23 @@ func CrossBuild() error { return mage.CrossBuild() } -// Fields generates a fields.yml and fields.go for each module. +// Clean cleans all generated files and build artifacts. +func Clean() error { + return mage.Clean() +} + +// Fields generates the fields.yml file and a fields.go for each module and +// input. func Fields() { - mg.Deps(fieldsYML, mage.GenerateModuleFieldsGo) + mg.Deps(fieldsYML, moduleFieldsGo, inputFieldsGo) +} + +func inputFieldsGo() error { + return mage.GenerateModuleFieldsGo("input") +} + +func moduleFieldsGo() error { + return mage.GenerateModuleFieldsGo("module") } // fieldsYML generates a fields.yml based on filebeat + x-pack/filebeat/modules. @@ -60,19 +74,49 @@ func Dashboards() error { return mage.KibanaDashboards(mage.OSSBeatDir("module"), "module") } +// ExportDashboard exports a dashboard and writes it into the correct directory. +// +// Required environment variables: +// - MODULE: Name of the module +// - ID: Dashboard id +func ExportDashboard() error { + return mage.ExportDashboard() +} + // Config generates both the short and reference configs. func Config() { mg.Deps(shortConfig, referenceConfig, createDirModulesD) } -// Update is an alias for running fields, dashboards, config. +// Update is an alias for executing fields, dashboards, config. func Update() { - mg.SerialDeps(Fields, Dashboards, Config) + mg.SerialDeps(Fields, Dashboards, Config, includeList) +} + +func includeList() error { + return mage.GenerateIncludeListGo([]string{"input/*"}, []string{"module"}) +} + +// Fmt formats source code and adds file headers. +func Fmt() { + mg.Deps(mage.Format) +} + +// Check runs fmt and update then returns an error if any modifications are found. +func Check() { + mg.SerialDeps(mage.Format, Update, mage.Check) +} + +// IntegTest executes integration tests (it uses Docker to run the tests). +func IntegTest() { + mage.AddIntegTestUsage() + defer mage.StopIntegTestEnv() + mg.SerialDeps(GoIntegTest, PythonIntegTest) } // UnitTest executes the unit tests. func UnitTest() { - mg.SerialDeps(GoUnitTest) + mg.SerialDeps(GoUnitTest, PythonUnitTest) } // GoUnitTest executes the Go unit tests. @@ -82,6 +126,34 @@ func GoUnitTest(ctx context.Context) error { return mage.GoTest(ctx, mage.DefaultGoTestUnitArgs()) } +// GoIntegTest executes the Go integration tests. +// Use TEST_COVERAGE=true to enable code coverage profiling. +// Use RACE_DETECTOR=true to enable the race detector. +func GoIntegTest(ctx context.Context) error { + return mage.RunIntegTest("goIntegTest", func() error { + return mage.GoTest(ctx, mage.DefaultGoTestIntegrationArgs()) + }) +} + +// PythonUnitTest executes the python system tests. +func PythonUnitTest() error { + mg.Deps(mage.BuildSystemTestBinary) + return mage.PythonNoseTest(mage.DefaultPythonTestUnitArgs()) +} + +// PythonIntegTest executes the python system tests in the integration environment (Docker). +func PythonIntegTest(ctx context.Context) error { + if !mage.IsInIntegTestEnv() { + mg.Deps(Fields) + } + return mage.RunIntegTest("pythonIntegTest", func() error { + mg.Deps(mage.BuildSystemTestBinary) + args := mage.DefaultPythonTestIntegrationArgs() + args.Env["MODULES_PATH"] = mage.CWD("module") + return mage.PythonNoseTest(args) + }) +} + // ----------------------------------------------------------------------------- // Customizations specific to Filebeat. // - Include modules directory in packages (minus _meta and test files).