class BatteryPacksAttached(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__count = None
        self.__oid = '1.3.6.1.4.1.318.1.1.1.2.2.5'

        Plugin.__init__(self,
                        'Check the number of attached external battery packs')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument(
            '-c',
            '--count',
            dest='count',
            required=True,
            type=int,
            help='Number of attached external battery packs')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__count = args.count

    def run(self):
        oids = self.__snmp_executor.run()

        if 1 != len(oids) or '0' != oids[0]['oid']:
            self.__status_builder.unknown(
                Output(
                    f'Couldn\'t get the number of attached external battery packs'
                ))
            return

        attached = oids[0]['value']

        output = Output(
            f'There are currently {attached} external batteries attached (required {self.__count})'
        )

        if attached != self.__count:
            self.__status_builder.critical(output)
        else:
            self.__status_builder.success(output)
Example #2
0
class LastDiagnosticTestResultTime(Plugin):

    def __init__(self):
        self.__logger = None
        self.__status_builder = None
        self.__warning = None
        self.__critical = None

        self.__snmp_executor = None
        self.__oid = '1.3.6.1.4.1.318.1.1.1.7.2.4'

        Plugin.__init__(self, 'Check last self diagnostic test result time')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger, self.__status_builder, self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-w', '--warning', dest='warning', required=False,
                                   type=int, help='Time, until exit in warning state (in days)',
                                   default=7)
        self.__parser.add_argument('-c', '--critical', dest='critical', required=False,
                                   type=int, help='Time, until exit in critical state (in days)',
                                   default=10)

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__warning = args.warning
        self.__critical = args.critical

    def run(self):
        oids = self.__snmp_executor.run()

        if 1 != len(oids) or '0' != oids[0]['oid']:
            self.__status_builder.unknown(Output(f'Couldn\'t get last diagnostic test result time'))
            return

        last_run = oids[0]["value"]
        last_check = datetime.strptime(last_run, '%m/%d/%Y')
        now = datetime.now()
        warning = timedelta(days=self.__warning)
        critical = timedelta(days=self.__critical)
        output = Output(f'Last selftest runtime {last_run}')

        if (now - critical) >= last_check:
            self.__status_builder.critical(output)
        elif (now - warning) >= last_check:
            self.__status_builder.warning(output)
        else:
            self.__status_builder.success(output)
Example #3
0
class Upgrade(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__oid = '1.3.6.1.4.1.6574.1.5.4'

        Plugin.__init__(self, 'Check if an upgrade is available on the system')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

    def configure(self, args):
        self.__snmp_executor.configure(args)

    def run(self):
        oids = self.__snmp_executor.run()

        if len(oids) != 1:
            self.__status_builder.unknown(
                Output('Can\'t find the upgrade status of the system.'))
            self.__status_builder.exit()

        if 1 == oids[0]['value']:
            self.__status_builder.critical(
                Output('System upgrade is available'))
        elif 2 == oids[0]['value']:
            self.__status_builder.success(
                Output('No system upgrade is available'))
        elif 3 == oids[0]['value']:
            self.__status_builder.unknown(
                Output('Connecting to update server'))
        elif 4 == oids[0]['value']:
            self.__status_builder.unknown(
                Output('Disconnected from update server'))
        elif 5 == oids[0]['value']:
            self.__status_builder.unknown(Output('Other unknown status'))
        else:
            self.__status_builder.unknown(
                Output('Can\'t find the upgrade status of the system.'))
Example #4
0
class BatteryStatus(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__oid = '1.3.6.1.4.1.318.1.1.1.2.1.1'

        Plugin.__init__(self, 'Check the battery status')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

    def configure(self, args):
        self.__snmp_executor.configure(args)

    def run(self):
        oids = self.__snmp_executor.run()

        if 1 != len(oids) or '0' != oids[0]['oid']:
            self.__status_builder.unknown(
                Output(f'Couldn\'t get Battery status information'))
            return

        if 1 == oids[0]['value']:
            self.__status_builder.unknown(
                Output(f'Got unknown battery status'))
        elif 2 == oids[0]['value']:
            self.__status_builder.success(Output(f'Battery status normal'))
        elif 3 == oids[0]['value']:
            self.__status_builder.warning(Output(f'Low Battery status'))
        elif 4 == oids[0]['value']:
            self.__status_builder.critical(
                Output(f'Battery in pre-fail status'))
        else:
            self.__status_builder.unknown(
                Output(
                    f'Got unknown Battery status information "{oids[0]["value"]}"'
                ))
class BatteryBadBatteryPacks(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__oid = '1.3.6.1.4.1.318.1.1.1.2.2.6'

        Plugin.__init__(
            self,
            'Check the number of attached defective external battery packs')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

    def configure(self, args):
        self.__snmp_executor.configure(args)

    def run(self):
        oids = self.__snmp_executor.run()

        if 1 != len(oids) or '0' != oids[0]['oid']:
            self.__status_builder.unknown(
                Output(
                    f'Couldn\'t get the number of attached external battery packs'
                ))
            return

        defective = oids[0]['value']

        output = Output(
            f'There are currently {defective} external batteries defective')

        if defective > 0:
            self.__status_builder.critical(output)
        else:
            self.__status_builder.success(output)
class PowerStatus(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__oid = '1.3.6.1.4.1.6574.1.3'

        Plugin.__init__(self, 'Check the power status of the system')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

    def configure(self, args):
        self.__snmp_executor.configure(args)

    def run(self):
        oids = self.__snmp_executor.run()

        if len(oids) != 1:
            self.__status_builder.unknown(
                Output('Can\'t find the status of the system.'))
            self.__status_builder.exit()

        if 1 == oids[0]['value']:
            self.__status_builder.success(
                Output('System power status is normal'))
        elif 2 == oids[0]['value']:
            self.__status_builder.critical(
                Output('System power status is critical'))
        else:
            self.__status_builder.unknown(
                Output('Got an unknown power status code "{code}"'.format(
                    code=oids[0]['value'])))

        self.__status_builder.exit(True)
class BatteryReplacement(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__oid = '1.3.6.1.4.1.318.1.1.1.2.2.4'

        Plugin.__init__(self, 'Check if a battery replacement is needed')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

    def configure(self, args):
        self.__snmp_executor.configure(args)

    def run(self):
        oids = self.__snmp_executor.run()

        if 1 != len(oids) or '0' != oids[0]['oid']:
            self.__status_builder.unknown(
                Output(f'Couldn\'t get Battery replacement information'))
            return

        if 1 == oids[0]['value']:
            self.__status_builder.success(
                Output(f'No Battery replacement needed'))
        elif 2 == oids[0]['value']:
            self.__status_builder.critical(
                Output(f'Battery replacement needed'))
        else:
            self.__status_builder.unknown(
                Output(
                    f'Got unknown Battery replacement information "{oids[0]["value"]}"'
                ))
Example #8
0
class BatteryTemperature(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.318.1.1.1.2.2.2'

        Plugin.__init__(self, 'Check the temperature of the battery')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-w',
                                   '--warning',
                                   dest='warning',
                                   required=False,
                                   type=int,
                                   help='Warning Temperature',
                                   default=25)
        self.__parser.add_argument('-c',
                                   '--critical',
                                   dest='critical',
                                   required=False,
                                   type=int,
                                   help='Critical Temperature',
                                   default=30)

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__warning = args.warning
        self.__critical = args.critical

    def run(self):
        oids = self.__snmp_executor.run()

        if 1 != len(oids) or '0' != oids[0]['oid']:
            self.__status_builder.unknown(
                Output(f'Couldn\'t get Battery temperature information'))
            return

        temperature = oids[0]['value']

        output = Output(f'Temperature is {temperature}°', [
            Perfdata('temperature',
                     temperature,
                     unit='°',
                     warning=self.__warning,
                     critical=self.__critical,
                     min=0,
                     max=50)
        ])

        if temperature >= self.__critical:
            self.__status_builder.critical(output)
        elif temperature >= self.__warning:
            self.__status_builder.warning(output)
        else:
            self.__status_builder.success(output)
Example #9
0
class ServiceUsed(Plugin):

    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__service = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.6574.6.1.1'

        Plugin.__init__(self, 'Check how many users using a service')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger, self.__status_builder, self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-w', '--warning', dest='warning', required=True,
                                   type=int, help='Warning users bound')
        self.__parser.add_argument('-c', '--critical', dest='critical', required=True,
                                   type=int, help='Critical users bound')
        self.__parser.add_argument('-s', '--service', dest='service', required=True,
                                   type=str, help='Service to check user status')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__service = args.service
        self.__warning = args.warning
        self.__critical = args.critical

    def run(self):
        oids = self.__snmp_executor.run()

        services_running = {}

        for oid in oids:
            base = oid['oid'].split('.')

            id = int(base[1])
            config = services_running.get(id, {})

            if '2' == base[0]:
                config['service'] = oid['value'].lower()
            elif '3' == base[0]:
                config['users'] = oid['value']

            services_running[id] = config

        for service_id in services_running:
            config = services_running[service_id]
            if config['service'] == self.__service.lower():
                output = Output(f"Service \"{config['service']}\" is currently used by {config['users']} users.",
                                [Perfdata(config["service"].replace('/', '_'), config["users"])])
                if config['users'] >= self.__critical:
                    self.__status_builder.critical(output)
                elif config['users'] >= self.__warning:
                    self.__status_builder.warning(output)
                else:
                    self.__status_builder.success(output)
                self.__status_builder.exit()

        self.__status_builder.unknown(Output(f'Service "{self.__service}" not found. Is it running?'))
Example #10
0
class RAIDStatus(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__num_raids = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.6574.3.1.1'

        Plugin.__init__(self, 'Check The RAID status')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-r',
                                   '--raids',
                                   dest='disks',
                                   required=True,
                                   type=int,
                                   help='Number of RAIDs')

        self.__parser.add_argument('-w',
                                   '--warning',
                                   dest='warning',
                                   required=True,
                                   type=int,
                                   help='Warning free disk space (%)')
        self.__parser.add_argument('-c',
                                   '--critical',
                                   dest='critical',
                                   required=True,
                                   type=int,
                                   help='Critical disk space (%)')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__num_raids = args.disks
        self.__warning = args.warning
        self.__critical = args.critical

        failed = False
        if self.__critical > 100:
            self.__status_builder.unknown(
                Output('Critical value can\'t be greater than 100 %'))
            failed = True
        elif self.__critical < 0:
            self.__status_builder.unknown(
                Output('Critical value must be at least 0 %'))
            failed = True

        if self.__warning > self.__critical:
            self.__status_builder.unknown(
                Output('Warning value can\'t be greater than critical value'))
            failed = True

        elif self.__warning < 0:
            self.__status_builder.unknown(
                Output('Warning value must be at least 0 %'))
            failed = True

        if failed:
            self.__status_builder.exit()

    def run(self):
        oids = self.__snmp_executor.run()

        if len(oids) != self.__num_raids * 5:
            self.__status_builder.unknown(
                Output(
                    'You try to check "{disks}" RAIDs but there are "{configured}" RAIDs in your system.'
                    .format(disks=self.__num_raids,
                            configured=int(len(oids) / 5))))
            self.__status_builder.exit()

        raids = [{} for i in range(0, self.__num_raids)]

        for oid in oids:
            base = oid['oid'].split('.')
            disk_id = int(base[1])

            if '1' == base[0]:
                raids[disk_id]['index'] = oid['value']
            elif '2' == base[0]:
                raids[disk_id]['name'] = oid['value']
            elif '3' == base[0]:
                raids[disk_id]['status'] = oid['value']
            elif '4' == base[0]:
                raids[disk_id]['free'] = oid['value']
            elif '5' == base[0]:
                raids[disk_id]['total'] = oid['value']

        status = {
            1: 'Normal',
            2: 'Repairing',
            3: 'Migrating',
            4: 'Expanding',
            5: 'Deleting',
            6: 'Creating',
            7: 'Raid syncing',
            8: 'Raid parity checking',
            9: 'Raid assembling',
            10: 'Canceling',
            11: 'Degrade',
            12: 'Crashed',
            13: 'Data scrubbing',
            14: 'Raid deploying',
            15: 'Raid undeploying',
            16: 'Raid mount cache',
            17: 'Raid unmount cache',
            18: 'Raid expanding unfinised SHR',
            19: 'Raid convert SHR to pool',
            20: 'Raid migrate SHR1 to HR2',
            21: 'Raid unknown status',
        }

        warning_states = [2, 3, 4, 13, 15]
        unknown_states = [6, 7, 8, 9, 14, 16, 17, 18, 19, 20, 21]
        critical_states = [5, 10, 11, 12]

        for raid in raids:
            usage = raid['total'] - raid['free']
            usage_percent = usage / raid['total'] * 100

            perfdata = [
                Perfdata(f'{raid["name"]}',
                         usage,
                         warning=self.__warning / 100 * raid['total'],
                         critical=self.__critical / 100 * raid['total'],
                         min=0,
                         max=raid['total']),
            ]

            output = Output(
                raid['name'] + ' - ' + status[raid['status']] + ' (' +
                str(usage_percent) + ' % used - ' + str(usage) + ' / ' +
                str(raid['total']) + ')', perfdata)

            if self.__critical <= usage_percent:
                self.__status_builder.critical(output)
            elif self.__warning <= usage_percent:
                if raid['status'] in critical_states:
                    self.__status_builder.critical(output)
                else:
                    self.__status_builder.warning(output)
            else:
                if raid['status'] in critical_states:
                    self.__status_builder.critical(output)
                elif raid['status'] in warning_states:
                    self.__status_builder.warning(output)
                elif raid['status'] in unknown_states:
                    self.__status_builder.unknown(output)
                else:
                    self.__status_builder.success(output)

        self.__status_builder.exit(True)
class BatteryRemainingRuntime(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.318.1.1.1.2.2.3'

        Plugin.__init__(
            self, 'Check the remaining runtime of the battery (in seconds)')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-w',
                                   '--warning',
                                   dest='warning',
                                   required=False,
                                   type=int,
                                   help='Warning Runtime (in seconds)',
                                   default=25 * 60)
        self.__parser.add_argument('-c',
                                   '--critical',
                                   dest='critical',
                                   required=False,
                                   type=int,
                                   help='Critical Runtime (in seconds)',
                                   default=15 * 60)

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__warning = args.warning
        self.__critical = args.critical

    def run(self):
        oids = self.__snmp_executor.run()

        if 1 != len(oids) or '0' != oids[0]['oid']:
            self.__status_builder.unknown(
                Output(f'Couldn\'t get Battery remaining runtime information'))
            return

        value = oids[0]['value']
        remaining = int(value[value.find('(') + 1:value.find(')')])

        sec = timedelta(seconds=remaining)
        d = datetime(1, 1, 1) + sec

        output = Output(
            f'Remaining runtime {remaining}s ({d.day - 1}d {d.hour}h {d.minute}m {d.second}s)',
            [
                Perfdata('remaining',
                         remaining,
                         unit='s',
                         warning=self.__warning,
                         critical=self.__critical,
                         min=0)
            ])

        if remaining <= self.__critical:
            self.__status_builder.critical(output)
        elif remaining <= self.__warning:
            self.__status_builder.warning(output)
        else:
            self.__status_builder.success(output)
Example #12
0
class GPUInfo(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__gpu_id = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.6574.108'

        Plugin.__init__(self, 'Check GPU information')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-g',
                                   '--gpu',
                                   dest='gpu',
                                   required=True,
                                   type=int,
                                   help='Number of the gpu to check')

        self.__parser.add_argument('-w',
                                   '--warning',
                                   dest='warning',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%)')
        self.__parser.add_argument('-c',
                                   '--critical',
                                   dest='critical',
                                   required=False,
                                   type=int,
                                   help='Critical usage (%)')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__gpu_id = args.gpu
        self.__warning = args.warning
        self.__critical = args.critical

        failed = False
        if None is not self.__critical:
            if self.__critical > 100:
                self.__status_builder.unknown(
                    Output('Critical value can\'t be greater than 100 %'))
                failed = True
            elif self.__critical < 0:
                self.__status_builder.unknown(
                    Output('Critical value must be at least 0 %'))
                failed = True

        if None is not self.__warning:

            if self.__warning < 0:
                self.__status_builder.unknown(
                    Output('Warning value must be at least 0 %'))
                failed = True

        if None is not self.__critical and None is self.__warning:
            self.__status_builder.unknown(
                Output(
                    'If you set a critical bound you have to specify a warning bound'
                ))
            failed = True
        elif None is self.__critical and None is not self.__warning:
            self.__status_builder.unknown(
                Output(
                    'If you set a warning bound you have to specify a critical bound'
                ))
            failed = True
        elif None is not self.__critical and None is not self.__warning:
            if self.__warning > self.__critical:
                self.__status_builder.unknown(
                    Output(
                        'Warning value can\'t be greater than critical value'))
                failed = True

        if failed:
            self.__status_builder.exit()

    def run(self):
        oids = self.__snmp_executor.run()

        status_data = {}

        keys = {
            '1': 'supported',
            '2': 'utilization',
            '3': 'usage',
            '4': 'free',
            '5': 'used',
            '6': 'total',
        }
        for oid in oids:
            base = oid['oid'].split('.')
            id = int(base[1])

            if int(base[1]) != self.__gpu_id:
                continue

            data = status_data.get(id, {})
            data[keys.get(base[0])] = oid['value']
            status_data[id] = data

        if 0 == len(status_data):
            self.__status_builder.unknown(
                Output(
                    f'GPU "{self.__gpu_id}" either does not exist or not accessible'
                ))
            self.__status_builder.exit()

        for status_data_id in status_data:
            data = status_data[status_data_id]

            if 1 == data['supported']:
                output = Output(f"GPU \"{self.__gpu_id}\" is unsupported")
                self.__status_builder.unknown(output)
                continue

            if None is self.__warning:
                perfdata = [
                    Perfdata(f'{self.__gpu_id}',
                             data['used'],
                             min=0,
                             max=data['total']),
                ]
            else:
                perfdata = [
                    Perfdata(f'{self.__gpu_id}',
                             data['used'],
                             warning=self.__warning / 100 * data['total'],
                             critical=self.__critical / 100 * data['total'],
                             min=0,
                             max=data['total']),
                ]

            output = Output(f"GPU \"{self.__gpu_id}\"", perfdata)

            if None is self.__warning:
                self.__status_builder.success(output)
            else:
                if self.__critical <= data['usage']:
                    self.__status_builder.critical(output)
                elif self.__warning <= data['usage']:
                    self.__status_builder.warning(output)
                else:
                    self.__status_builder.success(output)
Example #13
0
class Load(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__disk = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.2021.13.15.1.1'

        Plugin.__init__(self, 'Check Disk Load average')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-d',
                                   '--disk',
                                   dest='disk',
                                   required=False,
                                   default=None,
                                   type=int,
                                   help='Number of the disk to check')

        self.__parser.add_argument(
            '-w',
            '--warning',
            dest='warning',
            required=False,
            type=str,
            help='Warning load. Format: LOAD1,LOAD5,LOAD15')
        self.__parser.add_argument(
            '-c',
            '--critical',
            dest='critical',
            required=False,
            type=str,
            help='Critical load. Format: LOAD1,LOAD5,LOAD15')

    def configure(self, args):
        self.__snmp_executor.configure(args)

        self.__disk = args.disk

        if None is args.warning and args.critical is not None:
            self.__status_builder.unknown(
                Output(
                    'If critical load is defined, you have to set warning load'
                ))
            self.__status_builder.exit()

        if None is not args.warning and args.critical is None:
            self.__status_builder.unknown(
                Output(
                    'If warning load is defined, you have to set critical load'
                ))
            self.__status_builder.exit()

        warning = args.warning
        if None is not warning:
            warning = warning.split(',')
            if len(warning) != 3:
                self.__status_builder.unknown(
                    Output(
                        'Format for warning load mismatch. Expected Format: LOAD1,LOAD5,LOAD15'
                    ))
                self.__status_builder.exit()
            self.__warning = [
                float(warning[0]),
                float(warning[1]),
                float(warning[2])
            ]
        else:
            if args.critical is not None:
                self.__status_builder.unknown(
                    Output(
                        'If you set a critical value, you have to set a warning value too.'
                    ))
                self.__status_builder.exit()

        critical = args.critical
        if None is not critical:
            critical = critical.split(',')
            if len(critical) != 3:
                self.__status_builder.unknown(
                    Output(
                        'Format for critical load mismatch. Expected Format: LOAD1,LOAD5,LOAD15'
                    ))
                self.__status_builder.exit()
            self.__critical = [
                float(critical[0]),
                float(critical[1]),
                float(critical[2])
            ]
        else:
            if args.warning is not None:
                self.__status_builder.unknown(
                    Output(
                        'If you set a warning value, you have to set a critical value too.'
                    ))
                self.__status_builder.exit()

    def run(self):
        oids = self.__snmp_executor.run()

        status_data = {}

        keys = {
            '1': 'index',
            '2': 'device',
            '3': 'numberReads',
            '4': 'numberWrites',
            '5': 'reads',
            '6': 'writes',
            '9': 'load1',
            '10': 'load5',
            '11': 'load15',
            '12': 'reads64',
            '13': 'writes64',
        }
        for oid in oids:
            base = oid['oid'].split('.')

            id = int(base[1])

            if None is not self.__disk and id != self.__disk:
                continue

            data = status_data.get(id, {})
            data[keys.get(base[0])] = oid['value']
            status_data[id] = data

        if 0 == len(status_data):
            if None is self.__disk:
                self.__status_builder.unknown(
                    Output(
                        f'Either no disks exist or they are not accessible'))
            else:
                self.__status_builder.unknown(
                    Output(
                        f'Disk "{self.__disk}" either does not exist or not accessible'
                    ))
            self.__status_builder.exit()

        for status_data_id in status_data:
            data = status_data[status_data_id]
            prefix = '' if None is not self.__disk else f"{data['device'].replace(' ', '_')}."

            perfdata = [
                Perfdata(f'{prefix}numberReads', data['numberReads'],
                         unit='c'),
                Perfdata(f'{prefix}numberWrites',
                         data['numberWrites'],
                         unit='c'),
                Perfdata(f'{prefix}reads', data['reads'], unit='c'),
                Perfdata(f'{prefix}writes', data['writes'], unit='c'),
                Perfdata(f'{prefix}reads64', data['reads64'], unit='c'),
                Perfdata(f'{prefix}writes64', data['writes64'], unit='c'),
            ]

            if None is self.__warning:
                perfdata += [
                    Perfdata("load", data['load']),
                    Perfdata("load1", data['load1']),
                    Perfdata("load5", data['load5']),
                ]
            else:
                perfdata += [
                    Perfdata("load",
                             data['load'],
                             warning=self.__warning[0],
                             critical=self.__critical[0]),
                    Perfdata("load1",
                             data['load1'],
                             warning=self.__warning[0],
                             critical=self.__critical[0]),
                    Perfdata("load5",
                             data['load5'],
                             warning=self.__warning[0],
                             critical=self.__critical[0]),
                ]

            output = Output(f"Disk load \"{data['device']}\"", perfdata)

            if None is self.__warning:
                self.__status_builder.success(output)
            else:
                if self.__critical[0] <= data['load1'] \
                        or self.__critical[1] <= data['load5'] \
                        or self.__critical[2] <= data['load15']:
                    self.__status_builder.critical(output)
                elif self.__warning[0] <= data['load1'] \
                        or self.__warning[1] <= data['load5'] \
                        or self.__warning[2] <= data['load15']:
                    self.__status_builder.warning(output)
                else:
                    self.__status_builder.success(output)
Example #14
0
class SpaceIO(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__volume_id = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.6574.102.1.1'

        Plugin.__init__(self, 'Check space I/O information of volumes')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-v',
                                   '--volume',
                                   dest='volume',
                                   required=True,
                                   type=int,
                                   help='Number of the volume to check')

        self.__parser.add_argument(
            '-w',
            '--warning',
            dest='warning',
            required=False,
            type=str,
            help='Warning load. Format: LOAD1,LOAD5,LOAD15')
        self.__parser.add_argument(
            '-c',
            '--critical',
            dest='critical',
            required=False,
            type=str,
            help='Critical load. Format: LOAD1,LOAD5,LOAD15')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__volume_id = args.volume

        warning = args.warning
        if None is not warning:
            warning = warning.split(',')
            if len(warning) != 3:
                self.__status_builder.unknown(
                    Output(
                        'Format for warning load mismatch. Expected Format: LOAD1,LOAD5,LOAD15'
                    ))
                self.__status_builder.exit()
            self.__warning = [
                int(warning[0]),
                int(warning[1]),
                int(warning[2])
            ]

        critical = args.critical
        if None is not critical:
            critical = critical.split(',')
            if len(critical) != 3:
                self.__status_builder.unknown(
                    Output(
                        'Format for critical load mismatch. Expected Format: LOAD1,LOAD5,LOAD15'
                    ))
                self.__status_builder.exit()
            self.__critical = [
                int(critical[0]),
                int(critical[1]),
                int(critical[2])
            ]

        if None is self.__warning and self.__critical is not None:
            self.__status_builder.unknown(
                Output(
                    'If critical load is defined, you have to set warning load'
                ))
            self.__status_builder.exit()

        if None is not self.__warning and self.__critical is None:
            self.__status_builder.unknown(
                Output(
                    'If warning load is defined, you have to set critical load'
                ))
            self.__status_builder.exit()

    def run(self):
        oids = self.__snmp_executor.run()

        status_data = {}

        keys = {
            '2': 'device',
            '3': 'bytesRead32',
            '4': 'bytesWrite32',
            '5': 'reads',
            '6': 'writes',
            '8': 'load',
            '9': 'load1',
            '10': 'load5',
            '11': 'load15',
            '12': 'bytesRead64',
            '13': 'bytesWrite64',
            '14': 'uuid',
        }
        for oid in oids:
            base = oid['oid'].split('.')

            id = int(base[1])

            if base[0] == '1' or int(base[1]) != self.__volume_id:
                continue

            data = status_data.get(id, {})
            data[keys.get(base[0])] = oid['value']
            status_data[id] = data

        if 0 == len(status_data):
            self.__status_builder.unknown(
                Output(
                    f'Volume "{self.__volume_id}" either does not exist or not accessible'
                ))
            self.__status_builder.exit()

        for status_data_id in status_data:
            data = status_data[status_data_id]

            perfdata = [
                Perfdata("load15", data['load15']),
                Perfdata("bytesRead32", data['bytesRead32']),
                Perfdata("bytesRead64", data['bytesRead64']),
                Perfdata("bytesWrite32", data['bytesWrite32']),
                Perfdata("bytesWrite64", data['bytesWrite64']),
                Perfdata("reads", data['reads']),
                Perfdata("writes", data['writes']),
            ]
            if None is self.__warning:
                perfdata += [
                    Perfdata("load", data['load']),
                    Perfdata("load1", data['load1']),
                    Perfdata("load5", data['load5']),
                ]
            else:
                perfdata += [
                    Perfdata("load",
                             data['load'],
                             warning=self.__warning[0],
                             critical=self.__critical[0]),
                    Perfdata("load1",
                             data['load1'],
                             warning=self.__warning[0],
                             critical=self.__critical[0]),
                    Perfdata("load5",
                             data['load5'],
                             warning=self.__warning[0],
                             critical=self.__critical[0]),
                ]

            output = Output(
                f"Volume \"{data['device']}\" [{data.get('uuid', 'unknown UUID')}]",
                perfdata)

            if None is self.__warning:
                self.__status_builder.success(output)
            else:
                if self.__critical[0] <= data['load1'] \
                        or self.__critical[1] <= data['load5'] \
                        or self.__critical[2] <= data['load15']:
                    self.__status_builder.critical(output)
                elif self.__warning[0] <= data['load1'] \
                        or self.__warning[1] <= data['load5'] \
                        or self.__warning[2] <= data['load15']:
                    self.__status_builder.warning(output)
                else:
                    self.__status_builder.success(output)
Example #15
0
class SMART(Plugin):

    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__disk_id = None
        self.__oid = '1.3.6.1.4.1.6574.5.1.1'

        Plugin.__init__(self, 'Check the SMART status of a specific disk')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger, self.__status_builder, self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-d', '--disk', dest='disk', required=True,
                                   type=int, help='Number of the disk to check')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__disk_id = args.disk

    def run(self):
        oids = self.__snmp_executor.run()

        first_datapoint = self.__disk_id * 17 - 16
        last_datapoint = self.__disk_id * 17

        status_data = {}

        keys = {
            '3': 'attributeName',
            '4': 'attributeId',
            '5': 'current',
            '6': 'worst',
            '7': 'threshold',
            '8': 'raw',
            '9': 'status',
        }
        for oid in oids:
            base = oid['oid'].split('.')

            id = int(base[1])

            if base[0] in ['1', '2'] or id < first_datapoint or id > last_datapoint:
                continue

            data = status_data.get(id, {})
            data[keys.get(base[0])] = oid['value']
            status_data[id] = data

        critical_values = ['pre-fail', 'pre fail', 'pre_fail', 'old-age', 'old age', 'old_age']
        for status_data_id in status_data:
            data = status_data[status_data_id]

            perfdata = [
                Perfdata(f"{data['attributeName']}.id", data['attributeId']),
                Perfdata(f"{data['attributeName']}.status", data['status']),
                Perfdata(f"{data['attributeName']}.current", data['current']),
                Perfdata(f"{data['attributeName']}.threshold", data['threshold']),
                Perfdata(f"{data['attributeName']}.worst", data['worst']),
                Perfdata(f"{data['attributeName']}.raw", data['raw']),
            ]

            output = Output(f"{data['attributeName']} [{data['attributeId']}] is \"{data['status']}\" current: " \
                            f"{data['current']}, worst: {data['worst']}, threshold: {data['threshold']}, raw: " \
                            f"{data['raw']}", perfdata)

            if data['status'].lower() == 'ok':
                self.__status_builder.success(output)
            elif data['status'].lower() in critical_values:
                self.__status_builder.critical(output)
            else:
                self.__status_builder.warning(output)
Example #16
0
class DiskTemperature(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__num_disks = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.6574.2.1.1'

        Plugin.__init__(self, 'Check The temperature of the disks')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-d',
                                   '--disks',
                                   dest='disks',
                                   required=True,
                                   type=int,
                                   help='Number of disks')

        self.__parser.add_argument('-w',
                                   '--warning',
                                   dest='warning',
                                   required=True,
                                   type=int,
                                   help='Warning temperature')
        self.__parser.add_argument('-c',
                                   '--critical',
                                   dest='critical',
                                   required=True,
                                   type=int,
                                   help='Critical temperature')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__num_disks = args.disks
        self.__warning = args.warning
        self.__critical = args.critical

    def run(self):
        oids = self.__snmp_executor.run()

        if len(oids) != self.__num_disks * 6:
            self.__status_builder.unknown(
                Output(
                    'You try to check "{disks}" but there are "{configured}" disks in your system.'
                    .format(disks=self.__num_disks,
                            configured=int(len(oids) / 6))))
            self.__status_builder.exit()

        disks = [{} for i in range(0, self.__num_disks)]

        for oid in oids:
            base = oid['oid'].split('.')
            disk_id = int(base[1])

            if '1' == base[0]:
                disks[disk_id]['index'] = oid['value']
            elif '2' == base[0]:
                disks[disk_id]['id'] = oid['value']
            elif '3' == base[0]:
                disks[disk_id]['model'] = oid['value']
            elif '4' == base[0]:
                disks[disk_id]['type'] = oid['value']
            elif '5' == base[0]:
                disks[disk_id]['status'] = oid['value']
            elif '6' == base[0]:
                disks[disk_id]['temperature'] = oid['value']

        for disk in disks:
            if self.__critical <= disk['temperature']:
                self.__status_builder.critical(
                    Output(self.__get_disk_description(disk),
                           self.__get_disk_perfdata(disk)))
            elif self.__warning <= disk['temperature']:
                if 4 <= disk['status']:
                    self.__status_builder.critical(
                        Output(self.__get_disk_description(disk),
                               self.__get_disk_perfdata(disk)))
                else:
                    self.__status_builder.warning(
                        Output(self.__get_disk_description(disk),
                               self.__get_disk_perfdata(disk)))
            else:
                if 4 <= disk['status']:
                    self.__status_builder.critical(
                        Output(self.__get_disk_description(disk),
                               self.__get_disk_perfdata(disk)))
                elif 2 <= disk['status']:
                    self.__status_builder.warning(
                        Output(self.__get_disk_description(disk),
                               self.__get_disk_perfdata(disk)))
                else:
                    self.__status_builder.success(
                        Output(self.__get_disk_description(disk),
                               self.__get_disk_perfdata(disk)))

        self.__status_builder.exit(True)

    def __get_disk_description(self, disk):

        status = {
            1: 'Normal',
            2: 'No data',
            3: 'Not initialized',
            4: 'System partition failed',
            5: 'Crashed',
        }

        return disk['id'] + ' - ' + status[disk['status']] + ' / temperature "' + str(disk['temperature']) \
               + '°C" (' + str(disk['model']) + ' - ' + str(disk['type']) + ')'

    def __get_disk_perfdata(self, disk):
        return [
            Perfdata(disk['id'],
                     disk['temperature'],
                     unit='°C',
                     warning=self.__warning,
                     critical=self.__critical),
        ]
Example #17
0
class BatteryCapacity(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.318.1.1.1.2.2.1'

        Plugin.__init__(self, 'Check the capacity of the battery')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-w',
                                   '--warning',
                                   dest='warning',
                                   required=False,
                                   type=int,
                                   help='Warning Capacity',
                                   default=50)
        self.__parser.add_argument('-c',
                                   '--critical',
                                   dest='critical',
                                   required=False,
                                   type=int,
                                   help='Critical Capacity',
                                   default=20)

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__warning = args.warning
        self.__critical = args.critical

    def run(self):
        oids = self.__snmp_executor.run()

        if 1 != len(oids) or '0' != oids[0]['oid']:
            self.__status_builder.unknown(
                Output(f'Couldn\'t get Battery capacity information'))
            return

        capacity = oids[0]['value']

        output = Output(f'Capacity is {capacity}%', [
            Perfdata('capacity',
                     capacity,
                     unit='%',
                     warning=self.__warning,
                     critical=self.__critical,
                     min=0,
                     max=100)
        ])

        if capacity <= self.__critical:
            self.__status_builder.critical(output)
        elif capacity <= self.__warning:
            self.__status_builder.warning(output)
        else:
            self.__status_builder.success(output)
class Temperature(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.6574.1.2'

        Plugin.__init__(self, 'Check The temperature of the system')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-w',
                                   '--warning',
                                   dest='warning',
                                   required=True,
                                   type=int,
                                   help='Warning temperature')
        self.__parser.add_argument('-c',
                                   '--critical',
                                   dest='critical',
                                   required=True,
                                   type=int,
                                   help='Critical temperature')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__warning = args.warning
        self.__critical = args.critical

    def run(self):
        oids = self.__snmp_executor.run()

        if len(oids) != 1:
            self.__status_builder.unknown(
                Output('Can\'t find the temperature of the system.'))
            self.__status_builder.exit()

        perfdata = [
            Perfdata("temperature",
                     oids[0]['value'],
                     warning=self.__warning,
                     critical=self.__critical),
        ]

        output = Output('Temperature is "' + str(oids[0]['value']) + '°C"',
                        perfdata)
        if self.__critical <= oids[0]['value']:
            self.__status_builder.critical(output)
        elif self.__warning <= oids[0]['value']:
            self.__status_builder.warning(output)
        else:
            self.__status_builder.success(output)

        self.__status_builder.exit(True)
Example #19
0
class Memory(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__memory_id = None
        self.__warning_total = None
        self.__critical_total = None
        self.__check_total = None
        self.__warning_swap = None
        self.__critical_swap = None
        self.__check_swap = None
        self.__warning_swap_txt = None
        self.__critical_swap_txt = None
        self.__check_swap_txt = None
        self.__warning_real = None
        self.__critical_real = None
        self.__check_real = None
        self.__warning_real_txt = None
        self.__critical_real_txt = None
        self.__check_real_txt = None
        self.__warning_shared = None
        self.__critical_shared = None
        self.__check_shared = None
        self.__warning_buffer = None
        self.__critical_buffer = None
        self.__check_buffer = None
        self.__warning_cache = None
        self.__critical_cache = None
        self.__check_cache = None
        self.__warning_min_swap = None
        self.__critical_min_swap = None
        self.__check_min_swap = None
        self.__oid = '1.3.6.1.4.1.2021.4'

        Plugin.__init__(self, 'Check Memory status')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument('-m',
                                   '--memory',
                                   dest='memory',
                                   required=True,
                                   type=int,
                                   help='Number of the Memory to check')

        self.__parser.add_argument('-w',
                                   '--warning-total',
                                   dest='warningtotal',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for total memory')
        self.__parser.add_argument('-c',
                                   '--critical-total',
                                   dest='criticaltotal',
                                   required=False,
                                   type=int,
                                   help='Critical usage (%) for total memory')
        self.__parser.add_argument('--ignore-total',
                                   dest='ignoretotal',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Ignore the total memory check')

        self.__parser.add_argument('--warning-swap',
                                   dest='warningswap',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for swap memory')
        self.__parser.add_argument('--critical-swap',
                                   dest='criticalswap',
                                   required=False,
                                   type=int,
                                   help='Critical usage (%) for swap memory')
        self.__parser.add_argument('--ignore-swap',
                                   dest='ignoreswap',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Ignore the swap check')

        self.__parser.add_argument('--warning-swap-txt',
                                   dest='warningswaptxt',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for swaptxt memory')
        self.__parser.add_argument(
            '--critical-swap-txt',
            dest='criticalswaptxt',
            required=False,
            type=int,
            help='Critical usage (%) for swaptxt memory')
        self.__parser.add_argument('--ignore-swap-txt',
                                   dest='ignoreswaptxt',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Ignore the swap txt check')

        self.__parser.add_argument('--warning-real',
                                   dest='warningreal',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for real memory')
        self.__parser.add_argument('--critical-real',
                                   dest='criticalreal',
                                   required=False,
                                   type=int,
                                   help='Critical usage (%) for real memory')
        self.__parser.add_argument('--ignore-real',
                                   dest='ignorereal',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Ignore the real memory check')

        self.__parser.add_argument('--warning-real-txt',
                                   dest='warningrealtxt',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for realtxt memory')
        self.__parser.add_argument(
            '--critical-real-txt',
            dest='criticalrealtxt',
            required=False,
            type=int,
            help='Critical usage (%) for realtxt memory')
        self.__parser.add_argument('--ignore-real-txt',
                                   dest='ignorerealtxt',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Ignore the reaö txt check')

        self.__parser.add_argument('--warning-shared',
                                   dest='warningshared',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for shared memory')
        self.__parser.add_argument('--critical-shared',
                                   dest='criticalshared',
                                   required=False,
                                   type=int,
                                   help='Critical usage (%) for shared memory')
        self.__parser.add_argument('--check-shared',
                                   dest='checkshared',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Check the shared memory')

        self.__parser.add_argument('--warning-buffer',
                                   dest='warningbuffer',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for buffer memory')
        self.__parser.add_argument('--critical-buffer',
                                   dest='criticalbuffer',
                                   required=False,
                                   type=int,
                                   help='Critical usage (%) for buffer memory')
        self.__parser.add_argument('--check-buffer',
                                   dest='checkbuffer',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Check the buffer')

        self.__parser.add_argument('--warning-cache',
                                   dest='warningcache',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for cache memory')
        self.__parser.add_argument('--critical-cache',
                                   dest='criticalcache',
                                   required=False,
                                   type=int,
                                   help='Critical usage (%) for cache memory')
        self.__parser.add_argument('--check-cache',
                                   dest='checkcache',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Check the cache')

        self.__parser.add_argument('--warning-min-swap',
                                   dest='warningminswap',
                                   required=False,
                                   type=int,
                                   help='Warning usage (%) for minswap memory')
        self.__parser.add_argument(
            '--critical-min-swap',
            dest='criticalminswap',
            required=False,
            type=int,
            help='Critical usage (%) for minswap memory')
        self.__parser.add_argument('--check-min-swap',
                                   dest='checkminswap',
                                   required=False,
                                   default=False,
                                   action='store_true',
                                   help='Check the minimum swap')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__memory_id = args.memory
        self.__warning_total = args.warningtotal
        self.__critical_total = args.criticaltotal
        self.__check_total = not args.ignoretotal

        self.__warning_swap = args.warningswap
        self.__critical_swap = args.criticalswap
        self.__check_swap = not args.ignoreswap
        self.__warning_swap_txt = args.warningswaptxt
        self.__critical_swap_txt = args.criticalswaptxt
        self.__check_swap_txt = not args.ignoreswaptxt

        self.__warning_real = args.warningreal
        self.__critical_real = args.criticalreal
        self.__check_real = not args.ignorereal
        self.__warning_real_txt = args.warningrealtxt
        self.__critical_real_txt = args.criticalrealtxt
        self.__check_real_txt = not args.ignorerealtxt

        self.__warning_shared = args.warningshared
        self.__critical_shared = args.criticalshared
        self.__check_shared = args.checkshared

        self.__warning_buffer = args.warningbuffer
        self.__critical_buffer = args.criticalbuffer
        self.__check_buffer = args.checkbuffer

        self.__warning_cache = args.warningcache
        self.__critical_cache = args.criticalcache
        self.__check_cache = args.checkcache

        self.__warning_min_swap = args.warningminswap
        self.__critical_min_swap = args.criticalminswap
        self.__check_min_swap = args.checkminswap

        success = self.__check_bounds(self.__warning_total,
                                      self.__critical_total, 'total memory')
        success = self.__check_bounds(self.__warning_swap,
                                      self.__critical_swap, 'swap') and success
        success = self.__check_bounds(self.__warning_swap_txt,
                                      self.__critical_swap_txt,
                                      'swap txt') and success
        success = self.__check_bounds(self.__warning_real,
                                      self.__critical_real, 'real') and success
        success = self.__check_bounds(self.__warning_real_txt,
                                      self.__critical_real_txt,
                                      'real txt') and success
        success = self.__check_bounds(self.__warning_shared,
                                      self.__critical_shared,
                                      'shared') and success
        success = self.__check_bounds(self.__warning_buffer,
                                      self.__critical_buffer,
                                      'buffer') and success
        success = self.__check_bounds(
            self.__warning_cache, self.__critical_cache, 'cache') and success
        success = self.__check_bounds(self.__warning_min_swap,
                                      self.__critical_min_swap,
                                      'min swap') and success

        if not success:
            self.__status_builder.exit()

    def __check_bounds(self, warning, critical, name):
        success = True
        if None is not critical:
            if critical > 100:
                self.__status_builder.unknown(
                    Output(
                        f'Critical value for {name} can\'t be greater than 100 %'
                    ))
                success = False
            elif critical < 0:
                self.__status_builder.unknown(
                    Output(f'Critical value for {name} must be at least 0 %'))
                success = False

        if None is not warning:

            if warning < 0:
                self.__status_builder.unknown(
                    Output(f'Warning value for {name} must be at least 0 %'))
                success = False

        if None is not critical and None is warning:
            self.__status_builder.unknown(
                Output(
                    f'If you set a critical bound for {name} you have to specify a warning bound'
                ))
            success = False
        elif None is critical and None is not warning:
            self.__status_builder.unknown(
                Output(
                    f'If you set a warning bound for {name} you have to specify a critical bound'
                ))
            success = False
        elif None is not critical and None is not warning:
            if warning > critical:
                self.__status_builder.unknown(
                    Output(
                        f'Warning value for {name} can\'t be greater than critical value'
                    ))
                success = False

        return success

    def run(self):
        oids = self.__snmp_executor.run()
        status_data = {}

        keys = {
            '2': 'name',
            '3': 'totalSwap',
            '4': 'availableSwap',
            '5': 'totalReal',
            '6': 'availableReal',
            '7': 'totalSwapTXT',
            '8': 'availableSwapTXT',
            '9': 'totalRealTXT',
            '10': 'availableRealTXT',
            '11': 'totalFree',
            '12': 'minSwap',
            '13': 'shared',
            '14': 'buffer',
            '15': 'cached',
            '16': 'usedSwapTXT',
            '17': 'usedRealTXT',
            '100': 'swapError',
            '101': 'swapErrorMsg',
        }

        for oid in oids:
            base = oid['oid'].split('.')
            id = int(base[1])

            if int(base[1]) != self.__memory_id:
                continue

            data = status_data.get(id, {})
            data[keys.get(base[0])] = oid['value']
            status_data[id] = data

        if 0 == len(status_data):
            self.__status_builder.unknown(
                Output(
                    f'Memory "{self.__memory_id}" either does not exist or not accessible'
                ))
            self.__status_builder.exit()

        for status_data_id in status_data:
            data = status_data[status_data_id]
            self.__check_data(data, 'Swap', 'Swap', self.__warning_swap,
                              self.__critical_swap, self.__check_swap)
            self.__check_data(data, 'SwapTXT', 'Swap txt',
                              self.__warning_swap_txt,
                              self.__critical_swap_txt, self.__check_swap_txt)

            self.__check_data(data, 'Real', 'Real', self.__warning_real,
                              self.__critical_real, self.__check_real)
            self.__check_data(data, 'RealTXT', 'Real txt',
                              self.__warning_real_txt,
                              self.__critical_real_txt, self.__check_real_txt)

            total = data.get('totalSwap', 0) + data.get(
                'totalSwapTXT', 0) + data.get('totalReal', 0) + data.get(
                    'totalRealTXT', 0)
            self.__check_data(
                {
                    'totalTotal': total,
                    'availableTotal': total - data['totalFree'],
                    'name': data['name']
                }, 'Total', 'Total', self.__warning_total,
                self.__critical_total, self.__check_total)

            self.__check_value('shared', 'Shared', data, self.__warning_shared,
                               self.__critical_shared, self.__check_shared)
            self.__check_value('buffer', 'Buffer', data, self.__warning_buffer,
                               self.__critical_buffer, self.__check_buffer)
            self.__check_value('cached', 'Cached', data, self.__warning_cache,
                               self.__critical_cache, self.__check_cache)
            self.__check_value('minSwap', 'Min SWAP', data,
                               self.__warning_min_swap,
                               self.__critical_min_swap, self.__check_min_swap)

            if 0 != data['swapError']:
                self.__status_builder.critical(
                    Output(
                        f'Got an unexpected SWAP error "{data["swapErrorMessage"]}" '
                        f'(code {data["swapError"]})'))

    def __check_value(self, suffix, name, data, warning, critical, check):

        if not check:
            return

        self.__logger.debug(f'Check memory {suffix}')
        value = data.get(suffix, None)

        if value is None:
            self.__status_builder.unknown(
                Output(
                    f"Couldn't check {name} because it either not exist or is not accessible "
                    f"(value not found).|{suffix}=0;0;0;0;0"))
            return

        perfdata = f";;;" if None is warning else f"{warning};{critical};;"

        output = f"Memory \"{name}\";| {suffix}={value};{perfdata}"

        if None is warning:
            self.__status_builder.success(output)
        else:
            if critical <= value:
                self.__status_builder.critical(output)
            elif self.__warning_total <= value:
                self.__status_builder.warning(output)
            else:
                self.__status_builder.success(output)

    def __check_data(self, data, suffix, name, warning, critical, check):

        if not check:
            return

        self.__logger.debug(f'Check memory {suffix}')
        total = data.get('total' + suffix, None)
        available = data.get('available' + suffix, None)

        perfdata = [
            Perfdata(f'{suffix}',
                     0,
                     unit='B',
                     warning=0,
                     critical=0,
                     min=0,
                     max=0),
        ]

        if total is None:
            self.__status_builder.unknown(
                Output(
                    f"Couldn't check {name} because it either not exist or is not accessible "
                    f"(total value not found).", perfdata))
            return
        if available is None:
            self.__status_builder.unknown(
                Output(
                    f"Couldn't check {name} because it either not exist or is not accessible "
                    f"(available value not found).", perfdata))
            return

        used = total - available

        if None is warning:
            perfdata = [
                Perfdata(f'{suffix}',
                         used,
                         unit='B',
                         warning=0,
                         critical=0,
                         min=0,
                         max=total),
            ]
        else:
            perfdata = [
                Perfdata(f'{suffix}',
                         used,
                         unit='B',
                         warning=warning / 100 * total,
                         critical=critical / 100 * total,
                         min=0,
                         max=total),
            ]

        output = Output(f"Memory \"{name}\"", perfdata)

        if None is warning:
            self.__status_builder.success(output)
        else:
            usage = used / total * 100
            if critical <= usage:
                self.__status_builder.critical(output)
            elif self.__warning_total <= usage:
                self.__status_builder.warning(output)
            else:
                self.__status_builder.success(output)
Example #20
0
class Load(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__warning = None
        self.__critical = None
        self.__oid = '1.3.6.1.4.1.2021.10.1'

        Plugin.__init__(self, 'Check CPU Load average')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument(
            '-w',
            '--warning',
            dest='warning',
            required=False,
            type=str,
            help='Warning load. Format: LOAD1,LOAD5,LOAD15')
        self.__parser.add_argument(
            '-c',
            '--critical',
            dest='critical',
            required=False,
            type=str,
            help='Critical load. Format: LOAD1,LOAD5,LOAD15')

    def configure(self, args):
        self.__snmp_executor.configure(args)

        warning = args.warning
        if None is not warning:
            warning = warning.split(',')
            if len(warning) != 3:
                self.__status_builder.unknown(
                    Output(
                        'Format for warning load mismatch. Expected Format: LOAD1,LOAD5,LOAD15'
                    ))
                self.__status_builder.exit()
            self.__warning = [
                float(warning[0]),
                float(warning[1]),
                float(warning[2])
            ]

        critical = args.critical
        if None is not critical:
            critical = critical.split(',')
            if len(critical) != 3:
                self.__status_builder.unknown(
                    Output(
                        'Format for critical load mismatch. Expected Format: LOAD1,LOAD5,LOAD15'
                    ))
                self.__status_builder.exit()
            self.__critical = [
                float(critical[0]),
                float(critical[1]),
                float(critical[2])
            ]

        if None is self.__warning and self.__critical is not None:
            self.__status_builder.unknown(
                Output(
                    'If critical load is defined, you have to set warning load'
                ))
            self.__status_builder.exit()

        if None is not self.__warning and self.__critical is None:
            self.__status_builder.unknown(
                Output(
                    'If warning load is defined, you have to set critical load'
                ))
            self.__status_builder.exit()

    def run(self):
        oids = self.__snmp_executor.run()

        status_data = {1: {}, 2: {}, 3: {}}

        keys = {
            '2': 'name',
            '3': 'load',
            '4': 'configuredError',
            '5': 'loadInt',
            '6': 'loadFloat',
            '100': 'error',
            '101': 'errorMessage',
        }
        for oid in oids:
            base = oid['oid'].split('.')

            id = int(base[1])

            if base[0] == '1':
                continue

            status_data[id][keys.get(base[0])] = oid['value']

        for status_data_id in status_data:
            data = status_data[status_data_id]
            index = status_data_id - 1

            perfdata = [
                Perfdata(f'load',
                         data['loadFloat'],
                         warning=self.__warning[index],
                         critical=self.__critical[index]),
            ]

            if 0 != data['error']:
                output = Output(
                    f'Load \"{data["name"]}\" Got an unexpected error "{data["errorMessage"]}" (code {data["swapError"]})',
                    perfdata)
                self.__status_builder.critical(output)
                continue

            output = Output(f"Disk load \"{data['name']}\"", perfdata)

            if None is self.__warning:
                self.__status_builder.success(output)
            else:
                if self.__critical[index] <= data['loadFloat']:
                    self.__status_builder.critical(output)
                elif self.__warning[index] <= data['loadFloat']:
                    self.__status_builder.warning(output)
                else:
                    self.__status_builder.success(output)
class ServiceRunning(Plugin):
    def __init__(self):
        self.__logger = None
        self.__status_builder = None

        self.__snmp_executor = None
        self.__services = None
        self.__oid = '1.3.6.1.4.1.6574.6.1.1'

        Plugin.__init__(self, 'Check if the services running')

    def add_args(self):
        self.__parser = self.get_parser()
        self.__logger = self.get_logger()
        self.__status_builder = self.get_status_builder()
        self.__snmp_executor = SNMPExecutor(self.__logger,
                                            self.__status_builder,
                                            self.__parser, self.__oid)
        self.__snmp_executor.add_args()

        self.__parser.add_argument(
            '-s',
            '--service',
            dest='services',
            action='append',
            default=[],
            type=str,
            help='Service, which should run. Can be repeated')

    def configure(self, args):
        self.__snmp_executor.configure(args)
        self.__services = args.services

    def run(self):
        oids = self.__snmp_executor.run()

        services_running = {}

        for oid in oids:
            base = oid['oid'].split('.')

            id = int(base[1])
            config = services_running.get(id, {})

            if '2' == base[0]:
                config['service'] = oid['value'].lower()
            elif '3' == base[0]:
                config['users'] = oid['value']

            services_running[id] = config

        for service in self.__services:
            found = False
            for services_running_id in services_running:
                config = services_running[services_running_id]
                if config['service'] == service:
                    found = True
                    self.__status_builder.success(
                        Output(f'Service "{service}" up and running',
                               [Perfdata(f'{service}', config["users"])]))
                    break

            if not found:
                self.__status_builder.critical(
                    Output(
                        f'Service "{service}" should running but it doesn\'t'))

        for services_running_id in services_running:
            config = services_running[services_running_id]
            found = False
            for service in self.__services:
                if service == config['service']:
                    found = True
                    break

            if not found:
                self.__status_builder.warning(
                    Output(
                        f'Service "{config["service"]}" is running but it shouldn\'t',
                        [Perfdata(f'{config["service"]}', config["users"])]))

        self.__status_builder.exit(True)