← Back to team overview

nagios-charmers team mailing list archive

[Merge] ~aieri/hw-health-charm:oo-rewrite-cleanup1 into hw-health-charm:oo-rewrite-integration

 

Andrea Ieri has proposed merging ~aieri/hw-health-charm:oo-rewrite-cleanup1 into hw-health-charm:oo-rewrite-integration with ~aieri/hw-health-charm:oo-rewrite-core as a prerequisite.

Requested reviews:
  Canonical IS Reviewers (canonical-is-reviewers)

For more details, see:
https://code.launchpad.net/~aieri/hw-health-charm/+git/hw-health-charm/+merge/364756

Part 3 of the superseded MR#364694
-- 
Your team Nagios Charm developers is subscribed to branch hw-health-charm:oo-rewrite-integration.
diff --git a/src/config.yaml b/src/config.yaml
index 37dda77..a6e8797 100644
--- a/src/config.yaml
+++ b/src/config.yaml
@@ -20,3 +20,10 @@ options:
     type: boolean
     default: True
     description: Enable the use of freeipmi tools to monitor hardware status.
+  ipmi_check_options:
+    type: string
+    default: ''
+    description: |
+      Additional options to be passed to check_ipmi_sensor. For non-standard
+      ipmi implementations you might for example need
+      "--seloptions '--assume-system-event-records'"
diff --git a/src/lib/hwhealth/tooling.py b/src/lib/hwhealth/tooling.py
deleted file mode 100644
index 40b140c..0000000
--- a/src/lib/hwhealth/tooling.py
+++ /dev/null
@@ -1,225 +0,0 @@
-# -*- coding: us-ascii -*-
-import glob
-import os
-import shutil
-import subprocess
-import tempfile
-import zipfile
-
-from charmhelpers.contrib.charmsupport import nrpe
-from charmhelpers.core import hookenv
-
-TOOLING = {
-    'megacli': {
-        'snap': 'megacli',
-        'filename': 'megaraid/check_megacli.py',
-        'cronjob': 'megaraid/check_megacli.sh'
-    },
-    'sas2ircu': {
-        'snap': 'sas2ircu',
-        'filename': 'sas2ircu/check_sas2ircu.py',
-        'cronjob': 'sas2ircu/check_sas2ircu.sh'
-    },
-    'sas3ircu': {
-        'snap': 'sas3ircu',
-        'filename': 'sas3ircu/check_sas3ircu.py',
-        'cronjob': 'sas3ircu/check_sas3ircu.sh'
-    },
-    'mdadm': {
-        'filename': 'mdadm/check_mdadm.py',
-        'cronjob': 'mdadm/cron_mdadm.py'
-    },
-    'ipmi': {
-        'filename': 'ipmi/check_ipmi_sensor',
-        'sudoers': 'ipmi/check_ipmi_sensor_sudoer'
-    },
-}
-
-PLUGINS_DIR = '/usr/local/lib/nagios/plugins/'
-TOOLS_DIR = '/usr/local/bin/'
-CRONJOB_PATH = '/etc/cron.d/hw_health_{}'
-SUDOERS_DIR = '/etc/sudoers.d'
-
-
-def install_resource(tools, resource):
-    """Install hardware diagnostic tools from a charm resource
-
-    :param tools: set of tools to include
-    :param resource: resource object
-    :return: boolean, status of installation
-    """
-    if not isinstance(tools, set):
-        try:
-            tools = set(tools)
-        except TypeError as e:
-            hookenv.log("install_resources called with invalid 'tools', {}".format(e))
-            return False
-    if not tools:
-        return False
-    elif tools & {'mdadm', 'ipmi'}:
-        tools = tools - {'mdadm', 'ipmi'}
-        if not tools:
-            return True
-
-    if not isinstance(resource, str) \
-            or not resource.endswith('.zip') \
-            or not os.path.exists(resource):
-        hookenv.log("The resource 'tools' does not end with .zip or does not exist")
-        return False
-
-    with tempfile.TemporaryDirectory() as tmpdir:
-        try:
-            with zipfile.ZipFile(resource, 'r') as zf:
-                zf.extractall(tmpdir)
-
-            count = 0
-            for filepath in glob.glob(os.path.join(tmpdir, '*')):
-                filebasename = os.path.basename(filepath)
-                if filebasename in tools \
-                        and filebasename in TOOLING \
-                        and os.path.isfile(filepath):
-                    os.chmod(filepath, 0o755)
-                    shutil.chown(filepath, user=0, group=0)
-                    shutil.copy2(filepath, TOOLS_DIR)
-                    count += 1
-
-            return len(tools) == count and count > 0
-
-        except zipfile.BadZipFile as error:
-            hookenv.log('BadZipFile: {}'.format(error), hookenv.ERROR)
-
-        except PermissionError as error:
-            hookenv.log(
-                'Unable to unzip the resource: {}'.format(error), hookenv.ERROR)
-
-    return False
-
-
-def install_tools(tools, method='snap'):
-    """Install hardware management tools from a snap
-
-    :param tools: list of tools to install
-    :param method: default to snap if unspecified, other means have yet to be added
-    :return:
-    """
-    count = 0
-    for tool in tools:
-        if tool in TOOLING and method in TOOLING[tool]:
-            if method == 'snap':
-                try:
-                    # snap.install(TOOLING[tool][method])
-                    count += 1
-                except Exception as error:
-                    hookenv.log(
-                        'Snap install error: {}'.format(error), hookenv.ERROR)
-        elif tool == 'mdadm':
-            # Note(aluria): mdadm is assumed to be installed by default
-            count += 1
-
-    return len(tools) >= count > 0
-
-
-def _get_filepath(filename):
-    filepath = os.path.join(hookenv.charm_dir(), 'files', filename)
-    if os.path.exists(filepath):
-        return filepath
-
-
-def configure_tools(tools):
-    count = 0
-    for tool in tools:
-        if tool in TOOLING:
-            if 'cronjob' in TOOLING[tool]:
-                filepath = _get_filepath(TOOLING[tool]['cronjob'])
-                cronjob_scriptname = os.path.basename(TOOLING[tool]['cronjob'])
-                if filepath:
-                    subprocess.call(filepath)
-                    shutil.copy2(filepath, PLUGINS_DIR)
-                    hookenv.log(
-                        'Cronjob script [{}] copied to {}'.format(
-                            filepath, PLUGINS_DIR), hookenv.DEBUG)
-                else:
-                    continue
-                cronjob_file = CRONJOB_PATH.format(tool)
-                cronjob_line = '*/5 * * * * root {}\n'
-                cronjob_script = os.path.join(PLUGINS_DIR, cronjob_scriptname)
-                with open(cronjob_file, 'w') as fd:
-                    fd.write(cronjob_line.format(cronjob_script))
-                    hookenv.log(
-                        'Cronjob configured at {}'.format(cronjob_file),
-                        hookenv.DEBUG)
-                count += 1
-                hookenv.log('Cronjob for tool [{}] configured'.format(tool))
-
-            if 'filename' in TOOLING[tool]:
-                filepath = _get_filepath(TOOLING[tool]['filename'])
-                if filepath:
-                    shutil.copy2(filepath, PLUGINS_DIR)
-                    count += 1
-                    hookenv.log(
-                        'NRPE script for tool [{}] configured'.format(tool))
-            if 'sudoers' in TOOLING[tool]:
-                sudoers_path = _get_filepath(TOOLING[tool]['sudoers'])
-                if sudoers_path:
-                    shutil.copy2(sudoers_path, SUDOERS_DIR)
-                    count += 1
-                    hookenv.log('sudoers entry for tool [{}] added'.format(tool))
-    return count > 0
-
-
-def configure_cronjobs(tools):
-    pass
-
-
-def configure_nrpe_checks(tools):
-    if not configure_tools(tools):
-        hookenv.log(
-            "No tools configured. NRPE checks can't be configured",
-            hookenv.DEBUG)
-        return False
-
-    count = 0
-    hostname = nrpe.get_nagios_hostname()
-    nrpe_setup = nrpe.NRPE(hostname=hostname, primary=False)
-    for tool in tools:
-        if tool in TOOLING and 'filename' in TOOLING[tool]:
-            scriptname = os.path.basename(TOOLING[tool]['filename'])
-            cmd = os.path.join(PLUGINS_DIR, scriptname)  # TODO args to the command?
-            if os.path.exists(cmd):
-                nrpe_setup.add_check(tool, '{} Hardware Health', cmd)
-                nrpe_setup.write()
-                count += 1
-        else:
-            cronjob_file = os.path.join('/etc/cron.d', tool)
-            if os.path.exists(cronjob_file):
-                os.unlink(cronjob_file)
-                hookenv.log(
-                    'Cronjob file [{}] removed'.format(cronjob_file),
-                    hookenv.DEBUG)
-
-    return count > 0
-
-
-def remove_nrpe_checks(tools):
-    if len(tools) == 0:
-        return False
-
-    hostname = nrpe.get_nagios_hostname()
-    nrpe_setup = nrpe.NRPE(hostname=hostname, primary=False)
-    count = 0
-    for tool in tools:
-        if tool not in TOOLING:
-            continue
-        nrpe_setup.remove_check(
-            shortname=tool, check_cmd='check_{}'.format(tool))
-
-        if os.path.exists(CRONJOB_PATH.format(tool)):
-            os.remove(CRONJOB_PATH.format(tool))
-
-        hookenv.log('Check removed from nrpe: {}'.format(tool))
-        count += 1
-
-    if count > 0:
-        nrpe_setup.write()
-        return True
-    return False
diff --git a/src/tests/unit/test_tooling.py b/src/tests/unit/test_tooling.py
deleted file mode 100644
index 3421b7f..0000000
--- a/src/tests/unit/test_tooling.py
+++ /dev/null
@@ -1,133 +0,0 @@
-import os  # noqa: F401
-import sys
-import unittest
-import unittest.mock as mock
-import zipfile
-
-
-sys.path.append('lib/hwhealth')
-import tooling  # noqa: E402
-
-
-class TestTooling(unittest.TestCase):
-    def test_install_resource_notools(self):
-        self.assertEqual(tooling.install_resource([], False), False)
-        self.assertEqual(
-            tooling.install_resource([], '/path/to/resource'), False)
-
-    def test_install_resource_noresource_nomdadm(self):
-        self.assertEqual(tooling.install_resource(['unittest'], False), False)
-
-    def test_install_resource_noresource_yesmdadm(self):
-        self.assertEqual(tooling.install_resource(['mdadm'], False), True)
-
-    @mock.patch('glob.glob')
-    @mock.patch('os.chmod')
-    @mock.patch('os.path.exists')
-    @mock.patch('os.path.isfile')
-    @mock.patch('shutil.chown')
-    @mock.patch('shutil.copy2')
-    @mock.patch('tempfile.TemporaryDirectory')
-    @mock.patch('zipfile.ZipFile')
-    def test_install_resource_ok(self, zfile, tmpdir, shutil_copy2,
-                                 shutil_chown, path_isfile, path_exists,
-                                 os_chmod, glob_glob):
-        class _WrapCls(object):
-            def __init__(cls):
-                cls.extractall = lambda x: None
-                cls.close = lambda: None
-
-        class Test_resource_zipfile(object):
-            def __enter__(cls):
-                return _WrapCls()
-
-            def __exit__(cls, type, value, traceback):
-                pass
-
-        class Test_resource_tmpdir(Test_resource_zipfile):
-            def __enter__(cls):
-                return ''
-
-        path_exists.return_value = True
-        zfile.return_value = Test_resource_zipfile()
-        tmpdir.return_value = Test_resource_tmpdir()
-        glob_glob.return_value = ['/tmp/test/megacli']
-        os_chmod.return_value = None
-        path_isfile.return_value = True
-        shutil_chown.return_value = None
-        shutil_copy2.return_value = None
-        actual = tooling.install_resource(['megacli'], '/tmp/test.zip')
-        expected = True
-        self.assertEqual(actual, expected)
-
-    @mock.patch('os.path.exists')
-    @mock.patch('zipfile.ZipFile')
-    def test_install_resource_zipfile_error(self, zfile, path_exists):
-        path_exists.return_value = True
-        zfile.side_effect = zipfile.BadZipFile('Intended error for unit test')
-        actual = tooling.install_resource(['megacli'], '/tmp/test.zip')
-        expected = False
-        self.assertEqual(actual, expected)
-
-    @mock.patch('glob.glob')
-    @mock.patch('os.path.exists')
-    @mock.patch('os.path.isfile')
-    @mock.patch('tempfile.TemporaryDirectory')
-    @mock.patch('zipfile.ZipFile')
-    def test_install_resource_nomatchedresource(self, zfile, tmpdir,
-                                                path_isfile, path_exists,
-                                                glob_glob):
-        class _WrapCls(object):
-            def __init__(cls):
-                cls.extractall = lambda x: None
-                cls.close = lambda: None
-
-        class Test_resource_zipfile(object):
-            def __enter__(cls):
-                return _WrapCls()
-
-            def __exit__(cls, type, value, traceback):
-                pass
-
-        class Test_resource_tmpdir(Test_resource_zipfile):
-            def __enter__(cls):
-                return ''
-
-        path_exists.return_value = True
-        zfile.return_value = Test_resource_zipfile()
-        tmpdir.return_value = Test_resource_tmpdir()
-        glob_glob.return_value = ['/tmp/test/megacli']
-        path_isfile.return_value = True
-        self.assertEqual(
-            tooling.install_resource(['unittest'], '/tmp/test.zip'), False)
-
-    def test_install_tools_notools(self):
-        self.assertEqual(tooling.install_tools([]), False)
-
-    def test_install_tools_unsupported_tools(self):
-        actual = tooling.install_tools(['unittest1', 'unittest2'])
-        expected = False
-        self.assertEqual(actual, expected)
-
-    def test_install_tools_supported_tools(self):
-        self.assertEqual(tooling.install_tools(['megacli', 'sas2ircu']), True)
-
-    def test_install_tools_mdadm(self):
-        self.assertEqual(tooling.install_tools(['mdadm']), True)
-
-    @mock.patch('os.environ')
-    @mock.patch('os.path.exists')
-    @mock.patch('os.path.join')
-    def test_get_filepath(self, path_join, path_exists, environ):
-        expected = 'unittest1'
-        environ.return_value = {'CHARM_DIR': 'xxx'}
-        path_join.return_value = expected
-        path_exists.return_value = True
-        self.assertEqual(tooling._get_filepath('asdfasdf'), expected)
-
-    def test_configure_tools_notools(self):
-        self.assertEqual(tooling.configure_tools([]), False)
-
-    def test_configure_tools_unsupported_tools(self):
-        self.assertEqual(
-            tooling.configure_tools(['unittest1', 'unittest2']), False)

Follow ups