From 1c481cb6860b518a8ed3ef0dbd29dd33a6737f59 Mon Sep 17 00:00:00 2001 From: Jaime Soriano Pastor Date: Tue, 28 May 2019 17:34:39 +0200 Subject: [PATCH] Don't generate autodiscover config when no port matches host hints (#12086) (#12141) 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 ba36dce6d2a4a577bda3b45823cc847e80d5c2b5) --- 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 19fe5489979..db056126601 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -47,6 +47,7 @@ https://github.com/elastic/beats/compare/v7.0.0...7.0[Check the HEAD diff] *Metricbeat* - 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] - Change some field type from scaled_float to long in aws module. {pull}11982[11982] - Ignore prometheus metrics when their values are NaN or Inf. {pull}12084[12084] {issue}10849[10849] 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{