? GR0V Shell

GR0V shell

Linux server122.web-hosting.com 4.18.0-513.18.1.lve.el8.x86_64 #1 SMP Thu Feb 22 12:55:50 UTC 2024 x86_64

Path : /lib64/nagios/plugins/nccustom/
File Upload :
Current File : //lib64/nagios/plugins/nccustom/check_smartctl.py

#!/usr/libexec/platform-python
################################
#    Check SMART for drives    #
#    (from cached datafile)    #
# Created by Bogdan Kukharskiy #
#          Namecheap           #
################################
# This script checks SMART for drives based on cache data gathered with
#               'nc-zabbix-check-smart' by Alex Rabchenyuk
#            or 'nc-smart-data-exporter' by Vladimir Kuprikov
#
# Returns the nagios native status codes:
# 0 = OK
# 1 = WARNING
# 2 = CRITICAL
# 3 = UNKNOWN
#
# Also provides Nagios PerfData for every checked parameter

import os
import re
import sys
import time
import json
import argparse
from os import access, R_OK
from os.path import isfile
from datetime import datetime


if __name__ == "__main__":

    # parsing arguments
    parser = argparse.ArgumentParser()
    parser.add_argument("-v", "--verbose", default=False, action="store_true", help="Extra output")
    parser.add_argument("-f", "--cachefile", default="", type=str,
                         help="Path to file with cached SMART data")
    parser.add_argument("-t", "--tmpfilepath", default="/tmp/smartctl/", type=str,
                        help="tmp file path, default: /tmp/smartctl/")
    parser.add_argument("-c", "--configfile", type=str, default="",
                        help="Config file, full path and name (by default, check_smartctl.conf in script dir)")
    args = parser.parse_args()

    # determining config file full path
    if args.configfile == "":
        configFileName = os.path.join(os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(sys.argv[0]))),
                                      'check_smartctl.conf')
    else:
        configFileName = args.configfile

    if not (isfile(configFileName) and access(configFileName, R_OK)):
        print("Config file doesn't exist or isn't readable: " + configFileName)
        exit(3)

    try:
        if os.path.getsize(configFileName) > 0:
            configData = json.loads(open(configFileName).read())
            if args.verbose:
                print("Config file contents:")
                print(json.dumps(configData, indent=4, sort_keys=True))
        else:
            print("Config file is empty")
            exit(3)
    except OSError as e:
        print("Config file does not exist or not accessible: %s" % e)
        exit(3)
    except ValueError as e:
        print("Config file has invalid JSON format: %s" % e)
        exit(3)

    cacheFileName = ""
    if args.cachefile == "":
        for filename in os.listdir(args.tmpfilepath):
            if filename.startswith("smart"):
                cacheFileName = (os.path.join(args.tmpfilepath, filename))
                break  # we take first file which starts from 'smart', weird but should be ok
            else:
                continue
    else:
        cacheFileName = args.cachefile

    if args.verbose:
        print("Cache file name = " + cacheFileName)

    if not (isfile(cacheFileName) and access(cacheFileName, R_OK)):
        print("Cache file doesn't exist or isn't readable: " + cacheFileName)
        exit(3)

    try:
        if args.verbose:
            print("Information about cache file:")
            print("    *Created Time  : {0}".format(
                str(datetime.fromtimestamp(os.path.getctime(cacheFileName)).strftime('%Y-%m-%d %H:%M:%S'))))
            print("    *Modified Time : {0}".format(
                str(datetime.fromtimestamp(os.path.getmtime(cacheFileName)).strftime('%Y-%m-%d %H:%M:%S'))))
            print("    *Access Time   : {0}".format(
                str(datetime.fromtimestamp(os.path.getatime(cacheFileName)).strftime('%Y-%m-%d %H:%M:%S'))))
            print("    *Size          : {0}".format(os.path.getsize(cacheFileName)))
        if os.path.getmtime(cacheFileName) < (time.time() - 7200):
            print("Cache file is too old")
            exit(3)
        if os.path.getsize(cacheFileName) > 0:
            cacheData = json.loads(open(cacheFileName).read())
        else:
            print("Cache file is empty")
            exit(3)
    except OSError as e:
        print("Cache file does not exist or not accessible: %s" % e)
        exit(3)
    except ValueError as e:
        print("Cache file has invalid JSON format: %s" % e)
        exit(3)

    # now will iterate through all drive types
    flagDriveTypeOnServerFound = False
    warningArray = []
    criticalArray = []
    perfDataArray = []
    perfData = ""
    for driveTypeOnServerKey, driveSerialNumberKey in cacheData.items():
        for driveTypeInConfigKey, driveTypeInConfigValue in configData.items():
            if driveTypeOnServerKey == driveTypeInConfigKey:
                flagDriveTypeOnServerFound = True   # we have found server drive type in config
                for driveSerialKey, driveSmartParamKey in driveSerialNumberKey.items():
                    if args.verbose:
                        print("------------")
                        print("Drive serial = {0}".format(driveSerialKey))
                    for configParamNameKey, configParamNameValue in driveTypeInConfigValue.items():
                        for driveSmartParamNameKey, driveSmartParamNameValue in driveSmartParamKey.items():
                            if re.search(configParamNameKey, driveSmartParamNameKey):
                                perfData = ""
                                try:
                                    driveSmartParamNameValue=str(driveSmartParamNameValue) # fix for new nc-zabbix-kvmnodes-smart which stores values as ints instead of strings
                                    if args.verbose:
                                        print("  Parameter name: {0}".format(configParamNameKey))
                                        print("    Critical value          = {0}".format(configParamNameValue['Critical']))
                                        print("    Warning value           = {0}".format(configParamNameValue['Warning']))
                                        print("    Cached value from SMART = {0}".format(driveSmartParamNameValue))
                                    if len(str(configParamNameValue['Critical'])) < 1 or len(str(configParamNameValue['Warning'])) < 1 or len(driveSmartParamNameValue) < 1:
                                        print("Empty value of key for parameter {0} (in config file or in cache file)".format(configParamNameKey))
                                        exit(3)
                                    if driveSmartParamNameValue != "-" and int(driveSmartParamNameValue) > configParamNameValue['Critical']:
                                        criticalArray.append(driveSerialKey + ":" + driveSmartParamNameKey + "=" + driveSmartParamNameValue + ">" + str(configParamNameValue['Critical']))
                                    elif driveSmartParamNameValue != "-" and int(driveSmartParamNameValue) > configParamNameValue['Warning']:
                                        warningArray.append(driveSerialKey + ":" + driveSmartParamNameKey + "=" + driveSmartParamNameValue + ">" + str(configParamNameValue['Warning']))
                                    perfData = driveSerialKey + "_" + driveSmartParamNameKey + "=" + driveSmartParamNameValue + ";" + str(configParamNameValue['Warning']) + ";" + str(configParamNameValue['Critical'])
                                    perfDataArray.append(perfData)
                                except KeyError as k:
                                    print("{0} key was not found for parameter '{1}' in config file".format(k, configParamNameKey))
                                    exit(3)
                                except (TypeError, ValueError) as u:
                                    print("Numbers in cache JSON file are in invalid format: %s" % u)
                                    exit(3)
                                break
    if flagDriveTypeOnServerFound is False:
        print("Server drive type was not found in config file")
        exit(3)

    if len(criticalArray) > 0:
        print("CRITICAL! " + '; '.join(criticalArray) + " | " + ' '.join(perfDataArray))
        exit(2)
    elif len(warningArray) > 0:
        print("WARNING! " + '; '.join(warningArray) + " | " + ' '.join(perfDataArray))
        exit(1)
    else:
        print("SMART parameters for all drives are OK" + " | " + ' '.join(perfDataArray))
        exit(0)

T1KUS90T
  root-grov@198.54.114.191:~$