Merge lp:~paulgear/charm-helpers/nrpe-remove-checks into lp:charm-helpers

Proposed by Paul Gear
Status: Merged
Merged at revision: 476
Proposed branch: lp:~paulgear/charm-helpers/nrpe-remove-checks
Merge into: lp:charm-helpers
Diff against target: 116 lines (+43/-11)
2 files modified
charmhelpers/contrib/charmsupport/nrpe.py (+39/-7)
tests/contrib/charmsupport/test_nrpe.py (+4/-4)
To merge this branch: bzr merge lp:~paulgear/charm-helpers/nrpe-remove-checks
Reviewer Review Type Date Requested Status
Stuart Bishop (community) Needs Fixing
Review via email: mp+275665@code.launchpad.net

Description of the change

This branch adds support for removing nrpe checks, reduces duplicated paths, and reduces the chance of a small (rather unlikely) bug whereby one check could remove another's export files.

To post a comment you must log in.
Revision history for this message
Stuart Bishop (stub) wrote :

Looks good, except for one bug commented on inline (I think you wrote 'pass' when you meant 'return' in _remove_service_files).

I tend to prefer foo.endswith instead of re.search('.*...'), but whatever floats your boat.

review: Needs Fixing
Revision history for this message
Paul Gear (paulgear) wrote :

Hi Stuart - thanks for reviewing. The pass vs. return bug is fixed (I found it while testing as well); the re.search was just moving the existing code, but endswith seems like it would be a lot more efficient. Will fix that shortly.

Revision history for this message
Stuart Bishop (stub) wrote :

I have two failing tests, directly related to this change. The second one probably just needs the '3' changed to '4' to account for an extra call to exists. The first failure might be more serious, as an expected call to os.remove is not happening any more:

======================================================================
FAIL: tests.contrib.charmsupport.test_nrpe.NRPECheckTestCase.test_write_removes_existing_config
----------------------------------------------------------------------
_StringException: Traceback (most recent call last):
  File "/home/stub/charms/charm-helpers/trunk/tests/contrib/charmsupport/test_nrpe.py", line 209, in test_write_removes_existing_config
    self.patched['remove'].assert_called_once_with(expected)
  File "/home/stub/charms/charm-helpers/trunk/.venv/local/lib/python2.7/site-packages/mock.py", line 845, in assert_called_once_with
    raise AssertionError(msg)
AssertionError: Expected to be called once. Called 0 times.

======================================================================
FAIL: tests.contrib.charmsupport.test_nrpe.NRPETestCase.test_update_nrpe
----------------------------------------------------------------------
_StringException: Traceback (most recent call last):
  File "/home/stub/charms/charm-helpers/trunk/tests/contrib/charmsupport/test_nrpe.py", line 176, in test_update_nrpe
    relation_ids=2, relation_set=2)
  File "/home/stub/charms/charm-helpers/trunk/tests/contrib/charmsupport/test_nrpe.py", line 48, in check_call_counts
    self.assertEqual(expected, patcher.call_count, attr)
  File "/usr/lib/python2.7/dist-packages/testtools/testcase.py", line 348, in assertEqual
    self.assertThat(observed, matcher, message)
  File "/usr/lib/python2.7/dist-packages/testtools/testcase.py", line 433, in assertThat
    raise mismatch_error
MismatchError: 3 != 4: exists

review: Needs Fixing
Revision history for this message
Paul Gear (paulgear) wrote :

I don't know what I was doing wrong previously, but I reproduced the test failures on my system, updated the test suite, and it passes on both my branch and my branch merged into an up-to-date copy of devel.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'charmhelpers/contrib/charmsupport/nrpe.py'
2--- charmhelpers/contrib/charmsupport/nrpe.py 2015-10-12 20:55:04 +0000
3+++ charmhelpers/contrib/charmsupport/nrpe.py 2015-10-29 23:52:51 +0000
4@@ -148,6 +148,13 @@
5 self.description = description
6 self.check_cmd = self._locate_cmd(check_cmd)
7
8+ def _get_check_filename(self):
9+ return os.path.join(NRPE.nrpe_confdir, '{}.cfg'.format(self.command))
10+
11+ def _get_service_filename(self, hostname):
12+ return os.path.join(NRPE.nagios_exportdir,
13+ 'service__{}_{}.cfg'.format(hostname, self.command))
14+
15 def _locate_cmd(self, check_cmd):
16 search_path = (
17 '/usr/lib/nagios/plugins',
18@@ -163,9 +170,21 @@
19 log('Check command not found: {}'.format(parts[0]))
20 return ''
21
22+ def _remove_service_files(self):
23+ if not os.path.exists(NRPE.nagios_exportdir):
24+ return
25+ for f in os.listdir(NRPE.nagios_exportdir):
26+ if f.endswith('_{}.cfg'.format(self.command)):
27+ os.remove(os.path.join(NRPE.nagios_exportdir, f))
28+
29+ def remove(self, hostname):
30+ nrpe_check_file = self._get_check_filename()
31+ if os.path.exists(nrpe_check_file):
32+ os.remove(nrpe_check_file)
33+ self._remove_service_files()
34+
35 def write(self, nagios_context, hostname, nagios_servicegroups):
36- nrpe_check_file = '/etc/nagios/nrpe.d/{}.cfg'.format(
37- self.command)
38+ nrpe_check_file = self._get_check_filename()
39 with open(nrpe_check_file, 'w') as nrpe_check_config:
40 nrpe_check_config.write("# check {}\n".format(self.shortname))
41 nrpe_check_config.write("command[{}]={}\n".format(
42@@ -180,9 +199,7 @@
43
44 def write_service_config(self, nagios_context, hostname,
45 nagios_servicegroups):
46- for f in os.listdir(NRPE.nagios_exportdir):
47- if re.search('.*{}.cfg'.format(self.command), f):
48- os.remove(os.path.join(NRPE.nagios_exportdir, f))
49+ self._remove_service_files()
50
51 templ_vars = {
52 'nagios_hostname': hostname,
53@@ -192,8 +209,7 @@
54 'command': self.command,
55 }
56 nrpe_service_text = Check.service_template.format(**templ_vars)
57- nrpe_service_file = '{}/service__{}_{}.cfg'.format(
58- NRPE.nagios_exportdir, hostname, self.command)
59+ nrpe_service_file = self._get_service_filename(hostname)
60 with open(nrpe_service_file, 'w') as nrpe_service_config:
61 nrpe_service_config.write(str(nrpe_service_text))
62
63@@ -228,6 +244,22 @@
64 def add_check(self, *args, **kwargs):
65 self.checks.append(Check(*args, **kwargs))
66
67+ def remove_check(self, *args, **kwargs):
68+ if kwargs.get('shortname') is None:
69+ raise ValueError('shortname of check must be specified')
70+
71+ # Use sensible defaults if they're not specified - these are not
72+ # actually used during removal, but they're required for constructing
73+ # the Check object; check_disk is chosen because it's part of the
74+ # nagios-plugins-basic package.
75+ if kwargs.get('check_cmd') is None:
76+ kwargs['check_cmd'] = 'check_disk'
77+ if kwargs.get('description') is None:
78+ kwargs['description'] = ''
79+
80+ check = Check(*args, **kwargs)
81+ check.remove(self.hostname)
82+
83 def write(self):
84 try:
85 nagios_uid = pwd.getpwnam('nagios').pw_uid
86
87=== modified file 'tests/contrib/charmsupport/test_nrpe.py'
88--- tests/contrib/charmsupport/test_nrpe.py 2015-03-16 17:54:34 +0000
89+++ tests/contrib/charmsupport/test_nrpe.py 2015-10-29 23:52:51 +0000
90@@ -172,7 +172,7 @@
91 ]
92 self.patched['relation_set'].assert_has_calls(relation_set_calls, any_order=True)
93 self.check_call_counts(config=1, getpwnam=1, getgrnam=1,
94- exists=3, open=2, listdir=1,
95+ exists=4, open=2, listdir=1,
96 relation_ids=2, relation_set=2)
97
98
99@@ -200,14 +200,14 @@
100
101 def test_write_removes_existing_config(self):
102 self.patched['listdir'].return_value = [
103- 'foo', 'bar.cfg', 'check_shortname.cfg']
104+ 'foo', 'bar.cfg', '_check_shortname.cfg']
105 check = nrpe.Check('shortname', 'description', '/some/command')
106
107 self.assertEqual(None, check.write('testctx', 'hostname', 'testsgrp'))
108
109- expected = '/var/lib/nagios/export/check_shortname.cfg'
110+ expected = '/var/lib/nagios/export/_check_shortname.cfg'
111 self.patched['remove'].assert_called_once_with(expected)
112- self.check_call_counts(exists=2, remove=1, open=2, listdir=1)
113+ self.check_call_counts(exists=3, remove=1, open=2, listdir=1)
114
115 def test_check_write_nrpe_exportdir_not_accessible(self):
116 self.patched['exists'].return_value = False

Subscribers

People subscribed via source and target branches