Merge ~sajoupa/charm-telegraf:sudoers-template into charm-telegraf:master

Proposed by Laurent Sesquès
Status: Merged
Approved by: Laurent Sesquès
Approved revision: 9a5427c92add21c1c3083d009b6e5ddd4155d67f
Merged at revision: cd6438f0126130f9dec34891c1a5e062ad5c69d4
Proposed branch: ~sajoupa/charm-telegraf:sudoers-template
Merge into: charm-telegraf:master
Diff against target: 221 lines (+68/-30)
7 files modified
dev/null (+0/-5)
src/reactive/telegraf.py (+27/-12)
src/templates/sudoers/telegraf_iptables.tmpl (+2/-1)
src/templates/sudoers/telegraf_ovs.tmpl (+6/-0)
src/tests/lint/render_sudoers.py (+12/-0)
src/tests/unit/test_telegraf.py (+18/-10)
src/tox.ini (+3/-2)
Reviewer Review Type Date Requested Status
Haw Loeung +1 Approve
Barry Price Approve
BootStack Reviewers Pending
Review via email: mp+399441@code.launchpad.net

Commit message

make sudoers files templates, taking into account install_method

To post a comment you must log in.
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
Laurent Sesquès (sajoupa) wrote :

PAsses `make test`, with a small local fix to zaza for https://github.com/openstack-charmers/zaza/issues/436

Revision history for this message
Barry Price (barryprice) wrote :

LGTM, +1 here

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

Change successfully merged at revision cd6438f0126130f9dec34891c1a5e062ad5c69d4

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/files/sudoers/telegraf_ovs b/src/files/sudoers/telegraf_ovs
2deleted file mode 100644
3index 6be9f54..0000000
4--- a/src/files/sudoers/telegraf_ovs
5+++ /dev/null
6@@ -1,5 +0,0 @@
7-Defaults:telegraf !requiretty
8-
9-telegraf ALL = (root) NOPASSWD: /usr/bin/ovs-ofctl
10-telegraf ALL = (root) NOPASSWD: /usr/bin/ovs-vsctl
11-telegraf ALL = (root) NOPASSWD: /usr/bin/ovs-appctl
12diff --git a/src/reactive/telegraf.py b/src/reactive/telegraf.py
13index 1fbe002..469b961 100644
14--- a/src/reactive/telegraf.py
15+++ b/src/reactive/telegraf.py
16@@ -21,7 +21,6 @@ import ipaddress
17 import json
18 import os
19 import re
20-import shutil
21 import socket
22 import subprocess
23 import sys
24@@ -73,10 +72,12 @@ GRAFANA_DASHBOARD_NAME = "telegraf"
25 SNAP_SERVICE = "snap.telegraf.telegraf"
26 DEB_SERVICE = "telegraf"
27
28-SNAP_USER = "snap_daemon"
29+SNAP_OWNER = "snap_daemon"
30 SNAP_GROUP = "snap_daemon"
31-DEB_USER = "root"
32+SNAP_USER = "snap_daemon"
33+DEB_OWNER = "root"
34 DEB_GROUP = "telegraf"
35+DEB_USER = "telegraf"
36
37 # Utilities #
38
39@@ -93,7 +94,7 @@ def write_telegraf_file(path, content):
40 return host.write_file(
41 path,
42 content.encode("UTF-8"),
43- owner=get_telegraf_user(),
44+ owner=get_telegraf_owner(),
45 group=get_telegraf_group(),
46 perms=0o640,
47 )
48@@ -112,13 +113,18 @@ def get_install_method():
49 raise InvalidInstallMethod()
50
51
52-def install_sudoers_file(filename):
53- """Install a sudoers file from the charm directory to /etc/sudoers.d ."""
54+def render_sudoers_file(filename):
55+ """Generate and install a sudoers file from a template to /etc/sudoers.d ."""
56+ template = "{}.tmpl".format(filename)
57+ context = {"telegraf_user": get_telegraf_user()}
58 hookenv.log("Installing sudoers file {}".format(filename), level="DEBUG")
59- src = os.path.join(get_files_dir(), "sudoers", filename)
60- dst = os.path.join(SUDOERS_DIR, filename)
61- shutil.copy(src, dst)
62- os.chmod(dst, 0o640)
63+ render(
64+ source=template,
65+ templates_dir=os.path.join(get_templates_dir(), "sudoers"),
66+ target=os.path.join(SUDOERS_DIR, filename),
67+ context=context,
68+ perms=0o640,
69+ )
70
71
72 def remove_sudoers_file(filename):
73@@ -137,6 +143,15 @@ def get_telegraf_user():
74 return DEB_USER
75
76
77+def get_telegraf_owner():
78+ install_method = get_install_method()
79+
80+ # get_install_method() already checked that we got a valid value
81+ if install_method == "snap":
82+ return SNAP_OWNER
83+ return DEB_OWNER
84+
85+
86 def get_telegraf_group():
87 install_method = get_install_method()
88
89@@ -597,7 +612,7 @@ def configure_telegraf(): # noqa: C901
90 if host.service_running("openvswitch-switch"):
91 # add sudoers file for telegraf if openvswitch is running
92 sudoers_filename = "telegraf_ovs"
93- install_sudoers_file(sudoers_filename)
94+ render_sudoers_file(sudoers_filename)
95 else:
96 # disable the OVS checks if the service is not curently running
97 # no need to handle duplicates here, as those are handled during
98@@ -622,7 +637,7 @@ def configure_telegraf(): # noqa: C901
99 # handle the sudoers for iptables
100 sudoers_filename = "telegraf_iptables"
101 if config["collect_iptables_metrics"]:
102- install_sudoers_file(sudoers_filename)
103+ render_sudoers_file(sudoers_filename)
104 else:
105 remove_sudoers_file(sudoers_filename)
106
107diff --git a/src/files/sudoers/telegraf_iptables b/src/templates/sudoers/telegraf_iptables.tmpl
108similarity index 66%
109rename from src/files/sudoers/telegraf_iptables
110rename to src/templates/sudoers/telegraf_iptables.tmpl
111index a917a6f..49354db 100644
112--- a/src/files/sudoers/telegraf_iptables
113+++ b/src/templates/sudoers/telegraf_iptables.tmpl
114@@ -1,3 +1,4 @@
115 Cmnd_Alias IPTABLESSHOW = /sbin/iptables -w 5 -nvL *
116-telegraf ALL=(root) NOPASSWD: IPTABLESSHOW
117+{{ telegraf_user }} ALL=(root) NOPASSWD: IPTABLESSHOW
118 Defaults!IPTABLESSHOW !logfile, !syslog, !pam_session
119+
120diff --git a/src/templates/sudoers/telegraf_ovs.tmpl b/src/templates/sudoers/telegraf_ovs.tmpl
121new file mode 100644
122index 0000000..b15f8ee
123--- /dev/null
124+++ b/src/templates/sudoers/telegraf_ovs.tmpl
125@@ -0,0 +1,6 @@
126+Defaults:{{ telegraf_user }} !requiretty
127+
128+{{ telegraf_user }} ALL = (root) NOPASSWD: /usr/bin/ovs-ofctl
129+{{ telegraf_user }} ALL = (root) NOPASSWD: /usr/bin/ovs-vsctl
130+{{ telegraf_user }} ALL = (root) NOPASSWD: /usr/bin/ovs-appctl
131+
132diff --git a/src/tests/lint/render_sudoers.py b/src/tests/lint/render_sudoers.py
133new file mode 100644
134index 0000000..4005ce1
135--- /dev/null
136+++ b/src/tests/lint/render_sudoers.py
137@@ -0,0 +1,12 @@
138+import os
139+
140+from jinja2 import Environment, FileSystemLoader
141+
142+template_dir = os.path.join("templates/sudoers")
143+for template in os.listdir(template_dir):
144+ environment = Environment(loader=FileSystemLoader(template_dir))
145+ template = environment.get_template(template)
146+ # A simple print(telegraf_user="test-user") would append a newline.
147+ # We want to detect if the rendered template lacks a trailing
148+ # newline, as it would break sudo when deployed. Hence end=''.
149+ print(template.render(telegraf_user="test-user"), end="")
150diff --git a/src/tests/unit/test_telegraf.py b/src/tests/unit/test_telegraf.py
151index 537293d..d466780 100644
152--- a/src/tests/unit/test_telegraf.py
153+++ b/src/tests/unit/test_telegraf.py
154@@ -201,10 +201,10 @@ def check_sysstat_config(original, expected):
155 def test_write_telegraf_file(mocker, install_method):
156
157 if install_method == "deb":
158- user = telegraf.DEB_USER
159+ user = telegraf.DEB_OWNER
160 group = telegraf.DEB_GROUP
161 elif install_method == "snap":
162- user = telegraf.SNAP_USER
163+ user = telegraf.SNAP_OWNER
164 group = telegraf.SNAP_GROUP
165 write_file = mocker.patch("charmhelpers.core.host.write_file")
166 telegraf.write_telegraf_file("the-path", "the-content áéíóú")
167@@ -1504,16 +1504,24 @@ class TestGrafanaDashboard:
168 mock_clear_flag.assert_called_once_with("grafana.configured")
169
170
171-@mock.patch("shutil.copy")
172-@mock.patch("os.chmod")
173-def test_install_sudoers_file(os_chmod_mock, shutil_copy_mock):
174+@pytest.mark.parametrize("install_method", ["deb", "snap"])
175+@mock.patch("reactive.telegraf.render")
176+def test_render_sudoers_file(render_mock, install_method):
177+ if install_method == "deb":
178+ context = {"telegraf_user": "telegraf"}
179+ elif install_method == "snap":
180+ context = {"telegraf_user": "snap_daemon"}
181 filename = "test"
182+ template = "{}.tmpl".format(filename)
183 target_mode = 0o640
184- src = os.path.join(telegraf.get_files_dir(), "sudoers", filename)
185- dst = os.path.join(telegraf.SUDOERS_DIR, filename)
186- telegraf.install_sudoers_file(filename)
187- shutil_copy_mock.assert_called_with(src, dst)
188- os_chmod_mock.assert_called_with(dst, target_mode)
189+ telegraf.render_sudoers_file(filename)
190+ render_mock.assert_called_with(
191+ source=template,
192+ templates_dir=os.path.join(telegraf.get_templates_dir(), "sudoers"),
193+ target=os.path.join(telegraf.SUDOERS_DIR, filename),
194+ context=context,
195+ perms=target_mode,
196+ )
197
198
199 @mock.patch("os.unlink")
200diff --git a/src/tox.ini b/src/tox.ini
201index d9467a8..ec6b760 100644
202--- a/src/tox.ini
203+++ b/src/tox.ini
204@@ -26,14 +26,15 @@ passenv =
205 commands =
206 flake8
207 black --check --exclude "/(\.eggs|\.git|\.tox|\.venv|\.build|dist|charmhelpers|mod)/" .
208- bash -c "cat files/sudoers/* | visudo -csf -"
209+ bash -c "python3 tests/lint/render_sudoers.py | visudo -csf -"
210 deps =
211 black
212 flake8
213+ flake8-colors
214 flake8-docstrings
215 flake8-import-order
216+ jinja2
217 pep8-naming
218- flake8-colors
219 whitelist_externals = bash
220
221 [flake8]

Subscribers

People subscribed via source and target branches

to all changes: