From ba36dce6d2a4a577bda3b45823cc847e80d5c2b5 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Wed, 8 May 2019 11:10:45 +0200 Subject: [PATCH] Don't generate autodiscover config when no port matches host hints (#12086) On metricbeat, when the host autodiscover hint is used, and it includes the port, one of the exposed ports has to match with the one in the hint. If not, no configuration should be generated. If it is generated, it will have empty hosts, what would lead to unexpected errors as the seen in #8264. --- CHANGELOG.next.asciidoc | 1 + .../autodiscover/builder/hints/metrics.go | 17 ++++-- .../builder/hints/metrics_test.go | 61 ++++++++++++++++++- 3 files changed, 74 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index a90fd7406f1..78e16baf377 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -106,6 +106,7 @@ https://github.com/elastic/beats/compare/v7.0.0-alpha2...master[Check the HEAD d - Change diskio metrics retrieval method (only for Windows) from wmi query to DeviceIOControl function using the IOCTL_DISK_PERFORMANCE control code {pull}11635[11635] - Call GetMetricData api per region instead of per instance. {issue}11820[11820] {pull}11882[11882] - Update documentation with cloudwatch:ListMetrics permission. {pull}11987[11987] +- Avoid generating hints-based configuration with empty hosts when no exposed port is suitable for the hosts hint. {issue}8264[8264] {pull}12086[12086] *Packetbeat* diff --git a/metricbeat/autodiscover/builder/hints/metrics.go b/metricbeat/autodiscover/builder/hints/metrics.go index 42b20062c20..2432e60c5f2 100644 --- a/metricbeat/autodiscover/builder/hints/metrics.go +++ b/metricbeat/autodiscover/builder/hints/metrics.go @@ -101,7 +101,11 @@ func (m *metricHints) CreateConfig(event bus.Event) []*common.Config { return config } - hsts := m.getHostsWithPort(hints, port) + hosts, ok := m.getHostsWithPort(hints, port) + if !ok { + return config + } + ns := m.getNamespace(hints) msets := m.getMetricSets(hints, mod) tout := m.getTimeout(hints) @@ -112,7 +116,7 @@ func (m *metricHints) CreateConfig(event bus.Event) []*common.Config { moduleConfig := common.MapStr{ "module": mod, "metricsets": msets, - "hosts": hsts, + "hosts": hosts, "timeout": tout, "period": ival, "enabled": true, @@ -161,7 +165,7 @@ func (m *metricHints) getMetricSets(hints common.MapStr, module string) []string return msets } -func (m *metricHints) getHostsWithPort(hints common.MapStr, port int) []string { +func (m *metricHints) getHostsWithPort(hints common.MapStr, port int) ([]string, bool) { var result []string thosts := builder.GetHintAsList(hints, m.Key, hosts) @@ -175,7 +179,12 @@ func (m *metricHints) getHostsWithPort(hints common.MapStr, port int) []string { } } - return result + if len(thosts) > 0 && len(result) == 0 { + logp.Debug("hints.builder", "no hosts selected for port %d with hints: %+v", port, thosts) + return nil, false + } + + return result, true } func (m *metricHints) getNamespace(hints common.MapStr) string { diff --git a/metricbeat/autodiscover/builder/hints/metrics_test.go b/metricbeat/autodiscover/builder/hints/metrics_test.go index 00019f0cbc2..1f3d37c86bf 100644 --- a/metricbeat/autodiscover/builder/hints/metrics_test.go +++ b/metricbeat/autodiscover/builder/hints/metrics_test.go @@ -67,6 +67,65 @@ func TestGenerateHints(t *testing.T) { len: 0, result: common.MapStr{}, }, + { + message: "Hints without matching port should return nothing", + event: bus.Event{ + "host": "1.2.3.4", + "port": 9090, + "hints": common.MapStr{ + "metrics": common.MapStr{ + "module": "mockmoduledefaults", + "hosts": "${data.host}:8888", + }, + }, + }, + len: 0, + result: common.MapStr{}, + }, + { + message: "Hints with multiple hosts return only the matching one", + event: bus.Event{ + "host": "1.2.3.4", + "port": 9090, + "hints": common.MapStr{ + "metrics": common.MapStr{ + "module": "mockmoduledefaults", + "hosts": "${data.host}:8888,${data.host}:9090", + }, + }, + }, + len: 1, + result: common.MapStr{ + "module": "mockmoduledefaults", + "metricsets": []string{"default"}, + "timeout": "3s", + "period": "1m", + "enabled": true, + "hosts": []interface{}{"1.2.3.4:9090"}, + }, + }, + { + message: "Hints with multiple hosts return only the one with the template", + event: bus.Event{ + "host": "1.2.3.4", + "port": 9090, + "hints": common.MapStr{ + "metrics": common.MapStr{ + "module": "mockmoduledefaults", + "hosts": "${data.host}:8888,${data.host}:${data.port}", + }, + }, + }, + len: 1, + result: common.MapStr{ + "module": "mockmoduledefaults", + "metricsets": []string{"default"}, + "timeout": "3s", + "period": "1m", + "enabled": true, + "hosts": []interface{}{"1.2.3.4:9090"}, + }, + }, { message: "Only module hint should return all metricsets", event: bus.Event{ @@ -87,7 +146,7 @@ func TestGenerateHints(t *testing.T) { }, }, { - message: "metricsets hint works", + message: "Metricsets hint works", event: bus.Event{ "host": "1.2.3.4", "hints": common.MapStr{