Merge ~barryprice/charm-telegraf:add_ip_range_support into charm-telegraf:master

Proposed by Barry Price
Status: Merged
Approved by: Barry Price
Approved revision: bb61dba965d4a4183c8fde2a390102bd722f80bf
Merged at revision: 562a3cc1aaeb05a0e28874ddbd6a597459c44f8f
Proposed branch: ~barryprice/charm-telegraf:add_ip_range_support
Merge into: charm-telegraf:master
Prerequisite: ~barryprice/charm-telegraf:prometheus-client-default-port-9103
Diff against target: 188 lines (+57/-9)
5 files modified
src/config.yaml (+6/-0)
src/reactive/telegraf.py (+27/-7)
src/templates/prometheus_client.tmpl (+1/-0)
src/tests/functional/tests/bundles/bionic-monitoring.yaml (+1/-0)
src/tests/unit/test_telegraf.py (+22/-2)
Reviewer Review Type Date Requested Status
Haw Loeung +1 Approve
Canonical IS Reviewers Pending
BootStack Reviewers Pending
Review via email: mp+398221@code.launchpad.net

This proposal supersedes a proposal from 2021-01-27.

Commit message

Add support for ip_range in the prometheus-client output plugin

To post a comment you must log in.
Revision history for this message
Laurent Sesquès (sajoupa) wrote : Posted in a previous version of this proposal
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : Posted in a previous version of this proposal

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : Posted in a previous version of this proposal

Unable to determine commit message from repository - please click "Set commit message" and enter the commit message manually.

Revision history for this message
Paul Goins (vultaire) wrote : Posted in a previous version of this proposal

Just a quick note in passing so far:

* Generally looks good
* I need to take a proper look at the tests for this later, unit and functional - it seems sane, but I likely need more context than I'm seeing here to properly review. I'll try to come back to this when I have more time.

Left one minor code comment re: code which could be done in less lines.

Revision history for this message
Laurent Sesquès (sajoupa) wrote : Posted in a previous version of this proposal

Thanks. Replied to the comment inline.

Revision history for this message
Haw Loeung (hloeung) wrote : Posted in a previous version of this proposal

LGTM, comment inline.

review: Approve (+1)
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : Posted in a previous version of this proposal

Failed to merge change (unable to merge source repository due to conflicts), setting status to needs review.

Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

This merge proposal is being monitored by mergebot. Change the status to Approved to merge.

Revision history for this message
Haw Loeung (hloeung) wrote :

LGTM

review: Approve (+1)
Revision history for this message
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote :

Change successfully merged at revision 562a3cc1aaeb05a0e28874ddbd6a597459c44f8f

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/config.yaml b/src/config.yaml
2index 66f6105..b94071b 100644
3--- a/src/config.yaml
4+++ b/src/config.yaml
5@@ -206,3 +206,9 @@ options:
6 Note: The complete datasource inserted into dashboard will be
7 "$prometheus_datasource - Juju generated source"
8 This matches how the Prometheus2/Grafana charms format the datasource.
9+ prometheus_ip_range:
10+ default: ""
11+ type: string
12+ description: >
13+ If set, the list of IP Ranges which are allowed to access metrics.
14+ ex: prometheus_ip_range = "[192.168.0.0/24, 192.168.1.0/30]"
15diff --git a/src/reactive/telegraf.py b/src/reactive/telegraf.py
16index 82cf10e..47819cd 100644
17--- a/src/reactive/telegraf.py
18+++ b/src/reactive/telegraf.py
19@@ -362,6 +362,13 @@ def get_prometheus_port():
20 return int(config.get("prometheus_output_port"))
21
22
23+def get_prometheus_ip_range():
24+ config = hookenv.config()
25+ if config.get("prometheus_ip_range") == "":
26+ return []
27+ return config.get("prometheus_ip_range").split(",")
28+
29+
30 def get_socket_listener_port():
31 config = hookenv.config()
32 if not config.get("socket_listener_port", False):
33@@ -699,7 +706,9 @@ def handle_config_changes():
34 clear_flag("plugins.prometheus-client.configured")
35 clear_flag("prometheus-client.relation.configured")
36
37- if config.changed("prometheus_output_port"):
38+ if config.changed("prometheus_output_port") or config.changed(
39+ "prometheus_ip_range"
40+ ):
41 clear_flag("plugins.prometheus-client.configured")
42 clear_flag("prometheus-client.relation.configured")
43 clear_flag("telegraf.configured")
44@@ -1220,7 +1229,7 @@ def influxdb_api_output(influxdb):
45 set_flag("telegraf.needs_reload")
46
47
48-def generate_prometheus_output_config(prometheus_output_port):
49+def generate_prometheus_output_config(prometheus_output_port, prometheus_ip_range):
50 # If extra_options are set for prometheus_client, let's integrate them
51 extra_options = get_extra_options()
52 options = extra_options["outputs"].get("prometheus_client", {})
53@@ -1239,21 +1248,27 @@ def generate_prometheus_output_config(prometheus_output_port):
54 )
55 listen = "{}:{}".format(listen.split(":", 1)[0], prometheus_output_port)
56
57+ options_ip_range = options.pop("ip_range", [])
58+ ip_range = options_ip_range + prometheus_ip_range
59+
60 return {
61 "listen": listen,
62+ "ip_range": ip_range,
63 "extra_options": render_extra_options(
64 "outputs", "prometheus_client", extra_options=extra_options
65 ),
66 }
67
68
69-def render_prometheus_client_config(port):
70+def render_prometheus_client_config(port, ip_range):
71 config_path = "{}/{}.conf".format(get_configs_dir(), "prometheus_client")
72 hookenv.log(
73- "Updating {} plugin config file. Port is {}".format("prometheus_client", port),
74+ "Updating {} plugin config file. Port is {} and ip_range is {}".format(
75+ "prometheus_client", port, ip_range
76+ ),
77 level=hookenv.INFO,
78 )
79- context = generate_prometheus_output_config(port)
80+ context = generate_prometheus_output_config(port, ip_range)
81 render(
82 source="prometheus_client.tmpl",
83 templates_dir=get_templates_dir(),
84@@ -1301,7 +1316,11 @@ def configure_prometheus_client_with_relation(prometheus):
85 ip_addr = None
86 prometheus.configure(port, hostname=ip_addr, private_address=ip_addr)
87 check_prometheus_port("prometheus_output", port)
88- render_prometheus_client_config(port)
89+ # If prometheus_ip_range is empty, all remote IPs are allowed
90+ ip_range = get_prometheus_ip_range()
91+ if ip_range != []:
92+ ip_range = ip_range + remote_egress_subnets
93+ render_prometheus_client_config(port, ip_range)
94 set_flag("plugins.prometheus-client.configured")
95 set_flag("prometheus-client.relation.configured")
96 set_flag("telegraf.needs_reload")
97@@ -1318,7 +1337,8 @@ def configure_prometheus_client():
98 set_flag("plugins.prometheus-client.configured")
99 return
100 check_prometheus_port("prometheus_output", port)
101- render_prometheus_client_config(port)
102+ ip_range = get_prometheus_ip_range()
103+ render_prometheus_client_config(port, ip_range)
104 set_flag("plugins.prometheus-client.configured")
105 set_flag("telegraf.needs_reload")
106 clear_flag("prometheus-client.relation.configured")
107diff --git a/src/templates/prometheus_client.tmpl b/src/templates/prometheus_client.tmpl
108index add2099..a6e3c06 100644
109--- a/src/templates/prometheus_client.tmpl
110+++ b/src/templates/prometheus_client.tmpl
111@@ -1,3 +1,4 @@
112 [[outputs.prometheus_client]]
113 listen = "{{ listen }}"
114+ ip_range = {{ ip_range }}
115 {%- if extra_options %}{{ extra_options }}{%- endif %}
116diff --git a/src/tests/functional/tests/bundles/bionic-monitoring.yaml b/src/tests/functional/tests/bundles/bionic-monitoring.yaml
117index 120eab8..c7a487b 100644
118--- a/src/tests/functional/tests/bundles/bionic-monitoring.yaml
119+++ b/src/tests/functional/tests/bundles/bionic-monitoring.yaml
120@@ -8,6 +8,7 @@ applications:
121 num_units: 0
122 options:
123 prometheus_datasource: prometheus2
124+ prometheus_ip_range: '0.0.0.0/0'
125 grafana:
126 charm: cs:grafana
127 num_units: 1
128diff --git a/src/tests/unit/test_telegraf.py b/src/tests/unit/test_telegraf.py
129index 88603c8..8146f3f 100644
130--- a/src/tests/unit/test_telegraf.py
131+++ b/src/tests/unit/test_telegraf.py
132@@ -810,8 +810,9 @@ def test_prometheus_global(monkeypatch, config):
133 monkeypatch.setattr(telegraf.hookenv, "close_port", lambda p: open_ports.remove(p))
134 config["prometheus_output_port"] = "default"
135 telegraf.configure_prometheus_client()
136- expected = '''[[outputs.prometheus_client]]
137- listen = ":9103"'''
138+ expected = """[[outputs.prometheus_client]]
139+ listen = ":9103"
140+ ip_range = []"""
141 config_file = base_dir().join("telegraf.d", "prometheus_client.conf")
142 assert expected in config_file.read()
143
144@@ -834,6 +835,7 @@ outputs:
145 telegraf.configure_prometheus_client()
146 expected = """[[outputs.prometheus_client]]
147 listen = ":9103"
148+ ip_range = []
149 namedrop = ["aerospike*"]
150 [outputs.prometheus_client.tagpass]
151 cpu = ["cpu0"]"""
152@@ -1147,18 +1149,36 @@ def test_prometheus_client_output(mocker, monkeypatch, config):
153
154 interface = mocker.Mock(spec=RelationBase)
155 interface.configure = mocker.Mock()
156+
157+ # Test that telegraf will allow scraping from related prometheus, and from ranges in
158+ # prometheus_ip_range
159+ config["prometheus_ip_range"] = "127.0.0.1/32,10.0.0.0/8"
160 telegraf.configure_prometheus_client_with_relation(interface)
161 expected = """
162 [[outputs.prometheus_client]]
163 listen = ":9103"
164+ ip_range = ['127.0.0.1/32', '10.0.0.0/8', '5.6.7.8/32']
165 """
166 assert (
167 configs_dir().join("prometheus_client.conf").read().strip() == expected.strip()
168 )
169+ # prometheus_ip_range is empty, test that all IPs are allowed, not just the related
170+ # prometheus
171+ # prometheus_output_port is also empty, we should get 9103 by default
172 network_get_primary_address.assert_called_once_with("prometheus-client")
173 interface.configure.assert_called_once_with(
174 "9103", hostname="foo", private_address="foo"
175 )
176+ config["prometheus_ip_range"] = ""
177+ telegraf.configure_prometheus_client_with_relation(interface)
178+ expected = """
179+ [[outputs.prometheus_client]]
180+ listen = ":9103"
181+ ip_range = []
182+"""
183+ assert (
184+ configs_dir().join("prometheus_client.conf").read().strip() == expected.strip()
185+ )
186
187
188 def test_prometheus_client_output_departed(mocker, monkeypatch, config):

Subscribers

People subscribed via source and target branches

to all changes: