Merge ~xavpaice/charm-openstack-service-checks/+git/charm-openstack-service-checks:ssl-nagios-checks into ~canonical-bootstack/charm-openstack-service-checks:master
- Git
- lp:~xavpaice/charm-openstack-service-checks/+git/charm-openstack-service-checks
- ssl-nagios-checks
- Merge into master
Status: | Merged |
---|---|
Merge reported by: | David O Neill |
Merged at revision: | f6a6d6028e8675a05750720215ec58dbbb4757ab |
Proposed branch: | ~xavpaice/charm-openstack-service-checks/+git/charm-openstack-service-checks:ssl-nagios-checks |
Merge into: | ~canonical-bootstack/charm-openstack-service-checks:master |
Diff against target: |
586 lines (+282/-91) 10 files modified
.gitignore (+9/-0) Makefile (+7/-5) README.md (+9/-5) config.yaml (+25/-0) files/plugins/check_nova_services.py (+7/-7) layer.yaml (+11/-1) reactive/service_checks.py (+158/-64) templates/nagios.novarc (+6/-6) test-requirements.txt (+9/-0) tox.ini (+41/-3) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Joel Sing (community) | +1 | Approve | |
Andrea Ieri (community) | Needs Fixing | ||
Alvaro Uria (community) | Needs Fixing | ||
Review via email: mp+361325@code.launchpad.net |
This proposal has been superseded by a proposal from 2019-02-25.
Commit message
Add NRPE checks for all API endpoints in the Keystone catalog
This change implements the first stage of spec https:/
The intent is to add an NRPE check to the openstack-
Description of the change
🤖 Canonical IS Merge Bot (canonical-is-mergebot) wrote : | # |
Alvaro Uria (aluria) wrote : | # |
Please find comments inline. Other than that, I tested it in the charmlab and it looks good to me.
Xav Paice (xavpaice) wrote : | # |
Thanks for the review - couple of responses inline. Will update the actual change shortly.
- 7bac062... by Xav Paice
-
Address review points for additional service checks
- 90ee556... by Xav Paice
-
Add PEP8 test and fix failures
Joel Sing (jsing) wrote : | # |
Please add an actual commit message to this merge proposal - what is this change doing and why?
Readability/
Andrea Ieri (aieri) wrote : | # |
A bunch of inline comments :)
- 1d372dd... by Xav Paice
-
Address review comments
Xav Paice (xavpaice) wrote : | # |
Thanks for the detailed review(s). Fresh commit coming.
Couple of inline responses.
Joel Sing (jsing) : | # |
Joel Sing (jsing) wrote : | # |
LGTM for a readability/
Please ensure you get a peer approval before merging.
- f6a6d60... by Xav Paice
-
address review nits
Preview Diff
1 | diff --git a/.gitignore b/.gitignore |
2 | new file mode 100644 |
3 | index 0000000..5835925 |
4 | --- /dev/null |
5 | +++ b/.gitignore |
6 | @@ -0,0 +1,9 @@ |
7 | +*~ |
8 | +/bin |
9 | +debian/files |
10 | +/pkg |
11 | +*.pyc |
12 | +__pycache__ |
13 | +*.swp |
14 | +.tox |
15 | +.venv |
16 | diff --git a/Makefile b/Makefile |
17 | index a1ad3a5..27eeff6 100644 |
18 | --- a/Makefile |
19 | +++ b/Makefile |
20 | @@ -1,6 +1,6 @@ |
21 | #!/usr/bin/make |
22 | |
23 | -all: lint unit_test |
24 | +all: lint test |
25 | |
26 | |
27 | .PHONY: clean |
28 | @@ -10,15 +10,17 @@ clean: |
29 | .PHONY: apt_prereqs |
30 | apt_prereqs: |
31 | @# Need tox, but don't install the apt version unless we have to (don't want to conflict with pip) |
32 | - @which tox >/dev/null || (sudo apt-get install -y python-pip && sudo pip install tox) |
33 | + @which tox >/dev/null || (sudo apt-get install -y python3-pip && sudo pip3 install tox) |
34 | |
35 | .PHONY: lint |
36 | lint: apt_prereqs |
37 | - @tox --notest |
38 | - @PATH=.tox/py34/bin:.tox/py35/bin flake8 $(wildcard hooks reactive lib unit_tests tests) |
39 | + @tox -e pep8 |
40 | @charm proof |
41 | |
42 | -.PHONY: unit_test |
43 | +.PHONY: test |
44 | unit_test: apt_prereqs |
45 | @echo Starting tests... |
46 | tox |
47 | + |
48 | +build: |
49 | + charm build |
50 | diff --git a/README.md b/README.md |
51 | index 24a4b54..b3159af 100644 |
52 | --- a/README.md |
53 | +++ b/README.md |
54 | @@ -2,7 +2,7 @@ |
55 | |
56 | This charm provides OpenStack services checks for Nagios |
57 | |
58 | - # Build |
59 | +# Build |
60 | The fully built charm needs the following source branch |
61 | * https://git.launchpad.net/~canonical-bootstack/bootstack-ops/+git/charm-openstack-services-checks |
62 | |
63 | @@ -29,16 +29,20 @@ Build the charm, and symlink for juju-1 compatibility |
64 | |
65 | juju deploy local:xenial/openstack-services-checks |
66 | |
67 | -This charm supports relating to keystone, but keystone-credentials interface |
68 | -seems to be flaky, and hard to remove-relation, so the charm works around this |
69 | -by adding 'os-credentials' setting (see setting description hints) |
70 | +This charm supports relating to keystone via the keystone-credentials |
71 | +interface. If you do not wish to use this, you can supply your own credential |
72 | +set for Openstack by adding 'os-credentials' setting (see setting description |
73 | +hints) |
74 | |
75 | juju set openstack-services-checks os-credentials=" ... " |
76 | - |
77 | juju add-relation openstack-services-checks nagios |
78 | |
79 | With Keystone |
80 | |
81 | juju add-relation openstack-services-checks:identity-credentials keystone:identity-credentials |
82 | |
83 | +If your OpenStack API endpoints have a common URL for the Admin, Public and |
84 | +Internal addresses, you should consider disabling some endpoints which would be |
85 | +duplicated otherwise, e.g. |
86 | |
87 | + juju config openstack-service-checks check_internal_urls=False check_admin_urls=False |
88 | diff --git a/config.yaml b/config.yaml |
89 | index e4e8783..b71208c 100644 |
90 | --- a/config.yaml |
91 | +++ b/config.yaml |
92 | @@ -48,3 +48,28 @@ options: |
93 | default: false |
94 | description: | |
95 | An option to specify whether you want Warning alerts in nagios for disabled nova-compute hosts. |
96 | + tls_warn_days: |
97 | + type: int |
98 | + default: 30 |
99 | + description: | |
100 | + Number of days left for the TLS certificate to expire before warning. |
101 | + tls_crit_days: |
102 | + type: int |
103 | + default: 14 |
104 | + description: | |
105 | + Number of days left for the TLS certificate to expire before alerting Critical. |
106 | + check_public_urls: |
107 | + type: boolean |
108 | + default: True |
109 | + description: | |
110 | + If true, create NRPE checks matching all 'public' URLs in the Keystone catalog. |
111 | + check_internal_urls: |
112 | + type: boolean |
113 | + default: True |
114 | + description: | |
115 | + If true, create NRPE checks matching all 'internal' URLs in the Keystone catalog. |
116 | + check_admin_urls: |
117 | + type: boolean |
118 | + default: True |
119 | + description: | |
120 | + If true, create NRPE checks matching all 'admin' URLs in the Keystone catalog. |
121 | diff --git a/files/plugins/check_nova_services.py b/files/plugins/check_nova_services.py |
122 | index 1279c6a..6498542 100755 |
123 | --- a/files/plugins/check_nova_services.py |
124 | +++ b/files/plugins/check_nova_services.py |
125 | @@ -43,11 +43,11 @@ def check_hosts_up(args, aggregate, hosts, services_compute): |
126 | local_msg.append("Host Aggregate {} has {} hosts alive".format( |
127 | aggregate, counts['ok'])) |
128 | nova_status = { |
129 | - 'agg_name': aggregate, |
130 | - 'msg_text': ", ".join(local_msg), |
131 | - 'critical': status_crit, |
132 | - 'warning': status_warn, |
133 | - } |
134 | + 'agg_name': aggregate, |
135 | + 'msg_text': ", ".join(local_msg), |
136 | + 'critical': status_crit, |
137 | + 'warning': status_warn, |
138 | + } |
139 | return nova_status |
140 | |
141 | |
142 | @@ -103,8 +103,8 @@ if __name__ == '__main__': |
143 | command = ['/bin/bash', '-c', "source {} && env".format(args.env)] |
144 | proc = subprocess.Popen(command, stdout=subprocess.PIPE) |
145 | for line in proc.stdout: |
146 | - (key, _, value) = line.partition("=") |
147 | - os.environ[key] = value.rstrip() |
148 | + (key, _, value) = line.partition(b'=') |
149 | + os.environ[key.decode('utf-8')] = value.rstrip().decode('utf-8') |
150 | proc.communicate() |
151 | nova = os_client_config.session_client('compute', cloud='envvars') |
152 | nagios_plugin.try_check(check_nova_services, args, nova) |
153 | diff --git a/layer.yaml b/layer.yaml |
154 | index f364d90..72f0af5 100644 |
155 | --- a/layer.yaml |
156 | +++ b/layer.yaml |
157 | @@ -1,6 +1,16 @@ |
158 | includes: |
159 | + - 'layer:apt' |
160 | - 'layer:basic' |
161 | - - 'interface:nrpe-external-master' |
162 | - 'interface:keystone-credentials' |
163 | + - 'interface:nrpe-external-master' |
164 | ignore: ['.*.swp' ] |
165 | repo: 'lp:~canonical-bootstack/+git/charm-openstack-service-checks' |
166 | +options: |
167 | + basic: |
168 | + use_venv: true |
169 | + apt: |
170 | + packages: |
171 | + - nagios-nrpe-server |
172 | + - python3-keystoneclient |
173 | + - python3-openstackclient |
174 | + - python-openstackclient |
175 | diff --git a/reactive/service_checks.py b/reactive/service_checks.py |
176 | index 8341324..982b1a5 100644 |
177 | --- a/reactive/service_checks.py |
178 | +++ b/reactive/service_checks.py |
179 | @@ -17,112 +17,109 @@ from charmhelpers.core import ( |
180 | unitdata, |
181 | ) |
182 | |
183 | -from charmhelpers.fetch import ( |
184 | - apt_install, |
185 | - apt_update, |
186 | -) |
187 | - |
188 | from charmhelpers.contrib.charmsupport.nrpe import NRPE |
189 | +from urllib.parse import urlparse |
190 | |
191 | config = hookenv.config() |
192 | -install_packages = ['nagios-nrpe-server', 'python-openstackclient'] |
193 | +NOVARC = '/var/lib/nagios/nagios.novarc' |
194 | +PLUGINS_DIR = '/usr/local/lib/nagios/plugins/' |
195 | |
196 | |
197 | @when_not('os-service-checks.installed') |
198 | def install_service_checks(): |
199 | hookenv.status_set('maintenance', 'Installing software') |
200 | - apt_update() |
201 | - apt_install(install_packages) |
202 | + # moved to apt layer |
203 | set_state('os-service-checks.installed') |
204 | remove_state('os-service-checks.configured') |
205 | hookenv.status_set('active', 'Ready') |
206 | -# setup openstack user |
207 | |
208 | |
209 | @when('identity-credentials.connected') |
210 | -def configure_keystone_username(keystone): |
211 | +def configure_ident_username(keystone): |
212 | username = 'nagios' |
213 | keystone.request_credentials(username) |
214 | |
215 | |
216 | @when('identity-credentials.available') |
217 | def save_creds(keystone): |
218 | - creds = get_creds(keystone) |
219 | - unitdata.kv().set('keystone-relation-creds', creds) |
220 | - remove_state('os-service-checks.configured') |
221 | - |
222 | - |
223 | -def get_creds(keystone): |
224 | - |
225 | + """ |
226 | + Get credentials from the Keystone relation, |
227 | + reformat them into something the Keystone client |
228 | + can use, and save them into the unitdata. |
229 | + """ |
230 | + creds = { |
231 | + 'username': keystone.credentials_username(), |
232 | + 'password': keystone.credentials_password(), |
233 | + 'region': keystone.region(), |
234 | + } |
235 | if keystone.api_version() == '3': |
236 | api_url = "v3" |
237 | try: |
238 | domain = keystone.domain() |
239 | except AttributeError: |
240 | domain = 'service_domain' |
241 | - creds = { |
242 | - 'credentials_username': keystone.credentials_username(), |
243 | - 'credentials_password': keystone.credentials_password(), |
244 | - 'credentials_project': keystone.credentials_project(), |
245 | + # keystone relation sends info back with funny names, fix here |
246 | + creds.update({ |
247 | + 'project_name': keystone.credentials_project(), |
248 | 'auth_version': '3', |
249 | - 'region': keystone.region(), |
250 | - 'credentials_user_domain': domain, |
251 | - 'credentials_project_domain': domain |
252 | - } |
253 | + 'user_domain_name': domain, |
254 | + 'project_domain_name': domain |
255 | + }) |
256 | else: |
257 | api_url = "v2.0" |
258 | - creds = { |
259 | - 'credentials_username': keystone.credentials_username(), |
260 | - 'credentials_password': keystone.credentials_password(), |
261 | - 'credentials_project': keystone.credentials_project(), |
262 | - 'region': keystone.region(), |
263 | - } |
264 | + creds['tenant_name'] = keystone.credentials_project() |
265 | |
266 | auth_url = "%s://%s:%s/%s" % (keystone.auth_protocol(), |
267 | keystone.auth_host(), keystone.auth_port(), |
268 | api_url) |
269 | creds['auth_url'] = auth_url |
270 | - return creds |
271 | + unitdata.kv().set('keystonecreds', creds) |
272 | + remove_state('os-service-checks.configured') |
273 | |
274 | |
275 | -# allow user to override credentials (and the need to be related to keystone) |
276 | +# allow user to override credentials (and the need to be related to ident) |
277 | # with 'os-credentials' |
278 | def get_credentials(): |
279 | - keystone_creds = config_flags_parser(config.get('os-credentials')) |
280 | - if keystone_creds: |
281 | - if '/v3' in keystone_creds['auth_url']: |
282 | - creds = { |
283 | - 'credentials_username': keystone_creds['username'], |
284 | - 'credentials_password': keystone_creds['password'], |
285 | - 'credentials_project': keystone_creds['credentials_project'], |
286 | - 'region': keystone_creds['region_name'], |
287 | - 'auth_url': keystone_creds['auth_url'], |
288 | + ident_creds = config_flags_parser(config.get('os-credentials')) |
289 | + if ident_creds: |
290 | + creds = { |
291 | + 'username': ident_creds['username'], |
292 | + 'password': ident_creds['password'], |
293 | + 'region': ident_creds['region_name'], |
294 | + 'auth_url': ident_creds['auth_url'], |
295 | + } |
296 | + if '/v3' in ident_creds['auth_url']: |
297 | + creds.update({ |
298 | + 'project_name': ident_creds['credentials_project'], |
299 | 'auth_version': '3', |
300 | - 'credentials_user_domain': keystone_creds['domain'], |
301 | - 'credentials_project_domain': keystone_creds['domain'], |
302 | - } |
303 | + 'user_domain_name': ident_creds['domain'], |
304 | + 'project_domain_name': ident_creds['domain'], |
305 | + }) |
306 | else: |
307 | - creds = { |
308 | - 'credentials_username': keystone_creds['username'], |
309 | - 'credentials_password': keystone_creds['password'], |
310 | - 'credentials_project': keystone_creds['credentials_project'], |
311 | - 'region': keystone_creds['region_name'], |
312 | - 'auth_url': keystone_creds['auth_url'], |
313 | - } |
314 | + creds['tenant_name'] = ident_creds['credentials_project'] |
315 | else: |
316 | kv = unitdata.kv() |
317 | - creds = kv.get('keystone-relation-creds') |
318 | + creds = kv.get('keystonecreds') |
319 | + old_creds = kv.get('keystone-relation-creds') |
320 | + if old_creds and not creds: |
321 | + # This set of creds needs an update to a newer format |
322 | + creds['username'] = old_creds.pop('credentials_username') |
323 | + creds['password'] = old_creds.pop('credentials_password') |
324 | + creds['project_name'] = old_creds.pop('credentials_project') |
325 | + creds['tenant_name'] = old_creds['project_name'] |
326 | + creds['user_domain_name'] = old_creds.pop('credentials_user_domain', None) |
327 | + creds['project_domain_name'] = old_creds.pop('credentials_project_domain', None) |
328 | + kv.set('keystonecreds', creds) |
329 | + kv.update(creds, 'keystonecreds') |
330 | return creds |
331 | |
332 | |
333 | def render_checks(): |
334 | nrpe = NRPE() |
335 | - plugins_dir = '/usr/local/lib/nagios/plugins/' |
336 | - if not os.path.exists(plugins_dir): |
337 | - os.makedirs(plugins_dir) |
338 | + if not os.path.exists(PLUGINS_DIR): |
339 | + os.makedirs(PLUGINS_DIR) |
340 | charm_file_dir = os.path.join(hookenv.charm_dir(), 'files') |
341 | charm_plugin_dir = os.path.join(charm_file_dir, 'plugins') |
342 | - |
343 | host.rsync( |
344 | charm_plugin_dir, |
345 | '/usr/local/lib/nagios/', |
346 | @@ -133,9 +130,8 @@ def render_checks(): |
347 | crit = config.get("nova_crit") |
348 | skip_disabled = config.get("skip-disabled") |
349 | check_dns = config.get("check-dns") |
350 | - |
351 | - check_command = plugins_dir + 'check_nova_services.py --warn ' \ |
352 | - + str(warn) + ' --crit ' + str(crit) |
353 | + nova_check_command = os.path.join(PLUGINS_DIR, 'check_nova_services.py') |
354 | + check_command = '{} --warn {} --crit {}'.format(nova_check_command, warn, crit) |
355 | |
356 | if skip_disabled: |
357 | check_command = check_command + ' --skip-disabled' |
358 | @@ -146,15 +142,22 @@ def render_checks(): |
359 | |
360 | nrpe.add_check(shortname='neutron_agents', |
361 | description='Check that enabled Neutron agents are up', |
362 | - check_cmd=plugins_dir + 'check_neutron_agents.sh') |
363 | + check_cmd=os.path.join(PLUGINS_DIR, 'check_neutron_agents.sh')) |
364 | |
365 | if len(check_dns): |
366 | + dns_check_cmd = "{} {}".format( |
367 | + os.path.join(PLUGINS_DIR, 'check_dns_multi.sh'), |
368 | + ' '.join(check_dns.split()) |
369 | + ) |
370 | nrpe.add_check(shortname='dns_multi', |
371 | description='Check DNS names are resolvable', |
372 | - check_cmd=plugins_dir + 'check_dns_multi.sh ' + ' '.join(check_dns.split())) |
373 | + check_cmd=dns_check_cmd) |
374 | else: |
375 | nrpe.remove_check(shortname='dns_multi') |
376 | |
377 | + endpoint_checks = create_endpoint_checks() |
378 | + for check in endpoint_checks: |
379 | + nrpe.add_check(**check) |
380 | nrpe.write() |
381 | |
382 | |
383 | @@ -171,8 +174,8 @@ def render_config(): |
384 | hookenv.log('render_config: No credentials yet, skipping') |
385 | return |
386 | hookenv.log('render_config: Got credentials for username={}'.format( |
387 | - creds['credentials_username'])) |
388 | - render('nagios.novarc', '/var/lib/nagios/nagios.novarc', creds, |
389 | + creds['username'])) |
390 | + render('nagios.novarc', NOVARC, creds, |
391 | owner='nagios', group='nagios') |
392 | render_checks() |
393 | if config.get('trusted_ssl_ca', None): |
394 | @@ -198,3 +201,94 @@ def fix_ssl(): |
395 | with open(cert_file, 'w') as f: |
396 | print(cert_content, file=f) |
397 | subprocess.call(["/usr/sbin/update-ca-certificates"]) |
398 | + |
399 | + |
400 | +def create_endpoint_checks(): |
401 | + """ |
402 | + Read the Keystone catalog, and create a check for each endpoint listed. |
403 | + If there is a healthcheck endpoint for the API, use that URL, otherwise check |
404 | + the url '/'. |
405 | + If SSL, add a check for the cert. |
406 | + """ |
407 | + # provide URLs that can be used for healthcheck for some services |
408 | + # This also provides a nasty hack-ish way to add switches if we need |
409 | + # for some services. |
410 | + health_urls = { |
411 | + 'keystone': '/healthcheck', |
412 | + 's3': '/healthcheck', |
413 | + 'swift': '/healthcheck', |
414 | + 'aodh': '/ -e Unauthorized -d x-openstack-request-id', |
415 | + 'cinderv3': '/v3 -e Unauthorized -d x-openstack-request-id', |
416 | + 'cinderv2': '/v2 -e Unauthorized -d x-openstack-request-id', |
417 | + 'cinderv1': '/v1 -e Unauthorized -d x-openstack-request-id', |
418 | + 'glance': '/healthcheck', |
419 | + 'nova': '/healthcheck', |
420 | + } |
421 | + |
422 | + creds = get_credentials() |
423 | + keystone_client = get_keystone_client(creds) |
424 | + endpoints = keystone_client.endpoints.list() |
425 | + services = [x for x in keystone_client.services.list() if x.enabled] |
426 | + nrpe_checks = [] |
427 | + for endpoint in endpoints: |
428 | + endpoint.service_names = [x.name for x in services if x.id == endpoint.service_id] |
429 | + service_name = endpoint.service_names[0] |
430 | + endpoint.healthcheck_url = health_urls.get(service_name, '/') |
431 | + if config.get('check_{}_urls'.format(endpoint.interface)): |
432 | + cmd_params = ['/usr/lib/nagios/plugins/check_http '] |
433 | + check_url = urlparse(endpoint.url) |
434 | + host_port = check_url.netloc.split(':') |
435 | + cmd_params.append('-H {} -p {}'.format(host_port[0], host_port[1])) |
436 | + cmd_params.append('-u {}'.format(endpoint.healthcheck_url)) |
437 | + # if this is https, we want to add a check for cert expiry |
438 | + # also need to tell check_http use use TLS |
439 | + if check_url.scheme == 'https': |
440 | + cmd_params.append('-S') |
441 | + # Add an extra check for TLS cert expiry |
442 | + cert_check = ['-C {},{}'.format(config.get('tls_warn_days'), |
443 | + config.get('tls_crit_days'))] |
444 | + nrpe_checks.append({ |
445 | + 'shortname': "{}_{}_cert".format(service_name, |
446 | + endpoint.interface), |
447 | + 'description': 'Certificate expiry check for {} {}'.format( |
448 | + service_name, |
449 | + endpoint.interface), |
450 | + 'check_cmd': ' '.join(cmd_params + cert_check)}) |
451 | + # Add the actual health check for the URL |
452 | + nrpe_checks.append({ |
453 | + 'shortname': "{}_{}".format(service_name, |
454 | + endpoint.interface), |
455 | + 'description': 'Endpoint url check for {} {}'.format( |
456 | + service_name, |
457 | + endpoint.interface), |
458 | + 'check_cmd': (' '.join(cmd_params))}) |
459 | + return nrpe_checks |
460 | + |
461 | + |
462 | +def get_keystone_client(creds): |
463 | + ''' |
464 | + Import the appropriate Keystone client depending on API version. |
465 | + Return a client object. |
466 | + ''' |
467 | + from keystoneclient import session |
468 | + if int(creds['auth_version']) >= 3: |
469 | + from keystoneclient.v3 import client |
470 | + from keystoneclient.auth.identity import v3 |
471 | + auth_fields = ['auth_url', 'password', 'username', 'user_domain_name', |
472 | + 'project_domain_name', 'project_name'] |
473 | + auth_creds = {} |
474 | + for key in auth_fields: |
475 | + auth_creds[key] = creds[key] |
476 | + auth = v3.Password(**auth_creds) |
477 | + |
478 | + else: |
479 | + from keystoneclient.v2_0 import client |
480 | + from keystoneclient.auth.identity import v2 |
481 | + auth_fields = ['auth_url', 'password', 'username', 'tenant_name'] |
482 | + auth_creds = {} |
483 | + for key in auth_fields: |
484 | + auth_creds[key] = creds[key] |
485 | + auth = v2.Password(**auth_creds) |
486 | + |
487 | + sess = session.Session(auth=auth) |
488 | + return client.Client(session=sess) |
489 | diff --git a/templates/nagios.novarc b/templates/nagios.novarc |
490 | index e4c7e68..27f1c2a 100644 |
491 | --- a/templates/nagios.novarc |
492 | +++ b/templates/nagios.novarc |
493 | @@ -1,7 +1,7 @@ |
494 | -export OS_USERNAME={{ credentials_username }} |
495 | -export OS_TENANT_NAME={{ credentials_project }} |
496 | -export OS_PROJECT_NAME={{ credentials_project }} |
497 | -export OS_PASSWORD={{ credentials_password }} |
498 | +export OS_USERNAME={{ username }} |
499 | +export OS_TENANT_NAME={{ tenant_name }} |
500 | +export OS_PROJECT_NAME={{ project_name }} |
501 | +export OS_PASSWORD={{ password }} |
502 | export OS_REGION_NAME={{ region }} |
503 | export OS_AUTH_URL={{ auth_url }} |
504 | {%- if cacert %} |
505 | @@ -13,6 +13,6 @@ export HOME=${SNAP_COMMON} |
506 | {%- if auth_version %} |
507 | export OS_IDENTITY_API_VERSION={{ auth_version }} |
508 | export OS_AUTH_VERSION={{ auth_version }} |
509 | -export OS_USER_DOMAIN_NAME={{ credentials_user_domain }} |
510 | -export OS_PROJECT_DOMAIN_NAME={{ credentials_project_domain }} |
511 | +export OS_USER_DOMAIN_NAME={{ user_domain_name }} |
512 | +export OS_PROJECT_DOMAIN_NAME={{ project_domain_name }} |
513 | {%- endif %} |
514 | diff --git a/test-requirements.txt b/test-requirements.txt |
515 | new file mode 100644 |
516 | index 0000000..77ec3f5 |
517 | --- /dev/null |
518 | +++ b/test-requirements.txt |
519 | @@ -0,0 +1,9 @@ |
520 | +# Lint and unit test requirements |
521 | +flake8>=2.2.4,<=2.4.1 |
522 | +os-testr>=0.4.1 |
523 | +requests>=2.18.4 |
524 | +charms.reactive |
525 | +mock>=1.2 |
526 | +nose>=1.3.7 |
527 | +coverage>=3.6 |
528 | +netifaces |
529 | diff --git a/tox.ini b/tox.ini |
530 | index 0b8b27a..ba58ab5 100644 |
531 | --- a/tox.ini |
532 | +++ b/tox.ini |
533 | @@ -1,12 +1,50 @@ |
534 | [tox] |
535 | skipsdist=True |
536 | -envlist = py34, py35 |
537 | +envlist = pep8, py34, py35, py36 |
538 | skip_missing_interpreters = True |
539 | |
540 | [testenv] |
541 | -commands = py.test -v |
542 | +setenv = VIRTUAL_ENV={envdir} |
543 | + PYTHONHASHSEED=0 |
544 | + TERM=linux |
545 | + LAYER_PATH={toxinidir}/layers |
546 | + INTERFACE_PATH={toxinidir}/interfaces |
547 | + JUJU_REPOSITORY={toxinidir}/build |
548 | +passenv = http_proxy https_proxy |
549 | +install_command = |
550 | + pip install {opts} {packages} |
551 | deps = |
552 | -r{toxinidir}/requirements.txt |
553 | |
554 | +[testenv:build] |
555 | +basepython = python3 |
556 | +commands = |
557 | + charm-build --log-level DEBUG -o {toxinidir}/build src {posargs} |
558 | + |
559 | +[testenv:py34] |
560 | +basepython = python3.4 |
561 | +deps = -r{toxinidir}/test-requirements.txt |
562 | +commands = ostestr {posargs} |
563 | + |
564 | +[testenv:py35] |
565 | +basepython = python3.5 |
566 | +deps = -r{toxinidir}/test-requirements.txt |
567 | +commands = ostestr {posargs} |
568 | + |
569 | +[testenv:py36] |
570 | +basepython = python3.6 |
571 | +deps = -r{toxinidir}/test-requirements.txt |
572 | +commands = ostestr {posargs} |
573 | + |
574 | +[testenv:pep8] |
575 | +basepython = python3.6 |
576 | +deps = -r{toxinidir}/test-requirements.txt |
577 | +commands = flake8 {posargs} --max-complexity=10 --max-line-length=120 reactive files unit_tests |
578 | + |
579 | +[testenv:venv] |
580 | +basepython = python3 |
581 | +commands = {posargs} |
582 | + |
583 | [flake8] |
584 | -exclude=docs |
585 | +# E402 ignore necessary for path append before sys module import in actions |
586 | +ignore = E402 |
This merge proposal is being monitored by mergebot. Change the status to Approved to merge.