Merge ~xavpaice/charm-nagios:lint-20.08 into ~nagios-charmers/charm-nagios:master
- Git
- lp:~xavpaice/charm-nagios
- lint-20.08
- Merge into master
Proposed by
Xav Paice
Status: | Merged |
---|---|
Merged at revision: | b27a20af88bd66c4c5d43b0903b30fa69fd6abd5 |
Proposed branch: | ~xavpaice/charm-nagios:lint-20.08 |
Merge into: | ~nagios-charmers/charm-nagios:master |
Prerequisite: | ~xavpaice/charm-nagios:blacken-20.08 |
Diff against target: |
1205 lines (+185/-107) 9 files modified
hooks/common.py (+62/-11) hooks/monitors_relation_changed.py (+25/-12) hooks/upgrade_charm.py (+62/-25) hooks/website_relation_joined.py (+3/-6) tests/functional/conftest.py (+25/-19) tests/functional/test_config.py (+6/-8) tests/functional/test_deploy.py (+1/-0) tests/unit/test_website_relation_joined.py (+1/-0) tox.ini (+0/-26) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alvaro Uria (community) | Approve | ||
Celia Wang | Approve | ||
Review via email: mp+388634@code.launchpad.net |
Commit message
Extra Linting completed for 20.08 charm release
Description of the change
To post a comment you must log in.
Revision history for this message
Alvaro Uria (aluria) wrote : | # |
+1 this and the other 2 related MPs (blacken and makefile)
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | diff --git a/hooks/common.py b/hooks/common.py | |||
2 | index 3bff942..b320880 100644 | |||
3 | --- a/hooks/common.py | |||
4 | +++ b/hooks/common.py | |||
5 | @@ -1,17 +1,17 @@ | |||
6 | 1 | import subprocess | ||
7 | 2 | import socket | ||
8 | 3 | import os | 1 | import os |
9 | 4 | import os.path | 2 | import os.path |
10 | 5 | import re | 3 | import re |
11 | 6 | import shutil | 4 | import shutil |
12 | 5 | import socket | ||
13 | 6 | import subprocess | ||
14 | 7 | import tempfile | 7 | import tempfile |
15 | 8 | 8 | ||
16 | 9 | from charmhelpers.core.hookenv import ( | 9 | from charmhelpers.core.hookenv import ( |
17 | 10 | config, | ||
18 | 10 | log, | 11 | log, |
19 | 11 | network_get, | 12 | network_get, |
20 | 12 | network_get_primary_address, | 13 | network_get_primary_address, |
21 | 13 | unit_get, | 14 | unit_get, |
22 | 14 | config, | ||
23 | 15 | ) | 15 | ) |
24 | 16 | 16 | ||
25 | 17 | from pynag import Model | 17 | from pynag import Model |
26 | @@ -28,16 +28,18 @@ PLUGIN_PATH = "/usr/lib/nagios/plugins" | |||
27 | 28 | Model.cfg_file = INPROGRESS_CFG | 28 | Model.cfg_file = INPROGRESS_CFG |
28 | 29 | Model.pynag_directory = INPROGRESS_CONF_D | 29 | Model.pynag_directory = INPROGRESS_CONF_D |
29 | 30 | 30 | ||
31 | 31 | reduce_RE = re.compile(r"[\W_]") | 31 | REDUCE_RE = re.compile(r"[\W_]") |
32 | 32 | 32 | ||
33 | 33 | 33 | ||
34 | 34 | def check_ip(n): | 34 | def check_ip(n): |
35 | 35 | try: | 35 | try: |
36 | 36 | socket.inet_pton(socket.AF_INET, n) | 36 | socket.inet_pton(socket.AF_INET, n) |
37 | 37 | |||
38 | 37 | return True | 38 | return True |
39 | 38 | except socket.error: | 39 | except socket.error: |
40 | 39 | try: | 40 | try: |
41 | 40 | socket.inet_pton(socket.AF_INET6, n) | 41 | socket.inet_pton(socket.AF_INET6, n) |
42 | 42 | |||
43 | 41 | return True | 43 | return True |
44 | 42 | except socket.error: | 44 | except socket.error: |
45 | 43 | return False | 45 | return False |
46 | @@ -48,10 +50,12 @@ def get_local_ingress_address(binding="website"): | |||
47 | 48 | log("Getting hostname for binding %s" % binding) | 50 | log("Getting hostname for binding %s" % binding) |
48 | 49 | try: | 51 | try: |
49 | 50 | network_info = network_get(binding) | 52 | network_info = network_get(binding) |
50 | 53 | |||
51 | 51 | if network_info is not None and "ingress-addresses" in network_info: | 54 | if network_info is not None and "ingress-addresses" in network_info: |
52 | 52 | log("Using ingress-addresses") | 55 | log("Using ingress-addresses") |
53 | 53 | hostname = network_info["ingress-addresses"][0] | 56 | hostname = network_info["ingress-addresses"][0] |
54 | 54 | log(hostname) | 57 | log(hostname) |
55 | 58 | |||
56 | 55 | return hostname | 59 | return hostname |
57 | 56 | except NotImplementedError: | 60 | except NotImplementedError: |
58 | 57 | # We'll fallthrough to the Pre 2.3 code below. | 61 | # We'll fallthrough to the Pre 2.3 code below. |
59 | @@ -66,29 +70,36 @@ def get_local_ingress_address(binding="website"): | |||
60 | 66 | hostname = unit_get("private-address") | 70 | hostname = unit_get("private-address") |
61 | 67 | log("Using unit_get private address") | 71 | log("Using unit_get private address") |
62 | 68 | log(hostname) | 72 | log(hostname) |
63 | 73 | |||
64 | 69 | return hostname | 74 | return hostname |
65 | 70 | 75 | ||
66 | 71 | 76 | ||
67 | 72 | def get_remote_relation_attr(remote_unit, attr_name, relation_id=None): | 77 | def get_remote_relation_attr(remote_unit, attr_name, relation_id=None): |
68 | 73 | args = ["relation-get", attr_name, remote_unit] | 78 | args = ["relation-get", attr_name, remote_unit] |
69 | 79 | |||
70 | 74 | if relation_id is not None: | 80 | if relation_id is not None: |
71 | 75 | args.extend(["-r", relation_id]) | 81 | args.extend(["-r", relation_id]) |
72 | 82 | |||
73 | 76 | return subprocess.check_output(args).strip() | 83 | return subprocess.check_output(args).strip() |
74 | 77 | 84 | ||
75 | 78 | 85 | ||
76 | 79 | def get_ip_and_hostname(remote_unit, relation_id=None): | 86 | def get_ip_and_hostname(remote_unit, relation_id=None): |
77 | 80 | hostname = get_remote_relation_attr(remote_unit, "ingress-address", relation_id) | 87 | hostname = get_remote_relation_attr(remote_unit, "ingress-address", relation_id) |
78 | 88 | |||
79 | 81 | if hostname is None or not len(hostname): | 89 | if hostname is None or not len(hostname): |
80 | 82 | hostname = get_remote_relation_attr(remote_unit, "private-address", relation_id) | 90 | hostname = get_remote_relation_attr(remote_unit, "private-address", relation_id) |
81 | 83 | 91 | ||
82 | 84 | if hostname is None or not len(hostname): | 92 | if hostname is None or not len(hostname): |
83 | 85 | log("relation-get failed") | 93 | log("relation-get failed") |
84 | 94 | |||
85 | 86 | return 2 | 95 | return 2 |
86 | 96 | |||
87 | 87 | if check_ip(hostname): | 97 | if check_ip(hostname): |
88 | 88 | # Some providers don't provide hostnames, so use the remote unit name. | 98 | # Some providers don't provide hostnames, so use the remote unit name. |
89 | 89 | ip_address = hostname | 99 | ip_address = hostname |
90 | 90 | else: | 100 | else: |
91 | 91 | ip_address = socket.getaddrinfo(hostname, None)[0][4][0] | 101 | ip_address = socket.getaddrinfo(hostname, None)[0][4][0] |
92 | 102 | |||
93 | 92 | return (ip_address, remote_unit.replace("/", "-")) | 103 | return (ip_address, remote_unit.replace("/", "-")) |
94 | 93 | 104 | ||
95 | 94 | 105 | ||
96 | @@ -98,11 +109,13 @@ def refresh_hostgroups(): # noqa:C901 | |||
97 | 98 | hosts = [x["host_name"] for x in Model.Host.objects.all if x["host_name"]] | 109 | hosts = [x["host_name"] for x in Model.Host.objects.all if x["host_name"]] |
98 | 99 | 110 | ||
99 | 100 | hgroups = {} | 111 | hgroups = {} |
100 | 112 | |||
101 | 101 | for host in hosts: | 113 | for host in hosts: |
102 | 102 | try: | 114 | try: |
103 | 103 | (service, unit_id) = host.rsplit("-", 1) | 115 | (service, unit_id) = host.rsplit("-", 1) |
104 | 104 | except ValueError: | 116 | except ValueError: |
105 | 105 | continue | 117 | continue |
106 | 118 | |||
107 | 106 | if service in hgroups: | 119 | if service in hgroups: |
108 | 107 | hgroups[service].append(host) | 120 | hgroups[service].append(host) |
109 | 108 | else: | 121 | else: |
110 | @@ -114,6 +127,7 @@ def refresh_hostgroups(): # noqa:C901 | |||
111 | 114 | 127 | ||
112 | 115 | # Delete the ones not in hgroups | 128 | # Delete the ones not in hgroups |
113 | 116 | to_delete = set(auto_hgroups).difference(set(hgroups.keys())) | 129 | to_delete = set(auto_hgroups).difference(set(hgroups.keys())) |
114 | 130 | |||
115 | 117 | for hgroup_name in to_delete: | 131 | for hgroup_name in to_delete: |
116 | 118 | try: | 132 | try: |
117 | 119 | hgroup = Model.Hostgroup.objects.get_by_shortname(hgroup_name) | 133 | hgroup = Model.Hostgroup.objects.get_by_shortname(hgroup_name) |
118 | @@ -138,7 +152,7 @@ def _make_check_command(args): | |||
119 | 138 | args = [str(arg) for arg in args] | 152 | args = [str(arg) for arg in args] |
120 | 139 | # There is some worry of collision, but the uniqueness of the initial | 153 | # There is some worry of collision, but the uniqueness of the initial |
121 | 140 | # command should be enough. | 154 | # command should be enough. |
123 | 141 | signature = reduce_RE.sub("_", "".join([os.path.basename(arg) for arg in args])) | 155 | signature = REDUCE_RE.sub("_", "".join([os.path.basename(arg) for arg in args])) |
124 | 142 | Model.Command.objects.reload_cache() | 156 | Model.Command.objects.reload_cache() |
125 | 143 | try: | 157 | try: |
126 | 144 | cmd = Model.Command.objects.get_by_shortname(signature) | 158 | cmd = Model.Command.objects.get_by_shortname(signature) |
127 | @@ -147,6 +161,7 @@ def _make_check_command(args): | |||
128 | 147 | cmd.set_attribute("command_name", signature) | 161 | cmd.set_attribute("command_name", signature) |
129 | 148 | cmd.set_attribute("command_line", " ".join(args)) | 162 | cmd.set_attribute("command_line", " ".join(args)) |
130 | 149 | cmd.save() | 163 | cmd.save() |
131 | 164 | |||
132 | 150 | return signature | 165 | return signature |
133 | 151 | 166 | ||
134 | 152 | 167 | ||
135 | @@ -163,19 +178,23 @@ def customize_http(service, name, extra): | |||
136 | 163 | path = extra.get("path", "/") | 178 | path = extra.get("path", "/") |
137 | 164 | args = [port, path] | 179 | args = [port, path] |
138 | 165 | cmd_args = [plugin, "-p", '"$ARG1$"', "-u", '"$ARG2$"'] | 180 | cmd_args = [plugin, "-p", '"$ARG1$"', "-u", '"$ARG2$"'] |
139 | 181 | |||
140 | 166 | if "status" in extra: | 182 | if "status" in extra: |
141 | 167 | _extend_args(args, cmd_args, "-e", extra["status"]) | 183 | _extend_args(args, cmd_args, "-e", extra["status"]) |
142 | 184 | |||
143 | 168 | if "host" in extra: | 185 | if "host" in extra: |
144 | 169 | _extend_args(args, cmd_args, "-H", extra["host"]) | 186 | _extend_args(args, cmd_args, "-H", extra["host"]) |
145 | 170 | cmd_args.extend(("-I", "$HOSTADDRESS$")) | 187 | cmd_args.extend(("-I", "$HOSTADDRESS$")) |
146 | 171 | else: | 188 | else: |
147 | 172 | cmd_args.extend(("-H", "$HOSTADDRESS$")) | 189 | cmd_args.extend(("-H", "$HOSTADDRESS$")) |
148 | 173 | check_timeout = config("check_timeout") | 190 | check_timeout = config("check_timeout") |
149 | 191 | |||
150 | 174 | if check_timeout is not None: | 192 | if check_timeout is not None: |
151 | 175 | cmd_args.extend(("-t", check_timeout)) | 193 | cmd_args.extend(("-t", check_timeout)) |
152 | 176 | check_command = _make_check_command(cmd_args) | 194 | check_command = _make_check_command(cmd_args) |
153 | 177 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) | 195 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) |
154 | 178 | service.set_attribute("check_command", cmd) | 196 | service.set_attribute("check_command", cmd) |
155 | 197 | |||
156 | 179 | return True | 198 | return True |
157 | 180 | 199 | ||
158 | 181 | 200 | ||
159 | @@ -183,16 +202,20 @@ def customize_mysql(service, name, extra): | |||
160 | 183 | plugin = os.path.join(PLUGIN_PATH, "check_mysql") | 202 | plugin = os.path.join(PLUGIN_PATH, "check_mysql") |
161 | 184 | args = [] | 203 | args = [] |
162 | 185 | cmd_args = [plugin, "-H", "$HOSTADDRESS$"] | 204 | cmd_args = [plugin, "-H", "$HOSTADDRESS$"] |
163 | 205 | |||
164 | 186 | if "user" in extra: | 206 | if "user" in extra: |
165 | 187 | _extend_args(args, cmd_args, "-u", extra["user"]) | 207 | _extend_args(args, cmd_args, "-u", extra["user"]) |
166 | 208 | |||
167 | 188 | if "password" in extra: | 209 | if "password" in extra: |
168 | 189 | _extend_args(args, cmd_args, "-p", extra["password"]) | 210 | _extend_args(args, cmd_args, "-p", extra["password"]) |
169 | 190 | check_timeout = config("check_timeout") | 211 | check_timeout = config("check_timeout") |
170 | 212 | |||
171 | 191 | if check_timeout is not None: | 213 | if check_timeout is not None: |
172 | 192 | cmd_args.extend(("-t", check_timeout)) | 214 | cmd_args.extend(("-t", check_timeout)) |
173 | 193 | check_command = _make_check_command(cmd_args) | 215 | check_command = _make_check_command(cmd_args) |
174 | 194 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) | 216 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) |
175 | 195 | service.set_attribute("check_command", cmd) | 217 | service.set_attribute("check_command", cmd) |
176 | 218 | |||
177 | 196 | return True | 219 | return True |
178 | 197 | 220 | ||
179 | 198 | 221 | ||
180 | @@ -201,11 +224,13 @@ def customize_pgsql(service, name, extra): | |||
181 | 201 | args = [] | 224 | args = [] |
182 | 202 | cmd_args = [plugin, "-H", "$HOSTADDRESS$"] | 225 | cmd_args = [plugin, "-H", "$HOSTADDRESS$"] |
183 | 203 | check_timeout = config("check_timeout") | 226 | check_timeout = config("check_timeout") |
184 | 227 | |||
185 | 204 | if check_timeout is not None: | 228 | if check_timeout is not None: |
186 | 205 | cmd_args.extend(("-t", check_timeout)) | 229 | cmd_args.extend(("-t", check_timeout)) |
187 | 206 | check_command = _make_check_command(cmd_args) | 230 | check_command = _make_check_command(cmd_args) |
188 | 207 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) | 231 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) |
189 | 208 | service.set_attribute("check_command", cmd) | 232 | service.set_attribute("check_command", cmd) |
190 | 233 | |||
191 | 209 | return True | 234 | return True |
192 | 210 | 235 | ||
193 | 211 | 236 | ||
194 | @@ -213,6 +238,7 @@ def customize_nrpe(service, name, extra): | |||
195 | 213 | plugin = os.path.join(PLUGIN_PATH, "check_nrpe") | 238 | plugin = os.path.join(PLUGIN_PATH, "check_nrpe") |
196 | 214 | args = [] | 239 | args = [] |
197 | 215 | cmd_args = [plugin, "-H", "$HOSTADDRESS$"] | 240 | cmd_args = [plugin, "-H", "$HOSTADDRESS$"] |
198 | 241 | |||
199 | 216 | if name in ("mem", "swap"): | 242 | if name in ("mem", "swap"): |
200 | 217 | cmd_args.extend(("-c", "check_%s" % name)) | 243 | cmd_args.extend(("-c", "check_%s" % name)) |
201 | 218 | elif "command" in extra: | 244 | elif "command" in extra: |
202 | @@ -220,61 +246,77 @@ def customize_nrpe(service, name, extra): | |||
203 | 220 | else: | 246 | else: |
204 | 221 | cmd_args.extend(("-c", extra)) | 247 | cmd_args.extend(("-c", extra)) |
205 | 222 | check_timeout = config("check_timeout") | 248 | check_timeout = config("check_timeout") |
206 | 249 | |||
207 | 223 | if check_timeout is not None: | 250 | if check_timeout is not None: |
208 | 224 | cmd_args.extend(("-t", check_timeout)) | 251 | cmd_args.extend(("-t", check_timeout)) |
209 | 225 | check_command = _make_check_command(cmd_args) | 252 | check_command = _make_check_command(cmd_args) |
210 | 226 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) | 253 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) |
211 | 227 | service.set_attribute("check_command", cmd) | 254 | service.set_attribute("check_command", cmd) |
212 | 255 | |||
213 | 228 | return True | 256 | return True |
214 | 229 | 257 | ||
215 | 230 | 258 | ||
216 | 231 | def customize_rpc(service, name, extra): | 259 | def customize_rpc(service, name, extra): |
218 | 232 | """ Customize the check_rpc plugin to check things like nfs.""" | 260 | """Customize the check_rpc plugin to check things like nfs.""" |
219 | 233 | plugin = os.path.join(PLUGIN_PATH, "check_rpc") | 261 | plugin = os.path.join(PLUGIN_PATH, "check_rpc") |
220 | 234 | args = [] | 262 | args = [] |
221 | 235 | # /usr/lib/nagios/plugins/check_rpc -H <host> -C <rpc_command> | 263 | # /usr/lib/nagios/plugins/check_rpc -H <host> -C <rpc_command> |
222 | 236 | cmd_args = [plugin, "-H", "$HOSTADDRESS$"] | 264 | cmd_args = [plugin, "-H", "$HOSTADDRESS$"] |
223 | 265 | |||
224 | 237 | if "rpc_command" in extra: | 266 | if "rpc_command" in extra: |
225 | 238 | cmd_args.extend(("-C", extra["rpc_command"])) | 267 | cmd_args.extend(("-C", extra["rpc_command"])) |
226 | 268 | |||
227 | 239 | if "program_version" in extra: | 269 | if "program_version" in extra: |
228 | 240 | cmd_args.extend(("-c", extra["program_version"])) | 270 | cmd_args.extend(("-c", extra["program_version"])) |
229 | 241 | 271 | ||
230 | 242 | check_command = _make_check_command(cmd_args) | 272 | check_command = _make_check_command(cmd_args) |
231 | 243 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) | 273 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) |
232 | 244 | service.set_attribute("check_command", cmd) | 274 | service.set_attribute("check_command", cmd) |
233 | 275 | |||
234 | 245 | return True | 276 | return True |
235 | 246 | 277 | ||
236 | 247 | 278 | ||
237 | 248 | def customize_tcp(service, name, extra): | 279 | def customize_tcp(service, name, extra): |
239 | 249 | """ Customize tcp can be used to check things like memcached. """ | 280 | """Customize tcp can be used to check things like memcached.""" |
240 | 250 | plugin = os.path.join(PLUGIN_PATH, "check_tcp") | 281 | plugin = os.path.join(PLUGIN_PATH, "check_tcp") |
241 | 251 | args = [] | 282 | args = [] |
242 | 252 | # /usr/lib/nagios/plugins/check_tcp -H <host> -E | 283 | # /usr/lib/nagios/plugins/check_tcp -H <host> -E |
243 | 253 | cmd_args = [plugin, "-H", "$HOSTADDRESS$", "-E"] | 284 | cmd_args = [plugin, "-H", "$HOSTADDRESS$", "-E"] |
244 | 285 | |||
245 | 254 | if "port" in extra: | 286 | if "port" in extra: |
246 | 255 | cmd_args.extend(("-p", extra["port"])) | 287 | cmd_args.extend(("-p", extra["port"])) |
247 | 288 | |||
248 | 256 | if "string" in extra: | 289 | if "string" in extra: |
249 | 257 | cmd_args.extend(("-s", "'{}'".format(extra["string"]))) | 290 | cmd_args.extend(("-s", "'{}'".format(extra["string"]))) |
250 | 291 | |||
251 | 258 | if "expect" in extra: | 292 | if "expect" in extra: |
252 | 259 | cmd_args.extend(("-e", extra["expect"])) | 293 | cmd_args.extend(("-e", extra["expect"])) |
253 | 294 | |||
254 | 260 | if "warning" in extra: | 295 | if "warning" in extra: |
255 | 261 | cmd_args.extend(("-w", extra["warning"])) | 296 | cmd_args.extend(("-w", extra["warning"])) |
256 | 297 | |||
257 | 262 | if "critical" in extra: | 298 | if "critical" in extra: |
258 | 263 | cmd_args.extend(("-c", extra["critical"])) | 299 | cmd_args.extend(("-c", extra["critical"])) |
259 | 300 | |||
260 | 264 | if "timeout" in extra: | 301 | if "timeout" in extra: |
261 | 265 | cmd_args.extend(("-t", extra["timeout"])) | 302 | cmd_args.extend(("-t", extra["timeout"])) |
262 | 266 | check_timeout = config("check_timeout") | 303 | check_timeout = config("check_timeout") |
263 | 304 | |||
264 | 267 | if check_timeout is not None: | 305 | if check_timeout is not None: |
265 | 268 | cmd_args.extend(("-t", check_timeout)) | 306 | cmd_args.extend(("-t", check_timeout)) |
266 | 269 | 307 | ||
267 | 270 | check_command = _make_check_command(cmd_args) | 308 | check_command = _make_check_command(cmd_args) |
268 | 271 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) | 309 | cmd = "%s!%s" % (check_command, "!".join([str(x) for x in args])) |
269 | 272 | service.set_attribute("check_command", cmd) | 310 | service.set_attribute("check_command", cmd) |
270 | 311 | |||
271 | 273 | return True | 312 | return True |
272 | 274 | 313 | ||
273 | 275 | 314 | ||
274 | 276 | def customize_service(service, family, name, extra): | 315 | def customize_service(service, family, name, extra): |
276 | 277 | """ The monitors.yaml names are mapped to methods that customize services. """ | 316 | """Map names to service methods. |
277 | 317 | |||
278 | 318 | The monitors.yaml names are mapped to methods that customize services. | ||
279 | 319 | """ | ||
280 | 278 | customs = { | 320 | customs = { |
281 | 279 | "http": customize_http, | 321 | "http": customize_http, |
282 | 280 | "mysql": customize_mysql, | 322 | "mysql": customize_mysql, |
283 | @@ -283,17 +325,19 @@ def customize_service(service, family, name, extra): | |||
284 | 283 | "rpc": customize_rpc, | 325 | "rpc": customize_rpc, |
285 | 284 | "pgsql": customize_pgsql, | 326 | "pgsql": customize_pgsql, |
286 | 285 | } | 327 | } |
287 | 328 | |||
288 | 286 | if family in customs: | 329 | if family in customs: |
289 | 287 | return customs[family](service, name, extra) | 330 | return customs[family](service, name, extra) |
290 | 331 | |||
291 | 288 | return False | 332 | return False |
292 | 289 | 333 | ||
293 | 290 | 334 | ||
294 | 291 | def update_localhost(): | 335 | def update_localhost(): |
297 | 292 | """ Update the localhost definition to use the ubuntu icons.""" | 336 | """Update the localhost definition to use the ubuntu icons.""" |
296 | 293 | |||
298 | 294 | Model.cfg_file = MAIN_NAGIOS_CFG | 337 | Model.cfg_file = MAIN_NAGIOS_CFG |
299 | 295 | Model.pynag_directory = os.path.join(MAIN_NAGIOS_DIR, "conf.d") | 338 | Model.pynag_directory = os.path.join(MAIN_NAGIOS_DIR, "conf.d") |
300 | 296 | hosts = Model.Host.objects.filter(host_name="localhost", object_type="host") | 339 | hosts = Model.Host.objects.filter(host_name="localhost", object_type="host") |
301 | 340 | |||
302 | 297 | for host in hosts: | 341 | for host in hosts: |
303 | 298 | host.icon_image = "base/ubuntu.png" | 342 | host.icon_image = "base/ubuntu.png" |
304 | 299 | host.icon_image_alt = "Ubuntu Linux" | 343 | host.icon_image_alt = "Ubuntu Linux" |
305 | @@ -318,6 +362,7 @@ def get_pynag_host(target_id, owner_unit=None, owner_relation=None): | |||
306 | 318 | host.save() | 362 | host.save() |
307 | 319 | host = Model.Host.objects.get_by_shortname(target_id) | 363 | host = Model.Host.objects.get_by_shortname(target_id) |
308 | 320 | apply_host_policy(target_id, owner_unit, owner_relation) | 364 | apply_host_policy(target_id, owner_unit, owner_relation) |
309 | 365 | |||
310 | 321 | return host | 366 | return host |
311 | 322 | 367 | ||
312 | 323 | 368 | ||
313 | @@ -325,6 +370,7 @@ def get_pynag_service(target_id, service_name): | |||
314 | 325 | services = Model.Service.objects.filter( | 370 | services = Model.Service.objects.filter( |
315 | 326 | host_name=target_id, service_description=service_name | 371 | host_name=target_id, service_description=service_name |
316 | 327 | ) | 372 | ) |
317 | 373 | |||
318 | 328 | if len(services) == 0: | 374 | if len(services) == 0: |
319 | 329 | service = Model.Service() | 375 | service = Model.Service() |
320 | 330 | service.set_filename(CHARM_CFG) | 376 | service.set_filename(CHARM_CFG) |
321 | @@ -333,6 +379,7 @@ def get_pynag_service(target_id, service_name): | |||
322 | 333 | service.set_attribute("use", "generic-service") | 379 | service.set_attribute("use", "generic-service") |
323 | 334 | else: | 380 | else: |
324 | 335 | service = services[0] | 381 | service = services[0] |
325 | 382 | |||
326 | 336 | return service | 383 | return service |
327 | 337 | 384 | ||
328 | 338 | 385 | ||
329 | @@ -369,6 +416,7 @@ def initialize_inprogress_config(): | |||
330 | 369 | shutil.rmtree(INPROGRESS_DIR) | 416 | shutil.rmtree(INPROGRESS_DIR) |
331 | 370 | shutil.copytree(MAIN_NAGIOS_DIR, INPROGRESS_DIR) | 417 | shutil.copytree(MAIN_NAGIOS_DIR, INPROGRESS_DIR) |
332 | 371 | _replace_in_config(MAIN_NAGIOS_DIR, INPROGRESS_DIR) | 418 | _replace_in_config(MAIN_NAGIOS_DIR, INPROGRESS_DIR) |
333 | 419 | |||
334 | 372 | if os.path.exists(CHARM_CFG): | 420 | if os.path.exists(CHARM_CFG): |
335 | 373 | os.unlink(CHARM_CFG) | 421 | os.unlink(CHARM_CFG) |
336 | 374 | 422 | ||
337 | @@ -376,10 +424,13 @@ def initialize_inprogress_config(): | |||
338 | 376 | def flush_inprogress_config(): | 424 | def flush_inprogress_config(): |
339 | 377 | if not os.path.exists(INPROGRESS_DIR): | 425 | if not os.path.exists(INPROGRESS_DIR): |
340 | 378 | return | 426 | return |
341 | 427 | |||
342 | 379 | if os.path.exists(MAIN_NAGIOS_BAK): | 428 | if os.path.exists(MAIN_NAGIOS_BAK): |
343 | 380 | shutil.rmtree(MAIN_NAGIOS_BAK) | 429 | shutil.rmtree(MAIN_NAGIOS_BAK) |
344 | 430 | |||
345 | 381 | if os.path.exists(MAIN_NAGIOS_DIR): | 431 | if os.path.exists(MAIN_NAGIOS_DIR): |
346 | 382 | shutil.move(MAIN_NAGIOS_DIR, MAIN_NAGIOS_BAK) | 432 | shutil.move(MAIN_NAGIOS_DIR, MAIN_NAGIOS_BAK) |
347 | 383 | shutil.move(INPROGRESS_DIR, MAIN_NAGIOS_DIR) | 433 | shutil.move(INPROGRESS_DIR, MAIN_NAGIOS_DIR) |
349 | 384 | # now that directory has been changed need to update the config file to reflect the real stuff.. | 434 | # now that directory has been changed need to update the config file to |
350 | 435 | # reflect the real stuff.. | ||
351 | 385 | _commit_in_config(INPROGRESS_DIR, MAIN_NAGIOS_DIR) | 436 | _commit_in_config(INPROGRESS_DIR, MAIN_NAGIOS_DIR) |
352 | diff --git a/hooks/monitors_relation_changed.py b/hooks/monitors_relation_changed.py | |||
353 | index e3d5a5a..6df3303 100755 | |||
354 | --- a/hooks/monitors_relation_changed.py | |||
355 | +++ b/hooks/monitors_relation_changed.py | |||
356 | @@ -16,36 +16,32 @@ | |||
357 | 16 | # You should have received a copy of the GNU General Public License | 16 | # You should have received a copy of the GNU General Public License |
358 | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
359 | 18 | 18 | ||
360 | 19 | import sys | ||
361 | 20 | import os | 19 | import os |
362 | 21 | import yaml | ||
363 | 22 | import re | 20 | import re |
364 | 21 | import sys | ||
365 | 23 | from collections import defaultdict | 22 | from collections import defaultdict |
366 | 24 | 23 | ||
367 | 25 | from charmhelpers.core.hookenv import ( | 24 | from charmhelpers.core.hookenv import ( |
369 | 26 | relation_get, | 25 | DEBUG, |
370 | 27 | ingress_address, | 26 | ingress_address, |
371 | 27 | log, | ||
372 | 28 | related_units, | 28 | related_units, |
373 | 29 | relation_get, | ||
374 | 29 | relation_ids, | 30 | relation_ids, |
375 | 30 | log, | ||
376 | 31 | DEBUG, | ||
377 | 32 | ) | 31 | ) |
378 | 33 | 32 | ||
379 | 34 | from common import ( | 33 | from common import ( |
380 | 35 | customize_service, | 34 | customize_service, |
381 | 35 | flush_inprogress_config, | ||
382 | 36 | get_pynag_host, | 36 | get_pynag_host, |
383 | 37 | get_pynag_service, | 37 | get_pynag_service, |
384 | 38 | refresh_hostgroups, | ||
385 | 39 | initialize_inprogress_config, | 38 | initialize_inprogress_config, |
387 | 40 | flush_inprogress_config, | 39 | refresh_hostgroups, |
388 | 41 | ) | 40 | ) |
389 | 42 | 41 | ||
390 | 42 | import yaml | ||
391 | 43 | 43 | ||
397 | 44 | REQUIRED_REL_DATA_KEYS = [ | 44 | REQUIRED_REL_DATA_KEYS = ["target-address", "monitors", "target-id"] |
393 | 45 | "target-address", | ||
394 | 46 | "monitors", | ||
395 | 47 | "target-id", | ||
396 | 48 | ] | ||
398 | 49 | 45 | ||
399 | 50 | 46 | ||
400 | 51 | def _prepare_relation_data(unit, rid): | 47 | def _prepare_relation_data(unit, rid): |
401 | @@ -56,6 +52,7 @@ def _prepare_relation_data(unit, rid): | |||
402 | 56 | unit, rid | 52 | unit, rid |
403 | 57 | ) | 53 | ) |
404 | 58 | log(msg, level=DEBUG) | 54 | log(msg, level=DEBUG) |
405 | 55 | |||
406 | 59 | return {} | 56 | return {} |
407 | 60 | 57 | ||
408 | 61 | if rid.split(":")[0] == "nagios": | 58 | if rid.split(":")[0] == "nagios": |
409 | @@ -76,6 +73,7 @@ def _prepare_relation_data(unit, rid): | |||
410 | 76 | key, unit, rid | 73 | key, unit, rid |
411 | 77 | ) | 74 | ) |
412 | 78 | log(msg, level=DEBUG) | 75 | log(msg, level=DEBUG) |
413 | 76 | |||
414 | 79 | return {} | 77 | return {} |
415 | 80 | 78 | ||
416 | 81 | return relation_data | 79 | return relation_data |
417 | @@ -83,10 +81,12 @@ def _prepare_relation_data(unit, rid): | |||
418 | 83 | 81 | ||
419 | 84 | def _collect_relation_data(): | 82 | def _collect_relation_data(): |
420 | 85 | all_relations = defaultdict(dict) | 83 | all_relations = defaultdict(dict) |
421 | 84 | |||
422 | 86 | for relname in ["nagios", "monitors"]: | 85 | for relname in ["nagios", "monitors"]: |
423 | 87 | for relid in relation_ids(relname): | 86 | for relid in relation_ids(relname): |
424 | 88 | for unit in related_units(relid): | 87 | for unit in related_units(relid): |
425 | 89 | relation_data = _prepare_relation_data(unit=unit, rid=relid) | 88 | relation_data = _prepare_relation_data(unit=unit, rid=relid) |
426 | 89 | |||
427 | 90 | if relation_data: | 90 | if relation_data: |
428 | 91 | all_relations[relid][unit] = relation_data | 91 | all_relations[relid][unit] = relation_data |
429 | 92 | 92 | ||
430 | @@ -98,8 +98,10 @@ def main(argv): # noqa: C901 | |||
431 | 98 | # and target-address' so the hook can be tested without being in a hook | 98 | # and target-address' so the hook can be tested without being in a hook |
432 | 99 | # context. | 99 | # context. |
433 | 100 | # | 100 | # |
434 | 101 | |||
435 | 101 | if len(argv) > 1: | 102 | if len(argv) > 1: |
436 | 102 | relation_settings = {"monitors": open(argv[1]).read(), "target-id": argv[2]} | 103 | relation_settings = {"monitors": open(argv[1]).read(), "target-id": argv[2]} |
437 | 104 | |||
438 | 103 | if len(argv) > 3: | 105 | if len(argv) > 3: |
439 | 104 | relation_settings["target-address"] = argv[3] | 106 | relation_settings["target-address"] = argv[3] |
440 | 105 | all_relations = {"monitors:99": {"testing/0": relation_settings}} | 107 | all_relations = {"monitors:99": {"testing/0": relation_settings}} |
441 | @@ -108,11 +110,13 @@ def main(argv): # noqa: C901 | |||
442 | 108 | 110 | ||
443 | 109 | # Hack to work around http://pad.lv/1025478 | 111 | # Hack to work around http://pad.lv/1025478 |
444 | 110 | targets_with_addresses = set() | 112 | targets_with_addresses = set() |
445 | 113 | |||
446 | 111 | for relid, units in all_relations.iteritems(): | 114 | for relid, units in all_relations.iteritems(): |
447 | 112 | for unit, relation_settings in units.items(): | 115 | for unit, relation_settings in units.items(): |
448 | 113 | if "target-id" in relation_settings: | 116 | if "target-id" in relation_settings: |
449 | 114 | targets_with_addresses.add(relation_settings["target-id"]) | 117 | targets_with_addresses.add(relation_settings["target-id"]) |
450 | 115 | new_all_relations = {} | 118 | new_all_relations = {} |
451 | 119 | |||
452 | 116 | for relid, units in all_relations.iteritems(): | 120 | for relid, units in all_relations.iteritems(): |
453 | 117 | for unit, relation_settings in units.items(): | 121 | for unit, relation_settings in units.items(): |
454 | 118 | if relation_settings["target-id"] in targets_with_addresses: | 122 | if relation_settings["target-id"] in targets_with_addresses: |
455 | @@ -124,11 +128,14 @@ def main(argv): # noqa: C901 | |||
456 | 124 | initialize_inprogress_config() | 128 | initialize_inprogress_config() |
457 | 125 | # make a dict of machine ids to target-id hostnames | 129 | # make a dict of machine ids to target-id hostnames |
458 | 126 | all_hosts = {} | 130 | all_hosts = {} |
459 | 131 | |||
460 | 127 | for relid, units in all_relations.items(): | 132 | for relid, units in all_relations.items(): |
461 | 128 | for unit, relation_settings in units.iteritems(): | 133 | for unit, relation_settings in units.iteritems(): |
462 | 129 | machine_id = relation_settings.get("machine_id", None) | 134 | machine_id = relation_settings.get("machine_id", None) |
463 | 135 | |||
464 | 130 | if machine_id: | 136 | if machine_id: |
465 | 131 | all_hosts[machine_id] = relation_settings["target-id"] | 137 | all_hosts[machine_id] = relation_settings["target-id"] |
466 | 138 | |||
467 | 132 | for relid, units in all_relations.items(): | 139 | for relid, units in all_relations.items(): |
468 | 133 | apply_relation_config(relid, units, all_hosts) | 140 | apply_relation_config(relid, units, all_hosts) |
469 | 134 | refresh_hostgroups() | 141 | refresh_hostgroups() |
470 | @@ -142,10 +149,13 @@ def apply_relation_config(relid, units, all_hosts): # noqa: C901 | |||
471 | 142 | target_id = relation_settings["target-id"] | 149 | target_id = relation_settings["target-id"] |
472 | 143 | machine_id = relation_settings.get("machine_id", None) | 150 | machine_id = relation_settings.get("machine_id", None) |
473 | 144 | parent_host = None | 151 | parent_host = None |
474 | 152 | |||
475 | 145 | if machine_id: | 153 | if machine_id: |
476 | 146 | container_regex = re.compile(r"(\d+)/lx[cd]/\d+") | 154 | container_regex = re.compile(r"(\d+)/lx[cd]/\d+") |
477 | 155 | |||
478 | 147 | if container_regex.search(machine_id): | 156 | if container_regex.search(machine_id): |
479 | 148 | parent_machine = container_regex.search(machine_id).group(1) | 157 | parent_machine = container_regex.search(machine_id).group(1) |
480 | 158 | |||
481 | 149 | if parent_machine in all_hosts: | 159 | if parent_machine in all_hosts: |
482 | 150 | parent_host = all_hosts[parent_machine] | 160 | parent_host = all_hosts[parent_machine] |
483 | 151 | 161 | ||
484 | @@ -159,9 +169,11 @@ def apply_relation_config(relid, units, all_hosts): # noqa: C901 | |||
485 | 159 | 169 | ||
486 | 160 | # Output nagios config | 170 | # Output nagios config |
487 | 161 | host = get_pynag_host(target_id) | 171 | host = get_pynag_host(target_id) |
488 | 172 | |||
489 | 162 | if not target_address: | 173 | if not target_address: |
490 | 163 | raise Exception("No Target Address provied by NRPE service!") | 174 | raise Exception("No Target Address provied by NRPE service!") |
491 | 164 | host.set_attribute("address", target_address) | 175 | host.set_attribute("address", target_address) |
492 | 176 | |||
493 | 165 | if parent_host: | 177 | if parent_host: |
494 | 166 | # We assume that we only want one parent and will overwrite any | 178 | # We assume that we only want one parent and will overwrite any |
495 | 167 | # existing parents for this host. | 179 | # existing parents for this host. |
496 | @@ -172,6 +184,7 @@ def apply_relation_config(relid, units, all_hosts): # noqa: C901 | |||
497 | 172 | for mon_name, mon in mons.iteritems(): | 184 | for mon_name, mon in mons.iteritems(): |
498 | 173 | service_name = "%s-%s" % (target_id, mon_name) | 185 | service_name = "%s-%s" % (target_id, mon_name) |
499 | 174 | service = get_pynag_service(target_id, service_name) | 186 | service = get_pynag_service(target_id, service_name) |
500 | 187 | |||
501 | 175 | if customize_service(service, mon_family, mon_name, mon): | 188 | if customize_service(service, mon_family, mon_name, mon): |
502 | 176 | service.save() | 189 | service.save() |
503 | 177 | else: | 190 | else: |
504 | diff --git a/hooks/upgrade_charm.py b/hooks/upgrade_charm.py | |||
505 | index 5091f9a..ca410ef 100755 | |||
506 | --- a/hooks/upgrade_charm.py | |||
507 | +++ b/hooks/upgrade_charm.py | |||
508 | @@ -3,25 +3,26 @@ | |||
509 | 3 | # Rewritten from bash to python 3/2/2014 for charm helper inclusion | 3 | # Rewritten from bash to python 3/2/2014 for charm helper inclusion |
510 | 4 | # of SSL-Everywhere! | 4 | # of SSL-Everywhere! |
511 | 5 | import base64 | 5 | import base64 |
513 | 6 | from jinja2 import Template | 6 | import errno |
514 | 7 | import glob | 7 | import glob |
515 | 8 | import grp | ||
516 | 8 | import os | 9 | import os |
517 | 9 | |||
518 | 10 | # import re | ||
519 | 11 | import pwd | 10 | import pwd |
520 | 12 | import grp | ||
521 | 13 | import string | ||
522 | 14 | import stat | ||
523 | 15 | import errno | ||
524 | 16 | import shutil | 11 | import shutil |
525 | 12 | import stat | ||
526 | 13 | import string | ||
527 | 17 | import subprocess | 14 | import subprocess |
529 | 18 | import yaml | 15 | |
530 | 16 | from charmhelpers import fetch | ||
531 | 19 | from charmhelpers.contrib import ssl | 17 | from charmhelpers.contrib import ssl |
532 | 20 | from charmhelpers.core import hookenv, host | 18 | from charmhelpers.core import hookenv, host |
533 | 21 | from charmhelpers import fetch | ||
534 | 22 | 19 | ||
535 | 23 | from common import update_localhost | 20 | from common import update_localhost |
536 | 24 | 21 | ||
537 | 22 | from jinja2 import Template | ||
538 | 23 | |||
539 | 24 | import yaml | ||
540 | 25 | |||
541 | 25 | # Gather facts | 26 | # Gather facts |
542 | 26 | legacy_relations = hookenv.config("legacy") | 27 | legacy_relations = hookenv.config("legacy") |
543 | 27 | extra_config = hookenv.config("extraconfig") | 28 | extra_config = hookenv.config("extraconfig") |
544 | @@ -55,7 +56,7 @@ SSL_CONFIGURED = ssl_config in ["on", "only", "true"] | |||
545 | 55 | 56 | ||
546 | 56 | 57 | ||
547 | 57 | def warn_legacy_relations(): | 58 | def warn_legacy_relations(): |
549 | 58 | """Checks the charm relations for legacy relations. | 59 | """Check the charm relations for legacy relations. |
550 | 59 | 60 | ||
551 | 60 | Inserts warnings into the log about legacy relations, as they will be removed | 61 | Inserts warnings into the log about legacy relations, as they will be removed |
552 | 61 | in the future | 62 | in the future |
553 | @@ -70,7 +71,7 @@ def warn_legacy_relations(): | |||
554 | 70 | 71 | ||
555 | 71 | 72 | ||
556 | 72 | def parse_extra_contacts(yaml_string): | 73 | def parse_extra_contacts(yaml_string): |
558 | 73 | """Parses a list of extra Nagios contacts from a YAML string. | 74 | """Parse a list of extra Nagios contacts from a YAML string. |
559 | 74 | 75 | ||
560 | 75 | Does basic sanitization only | 76 | Does basic sanitization only |
561 | 76 | """ | 77 | """ |
562 | @@ -82,6 +83,7 @@ def parse_extra_contacts(yaml_string): | |||
563 | 82 | 83 | ||
564 | 83 | try: | 84 | try: |
565 | 84 | extra_contacts_raw = yaml.load(yaml_string, Loader=yaml.SafeLoader) or [] | 85 | extra_contacts_raw = yaml.load(yaml_string, Loader=yaml.SafeLoader) or [] |
566 | 86 | |||
567 | 85 | if not isinstance(extra_contacts_raw, list): | 87 | if not isinstance(extra_contacts_raw, list): |
568 | 86 | raise ValueError("not a list") | 88 | raise ValueError("not a list") |
569 | 87 | 89 | ||
570 | @@ -90,6 +92,7 @@ def parse_extra_contacts(yaml_string): | |||
571 | 90 | hookenv.log( | 92 | hookenv.log( |
572 | 91 | "Contact {} is missing fields.".format(contact), hookenv.WARNING | 93 | "Contact {} is missing fields.".format(contact), hookenv.WARNING |
573 | 92 | ) | 94 | ) |
574 | 95 | |||
575 | 93 | continue | 96 | continue |
576 | 94 | 97 | ||
577 | 95 | if set(contact["name"]) > set(valid_name_chars): | 98 | if set(contact["name"]) > set(valid_name_chars): |
578 | @@ -97,10 +100,12 @@ def parse_extra_contacts(yaml_string): | |||
579 | 97 | "Contact name {} is illegal".format(contact["name"]), | 100 | "Contact name {} is illegal".format(contact["name"]), |
580 | 98 | hookenv.WARNING, | 101 | hookenv.WARNING, |
581 | 99 | ) | 102 | ) |
582 | 103 | |||
583 | 100 | continue | 104 | continue |
584 | 101 | 105 | ||
585 | 102 | if "\n" in (contact["host"] + contact["service"]): | 106 | if "\n" in (contact["host"] + contact["service"]): |
586 | 103 | hookenv.log("Line breaks not allowed in commands", hookenv.WARNING) | 107 | hookenv.log("Line breaks not allowed in commands", hookenv.WARNING) |
587 | 108 | |||
588 | 104 | continue | 109 | continue |
589 | 105 | 110 | ||
590 | 106 | contact["name"] = contact["name"].lower() | 111 | contact["name"] = contact["name"].lower() |
591 | @@ -111,6 +116,7 @@ def parse_extra_contacts(yaml_string): | |||
592 | 111 | hookenv.log( | 116 | hookenv.log( |
593 | 112 | 'Invalid "extra_contacts" configuration: {}'.format(e), hookenv.WARNING | 117 | 'Invalid "extra_contacts" configuration: {}'.format(e), hookenv.WARNING |
594 | 113 | ) | 118 | ) |
595 | 119 | |||
596 | 114 | if len(extra_contacts_raw) != len(extra_contacts): | 120 | if len(extra_contacts_raw) != len(extra_contacts): |
597 | 115 | hookenv.log( | 121 | hookenv.log( |
598 | 116 | "Invalid extra_contacts config, found {} contacts defined, " | 122 | "Invalid extra_contacts config, found {} contacts defined, " |
599 | @@ -125,10 +131,12 @@ def parse_extra_contacts(yaml_string): | |||
600 | 125 | # proper nagios3 configuration file, otherwise remove the config | 131 | # proper nagios3 configuration file, otherwise remove the config |
601 | 126 | def write_extra_config(): | 132 | def write_extra_config(): |
602 | 127 | # Be predjudice about this - remove the file always. | 133 | # Be predjudice about this - remove the file always. |
603 | 134 | |||
604 | 128 | if host.file_hash("/etc/nagios3/conf.d/extra.cfg") is not None: | 135 | if host.file_hash("/etc/nagios3/conf.d/extra.cfg") is not None: |
605 | 129 | os.remove("/etc/nagios3/conf.d/extra.cfg") | 136 | os.remove("/etc/nagios3/conf.d/extra.cfg") |
606 | 130 | # If we have a config, then write it. the hook reconfiguration will | 137 | # If we have a config, then write it. the hook reconfiguration will |
607 | 131 | # handle the details | 138 | # handle the details |
608 | 139 | |||
609 | 132 | if extra_config is not None: | 140 | if extra_config is not None: |
610 | 133 | host.write_file("/etc/nagios3/conf.d/extra.cfg", extra_config) | 141 | host.write_file("/etc/nagios3/conf.d/extra.cfg", extra_config) |
611 | 134 | 142 | ||
612 | @@ -150,6 +158,7 @@ def fixpath(path): | |||
613 | 150 | if os.path.isdir(path): | 158 | if os.path.isdir(path): |
614 | 151 | st = os.stat(path) | 159 | st = os.stat(path) |
615 | 152 | os.chmod(path, st.st_mode | stat.S_IXOTH) | 160 | os.chmod(path, st.st_mode | stat.S_IXOTH) |
616 | 161 | |||
617 | 153 | if path != "/": | 162 | if path != "/": |
618 | 154 | fixpath(os.path.split(path)[0]) | 163 | fixpath(os.path.split(path)[0]) |
619 | 155 | 164 | ||
620 | @@ -163,6 +172,7 @@ def enable_livestatus_config(): | |||
621 | 163 | # Make the directory and fix perms on it | 172 | # Make the directory and fix perms on it |
622 | 164 | hookenv.log("Fixing perms on livestatus_path") | 173 | hookenv.log("Fixing perms on livestatus_path") |
623 | 165 | livestatus_dir = os.path.dirname(livestatus_path) | 174 | livestatus_dir = os.path.dirname(livestatus_path) |
624 | 175 | |||
625 | 166 | if not os.path.isdir(livestatus_dir): | 176 | if not os.path.isdir(livestatus_dir): |
626 | 167 | hookenv.log("Making path for livestatus_dir") | 177 | hookenv.log("Making path for livestatus_dir") |
627 | 168 | mkdir_p(livestatus_dir) | 178 | mkdir_p(livestatus_dir) |
628 | @@ -202,16 +212,16 @@ def enable_pagerduty_config(): | |||
629 | 202 | } | 212 | } |
630 | 203 | 213 | ||
631 | 204 | with open("hooks/templates/pagerduty_nagios_cfg.tmpl", "r") as f: | 214 | with open("hooks/templates/pagerduty_nagios_cfg.tmpl", "r") as f: |
633 | 205 | templateDef = f.read() | 215 | template_def = f.read() |
634 | 206 | 216 | ||
636 | 207 | t = Template(templateDef) | 217 | t = Template(template_def) |
637 | 208 | with open(pagerduty_cfg, "w") as f: | 218 | with open(pagerduty_cfg, "w") as f: |
638 | 209 | f.write(t.render(template_values)) | 219 | f.write(t.render(template_values)) |
639 | 210 | 220 | ||
640 | 211 | with open("hooks/templates/nagios-pagerduty-flush-cron.tmpl", "r") as f2: | 221 | with open("hooks/templates/nagios-pagerduty-flush-cron.tmpl", "r") as f2: |
642 | 212 | templateDef = f2.read() | 222 | template_def = f2.read() |
643 | 213 | 223 | ||
645 | 214 | t2 = Template(templateDef) | 224 | t2 = Template(template_def) |
646 | 215 | with open(pagerduty_cron, "w") as f2: | 225 | with open(pagerduty_cron, "w") as f2: |
647 | 216 | f2.write(t2.render(template_values)) | 226 | f2.write(t2.render(template_values)) |
648 | 217 | 227 | ||
649 | @@ -219,6 +229,7 @@ def enable_pagerduty_config(): | |||
650 | 219 | shutil.copy("files/pagerduty_nagios.pl", "/usr/local/bin/pagerduty_nagios.pl") | 229 | shutil.copy("files/pagerduty_nagios.pl", "/usr/local/bin/pagerduty_nagios.pl") |
651 | 220 | 230 | ||
652 | 221 | # Create the pagerduty queue dir | 231 | # Create the pagerduty queue dir |
653 | 232 | |||
654 | 222 | if not os.path.isdir(pagerduty_path): | 233 | if not os.path.isdir(pagerduty_path): |
655 | 223 | hookenv.log("Making path for pagerduty_path") | 234 | hookenv.log("Making path for pagerduty_path") |
656 | 224 | mkdir_p(pagerduty_path) | 235 | mkdir_p(pagerduty_path) |
657 | @@ -228,14 +239,18 @@ def enable_pagerduty_config(): | |||
658 | 228 | os.chown(pagerduty_path, uid, gid) | 239 | os.chown(pagerduty_path, uid, gid) |
659 | 229 | else: | 240 | else: |
660 | 230 | # Clean up the files if we don't want pagerduty | 241 | # Clean up the files if we don't want pagerduty |
661 | 242 | |||
662 | 231 | if os.path.isfile(pagerduty_cfg): | 243 | if os.path.isfile(pagerduty_cfg): |
663 | 232 | os.remove(pagerduty_cfg) | 244 | os.remove(pagerduty_cfg) |
664 | 245 | |||
665 | 233 | if os.path.isfile(pagerduty_cron): | 246 | if os.path.isfile(pagerduty_cron): |
666 | 234 | os.remove(pagerduty_cron) | 247 | os.remove(pagerduty_cron) |
667 | 235 | 248 | ||
668 | 236 | # Update contacts for admin | 249 | # Update contacts for admin |
669 | 250 | |||
670 | 237 | if enable_pagerduty: | 251 | if enable_pagerduty: |
671 | 238 | # avoid duplicates | 252 | # avoid duplicates |
672 | 253 | |||
673 | 239 | if "pagerduty" not in contactgroup_members: | 254 | if "pagerduty" not in contactgroup_members: |
674 | 240 | forced_contactgroup_members.append("pagerduty") | 255 | forced_contactgroup_members.append("pagerduty") |
675 | 241 | 256 | ||
676 | @@ -249,6 +264,7 @@ def enable_traps_config(): | |||
677 | 249 | if os.path.isfile(traps_cfg): | 264 | if os.path.isfile(traps_cfg): |
678 | 250 | os.remove(traps_cfg) | 265 | os.remove(traps_cfg) |
679 | 251 | hookenv.log("Send traps feature is disabled") | 266 | hookenv.log("Send traps feature is disabled") |
680 | 267 | |||
681 | 252 | return | 268 | return |
682 | 253 | 269 | ||
683 | 254 | hookenv.log("Send traps feature is enabled, target address is %s" % send_traps_to) | 270 | hookenv.log("Send traps feature is enabled, target address is %s" % send_traps_to) |
684 | @@ -259,9 +275,9 @@ def enable_traps_config(): | |||
685 | 259 | template_values = {"send_traps_to": send_traps_to} | 275 | template_values = {"send_traps_to": send_traps_to} |
686 | 260 | 276 | ||
687 | 261 | with open("hooks/templates/traps.tmpl", "r") as f: | 277 | with open("hooks/templates/traps.tmpl", "r") as f: |
689 | 262 | templateDef = f.read() | 278 | template_def = f.read() |
690 | 263 | 279 | ||
692 | 264 | t = Template(templateDef) | 280 | t = Template(template_def) |
693 | 265 | with open(traps_cfg, "w") as f: | 281 | with open(traps_cfg, "w") as f: |
694 | 266 | f.write(t.render(template_values)) | 282 | f.write(t.render(template_values)) |
695 | 267 | 283 | ||
696 | @@ -271,17 +287,20 @@ def update_contacts(): | |||
697 | 271 | admin_members = "" | 287 | admin_members = "" |
698 | 272 | contacts = [] | 288 | contacts = [] |
699 | 273 | admin_email = list(filter(None, set(hookenv.config("admin_email").split(",")))) | 289 | admin_email = list(filter(None, set(hookenv.config("admin_email").split(",")))) |
700 | 290 | |||
701 | 274 | if len(admin_email) == 0: | 291 | if len(admin_email) == 0: |
702 | 275 | hookenv.log("admin_email is unset, this isn't valid config") | 292 | hookenv.log("admin_email is unset, this isn't valid config") |
703 | 276 | hookenv.status_set("blocked", "admin_email is not configured") | 293 | hookenv.status_set("blocked", "admin_email is not configured") |
704 | 277 | exit(1) | 294 | exit(1) |
705 | 278 | hookenv.status_set("active", "ready") | 295 | hookenv.status_set("active", "ready") |
706 | 296 | |||
707 | 279 | if len(admin_email) == 1: | 297 | if len(admin_email) == 1: |
708 | 280 | hookenv.log("Setting one admin email address '%s'" % admin_email[0]) | 298 | hookenv.log("Setting one admin email address '%s'" % admin_email[0]) |
709 | 281 | contacts = [{"contact_name": "root", "alias": "Root", "email": admin_email[0]}] | 299 | contacts = [{"contact_name": "root", "alias": "Root", "email": admin_email[0]}] |
710 | 282 | elif len(admin_email) > 1: | 300 | elif len(admin_email) > 1: |
711 | 283 | hookenv.log("Setting %d admin email addresses" % len(admin_email)) | 301 | hookenv.log("Setting %d admin email addresses" % len(admin_email)) |
712 | 284 | contacts = [] | 302 | contacts = [] |
713 | 303 | |||
714 | 285 | for email in admin_email: | 304 | for email in admin_email: |
715 | 286 | contact_name = email.replace("@", "").replace(".", "").lower() | 305 | contact_name = email.replace("@", "").replace(".", "").lower() |
716 | 287 | contact_alias = contact_name.capitalize() | 306 | contact_alias = contact_name.capitalize() |
717 | @@ -292,6 +311,7 @@ def update_contacts(): | |||
718 | 292 | admin_members = ", ".join([c["contact_name"] for c in contacts]) | 311 | admin_members = ", ".join([c["contact_name"] for c in contacts]) |
719 | 293 | 312 | ||
720 | 294 | resulting_members = contactgroup_members | 313 | resulting_members = contactgroup_members |
721 | 314 | |||
722 | 295 | if admin_members: | 315 | if admin_members: |
723 | 296 | # if multiple admin emails are passed ignore contactgroup_members | 316 | # if multiple admin emails are passed ignore contactgroup_members |
724 | 297 | resulting_members = admin_members | 317 | resulting_members = admin_members |
725 | @@ -338,8 +358,10 @@ def update_contacts(): | |||
726 | 338 | 358 | ||
727 | 339 | def ssl_configured(): | 359 | def ssl_configured(): |
728 | 340 | allowed_options = ["on", "only"] | 360 | allowed_options = ["on", "only"] |
729 | 361 | |||
730 | 341 | if str(ssl_config).lower() in allowed_options: | 362 | if str(ssl_config).lower() in allowed_options: |
731 | 342 | return True | 363 | return True |
732 | 364 | |||
733 | 343 | return False | 365 | return False |
734 | 344 | 366 | ||
735 | 345 | 367 | ||
736 | @@ -359,8 +381,10 @@ chain_file = "/etc/ssl/certs/%s.csr" % (cert_domain) | |||
737 | 359 | def check_ssl_files(): | 381 | def check_ssl_files(): |
738 | 360 | key = os.path.exists(deploy_key_path) | 382 | key = os.path.exists(deploy_key_path) |
739 | 361 | cert = os.path.exists(deploy_cert_path) | 383 | cert = os.path.exists(deploy_cert_path) |
740 | 384 | |||
741 | 362 | if key is False or cert is False: | 385 | if key is False or cert is False: |
742 | 363 | return False | 386 | return False |
743 | 387 | |||
744 | 364 | return True | 388 | return True |
745 | 365 | 389 | ||
746 | 366 | 390 | ||
747 | @@ -370,9 +394,11 @@ def decode_ssl_keys(): | |||
748 | 370 | hookenv.log("Writing key from config ssl_key: %s" % key_file) | 394 | hookenv.log("Writing key from config ssl_key: %s" % key_file) |
749 | 371 | with open(key_file, "w") as f: | 395 | with open(key_file, "w") as f: |
750 | 372 | f.write(str(base64.b64decode(hookenv.config("ssl_key")))) | 396 | f.write(str(base64.b64decode(hookenv.config("ssl_key")))) |
751 | 397 | |||
752 | 373 | if hookenv.config("ssl_cert"): | 398 | if hookenv.config("ssl_cert"): |
753 | 374 | with open(cert_file, "w") as f: | 399 | with open(cert_file, "w") as f: |
754 | 375 | f.write(str(base64.b64decode(hookenv.config("ssl_cert")))) | 400 | f.write(str(base64.b64decode(hookenv.config("ssl_cert")))) |
755 | 401 | |||
756 | 376 | if hookenv.config("ssl_chain"): | 402 | if hookenv.config("ssl_chain"): |
757 | 377 | with open(chain_file, "w") as f: | 403 | with open(chain_file, "w") as f: |
758 | 378 | f.write(str(base64.b64decode(hookenv.config("ssl_cert")))) | 404 | f.write(str(base64.b64decode(hookenv.config("ssl_cert")))) |
759 | @@ -382,10 +408,13 @@ def enable_ssl(): | |||
760 | 382 | # Set the basename of all ssl files | 408 | # Set the basename of all ssl files |
761 | 383 | 409 | ||
762 | 384 | # Validate that we have configs, and generate a self signed certificate. | 410 | # Validate that we have configs, and generate a self signed certificate. |
763 | 411 | |||
764 | 385 | if not hookenv.config("ssl_cert"): | 412 | if not hookenv.config("ssl_cert"): |
765 | 386 | # bail if keys already exist | 413 | # bail if keys already exist |
766 | 414 | |||
767 | 387 | if os.path.exists(cert_file): | 415 | if os.path.exists(cert_file): |
768 | 388 | hookenv.log("Keys exist, not creating keys!", "WARNING") | 416 | hookenv.log("Keys exist, not creating keys!", "WARNING") |
769 | 417 | |||
770 | 389 | return | 418 | return |
771 | 390 | # Generate a self signed key using CharmHelpers | 419 | # Generate a self signed key using CharmHelpers |
772 | 391 | hookenv.log("Generating Self Signed Certificate", "INFO") | 420 | hookenv.log("Generating Self Signed Certificate", "INFO") |
773 | @@ -405,6 +434,7 @@ def update_config(): | |||
774 | 405 | local_host_name = "nagios" | 434 | local_host_name = "nagios" |
775 | 406 | principal_unitname = hookenv.principal_unit() | 435 | principal_unitname = hookenv.principal_unit() |
776 | 407 | # Fallback to using "primary" if it exists. | 436 | # Fallback to using "primary" if it exists. |
777 | 437 | |||
778 | 408 | if principal_unitname: | 438 | if principal_unitname: |
779 | 409 | local_host_name = principal_unitname | 439 | local_host_name = principal_unitname |
780 | 410 | else: | 440 | else: |
781 | @@ -437,16 +467,16 @@ def update_config(): | |||
782 | 437 | } | 467 | } |
783 | 438 | 468 | ||
784 | 439 | with open("hooks/templates/nagios-cfg.tmpl", "r") as f: | 469 | with open("hooks/templates/nagios-cfg.tmpl", "r") as f: |
786 | 440 | templateDef = f.read() | 470 | template_def = f.read() |
787 | 441 | 471 | ||
789 | 442 | t = Template(templateDef) | 472 | t = Template(template_def) |
790 | 443 | with open(nagios_cfg, "w") as f: | 473 | with open(nagios_cfg, "w") as f: |
791 | 444 | f.write(t.render(template_values)) | 474 | f.write(t.render(template_values)) |
792 | 445 | 475 | ||
793 | 446 | with open("hooks/templates/localhost_nagios2.cfg.tmpl", "r") as f: | 476 | with open("hooks/templates/localhost_nagios2.cfg.tmpl", "r") as f: |
795 | 447 | templateDef = f.read() | 477 | template_def = f.read() |
796 | 448 | 478 | ||
798 | 449 | t = Template(templateDef) | 479 | t = Template(template_def) |
799 | 450 | with open("/etc/nagios3/conf.d/localhost_nagios2.cfg", "w") as f: | 480 | with open("/etc/nagios3/conf.d/localhost_nagios2.cfg", "w") as f: |
800 | 451 | f.write(t.render(template_values)) | 481 | f.write(t.render(template_values)) |
801 | 452 | 482 | ||
802 | @@ -456,9 +486,9 @@ def update_config(): | |||
803 | 456 | def update_cgi_config(): | 486 | def update_cgi_config(): |
804 | 457 | template_values = {"nagiosadmin": nagiosadmin, "ro_password": ro_password} | 487 | template_values = {"nagiosadmin": nagiosadmin, "ro_password": ro_password} |
805 | 458 | with open("hooks/templates/nagios-cgi.tmpl", "r") as f: | 488 | with open("hooks/templates/nagios-cgi.tmpl", "r") as f: |
807 | 459 | templateDef = f.read() | 489 | template_def = f.read() |
808 | 460 | 490 | ||
810 | 461 | t = Template(templateDef) | 491 | t = Template(template_def) |
811 | 462 | with open(nagios_cgi_cfg, "w") as f: | 492 | with open(nagios_cgi_cfg, "w") as f: |
812 | 463 | f.write(t.render(template_values)) | 493 | f.write(t.render(template_values)) |
813 | 464 | 494 | ||
814 | @@ -472,12 +502,12 @@ def update_cgi_config(): | |||
815 | 472 | # note: i tried to use cheetah, and it barfed, several times. It can go play | 502 | # note: i tried to use cheetah, and it barfed, several times. It can go play |
816 | 473 | # in a fire. I'm jusing jinja2. | 503 | # in a fire. I'm jusing jinja2. |
817 | 474 | def update_apache(): | 504 | def update_apache(): |
819 | 475 | """ | 505 | """Add SSL keys to default-ssl config. |
820 | 506 | |||
821 | 476 | Nagios3 is deployed as a global apache application from the archive. | 507 | Nagios3 is deployed as a global apache application from the archive. |
822 | 477 | We'll get a little funky and add the SSL keys to the default-ssl config | 508 | We'll get a little funky and add the SSL keys to the default-ssl config |
823 | 478 | which sets our keys, including the self-signed ones, as the host keyfiles. | 509 | which sets our keys, including the self-signed ones, as the host keyfiles. |
824 | 479 | """ | 510 | """ |
825 | 480 | |||
826 | 481 | # Start by Setting the ports.conf | 511 | # Start by Setting the ports.conf |
827 | 482 | 512 | ||
828 | 483 | with open("hooks/templates/ports-cfg.jinja2", "r") as f: | 513 | with open("hooks/templates/ports-cfg.jinja2", "r") as f: |
829 | @@ -489,6 +519,7 @@ def update_apache(): | |||
830 | 489 | f.write(t.render({"enable_http": HTTP_ENABLED})) | 519 | f.write(t.render({"enable_http": HTTP_ENABLED})) |
831 | 490 | 520 | ||
832 | 491 | # Next setup the default-ssl.conf | 521 | # Next setup the default-ssl.conf |
833 | 522 | |||
834 | 492 | if os.path.exists(chain_file) and os.path.getsize(chain_file) > 0: | 523 | if os.path.exists(chain_file) and os.path.getsize(chain_file) > 0: |
835 | 493 | ssl_chain = chain_file | 524 | ssl_chain = chain_file |
836 | 494 | else: | 525 | else: |
837 | @@ -515,6 +546,7 @@ def update_apache(): | |||
838 | 515 | # Configure the behavior of http sites | 546 | # Configure the behavior of http sites |
839 | 516 | sites = glob.glob("/etc/apache2/sites-available/*.conf") | 547 | sites = glob.glob("/etc/apache2/sites-available/*.conf") |
840 | 517 | non_ssl = set(sites) - {ssl_conf} | 548 | non_ssl = set(sites) - {ssl_conf} |
841 | 549 | |||
842 | 518 | for each in non_ssl: | 550 | for each in non_ssl: |
843 | 519 | site = os.path.basename(each).rsplit(".", 1)[0] | 551 | site = os.path.basename(each).rsplit(".", 1)[0] |
844 | 520 | Apache2Site(site).action(enabled=HTTP_ENABLED) | 552 | Apache2Site(site).action(enabled=HTTP_ENABLED) |
845 | @@ -549,6 +581,7 @@ class Apache2Site: | |||
846 | 549 | def _enable(self): | 581 | def _enable(self): |
847 | 550 | hookenv.log("Apache2Site: Enabling %s..." % self.site, "INFO") | 582 | hookenv.log("Apache2Site: Enabling %s..." % self.site, "INFO") |
848 | 551 | self._call(["a2ensite", self.site]) | 583 | self._call(["a2ensite", self.site]) |
849 | 584 | |||
850 | 552 | if self.port == 443: | 585 | if self.port == 443: |
851 | 553 | self._call(["a2enmod", "ssl"]) | 586 | self._call(["a2enmod", "ssl"]) |
852 | 554 | hookenv.open_port(self.port) | 587 | hookenv.open_port(self.port) |
853 | @@ -562,6 +595,7 @@ class Apache2Site: | |||
854 | 562 | def update_password(account, password): | 595 | def update_password(account, password): |
855 | 563 | """Update the charm and Apache's record of the password for the supplied account.""" | 596 | """Update the charm and Apache's record of the password for the supplied account.""" |
856 | 564 | account_file = "".join(["/var/lib/juju/nagios.", account, ".passwd"]) | 597 | account_file = "".join(["/var/lib/juju/nagios.", account, ".passwd"]) |
857 | 598 | |||
858 | 565 | if password: | 599 | if password: |
859 | 566 | with open(account_file, "w") as f: | 600 | with open(account_file, "w") as f: |
860 | 567 | f.write(password) | 601 | f.write(password) |
861 | @@ -580,6 +614,7 @@ write_extra_config() | |||
862 | 580 | # enable_traps_config and enable_pagerduty_config modify forced_contactgroup_members | 614 | # enable_traps_config and enable_pagerduty_config modify forced_contactgroup_members |
863 | 581 | # they need to run before update_contacts that will consume that global var. | 615 | # they need to run before update_contacts that will consume that global var. |
864 | 582 | enable_traps_config() | 616 | enable_traps_config() |
865 | 617 | |||
866 | 583 | if ssl_configured(): | 618 | if ssl_configured(): |
867 | 584 | enable_ssl() | 619 | enable_ssl() |
868 | 585 | enable_pagerduty_config() | 620 | enable_pagerduty_config() |
869 | @@ -591,8 +626,10 @@ update_localhost() | |||
870 | 591 | update_cgi_config() | 626 | update_cgi_config() |
871 | 592 | update_contacts() | 627 | update_contacts() |
872 | 593 | update_password("nagiosro", ro_password) | 628 | update_password("nagiosro", ro_password) |
873 | 629 | |||
874 | 594 | if password: | 630 | if password: |
875 | 595 | update_password(nagiosadmin, password) | 631 | update_password(nagiosadmin, password) |
876 | 632 | |||
877 | 596 | if nagiosadmin != "nagiosadmin": | 633 | if nagiosadmin != "nagiosadmin": |
878 | 597 | update_password("nagiosadmin", False) | 634 | update_password("nagiosadmin", False) |
879 | 598 | 635 | ||
880 | diff --git a/hooks/website_relation_joined.py b/hooks/website_relation_joined.py | |||
881 | index 706a561..126e7cd 100755 | |||
882 | --- a/hooks/website_relation_joined.py | |||
883 | +++ b/hooks/website_relation_joined.py | |||
884 | @@ -15,18 +15,15 @@ | |||
885 | 15 | # You should have received a copy of the GNU General Public License | 15 | # You should have received a copy of the GNU General Public License |
886 | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 16 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
887 | 17 | 17 | ||
889 | 18 | import common | 18 | from charmhelpers.core.hookenv import config, log, relation_set |
890 | 19 | 19 | ||
896 | 20 | from charmhelpers.core.hookenv import ( | 20 | import common |
892 | 21 | config, | ||
893 | 22 | log, | ||
894 | 23 | relation_set, | ||
895 | 24 | ) | ||
897 | 25 | 21 | ||
898 | 26 | 22 | ||
899 | 27 | def main(): | 23 | def main(): |
900 | 28 | relation_data = {"hostname": common.get_local_ingress_address()} | 24 | relation_data = {"hostname": common.get_local_ingress_address()} |
901 | 29 | sslcfg = config()["ssl"] | 25 | sslcfg = config()["ssl"] |
902 | 26 | |||
903 | 30 | if sslcfg == "only": | 27 | if sslcfg == "only": |
904 | 31 | relation_data["port"] = 443 | 28 | relation_data["port"] = 443 |
905 | 32 | else: | 29 | else: |
906 | diff --git a/tests/functional/conftest.py b/tests/functional/conftest.py | |||
907 | index a31034c..7ab5b1a 100644 | |||
908 | --- a/tests/functional/conftest.py | |||
909 | +++ b/tests/functional/conftest.py | |||
910 | @@ -42,9 +42,11 @@ async def model(controller): | |||
911 | 42 | model = await controller.add_model(model_name) | 42 | model = await controller.add_model(model_name) |
912 | 43 | yield model | 43 | yield model |
913 | 44 | await model.disconnect() | 44 | await model.disconnect() |
914 | 45 | |||
915 | 45 | if os.getenv("PYTEST_KEEP_MODEL"): | 46 | if os.getenv("PYTEST_KEEP_MODEL"): |
916 | 46 | return | 47 | return |
917 | 47 | await controller.destroy_model(model_name) | 48 | await controller.destroy_model(model_name) |
918 | 49 | |||
919 | 48 | while model_name in await controller.list_models(): | 50 | while model_name in await controller.list_models(): |
920 | 49 | await asyncio.sleep(1) | 51 | await asyncio.sleep(1) |
921 | 50 | 52 | ||
922 | @@ -60,7 +62,7 @@ async def current_model(): | |||
923 | 60 | 62 | ||
924 | 61 | @pytest.fixture | 63 | @pytest.fixture |
925 | 62 | async def get_app(model): | 64 | async def get_app(model): |
927 | 63 | """Return the application requested.""" | 65 | """Return the application requested.""" # noqa D202 |
928 | 64 | 66 | ||
929 | 65 | async def _get_app(name): | 67 | async def _get_app(name): |
930 | 66 | try: | 68 | try: |
931 | @@ -73,11 +75,12 @@ async def get_app(model): | |||
932 | 73 | 75 | ||
933 | 74 | @pytest.fixture | 76 | @pytest.fixture |
934 | 75 | async def get_unit(model): | 77 | async def get_unit(model): |
936 | 76 | """Return the requested <app_name>/<unit_number> unit.""" | 78 | """Return the requested <app_name>/<unit_number> unit.""" # noqa D202 |
937 | 77 | 79 | ||
938 | 78 | async def _get_unit(name): | 80 | async def _get_unit(name): |
939 | 79 | try: | 81 | try: |
940 | 80 | (app_name, unit_number) = name.split("/") | 82 | (app_name, unit_number) = name.split("/") |
941 | 83 | |||
942 | 81 | return model.applications[app_name].units[unit_number] | 84 | return model.applications[app_name].units[unit_number] |
943 | 82 | except (KeyError, ValueError): | 85 | except (KeyError, ValueError): |
944 | 83 | raise JujuError("Cannot find unit {}".format(name)) | 86 | raise JujuError("Cannot find unit {}".format(name)) |
945 | @@ -87,7 +90,7 @@ async def get_unit(model): | |||
946 | 87 | 90 | ||
947 | 88 | @pytest.fixture | 91 | @pytest.fixture |
948 | 89 | async def get_entity(model, get_unit, get_app): | 92 | async def get_entity(model, get_unit, get_app): |
950 | 90 | """Return a unit or an application.""" | 93 | """Return a unit or an application.""" # noqa D202 |
951 | 91 | 94 | ||
952 | 92 | async def _get_entity(name): | 95 | async def _get_entity(name): |
953 | 93 | try: | 96 | try: |
954 | @@ -103,7 +106,7 @@ async def get_entity(model, get_unit, get_app): | |||
955 | 103 | 106 | ||
956 | 104 | @pytest.fixture | 107 | @pytest.fixture |
957 | 105 | async def run_command(get_unit): | 108 | async def run_command(get_unit): |
959 | 106 | """Run a command on a unit.""" | 109 | """Run a command on a unit.""" # noqa D202 |
960 | 107 | 110 | ||
961 | 108 | async def _run_command(cmd, target): | 111 | async def _run_command(cmd, target): |
962 | 109 | """ | 112 | """ |
963 | @@ -114,6 +117,7 @@ async def run_command(get_unit): | |||
964 | 114 | """ | 117 | """ |
965 | 115 | unit = target if type(target) is juju.unit.Unit else await get_unit(target) | 118 | unit = target if type(target) is juju.unit.Unit else await get_unit(target) |
966 | 116 | action = await unit.run(cmd) | 119 | action = await unit.run(cmd) |
967 | 120 | |||
968 | 117 | return action.results | 121 | return action.results |
969 | 118 | 122 | ||
970 | 119 | return _run_command | 123 | return _run_command |
971 | @@ -121,16 +125,16 @@ async def run_command(get_unit): | |||
972 | 121 | 125 | ||
973 | 122 | @pytest.fixture | 126 | @pytest.fixture |
974 | 123 | async def file_stat(run_command): | 127 | async def file_stat(run_command): |
977 | 124 | """ | 128 | """Run stat on a file. |
976 | 125 | Run stat on a file. | ||
978 | 126 | 129 | ||
979 | 127 | :param path: File path | 130 | :param path: File path |
980 | 128 | :param target: Unit object or unit name string | 131 | :param target: Unit object or unit name string |
982 | 129 | """ | 132 | """ # noqa D202 |
983 | 130 | 133 | ||
984 | 131 | async def _file_stat(path, target): | 134 | async def _file_stat(path, target): |
985 | 132 | cmd = STAT_FILE % path | 135 | cmd = STAT_FILE % path |
986 | 133 | results = await run_command(cmd, target) | 136 | results = await run_command(cmd, target) |
987 | 137 | |||
988 | 134 | return json.loads(results["Stdout"]) | 138 | return json.loads(results["Stdout"]) |
989 | 135 | 139 | ||
990 | 136 | return _file_stat | 140 | return _file_stat |
991 | @@ -138,16 +142,17 @@ async def file_stat(run_command): | |||
992 | 138 | 142 | ||
993 | 139 | @pytest.fixture | 143 | @pytest.fixture |
994 | 140 | async def file_contents(run_command): | 144 | async def file_contents(run_command): |
996 | 141 | """Return the contents of a file.""" | 145 | """Return the contents of a file.""" # noqa D202 |
997 | 142 | 146 | ||
998 | 143 | async def _file_contents(path, target): | 147 | async def _file_contents(path, target): |
999 | 144 | """Return the contents of a file. | 148 | """Return the contents of a file. |
1000 | 145 | 149 | ||
1003 | 146 | :param path: File path | 150 | :param path: File path |
1004 | 147 | :param target: Unit object or unit name string | 151 | :param target: Unit object or unit name string |
1005 | 148 | """ | 152 | """ |
1006 | 149 | cmd = "cat {}".format(path) | 153 | cmd = "cat {}".format(path) |
1007 | 150 | results = await run_command(cmd, target) | 154 | results = await run_command(cmd, target) |
1008 | 155 | |||
1009 | 151 | return results["Stdout"] | 156 | return results["Stdout"] |
1010 | 152 | 157 | ||
1011 | 153 | return _file_contents | 158 | return _file_contents |
1012 | @@ -155,7 +160,7 @@ async def file_contents(run_command): | |||
1013 | 155 | 160 | ||
1014 | 156 | @pytest.fixture | 161 | @pytest.fixture |
1015 | 157 | async def reconfigure_app(get_app, model): | 162 | async def reconfigure_app(get_app, model): |
1017 | 158 | """Apply a different config to the requested app.""" | 163 | """Apply a different config to the requested app.""" # noqa D202 |
1018 | 159 | 164 | ||
1019 | 160 | async def _reconfigure_app(cfg, target): | 165 | async def _reconfigure_app(cfg, target): |
1020 | 161 | application = ( | 166 | application = ( |
1021 | @@ -172,7 +177,7 @@ async def reconfigure_app(get_app, model): | |||
1022 | 172 | 177 | ||
1023 | 173 | @pytest.fixture | 178 | @pytest.fixture |
1024 | 174 | async def create_group(run_command): | 179 | async def create_group(run_command): |
1026 | 175 | """Create the UNIX group specified.""" | 180 | """Create the UNIX group specified.""" # noqa D202 |
1027 | 176 | 181 | ||
1028 | 177 | async def _create_group(group_name, target): | 182 | async def _create_group(group_name, target): |
1029 | 178 | cmd = "sudo groupadd %s" % group_name | 183 | cmd = "sudo groupadd %s" % group_name |
1030 | @@ -185,11 +190,7 @@ pytestmark = pytest.mark.asyncio | |||
1031 | 185 | 190 | ||
1032 | 186 | CHARM_BUILD_DIR = os.getenv("CHARM_BUILD_DIR", "..").rstrip("/") | 191 | CHARM_BUILD_DIR = os.getenv("CHARM_BUILD_DIR", "..").rstrip("/") |
1033 | 187 | 192 | ||
1039 | 188 | SERIES = [ | 193 | SERIES = ["trusty", "xenial", "bionic"] |
1035 | 189 | "trusty", | ||
1036 | 190 | "xenial", | ||
1037 | 191 | "bionic", | ||
1038 | 192 | ] | ||
1040 | 193 | 194 | ||
1041 | 194 | 195 | ||
1042 | 195 | ############ | 196 | ############ |
1043 | @@ -210,6 +211,7 @@ async def relatives(model, series): | |||
1044 | 210 | ) | 211 | ) |
1045 | 211 | 212 | ||
1046 | 212 | mysql = "mysql" | 213 | mysql = "mysql" |
1047 | 214 | |||
1048 | 213 | if series != "trusty": | 215 | if series != "trusty": |
1049 | 214 | mysql = "percona-cluster" | 216 | mysql = "percona-cluster" |
1050 | 215 | 217 | ||
1051 | @@ -224,7 +226,7 @@ async def relatives(model, series): | |||
1052 | 224 | ) | 226 | ) |
1053 | 225 | await model.block_until( | 227 | await model.block_until( |
1054 | 226 | lambda: mysql_app.units[0].workload_status == "active" | 228 | lambda: mysql_app.units[0].workload_status == "active" |
1056 | 227 | and mysql_app.units[0].agent_status == "idle" | 229 | and mysql_app.units[0].agent_status == "idle" # noqa W503 |
1057 | 228 | ) | 230 | ) |
1058 | 229 | 231 | ||
1059 | 230 | yield { | 232 | yield { |
1060 | @@ -256,10 +258,11 @@ async def deploy_app(relatives, model, series): | |||
1061 | 256 | ) | 258 | ) |
1062 | 257 | await model.block_until( | 259 | await model.block_until( |
1063 | 258 | lambda: nagios_app.units[0].agent_status == "idle" | 260 | lambda: nagios_app.units[0].agent_status == "idle" |
1065 | 259 | and relatives["mysql"]["app"].units[0].agent_status == "idle" | 261 | and relatives["mysql"]["app"].units[0].agent_status == "idle" # noqa W503 |
1066 | 260 | ) | 262 | ) |
1067 | 261 | 263 | ||
1068 | 262 | yield nagios_app | 264 | yield nagios_app |
1069 | 265 | |||
1070 | 263 | if os.getenv("PYTEST_KEEP_MODEL"): | 266 | if os.getenv("PYTEST_KEEP_MODEL"): |
1071 | 264 | return | 267 | return |
1072 | 265 | 268 | ||
1073 | @@ -277,6 +280,7 @@ class Agent: | |||
1074 | 277 | 280 | ||
1075 | 278 | def is_active(self, status): | 281 | def is_active(self, status): |
1076 | 279 | u = self.u | 282 | u = self.u |
1077 | 283 | |||
1078 | 280 | return u.agent_status == status and u.workload_status == "active" | 284 | return u.agent_status == status and u.workload_status == "active" |
1079 | 281 | 285 | ||
1080 | 282 | async def block_until_or_timeout(self, lambda_f, **kwargs): | 286 | async def block_until_or_timeout(self, lambda_f, **kwargs): |
1081 | @@ -299,6 +303,7 @@ async def unit(model, deploy_app): | |||
1082 | 299 | """Return the unit we've deployed.""" | 303 | """Return the unit we've deployed.""" |
1083 | 300 | unit = Agent(deploy_app.units[0], deploy_app) | 304 | unit = Agent(deploy_app.units[0], deploy_app) |
1084 | 301 | await unit.block_until(lambda: unit.is_active("idle")) | 305 | await unit.block_until(lambda: unit.is_active("idle")) |
1085 | 306 | |||
1086 | 302 | return unit | 307 | return unit |
1087 | 303 | 308 | ||
1088 | 304 | 309 | ||
1089 | @@ -306,4 +311,5 @@ async def unit(model, deploy_app): | |||
1090 | 306 | async def auth(file_contents, unit): | 311 | async def auth(file_contents, unit): |
1091 | 307 | """Return the basic auth credentials.""" | 312 | """Return the basic auth credentials.""" |
1092 | 308 | nagiospwd = await file_contents("/var/lib/juju/nagios.passwd", unit.u) | 313 | nagiospwd = await file_contents("/var/lib/juju/nagios.passwd", unit.u) |
1093 | 314 | |||
1094 | 309 | return "nagiosadmin", nagiospwd.strip() | 315 | return "nagiosadmin", nagiospwd.strip() |
1095 | diff --git a/tests/functional/test_config.py b/tests/functional/test_config.py | |||
1096 | index 1b9310a..6bc36a6 100644 | |||
1097 | --- a/tests/functional/test_config.py | |||
1098 | +++ b/tests/functional/test_config.py | |||
1099 | @@ -1,5 +1,7 @@ | |||
1100 | 1 | from async_generator import asynccontextmanager | 1 | from async_generator import asynccontextmanager |
1101 | 2 | |||
1102 | 2 | import pytest | 3 | import pytest |
1103 | 4 | |||
1104 | 3 | import requests | 5 | import requests |
1105 | 4 | 6 | ||
1106 | 5 | pytestmark = pytest.mark.asyncio | 7 | pytestmark = pytest.mark.asyncio |
1107 | @@ -18,8 +20,7 @@ async def config(unit, item, test_value, post_test): | |||
1108 | 18 | 20 | ||
1109 | 19 | @pytest.fixture(params=["on", "only"]) | 21 | @pytest.fixture(params=["on", "only"]) |
1110 | 20 | async def ssl(unit, request): | 22 | async def ssl(unit, request): |
1113 | 21 | """ | 23 | """Enable SSL before a test, then disable after test. |
1112 | 22 | Enable SSL before a test, then disable after test | ||
1114 | 23 | 24 | ||
1115 | 24 | :param Agent unit: unit from the fixture | 25 | :param Agent unit: unit from the fixture |
1116 | 25 | :param request: test parameters | 26 | :param request: test parameters |
1117 | @@ -30,8 +31,7 @@ async def ssl(unit, request): | |||
1118 | 30 | 31 | ||
1119 | 31 | @pytest.fixture | 32 | @pytest.fixture |
1120 | 32 | async def extra_config(unit): | 33 | async def extra_config(unit): |
1123 | 33 | """ | 34 | """Enable extraconfig for a test, and revert afterwards. |
1122 | 34 | Enable extraconfig for a test, and revert afterwards | ||
1124 | 35 | 35 | ||
1125 | 36 | :param Agent unit: unit from the fixture | 36 | :param Agent unit: unit from the fixture |
1126 | 37 | """ | 37 | """ |
1127 | @@ -48,8 +48,7 @@ async def extra_config(unit): | |||
1128 | 48 | 48 | ||
1129 | 49 | @pytest.fixture | 49 | @pytest.fixture |
1130 | 50 | async def livestatus_path(unit): | 50 | async def livestatus_path(unit): |
1133 | 51 | """ | 51 | """Enable livestatus before a test, then disable after test. |
1132 | 52 | Enable livestatus before a test, then disable after test | ||
1134 | 53 | 52 | ||
1135 | 54 | :param Agent unit: unit from the fixture | 53 | :param Agent unit: unit from the fixture |
1136 | 55 | """ | 54 | """ |
1137 | @@ -60,8 +59,7 @@ async def livestatus_path(unit): | |||
1138 | 60 | 59 | ||
1139 | 61 | @pytest.fixture() | 60 | @pytest.fixture() |
1140 | 62 | async def enable_pagerduty(unit): | 61 | async def enable_pagerduty(unit): |
1143 | 63 | """ | 62 | """Enable enable_pagerduty before first test, then disable after last test. |
1142 | 64 | Enable enable_pagerduty before first test, then disable after last test | ||
1144 | 65 | 63 | ||
1145 | 66 | :param Agent unit: unit from the fixture | 64 | :param Agent unit: unit from the fixture |
1146 | 67 | """ | 65 | """ |
1147 | diff --git a/tests/functional/test_deploy.py b/tests/functional/test_deploy.py | |||
1148 | index 32503c2..efbafb7 100644 | |||
1149 | --- a/tests/functional/test_deploy.py | |||
1150 | +++ b/tests/functional/test_deploy.py | |||
1151 | @@ -1,4 +1,5 @@ | |||
1152 | 1 | import pytest | 1 | import pytest |
1153 | 2 | |||
1154 | 2 | import requests | 3 | import requests |
1155 | 3 | 4 | ||
1156 | 4 | pytestmark = pytest.mark.asyncio | 5 | pytestmark = pytest.mark.asyncio |
1157 | diff --git a/tests/unit/test_website_relation_joined.py b/tests/unit/test_website_relation_joined.py | |||
1158 | index b4ca91a..7dff088 100644 | |||
1159 | --- a/tests/unit/test_website_relation_joined.py | |||
1160 | +++ b/tests/unit/test_website_relation_joined.py | |||
1161 | @@ -1,6 +1,7 @@ | |||
1162 | 1 | import unittest.mock as mock | 1 | import unittest.mock as mock |
1163 | 2 | 2 | ||
1164 | 3 | import pytest | 3 | import pytest |
1165 | 4 | |||
1166 | 4 | import website_relation_joined | 5 | import website_relation_joined |
1167 | 5 | 6 | ||
1168 | 6 | 7 | ||
1169 | diff --git a/tox.ini b/tox.ini | |||
1170 | index 8f1b11b..17cb36f 100644 | |||
1171 | --- a/tox.ini | |||
1172 | +++ b/tox.ini | |||
1173 | @@ -48,33 +48,7 @@ ignore = # TODO remove most of these | |||
1174 | 48 | D101, | 48 | D101, |
1175 | 49 | D102, | 49 | D102, |
1176 | 50 | D103, | 50 | D103, |
1177 | 51 | D104, | ||
1178 | 52 | D107, | 51 | D107, |
1179 | 53 | D202, | ||
1180 | 54 | D205, | ||
1181 | 55 | D208, | ||
1182 | 56 | D210, | ||
1183 | 57 | D400, | ||
1184 | 58 | D401, | ||
1185 | 59 | I100, | ||
1186 | 60 | I101, | ||
1187 | 61 | I201, | ||
1188 | 62 | I202, | ||
1189 | 63 | E201, | ||
1190 | 64 | E202, | ||
1191 | 65 | E231, | ||
1192 | 66 | E121, | ||
1193 | 67 | E126, | ||
1194 | 68 | E131, | ||
1195 | 69 | D201, | ||
1196 | 70 | E302, | ||
1197 | 71 | E501, | ||
1198 | 72 | N806, | ||
1199 | 73 | N816, | ||
1200 | 74 | W503, | ||
1201 | 75 | W504 | ||
1202 | 76 | |||
1203 | 77 | |||
1204 | 78 | max-line-length = 88 | 52 | max-line-length = 88 |
1205 | 79 | max-complexity = 10 | 53 | max-complexity = 10 |
1206 | 80 | 54 |
LGTM