From aa05f6a8c3710622abf96a8c077dcaab1833ec85 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 28 May 2019 17:35:01 +0200 Subject: [PATCH] Don't generate autodiscover config when no port matches host hints (#12086) (#12098) 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. (cherry picked from commit cc73643c52a53a59e0c52f9cf5fd771f9727f159) --- 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 d97da61c21d..b25aa199b48 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -57,6 +57,7 @@ https://github.com/elastic/beats/compare/v6.7.2...6.8[Check the HEAD diff] *Metricbeat* +- Avoid generating hints-based configuration with empty hosts when no exposed port is suitable for the hosts hint. {issue}8264[8264] {pull}12086[12086] - Fix direction of incoming IPv6 sockets. {pull}12248[12248] - Validate that kibana/status metricset cannot be used when xpack is enabled. {pull}12264[12264] 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{