py3 portage from https://git.securmail.fr/gizmo/Check-zfs
This commit is contained in:
parent
e5cdfee69d
commit
007ccd5b15
449
check_zfs.py
Executable file → Normal file
449
check_zfs.py
Executable file → Normal file
|
@ -1,4 +1,6 @@
|
||||||
#!/usr/bin/python
|
#!/usr/bin/env python3
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""Get zfs pool status."""
|
||||||
|
|
||||||
########################################################################
|
########################################################################
|
||||||
##
|
##
|
||||||
|
@ -10,8 +12,7 @@
|
||||||
## in Linux.
|
## in Linux.
|
||||||
##
|
##
|
||||||
## Tested operating systems/ZFS versions:
|
## Tested operating systems/ZFS versions:
|
||||||
## * Ubuntu 14.04 LTS, ZFS v5
|
## * See README.md
|
||||||
## * CentOS 7, ZFS v5
|
|
||||||
##
|
##
|
||||||
## This program is free software: you can redistribute it and/or modify
|
## This program is free software: you can redistribute it and/or modify
|
||||||
## it under the terms of the GNU General Public License as published by
|
## it under the terms of the GNU General Public License as published by
|
||||||
|
@ -28,39 +29,47 @@
|
||||||
##
|
##
|
||||||
########################################################################
|
########################################################################
|
||||||
|
|
||||||
from sys import exit
|
|
||||||
import subprocess
|
import subprocess
|
||||||
import argparse
|
import argparse
|
||||||
from array import *
|
import logging
|
||||||
from types import *
|
import sys
|
||||||
from os import geteuid
|
# from sys import exit
|
||||||
|
# from array import *
|
||||||
|
# from types import *
|
||||||
|
# import array
|
||||||
|
# import types
|
||||||
|
# from os import geteuid
|
||||||
|
|
||||||
##
|
##
|
||||||
# Commands to run
|
# Commands to run
|
||||||
# CHANGE THESE IF YOU NEED TO
|
# CHANGE THESE IF YOU NEED TO
|
||||||
##
|
##
|
||||||
zpoolCommand='/sbin/zpool'
|
zpoolCommand = '/sbin/zpool'
|
||||||
zfsCommand='/sbin/zfs'
|
zfsCommand = '/sbin/zfs'
|
||||||
|
|
||||||
##
|
##
|
||||||
# Variables to print at the end
|
# Variables to print at the end
|
||||||
##
|
##
|
||||||
nagiosStatus=('OK','WARNING','CRITICAL','UNKNOWN')
|
nagiosStatus = ('OK', 'WARNING', 'CRITICAL', 'UNKNOWN')
|
||||||
stateNum=0
|
stateNum = 0
|
||||||
msg=''
|
msg = ''
|
||||||
perfdata=''
|
perfdata = ''
|
||||||
|
|
||||||
##
|
##
|
||||||
# Filled from command line arguments
|
# Filled from command line arguments
|
||||||
##
|
##
|
||||||
checkCapacity=False
|
checkCapacity = False
|
||||||
capWarnThreshold=50
|
capWarnThreshold = 50
|
||||||
capCritThreshold=80
|
capCritThreshold = 80
|
||||||
checkFragmentation=False
|
checkFragmentation = False
|
||||||
fragWarnThreshold=50
|
fragWarnThreshold = 50
|
||||||
fragCritThreshold=80
|
fragCritThreshold = 80
|
||||||
|
|
||||||
def CheckArgBounds( valueArr, minVal, maxVal ):
|
logging.basicConfig(stream=sys.stdout, format='%(message)s', level=logging.WARN)
|
||||||
|
|
||||||
|
|
||||||
|
def CheckArgBounds(valueArr, minVal, maxVal):
|
||||||
|
"""Check value bounds."""
|
||||||
for value in valueArr:
|
for value in valueArr:
|
||||||
if value < minVal:
|
if value < minVal:
|
||||||
return False
|
return False
|
||||||
|
@ -68,26 +77,31 @@ def CheckArgBounds( valueArr, minVal, maxVal ):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def ConvertToGB( valueStr ):
|
|
||||||
|
def ConvertToGB(valueStr):
|
||||||
|
"""Convert to GB."""
|
||||||
value = valueStr[:-1]
|
value = valueStr[:-1]
|
||||||
value = value.replace(',', '.')
|
value = value.replace(',', '.')
|
||||||
if valueStr.endswith('G'):
|
if valueStr.endswith('G'):
|
||||||
return float(value)
|
return float(value)
|
||||||
elif valueStr.endswith('T'):
|
elif valueStr.endswith('T'):
|
||||||
gigs=float(value)*1024
|
gigs = float(value)*1024
|
||||||
return float(gigs)
|
return float(gigs)
|
||||||
elif valueStr.endswith('M'):
|
elif valueStr.endswith('M'):
|
||||||
gigs=float(value) / 1024.0
|
gigs = float(value) / 1024.0
|
||||||
return float(gigs)
|
return float(gigs)
|
||||||
elif valueStr.endswith('K'):
|
elif valueStr.endswith('K'):
|
||||||
gigs=float(value) / (1024.0 * 1024.0)
|
gigs = float(value) / (1024.0 * 1024.0)
|
||||||
return float(gigs)
|
return float(gigs)
|
||||||
|
|
||||||
def RaiseStateNum( stateNumIn, stateNum ):
|
|
||||||
|
def RaiseStateNum(stateNumIn, stateNum):
|
||||||
|
"""Raise state num."""
|
||||||
if stateNumIn > stateNum:
|
if stateNumIn > stateNum:
|
||||||
return stateNumIn
|
return stateNumIn
|
||||||
return stateNum
|
return stateNum
|
||||||
|
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
##
|
##
|
||||||
# Parse command line args
|
# Parse command line args
|
||||||
|
@ -95,57 +109,55 @@ def RaiseStateNum( stateNumIn, stateNum ):
|
||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
prog='check_zfs',
|
prog='check_zfs',
|
||||||
description='Check the ZFS pool specified by an argument.',
|
description='Check the ZFS pool specified by an argument.',
|
||||||
epilog='Note that monitor flags (e.g. capacity) require 2 arguments: warning threshold, and critical threshold')
|
epilog='Note that monitor flags (e.g. capacity) require 2 arguments:\
|
||||||
parser.add_argument('--capacity', help="monitor utilization of zpool (%%, int [0-100])", type=int, nargs=2)
|
warning threshold, and critical threshold')
|
||||||
parser.add_argument('--fragmentation', help="monitor fragmentation of zpool (%%, int [0-100])", type=int, nargs=2)
|
parser.add_argument('--capacity', help="monitor utilization of zpool (%%, int [0-100])",
|
||||||
|
type=int, nargs=2)
|
||||||
|
parser.add_argument('--fragmentation', help="monitor fragmentation of zpool (%%, int [0-100])",
|
||||||
|
type=int, nargs=2)
|
||||||
parser.add_argument('pool', help="name of the zpool to check", type=str)
|
parser.add_argument('pool', help="name of the zpool to check", type=str)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
retVal = True
|
retVal = True
|
||||||
if args.capacity is not None:
|
if args.capacity is not None:
|
||||||
checkCapacity=True
|
checkCapacity = True
|
||||||
capWarnThreshold=args.capacity[0]
|
capWarnThreshold = args.capacity[0]
|
||||||
capCritThreshold=args.capacity[1]
|
capCritThreshold = args.capacity[1]
|
||||||
capArr = array('i', [capWarnThreshold, capCritThreshold])
|
capArr = ['i', [capWarnThreshold, capCritThreshold]]
|
||||||
retVal = CheckArgBounds(capArr, 0, 100)
|
retVal = CheckArgBounds(capArr, 0, 100)
|
||||||
if retVal is False:
|
if retVal is False:
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": Capacity thresholds must be between 0 and 100 (as a percent)."
|
logging.warning("%s : Capacity thresholds must be between 0 and 100 (as a percent).",
|
||||||
|
nagiosStatus[stateNum])
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
retVal = True
|
retVal = True
|
||||||
if args.fragmentation is not None:
|
if args.fragmentation is not None:
|
||||||
checkFragmentation=True
|
checkFragmentation = True
|
||||||
fragWarnThreshold=args.fragmentation[0]
|
fragWarnThreshold = args.fragmentation[0]
|
||||||
fragCritThreshold=args.fragmentation[1]
|
fragCritThreshold = args.fragmentation[1]
|
||||||
fragArr = array('i', [fragWarnThreshold, fragCritThreshold])
|
fragArr = ['i', [fragWarnThreshold, fragCritThreshold]]
|
||||||
retVal = CheckArgBounds(fragArr, 0, 100)
|
retVal = CheckArgBounds(fragArr, 0, 100)
|
||||||
if retVal is False:
|
if retVal is False:
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": Fragmentation thresholds must be between 0 and 100 (as a percent)."
|
logging.warning("%s : Fragmentation thresholds must be between 0 and 100 (as a percent).",
|
||||||
|
nagiosStatus[stateNum])
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
###################################################################################
|
|
||||||
###################################################################################
|
|
||||||
##
|
|
||||||
# Verify that we're running as root. This should render redundant some checks
|
|
||||||
# below, but we'll leave them there in case of bugs and to make this more readable.
|
|
||||||
#if geteuid() != 0:
|
|
||||||
# stateNum = RaiseStateNum(3, stateNum)
|
|
||||||
# print nagiosStatus[stateNum] + ": process must be run as root. Did you for get sudo? If not, possible solution: add the following toyour visudo: nagios ALL=NOPASSWD: /sbin/zfs"
|
|
||||||
# exit(stateNum)
|
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
##
|
##
|
||||||
# Get generic info about the ZFS environment
|
# Get generic info about the ZFS environment
|
||||||
zfsEntries = []
|
zfsEntries = []
|
||||||
fullCommand=['/usr/bin/sudo', '-n', zfsCommand, 'list']
|
fullCommand = ['/usr/bin/sudo', '-n', zfsCommand, 'list']
|
||||||
try:
|
try:
|
||||||
childProcess = subprocess.Popen(fullCommand, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
childProcess = subprocess.Popen(fullCommand, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE)
|
||||||
except OSError:
|
except OSError:
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": process must be run as root. Possible solution: add the following to your visudo: nagios ALL=NOPASSWD: /sbin/zfs"
|
logging.warning("%s : process must be run as root. Possible solution: add the following to your\
|
||||||
|
visudo: nagios ALL=NOPASSWD: /sbin/zfs", nagiosStatus[stateNum])
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
|
|
||||||
zfsString = childProcess.communicate()[0]
|
zfsString = childProcess.communicate()[0]
|
||||||
|
@ -153,215 +165,312 @@ zfsRetval = childProcess.returncode
|
||||||
|
|
||||||
if zfsRetval is 1:
|
if zfsRetval is 1:
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": process must be run as root. Possible solution: add the following to your visudo: nagios ALL=NOPASSWD: /sbin/zfs"
|
logging.warning("%s : process must be run as root. Possible solution: add the following to\
|
||||||
|
your visudo: nagios ALL=NOPASSWD: /sbin/zfs", nagiosStatus[stateNum])
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
|
|
||||||
zfsLines = zfsString.splitlines()
|
zfsLines = zfsString.splitlines()
|
||||||
for idx, line in enumerate(zfsLines):
|
for idx, line in enumerate(zfsLines):
|
||||||
if idx != 0:
|
if idx != 0:
|
||||||
zfsEntry=line.split()
|
zfsEntry = line.split()
|
||||||
zfsEntries.append(zfsEntry)
|
zfsEntries.append(zfsEntry)
|
||||||
|
|
||||||
# Make sure the pool we specified is valid
|
# Make sure the pool we specified is valid
|
||||||
validPool=False
|
validPool = False
|
||||||
for entry in zfsEntries:
|
for entry in zfsEntries:
|
||||||
if entry[0] == args.pool:
|
if entry[0].decode() == args.pool:
|
||||||
validPool=True
|
validPool = True
|
||||||
if not validPool:
|
if not validPool:
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": Pool " + args.pool + " is invalid. Please select a valid pool."
|
logging.warning("%s : Pool %s is invalid. Please select a valid pool.",
|
||||||
|
nagiosStatus[stateNum], args.pool)
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
##
|
##
|
||||||
# Get info on zpool
|
# Get info on zpool
|
||||||
|
|
||||||
fullCommand=['/usr/bin/sudo', '-n', zpoolCommand, 'list', args.pool]
|
fullCommand = ['/usr/bin/sudo', '-n', zpoolCommand, 'list', args.pool]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
childProcess = subprocess.Popen(fullCommand, stdin=subprocess.PIPE,
|
childProcess = subprocess.Popen(fullCommand, stdin=subprocess.PIPE,
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
except OSError:
|
except OSError:
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": process must be run as root. Possible solution: add the following to your visudo: nagios ALL=NOPASSWD: /sbin/zpool"
|
logging.warning("%s : process must be run as root. Possible solution: add the following to\
|
||||||
|
your visudo: nagios ALL=NOPASSWD: /sbin/zpool", nagiosStatus[stateNum])
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
zpoolString = childProcess.communicate()[0]
|
zpoolString = childProcess.communicate()[0]
|
||||||
zpoolRetval = childProcess.returncode
|
zpoolRetval = childProcess.returncode
|
||||||
|
|
||||||
if zpoolRetval is 1:
|
if zpoolRetval is 1:
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": process must be run as root. Possible solution: add the following to your visudo: nagios ALL=NOPASSWD: /sbin/zpool"
|
logging.warning("%s : process must be run as root. Possible solution: add the following to\
|
||||||
|
your visudo: nagios ALL=NOPASSWD: /sbin/zpool", nagiosStatus[stateNum])
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
|
|
||||||
zpoolLines=zpoolString.splitlines()
|
zpoolLines = zpoolString.splitlines()
|
||||||
zpoolMeta=zpoolLines[0].split()
|
zpoolMeta = zpoolLines[0].decode().split()
|
||||||
zpoolMetaStr=','.join(zpoolMeta)
|
zpoolMetaStr = ','.join(zpoolMeta)
|
||||||
zpoolEntry=zpoolLines[1].split()
|
zpoolEntry = zpoolLines[1].decode().split()
|
||||||
zpoolEntryStr=','.join(zpoolEntry)
|
zpoolEntryStr = ','.join(zpoolEntry)
|
||||||
|
|
||||||
name=''
|
name = ''
|
||||||
size=''
|
size = ''
|
||||||
alloc=''
|
alloc = ''
|
||||||
free=''
|
free = ''
|
||||||
expandsz=''
|
expandsz = ''
|
||||||
frag=''
|
frag = ''
|
||||||
cap=''
|
cap = ''
|
||||||
dedup=''
|
dedup = ''
|
||||||
health=''
|
health = ''
|
||||||
altroot=''
|
altroot = ''
|
||||||
|
|
||||||
for idx, fieldName in enumerate(zpoolMeta):
|
for idx, fieldName in enumerate(zpoolMeta):
|
||||||
if fieldName=='NAME':
|
if fieldName == 'NAME':
|
||||||
name=zpoolEntry[idx]
|
name = zpoolEntry[idx]
|
||||||
elif fieldName=='SIZE':
|
elif fieldName == 'SIZE':
|
||||||
size=zpoolEntry[idx]
|
size = zpoolEntry[idx]
|
||||||
elif fieldName=='ALLOC':
|
elif fieldName == 'ALLOC':
|
||||||
alloc=zpoolEntry[idx]
|
alloc = zpoolEntry[idx]
|
||||||
elif fieldName=='FREE':
|
elif fieldName == 'FREE':
|
||||||
free=zpoolEntry[idx]
|
free = zpoolEntry[idx]
|
||||||
elif fieldName=='EXPANDSZ':
|
elif fieldName == 'EXPANDSZ':
|
||||||
expandsz=zpoolEntry[idx]
|
expandsz = zpoolEntry[idx]
|
||||||
elif fieldName=='FRAG':
|
elif fieldName == 'FRAG':
|
||||||
frag=zpoolEntry[idx]
|
frag = zpoolEntry[idx]
|
||||||
elif fieldName=='CAP':
|
elif fieldName == 'CAP':
|
||||||
cap=zpoolEntry[idx]
|
cap = zpoolEntry[idx]
|
||||||
elif fieldName=='DEDUP':
|
elif fieldName == 'DEDUP':
|
||||||
dedup=zpoolEntry[idx]
|
dedup = zpoolEntry[idx]
|
||||||
elif fieldName=='HEALTH':
|
elif fieldName == 'HEALTH':
|
||||||
health=zpoolEntry[idx]
|
health = zpoolEntry[idx]
|
||||||
elif fieldName=='ALTROOT':
|
elif fieldName == 'ALTROOT':
|
||||||
altroot=zpoolEntry[idx]
|
altroot = zpoolEntry[idx]
|
||||||
|
|
||||||
if name=='':
|
if name == '':
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": Missing required field in zpool output: NAME"
|
logging.warning("%s : Missing required field in zpool output: NAME", nagiosStatus[stateNum])
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
if health=='':
|
if health == '':
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": Missing required field in zpool output: HEALTH"
|
logging.warning("%s : Missing required field in zpool output: HEALTH", nagiosStatus[stateNum])
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
if checkCapacity and cap=='':
|
if checkCapacity and cap == '':
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": Cannot monitor capacity without zpool output: CAP. Outputs are" + zpoolMetaStr
|
logging.warning("%s Cannot monitor capacity without zpool output: CAP.\
|
||||||
|
Outputs are %s", nagiosStatus[stateNum], zpoolMetaStr)
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
if checkFragmentation and frag=='':
|
if checkFragmentation and frag == '':
|
||||||
stateNum = RaiseStateNum(3, stateNum)
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
print nagiosStatus[stateNum] + ": Cannot monitor fragmentation without zpool output: FRAG. Outputs are " + zpoolMetaStr
|
logging.warning("%s : Cannot monitor fragmentation without zpool output: FRAG.\
|
||||||
|
Outputs are %s", nagiosStatus[stateNum], zpoolMetaStr)
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
|
|
||||||
|
# Get compressratio on zpool
|
||||||
|
|
||||||
|
checkForCompression = ['/usr/bin/sudo', '-n', zfsCommand, 'get', 'compression', args.pool]
|
||||||
|
|
||||||
|
try:
|
||||||
|
childProcess = subprocess.Popen(checkForCompression, stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
except OSError:
|
||||||
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
|
logging.warning("%s : process must be run as root. Possible solution: add the following to\
|
||||||
|
your visudo: nagios ALL=NOPASSWD: /sbin/zpool", nagiosStatus[stateNum])
|
||||||
|
exit(stateNum)
|
||||||
|
zpoolString = childProcess.communicate()[0]
|
||||||
|
zpoolRetval = childProcess.returncode
|
||||||
|
|
||||||
|
if zpoolRetval is 1:
|
||||||
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
|
logging.warning("%s : process must be run as root. Possible solution: add the following to\
|
||||||
|
your visudo: nagios ALL=NOPASSWD: /sbin/zpool", nagiosStatus[stateNum])
|
||||||
|
exit(stateNum)
|
||||||
|
|
||||||
|
zpoolLines = zpoolString.splitlines()
|
||||||
|
zpoolMeta = zpoolLines[0].decode().split()
|
||||||
|
zpoolMetaStr = ','.join(zpoolMeta)
|
||||||
|
zpoolEntry = zpoolLines[1].decode().split()
|
||||||
|
zpoolEntryStr = ','.join(zpoolEntry)
|
||||||
|
|
||||||
|
compressName = ''
|
||||||
|
compressValue = ''
|
||||||
|
|
||||||
|
compressRatioName = ''
|
||||||
|
compressRatioValue = ''
|
||||||
|
|
||||||
|
for idx, fieldName in enumerate(zpoolMeta):
|
||||||
|
if fieldName == 'NAME':
|
||||||
|
compressName = zpoolEntry[idx]
|
||||||
|
elif fieldName == 'VALUE':
|
||||||
|
compressValue = zpoolEntry[idx]
|
||||||
|
|
||||||
|
if compressName == '':
|
||||||
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
|
logging.warning("%s : Missing required field in zpool output: NAME", nagiosStatus[stateNum])
|
||||||
|
exit(stateNum)
|
||||||
|
if compressValue == 'on':
|
||||||
|
getCompressRatioCommand = ['/usr/bin/sudo', '-n', zfsCommand, 'get', 'compressratio', args.pool]
|
||||||
|
|
||||||
|
try:
|
||||||
|
childProcess = subprocess.Popen(getCompressRatioCommand, stdin=subprocess.PIPE,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||||
|
except OSError:
|
||||||
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
|
logging.warning("%s : process must be run as root. Possible solution: add the following to\
|
||||||
|
your visudo: nagios ALL=NOPASSWD: /sbin/zpool", nagiosStatus[stateNum])
|
||||||
|
exit(stateNum)
|
||||||
|
zpoolString = childProcess.communicate()[0]
|
||||||
|
zpoolRetval = childProcess.returncode
|
||||||
|
|
||||||
|
if zpoolRetval is 1:
|
||||||
|
stateNum = RaiseStateNum(3, stateNum)
|
||||||
|
logging.warning("%s : process must be run as root. Possible solution: add the following to\
|
||||||
|
your visudo: nagios ALL=NOPASSWD: /sbin/zpool", nagiosStatus[stateNum])
|
||||||
|
exit(stateNum)
|
||||||
|
|
||||||
|
zpoolLines = zpoolString.splitlines()
|
||||||
|
zpoolMeta = zpoolLines[0].decode().split()
|
||||||
|
zpoolMetaStr = ','.join(zpoolMeta)
|
||||||
|
zpoolEntry = zpoolLines[1].decode().split()
|
||||||
|
zpoolEntryStr = ','.join(zpoolEntry)
|
||||||
|
|
||||||
|
for idx, fieldName in enumerate(zpoolMeta):
|
||||||
|
if fieldName == 'NAME':
|
||||||
|
compressRatioName = zpoolEntry[idx]
|
||||||
|
elif fieldName == 'VALUE':
|
||||||
|
compressRatioValue = zpoolEntry[idx]
|
||||||
|
|
||||||
###################################################################################
|
###################################################################################
|
||||||
##
|
##
|
||||||
# OK, finally in the actual status checking of the zpool
|
# OK, finally in the actual status checking of the zpool
|
||||||
|
|
||||||
# Let's build up our perfdata, regardless of what we're checking
|
# Let's build up our perfdata, regardless of what we're checking
|
||||||
fragPercent=''
|
fragPercent = ''
|
||||||
if frag!='':
|
if frag != '':
|
||||||
fragPercent=frag.replace("%", "")
|
fragPercent = frag.replace("%", "")
|
||||||
fragPerfStr="frag="+str(fragPercent)+"%;"
|
fragPerfStr = "frag="+str(fragPercent)+"%;"
|
||||||
if checkFragmentation:
|
if checkFragmentation:
|
||||||
fragPerfStr=fragPerfStr+str(fragWarnThreshold)+";"+str(fragCritThreshold)+";"
|
fragPerfStr = fragPerfStr+str(fragWarnThreshold)+";"+str(fragCritThreshold)+";"
|
||||||
else:
|
else:
|
||||||
fragPerfStr+=(";;");
|
fragPerfStr += (";;")
|
||||||
perfdata+=(fragPerfStr)
|
perfdata += (fragPerfStr)
|
||||||
perfdata+=" "
|
perfdata += " "
|
||||||
|
|
||||||
capPercent=''
|
capPercent = ''
|
||||||
if cap!='':
|
if cap != '':
|
||||||
capPercent=cap.replace("%", "")
|
capPercent = cap.replace("%", "")
|
||||||
capPerfStr="cap="+str(capPercent)+"%;"
|
capPerfStr = "cap="+str(capPercent)+"%;"
|
||||||
if checkCapacity:
|
if checkCapacity:
|
||||||
capPerfStr=capPerfStr+str(capWarnThreshold)+";"+str(capCritThreshold)+";"
|
capPerfStr = capPerfStr+str(capWarnThreshold)+";"+str(capCritThreshold)+";"
|
||||||
else:
|
else:
|
||||||
capPerfStr+=(";;");
|
capPerfStr += (";;")
|
||||||
perfdata+=(capPerfStr)
|
perfdata += (capPerfStr)
|
||||||
perfdata+=" "
|
perfdata += " "
|
||||||
|
|
||||||
|
# Perfdata for dedup & compression factor
|
||||||
|
if dedup != '':
|
||||||
|
dedup_no_x = dedup.rstrip('x')
|
||||||
|
perfdata += "dedup="+str(dedup_no_x)
|
||||||
|
perfdata += " "
|
||||||
|
|
||||||
|
if compressRatioValue != '':
|
||||||
|
compressRatioNoX = compressRatioValue.rstrip('x')
|
||||||
|
perfdata += "compress_ratio="+str(compressRatioNoX)
|
||||||
|
perfdata += " "
|
||||||
|
|
||||||
# Sizes can be in K, M, G, or T (maybe P, but I'm not doing this yet)
|
# Sizes can be in K, M, G, or T (maybe P, but I'm not doing this yet)
|
||||||
if size!='':
|
if size != '':
|
||||||
sizeGB = ConvertToGB(size)
|
sizeGB = ConvertToGB(size)
|
||||||
perfdata+="size="+str(sizeGB)+"GB;;;"
|
perfdata += "size="+str(sizeGB)+"GB;;;"
|
||||||
perfdata+=" "
|
perfdata += " "
|
||||||
|
|
||||||
if alloc!='':
|
if alloc != '':
|
||||||
allocGB = ConvertToGB(alloc)
|
allocGB = ConvertToGB(alloc)
|
||||||
perfdata+="alloc="+str(allocGB)+"GB;;;"
|
perfdata += "alloc="+str(allocGB)+"GB;;;"
|
||||||
perfdata+=" "
|
perfdata += " "
|
||||||
|
|
||||||
if free!='':
|
if free != '':
|
||||||
freeGB = ConvertToGB(free)
|
freeGB = ConvertToGB(free)
|
||||||
perfdata+="free="+str(freeGB)+"GB;;;"
|
perfdata += "free="+str(freeGB)+"GB;;;"
|
||||||
perfdata+=" "
|
perfdata += " "
|
||||||
|
|
||||||
##
|
##
|
||||||
# Do mandatory checks
|
# Do mandatory checks
|
||||||
healthNum=-1
|
healthNum = -1
|
||||||
if health=='ONLINE':
|
if health == 'ONLINE':
|
||||||
healthNum=0
|
healthNum = 0
|
||||||
elif health=='OFFLINE':
|
elif health == 'OFFLINE':
|
||||||
stateNum = RaiseStateNum(1, stateNum)
|
stateNum = RaiseStateNum(1, stateNum)
|
||||||
healthNum=1
|
healthNum = 1
|
||||||
elif health=='REMOVED':
|
elif health == 'REMOVED':
|
||||||
stateNum = RaiseStateNum(1, stateNum)
|
stateNum = RaiseStateNum(1, stateNum)
|
||||||
healthNum=2
|
healthNum = 2
|
||||||
elif health=='UNAVAIL':
|
elif health == 'UNAVAIL':
|
||||||
stateNum = RaiseStateNum(1, stateNum)
|
stateNum = RaiseStateNum(1, stateNum)
|
||||||
healthNum=3
|
healthNum = 3
|
||||||
elif health=='DEGRADED':
|
elif health == 'DEGRADED':
|
||||||
stateNum = RaiseStateNum(2, stateNum)
|
stateNum = RaiseStateNum(2, stateNum)
|
||||||
healthNum=4
|
healthNum = 4
|
||||||
elif health=='FAULTED':
|
elif health == 'FAULTED':
|
||||||
stateNum = RaiseStateNum(2, stateNum)
|
stateNum = RaiseStateNum(2, stateNum)
|
||||||
healthNum=5
|
healthNum = 5
|
||||||
perfdata+="health="+str(healthNum)+";1;3;"
|
perfdata += "health="+str(healthNum)+";1;3;"
|
||||||
perfdata+=" "
|
perfdata += " "
|
||||||
|
|
||||||
##
|
##
|
||||||
# Initial part of msg
|
# Initial part of msg
|
||||||
msg="POOL: "+str(name)
|
msg = "POOL: " + str(name)
|
||||||
healthMsgFilled=False
|
healthMsgFilled = False
|
||||||
if healthNum > 0:
|
if healthNum > 0:
|
||||||
msg+=", STATUS: "+str(health)
|
msg += ", STATUS: "+str(health)
|
||||||
healthMsgFilled=True
|
healthMsgFilled = True
|
||||||
|
|
||||||
##
|
##
|
||||||
# Do optional checks
|
# Do optional checks
|
||||||
fragMsgFilled=False
|
fragMsgFilled = False
|
||||||
capMsgFilled=False
|
capMsgFilled = False
|
||||||
if checkFragmentation and fragPercent!='':
|
if checkFragmentation and fragPercent != '':
|
||||||
|
if fragPercent.isdigit() is True:
|
||||||
if int(fragPercent) > int(fragCritThreshold):
|
if int(fragPercent) > int(fragCritThreshold):
|
||||||
fragMsgFilled=True
|
fragMsgFilled = True
|
||||||
stateNum = RaiseStateNum(2, stateNum)
|
stateNum = RaiseStateNum(2, stateNum)
|
||||||
msg+=", FRAG CRIT: "+str(frag)
|
msg += ", FRAG CRIT: " + str(frag)
|
||||||
elif int(fragPercent) > int(fragWarnThreshold):
|
elif int(fragPercent) > int(fragWarnThreshold):
|
||||||
fragMsgFilled=True
|
fragMsgFilled = True
|
||||||
stateNum = RaiseStateNum(1, stateNum)
|
stateNum = RaiseStateNum(1, stateNum)
|
||||||
msg+=", FRAG WARN: "+str(frag)
|
msg += ", FRAG WARN: " + str(frag)
|
||||||
if checkCapacity and capPercent!='':
|
if checkCapacity and capPercent != '':
|
||||||
if int(capPercent) > int(capCritThreshold):
|
if int(capPercent) > int(capCritThreshold):
|
||||||
capMsgFilled=True
|
capMsgFilled = True
|
||||||
stateNum = RaiseStateNum(2, stateNum)
|
stateNum = RaiseStateNum(2, stateNum)
|
||||||
msg+=", CAP CRIT: "+str(cap)
|
msg += ", CAP CRIT: " + str(cap)
|
||||||
elif int(capPercent) > int(capWarnThreshold):
|
elif int(capPercent) > int(capWarnThreshold):
|
||||||
capMsgFilled=True
|
capMsgFilled = True
|
||||||
stateNum = RaiseStateNum(1, stateNum)
|
stateNum = RaiseStateNum(1, stateNum)
|
||||||
msg+=", CAP WARN: "+str(cap)
|
msg += ", CAP WARN: "+str(cap)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Build up rest of message
|
# Build up rest of message
|
||||||
if not healthMsgFilled:
|
if not healthMsgFilled:
|
||||||
msg+=", STATUS: "+str(health)
|
msg += ", STATUS: " + str(health)
|
||||||
if size!='':
|
if size != '':
|
||||||
msg+=", SIZE: "+str(size)
|
msg += ", SIZE: " + str(size)
|
||||||
if alloc!='':
|
if alloc != '':
|
||||||
msg+=", ALLOC: "+str(alloc)
|
msg += ", ALLOC: " + str(alloc)
|
||||||
if free!='':
|
if free != '':
|
||||||
msg+=", FREE: "+str(free)
|
msg += ", FREE: " + str(free)
|
||||||
if frag!='' and not fragMsgFilled:
|
if dedup != '':
|
||||||
msg+=", FRAG: "+str(frag)
|
msg += ", DEDUP: " + str(dedup)
|
||||||
if cap!='' and not capMsgFilled:
|
if compressRatioValue != '':
|
||||||
msg+=", CAP: "+str(cap)
|
msg += ", COMPRESS: " + str(compressRatioValue)
|
||||||
|
if frag != '' and not fragMsgFilled:
|
||||||
|
msg += ", FRAG: " + str(frag)
|
||||||
|
if cap != '' and not capMsgFilled:
|
||||||
|
msg += ", CAP: " + str(cap)
|
||||||
|
|
||||||
##
|
##
|
||||||
# Print our output and return
|
# Print our output and return
|
||||||
print nagiosStatus[stateNum]+": "+msg+" | "+perfdata
|
logging.warning("%s: %s | %s", nagiosStatus[stateNum], msg, perfdata)
|
||||||
exit(stateNum)
|
exit(stateNum)
|
||||||
|
|
Loading…
Reference in a new issue