Source code for accre.nrpe

"""
Shared utility functions to use in nrpe scripts
"""
import datetime
import os.path
import re
import sys


[docs]def nrpe_precheck(fname, timeout=600, reboot_grace=7200): """ Check that the given nrpe precheck file exists and has been updated within the specified timeout, or exit critical (2). If ok, return file contents. If the file does not exist and the machine has recently rebooted, an ok will be given instead of a critical status. A precheck file is a small output file generated by some command that needs to be run as root which has output to be inspected by an NRPE check. This is done as a cronjob on a node so that the NRPE user does not need sudo access to run diagnostics. Running checks this way also makes it easy to test the check itself against expected failures. :param str fname: Absolute path to the precheck file :param int timeout: Maximum number of seconds that may have passed since the precheck file was last updated :param int reboot_grace: Maximum number of seconds after reboot to allow a grace period where the file may not exist :returns: Precheck file contents :rtype: str """ grace = False try: raw = open('/proc/uptime').read() uptime = float(raw.split()[0]) if uptime < reboot_grace: grace = True except Exception: # No grace period if we can't read /proc/uptime pass try: last = datetime.datetime.fromtimestamp(os.path.getmtime(fname)) except FileNotFoundError: if grace: print( 'OK - NRPE precheck file {0} not found but machine recently ' 'rebooted'.format(fname) ) sys.exit(0) print('CRITICAL - NRPE precheck file {0} not found'.format(fname)) sys.exit(2) ttl = (datetime.datetime.now() - last).total_seconds() if ttl > timeout: print( 'CRITICAL - NRPE precheck file {0} not modified in last {1}s' .format(fname, int(ttl)) ) sys.exit(2) try: return open(fname).read() except Exception: print( 'CRITICAL - NRPE precheck file {0} could not be read' .format(fname) ) sys.exit(2)
[docs]def parse_mmlsdisk(raw): """ Return mmlsdisk info for each device :param str raw: Raw input text presumably from an mmlsdisk command run with the -Y option :returns: List of device data dictionaries :rtype: list(dict(str, str)) """ lines = raw.splitlines() lines = [s[len('mmlsdisk:'):].strip(':') for s in lines] keys = lines[0].split(':') result = [] for line in lines[1:]: dev = {} for idx, val in enumerate(line.split(':')): dev[keys[idx]] = val result.append(dev) return result
[docs]def parse_multipath_info(raw): """ Return information for each multipath device from output presumably returned by "multipath -ll" with their name (i.e. "dm-X"), their serial number, and number of links in the "active ready running" state. :param str raw: Raw input text presumably from a multipath -ll command :returns: List of device data dictionaries :rtype: list(dict(str, str)) """ redev = re.compile( r'(mpath[a-z]+|accre-[a-z0-9-]+|dors2[a-z0-9-]+) ' r'\(([0-9a-f]+)\) (dm-[0-9]+)' ) result = [] dev = None for line in raw.splitlines(): m = redev.match(line) if m: if dev is not None: result.append(dev) dev = {} dev['title'] = m.group(1) dev['serial'] = m.group(2) dev['name'] = m.group(3) dev['good_links'] = 0 else: if re.search('active ready running', line) and dev is not None: dev['good_links'] += 1 if dev is not None: result.append(dev) return result