From 82059be23c5a0d77af9584dd9aa9c21f13972b13 Mon Sep 17 00:00:00 2001 From: Thorsten Spille Date: Thu, 10 Mar 2022 19:38:37 +0100 Subject: [PATCH] v0.87 --- opnsense_checkmk_agent.py | 100 ++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 54 deletions(-) diff --git a/opnsense_checkmk_agent.py b/opnsense_checkmk_agent.py index b096ffc..9fe11cd 100644 --- a/opnsense_checkmk_agent.py +++ b/opnsense_checkmk_agent.py @@ -22,7 +22,7 @@ ## copy to /usr/local/etc/rc.syshook.d/start/99-checkmk_agent and chmod +x ## -__VERSION__ = "0.85" +__VERSION__ = "0.87" import sys import os @@ -52,10 +52,9 @@ from socketserver import TCPServer,StreamRequestHandler SCRIPTPATH = os.path.abspath(os.path.basename(__file__)) if os.path.islink(SCRIPTPATH): SCRIPTPATH = os.path.realpath(os.readlink(SCRIPTPATH)) -BASEDIR = os.path.dirname(SCRIPTPATH) -if BASEDIR.endswith("/bin"): - BASEDIR = BASEDIR[:-4] +BASEDIR = "/usr/local" MK_CONFDIR = os.path.join(BASEDIR,"etc") +CHECKMK_CONFIG = os.path.join(MK_CONFDIR,"checkmk.conf") LOCALDIR = os.path.join(BASEDIR,"local") SPOOLDIR = os.path.join(BASEDIR,"spool") @@ -108,7 +107,6 @@ class checkmk_handler(StreamRequestHandler): try: self.wfile.write(_strmsg) except: - raise pass class checkmk_checker(object): @@ -166,6 +164,8 @@ class checkmk_checker(object): for _check in dir(self): if _check.startswith("check_"): _name = _check.split("_",1)[1] + if _name in self.skipcheck: + continue try: _lines += getattr(self,_check)() except: @@ -176,6 +176,8 @@ class checkmk_checker(object): for _check in dir(self): if _check.startswith("checklocal_"): _name = _check.split("_",1)[1] + if _name in self.skipcheck: + continue try: _lines += getattr(self,_check)() except: @@ -460,52 +462,6 @@ class checkmk_checker(object): return _ret - def _old_check_net(self): - _opnsense_ifs = self.get_opnsense_interfaces() - _now = int(time.time()) - _ret = ["<<>>"] - _interface_status = dict( - map(lambda x: (x[0],(x[1:])), - re.findall("^(?P[\w.]+):.*?(?PUP|DOWN),.*?\n(?:\s+(?:media:.*?(?P\d+G?).*?\<(?P.*?)\>|(?:status:\s(?P[ \w]+))|).*?\n)*", - self._run_prog("ifconfig"),re.M) - ) - ) - _interface_data = self._run_prog("/usr/bin/netstat -i -b -d -n -W -f link").split("\n") - _header = _interface_data[0].lower() - _header = _header.replace("pkts","packets").replace("coll","collisions").replace("errs","error").replace("ibytes","rx").replace("obytes","tx") - _header = _header.split() - - for _line in _interface_data[1:]: - _fields = _line.split() - if not _fields: - continue - _iface = _fields[0] - if _iface.replace("*","") in ("pflog0","lo0"): - continue - _ifconfig = _interface_status.get(_iface,("","","unknown","")) - _name = _opnsense_ifs.get(_iface) - if not _name: - continue - _ifacedict = dict(zip(_header,_fields)) - _ifacedict.update({ - "interface_name" : _name, - "duplex" : _ifconfig[2], - "speed" : _ifconfig[1].replace("G","000"), - "systime" : _now, - "up" : str(bool(_ifconfig[3] in ("active",""))).lower(), - "admin_status" : str(bool(_ifconfig[0] == "UP")).lower(), - "phys_address" : _ifacedict.get("address") - }) - for _key,_val in _ifacedict.items(): - if _key in ("name","network","address"): - continue - if type(_val) == str: - _val = _val.replace(" ","_") - if not _val: - continue - _ret.append(f"{_iface}.{_key} {_val}") - return _ret - def checklocal_services(self): _phpcode = '' _proc = subprocess.Popen(["php"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL,encoding="utf-8") @@ -949,6 +905,14 @@ class checkmk_checker(object): pass return _ret + def check_ipmi(self): + if not os.path.exists("/usr/local/bin/ipmitool"): + return [] + _ret = ["<<>>"] + _out = self._run_prog("/usr/local/bin/ipmitool sensor list") + _ret += re.findall("^(?!.*\sna\s.*$).*",_out,re.M) + return _ret + def check_df(self): _ret = ["<<>>"] _ret += self._run_prog("df -kTP -t ufs").split("\n")[1:] @@ -1129,9 +1093,10 @@ class checkmk_cached_process(object): return _data class checkmk_server(TCPServer,checkmk_checker): - def __init__(self,port,pidfile,user,onlyfrom=None,encryptionkey=None,**kwargs): + def __init__(self,port,pidfile,user,onlyfrom=None,encryptionkey=None,skipcheck=None,**kwargs): self.pidfile = pidfile - self.onlyfrom=onlyfrom.split(",") if onlyfrom else None + self.onlyfrom = onlyfrom.split(",") if onlyfrom else None + self.skipcheck = skipcheck.split(",") if skipcheck else [] self.encryptionkey = encryptionkey self._mutex = threading.Lock() self.user = pwd.getpwnam(user) @@ -1321,8 +1286,16 @@ class smart_disc(object): if __name__ == "__main__": import argparse + class SmartFormatter(argparse.HelpFormatter): + + def _split_lines(self, text, width): + if text.startswith('R|'): + return text[2:].splitlines() + # this is the RawTextHelpFormatter._split_lines + return argparse.HelpFormatter._split_lines(self, text, width) + _checks_available = sorted(list(map(lambda x: x.split("_")[1],filter(lambda x: x.startswith("check_") or x.startswith("checklocal_"),dir(checkmk_checker))))) _ = lambda x: x - _parser = argparse.ArgumentParser(f"checkmk_agent for opnsense\nVersion: {__VERSION__}\n##########################################\n") + _parser = argparse.ArgumentParser(f"checkmk_agent for opnsense\nVersion: {__VERSION__}\n##########################################\n", formatter_class=SmartFormatter) _parser.add_argument("--port",type=int,default=6556, help=_("Port checkmk_agent listen")) _parser.add_argument("--start",action="store_true", @@ -1333,6 +1306,8 @@ if __name__ == "__main__": help=_("run in foreground")) _parser.add_argument("--status",action="store_true", help=_("show status if running")) + _parser.add_argument("--config",type=str,dest="configfile",default=CHECKMK_CONFIG, + help=_("path to config file")) _parser.add_argument("--user",type=str,default="root", help=_("")) _parser.add_argument("--encrypt",type=str,dest="encryptionkey", @@ -1341,9 +1316,26 @@ if __name__ == "__main__": help=_("")) _parser.add_argument("--onlyfrom",type=str, help=_("comma seperated ip addresses to allow")) + _parser.add_argument("--skipcheck",type=str, + help=_("R|comma seperated checks that will be skipped \n{0}".format("\n".join([", ".join(_checks_available[i:i+10]) for i in range(0,len(_checks_available),10)])))) _parser.add_argument("--debug",action="store_true", help=_("debug Ausgabe")) args = _parser.parse_args() + if args.configfile and os.path.exists(args.configfile): + for _k,_v in re.findall(f"^(\w+):\s*(.*?)(?:\s+#|$)",open(args.configfile,"rt").read(),re.M): + if _k == "port": + args.port = int(_v) + if _k == "encrypt": + args.encryptionkey = _v + if _k == "onlyfrom": + args.onlyfrom = _v + if _k == "skipcheck": + args.skipcheck = _v + if _k.lower() == "localdir": + LOCALDIR = _v + if _k.lower() == "spooldir": + SPOOLDIR = _v + _server = checkmk_server(**args.__dict__) _pid = None try: