Search Exchange
Search All Sites
Nagios Live Webinars
Let our experts show you how Nagios can help your organization.Login
Directory Tree
Directory
charles123
bycharles123, May 3, 2024
The latest script works only in Python 2
so here the script rewritten for python 3
#!/usr/bin/python3
# -*- coding:utf-8 -*-
####
#
# NAME: check_smartarray.py
#
# AUTHOR: Christophe Robert - christophe °dot° robert °at° cocoche °dot° fr
#
# DESC: Check HP SmartArray RAID status on Linux - hpacucli/hpssacli/ssacli command line tool
#
# VERSION: 1.6 - Support for `hpacucli`, `hpssacli` and `ssacli` - 2018-02-22 (22. Feb. 2018)
#
####
import os
import sys
import re
from subprocess import Popen, PIPE
import logging
import logging.handlers
class ReadHPSmartArrayStatus:
def __init__(self, tuple, logger):
self.nagios = tuple
self.logger = logger
# Creation de table de hash qui permet d'associer une clé et une valeur
self.system = {'ctrl': [], 'array': [], 'logical': [], 'physical': []}
self.ctrl_nb = 0
self.array_nb = 0
self.lv_nb = 0
self.pd_nb = 0
def process(self):
for element in self.nagios:
sata = re.compile('^.*[Aa]rray.*SATA.*$')
sas = re.compile('^.*[Aa]rray.*SAS.*$')
scsi = re.compile('^.*[Aa]rray.*SCSI.*$')
smart = re.compile('^Smart Array .*$')
logical = re.compile('^.*logicaldrive.*$')
physical = re.compile('^.*physicaldrive.*$')
if smart.match(element):
self.logger.debug('--Debug-- Enter smart')
self.logger.debug('--Debug-- Value = ' + element)
self.ctrl_nb += 1
self.system['ctrl'].append(element)
self.logger.debug('--Debug-- Dict :' + str(self.system))
elif sata.match(element) or sas.match(element) or scsi.match(element):
self.logger.debug('--Debug-- Enter array')
self.logger.debug('--Debug-- Value = ' + element)
self.array_nb += 1
self.system['array'].append(element)
self.logger.debug('--Debug-- Dict :' + str(self.system))
elif logical.match(element):
self.logger.debug('--Debug-- Enter logical')
self.logger.debug('--Debug-- Value = ' + element)
self.lv_nb += 1
self.system['logical'].append(element)
self.logger.debug('--Debug-- Dict :' + str(self.system))
elif physical.match(element):
self.logger.debug('--Debug-- Enter physical')
self.logger.debug('--Debug-- Value = ' + element)
self.pd_nb += 1
self.system['physical'].append(element)
self.logger.debug('--Debug-- Dict :' + str(self.system))
self.logger.debug('--Debug-- Show "system" dict content')
self.logger.debug('--Debug-- Value = ' + str(self.system))
return self.system
class GetErrors:
def __init__(self, buffer, logger):
self.errors = {'CRITICAL': [], 'WARNING': [], 'UNKNOWN': []}
self.tocheck = buffer
self.logger = logger
self.nb_ctrl = 0
self.nb_array = 0
self.nb_logical = 0
self.nb_physical = 0
def check(self):
sata = re.compile('^.*array.*SATA.*$')
sas = re.compile('^.*array.*SAS.*$')
scsi = re.compile('^.*array.*SCSI.*$')
logical = re.compile('^.*logicaldrive.*$')
physical = re.compile('^.*physicaldrive.*$')
for i in range(len(self.tocheck['ctrl'])):
self.logger.debug('--Debug-- Controller : ' + str(self.tocheck['ctrl'][i]))
self.nb_ctrl += 1
self.logger.debug('--Debug-- Slot : ' + self.tocheck['ctrl'][i].split('Slot ')[1].split(' ')[0])
ctrl_status = Popen(['sudo', smartarray_bin, 'ctrl', 'slot=' + self.tocheck['ctrl'][i].split('Slot ')[1].split(' ')[0], 'show', 'status'], stdout=PIPE, text=True)
res = ctrl_status.communicate()[0]
ctrl_status.stdout.close()
ctrl = []
for r in res.splitlines():
r = r.lstrip()
self.logger.debug(str(r))
if r:
ctrl.append(r)
self.logger.debug('--Debug-- Controller internal status : ' + str(ctrl))
for element in ctrl:
if re.compile('.*Status:.*').match(element):
self.logger.debug('--Debug-- Controller element status : ' + element)
if element.split(': ')[1].split('\n')[0] != 'OK':
self.errors['WARNING'].append(element)
for i in range(len(self.tocheck['array'])):
self.logger.debug('--Debug-- Enter "array"')
self.logger.debug('--Debug-- Value = ' + str(self.tocheck['array'][i]))
self.nb_array += 1
for i in range(len(self.tocheck['logical'])):
self.logger.debug('--Debug-- Enter "logicaldrive"')
self.logger.debug('--Debug-- Value = ' + str(self.tocheck['logical'][i]))
self.nb_logical += 1
if re.compile('^.*OK.*$').match(self.tocheck['logical'][i]):
pass
elif re.compile('^.*Failed.*$').match(self.tocheck['logical'][i]):
self.errors['CRITICAL'].append(self.tocheck['logical'][i])
elif re.compile('^.*Recover.*$').match(self.tocheck['logical'][i]):
self.errors['WARNING'].append(self.tocheck['logical'][i])
else:
self.errors['UNKNOWN'].append(self.tocheck['logical'][i])
for i in range(len(self.tocheck['physical'])):
self.logger.debug('--Debug-- Enter "physicaldrive"')
self.logger.debug('--Debug-- Value = ' + str(self.tocheck['physical'][i]))
self.nb_physical += 1
if re.compile('^.*OK.*$').match(self.tocheck['physical'][i]):
pass
elif re.compile('^.*Failed.*$').match(self.tocheck['physical'][i]):
self.errors['CRITICAL'].append(self.tocheck['physical'][i])
elif re.compile('^.*Rebuilding.*$').match(self.tocheck['physical'][i]):
self.errors['WARNING'].append(self.tocheck['physical'][i])
else:
self.errors['UNKNOWN'].append(self.tocheck['physical'][i])
self.logger.debug('--Debug-- Errors dict : ' + str(self.errors))
return self.errors, self.nb_ctrl, self.nb_array, self.nb_logical, self.nb_physical
### Core ###
logger = logging.getLogger('check_smartarray')
logger.setLevel(logging.DEBUG)
handler = logging.handlers.SysLogHandler(address='/dev/log')
logger.addHandler(handler)
# Check which HP SmartArray management utility is installed
smartarray_bin = None
if os.path.isfile('/usr/sbin/hpacucli'):
smartarray_bin = 'hpacucli'
elif os.path.isfile('/usr/sbin/hpssacli'):
smartarray_bin = 'hpssacli'
elif os.path.isfile('/usr/sbin/ssacli'):
smartarray_bin = 'ssacli'
else:
logger.debug('--Debug-- HP SmartArray management utility not found.')
sys.exit(2)
# Get array status from SmartArray management utility
hpacucli = Popen(['sudo', smartarray_bin, 'ctrl', 'all', 'show', 'config'], stdout=PIPE, text=True)
res = hpacucli.communicate()[0]
hpacucli.stdout.close()
nagios = []
for r in res.splitlines():
r = r.lstrip()
logger.debug(str(r))
if r:
nagios.append(r)
logger.debug('--Debug-- List command results :')
logger.debug(nagios)
nb_warning = 0
nb_critical = 0
nb_unknown = 0
tosend = ""
try:
state = ReadHPSmartArrayStatus(nagios, logger)
config = state.process()
errors = GetErrors(config, logger)
health, nb_ctrl, nb_array, nb_logical, nb_physical = errors.check()
logger.debug('--Debug-- Health dict : ' + str(health))
if len(health['CRITICAL']):
logger.debug('--Debug-- Enter critical')
nb_critical += 1
for l in range(len(health['CRITICAL'])):
tosend += 'CRITICAL - ' + health['CRITICAL'][l] + '\\n'
elif len(health['WARNING']) and nb_critical==0:
logger.debug('--Debug-- Enter warning')
nb_warning += 1
for l in range(len(health['WARNING'])):
tosend += 'WARNING - ' + health['WARNING'][l] + '\\n'
elif len(health['UNKNOWN']) and nb_critical==0 and nb_warning==0:
logger.debug('--Debug-- Enter unknown')
nb_unknown += 1
for l in range(len(health['UNKNOWN'])):
tosend += 'UNKNOWN - ' + health['UNKNOWN'][l] + '\\n'
elif nb_ctrl == 0 or nb_array == 0 or nb_logical == 0 or nb_physical == 0:
logger.debug('--Debug-- Enter unknown')
nb_unknown += 1
tosend += 'UNKNOWN - One of element of these : controller (' + str(nb_ctrl) + '), array (' + str(nb_array) + '), logicaldrive (' + str(nb_logical) + ') or physicaldrive (' +str(nb_physical) + ') is missing !\\n'
else:
tosend = 'OK - RAID status is good - Nb Ctrl : ' + str(nb_ctrl) + ' - Nb Array : ' + str(nb_array) + ' - Nb logicaldrive : ' + str(nb_logical) + ' - Nb physicaldrive : ' + str(nb_physical)
tosend = tosend.strip('^\n')
logger.debug(str(tosend))
except Exception as e:
tosend = str(e)
logger.debug('--Debug-- Exception : ' + tosend)
print('--Debug2-- Exception : ' + tosend)
finally:
print(str(tosend))
if nb_critical != 0:
sys.exit(2)
elif nb_warning != 0:
sys.exit(1)
elif nb_unknown != 0:
sys.exit(3)
else:
sys.exit(0)
so here the script rewritten for python 3
#!/usr/bin/python3
# -*- coding:utf-8 -*-
####
#
# NAME: check_smartarray.py
#
# AUTHOR: Christophe Robert - christophe °dot° robert °at° cocoche °dot° fr
#
# DESC: Check HP SmartArray RAID status on Linux - hpacucli/hpssacli/ssacli command line tool
#
# VERSION: 1.6 - Support for `hpacucli`, `hpssacli` and `ssacli` - 2018-02-22 (22. Feb. 2018)
#
####
import os
import sys
import re
from subprocess import Popen, PIPE
import logging
import logging.handlers
class ReadHPSmartArrayStatus:
def __init__(self, tuple, logger):
self.nagios = tuple
self.logger = logger
# Creation de table de hash qui permet d'associer une clé et une valeur
self.system = {'ctrl': [], 'array': [], 'logical': [], 'physical': []}
self.ctrl_nb = 0
self.array_nb = 0
self.lv_nb = 0
self.pd_nb = 0
def process(self):
for element in self.nagios:
sata = re.compile('^.*[Aa]rray.*SATA.*$')
sas = re.compile('^.*[Aa]rray.*SAS.*$')
scsi = re.compile('^.*[Aa]rray.*SCSI.*$')
smart = re.compile('^Smart Array .*$')
logical = re.compile('^.*logicaldrive.*$')
physical = re.compile('^.*physicaldrive.*$')
if smart.match(element):
self.logger.debug('--Debug-- Enter smart')
self.logger.debug('--Debug-- Value = ' + element)
self.ctrl_nb += 1
self.system['ctrl'].append(element)
self.logger.debug('--Debug-- Dict :' + str(self.system))
elif sata.match(element) or sas.match(element) or scsi.match(element):
self.logger.debug('--Debug-- Enter array')
self.logger.debug('--Debug-- Value = ' + element)
self.array_nb += 1
self.system['array'].append(element)
self.logger.debug('--Debug-- Dict :' + str(self.system))
elif logical.match(element):
self.logger.debug('--Debug-- Enter logical')
self.logger.debug('--Debug-- Value = ' + element)
self.lv_nb += 1
self.system['logical'].append(element)
self.logger.debug('--Debug-- Dict :' + str(self.system))
elif physical.match(element):
self.logger.debug('--Debug-- Enter physical')
self.logger.debug('--Debug-- Value = ' + element)
self.pd_nb += 1
self.system['physical'].append(element)
self.logger.debug('--Debug-- Dict :' + str(self.system))
self.logger.debug('--Debug-- Show "system" dict content')
self.logger.debug('--Debug-- Value = ' + str(self.system))
return self.system
class GetErrors:
def __init__(self, buffer, logger):
self.errors = {'CRITICAL': [], 'WARNING': [], 'UNKNOWN': []}
self.tocheck = buffer
self.logger = logger
self.nb_ctrl = 0
self.nb_array = 0
self.nb_logical = 0
self.nb_physical = 0
def check(self):
sata = re.compile('^.*array.*SATA.*$')
sas = re.compile('^.*array.*SAS.*$')
scsi = re.compile('^.*array.*SCSI.*$')
logical = re.compile('^.*logicaldrive.*$')
physical = re.compile('^.*physicaldrive.*$')
for i in range(len(self.tocheck['ctrl'])):
self.logger.debug('--Debug-- Controller : ' + str(self.tocheck['ctrl'][i]))
self.nb_ctrl += 1
self.logger.debug('--Debug-- Slot : ' + self.tocheck['ctrl'][i].split('Slot ')[1].split(' ')[0])
ctrl_status = Popen(['sudo', smartarray_bin, 'ctrl', 'slot=' + self.tocheck['ctrl'][i].split('Slot ')[1].split(' ')[0], 'show', 'status'], stdout=PIPE, text=True)
res = ctrl_status.communicate()[0]
ctrl_status.stdout.close()
ctrl = []
for r in res.splitlines():
r = r.lstrip()
self.logger.debug(str(r))
if r:
ctrl.append(r)
self.logger.debug('--Debug-- Controller internal status : ' + str(ctrl))
for element in ctrl:
if re.compile('.*Status:.*').match(element):
self.logger.debug('--Debug-- Controller element status : ' + element)
if element.split(': ')[1].split('\n')[0] != 'OK':
self.errors['WARNING'].append(element)
for i in range(len(self.tocheck['array'])):
self.logger.debug('--Debug-- Enter "array"')
self.logger.debug('--Debug-- Value = ' + str(self.tocheck['array'][i]))
self.nb_array += 1
for i in range(len(self.tocheck['logical'])):
self.logger.debug('--Debug-- Enter "logicaldrive"')
self.logger.debug('--Debug-- Value = ' + str(self.tocheck['logical'][i]))
self.nb_logical += 1
if re.compile('^.*OK.*$').match(self.tocheck['logical'][i]):
pass
elif re.compile('^.*Failed.*$').match(self.tocheck['logical'][i]):
self.errors['CRITICAL'].append(self.tocheck['logical'][i])
elif re.compile('^.*Recover.*$').match(self.tocheck['logical'][i]):
self.errors['WARNING'].append(self.tocheck['logical'][i])
else:
self.errors['UNKNOWN'].append(self.tocheck['logical'][i])
for i in range(len(self.tocheck['physical'])):
self.logger.debug('--Debug-- Enter "physicaldrive"')
self.logger.debug('--Debug-- Value = ' + str(self.tocheck['physical'][i]))
self.nb_physical += 1
if re.compile('^.*OK.*$').match(self.tocheck['physical'][i]):
pass
elif re.compile('^.*Failed.*$').match(self.tocheck['physical'][i]):
self.errors['CRITICAL'].append(self.tocheck['physical'][i])
elif re.compile('^.*Rebuilding.*$').match(self.tocheck['physical'][i]):
self.errors['WARNING'].append(self.tocheck['physical'][i])
else:
self.errors['UNKNOWN'].append(self.tocheck['physical'][i])
self.logger.debug('--Debug-- Errors dict : ' + str(self.errors))
return self.errors, self.nb_ctrl, self.nb_array, self.nb_logical, self.nb_physical
### Core ###
logger = logging.getLogger('check_smartarray')
logger.setLevel(logging.DEBUG)
handler = logging.handlers.SysLogHandler(address='/dev/log')
logger.addHandler(handler)
# Check which HP SmartArray management utility is installed
smartarray_bin = None
if os.path.isfile('/usr/sbin/hpacucli'):
smartarray_bin = 'hpacucli'
elif os.path.isfile('/usr/sbin/hpssacli'):
smartarray_bin = 'hpssacli'
elif os.path.isfile('/usr/sbin/ssacli'):
smartarray_bin = 'ssacli'
else:
logger.debug('--Debug-- HP SmartArray management utility not found.')
sys.exit(2)
# Get array status from SmartArray management utility
hpacucli = Popen(['sudo', smartarray_bin, 'ctrl', 'all', 'show', 'config'], stdout=PIPE, text=True)
res = hpacucli.communicate()[0]
hpacucli.stdout.close()
nagios = []
for r in res.splitlines():
r = r.lstrip()
logger.debug(str(r))
if r:
nagios.append(r)
logger.debug('--Debug-- List command results :')
logger.debug(nagios)
nb_warning = 0
nb_critical = 0
nb_unknown = 0
tosend = ""
try:
state = ReadHPSmartArrayStatus(nagios, logger)
config = state.process()
errors = GetErrors(config, logger)
health, nb_ctrl, nb_array, nb_logical, nb_physical = errors.check()
logger.debug('--Debug-- Health dict : ' + str(health))
if len(health['CRITICAL']):
logger.debug('--Debug-- Enter critical')
nb_critical += 1
for l in range(len(health['CRITICAL'])):
tosend += 'CRITICAL - ' + health['CRITICAL'][l] + '\\n'
elif len(health['WARNING']) and nb_critical==0:
logger.debug('--Debug-- Enter warning')
nb_warning += 1
for l in range(len(health['WARNING'])):
tosend += 'WARNING - ' + health['WARNING'][l] + '\\n'
elif len(health['UNKNOWN']) and nb_critical==0 and nb_warning==0:
logger.debug('--Debug-- Enter unknown')
nb_unknown += 1
for l in range(len(health['UNKNOWN'])):
tosend += 'UNKNOWN - ' + health['UNKNOWN'][l] + '\\n'
elif nb_ctrl == 0 or nb_array == 0 or nb_logical == 0 or nb_physical == 0:
logger.debug('--Debug-- Enter unknown')
nb_unknown += 1
tosend += 'UNKNOWN - One of element of these : controller (' + str(nb_ctrl) + '), array (' + str(nb_array) + '), logicaldrive (' + str(nb_logical) + ') or physicaldrive (' +str(nb_physical) + ') is missing !\\n'
else:
tosend = 'OK - RAID status is good - Nb Ctrl : ' + str(nb_ctrl) + ' - Nb Array : ' + str(nb_array) + ' - Nb logicaldrive : ' + str(nb_logical) + ' - Nb physicaldrive : ' + str(nb_physical)
tosend = tosend.strip('^\n')
logger.debug(str(tosend))
except Exception as e:
tosend = str(e)
logger.debug('--Debug-- Exception : ' + tosend)
print('--Debug2-- Exception : ' + tosend)
finally:
print(str(tosend))
if nb_critical != 0:
sys.exit(2)
elif nb_warning != 0:
sys.exit(1)
elif nb_unknown != 0:
sys.exit(3)
else:
sys.exit(0)