#!/bin/bash
#< Nagios Plugin - Check status of a Solaris SMF controlled service
AWK="/usr/bin/awk"
BASENAME="/usr/bin/basename"
ECHO="/bin/echo"
GREP="/usr/xpg4/bin/grep"
SED="/usr/bin/sed"
SUDO="/usr/local/bin/sudo"
SVCS="/usr/bin/svcs"
WC="/usr/bin/wc"
ZLOGIN="/usr/sbin/zlogin"
ZONEADM="/usr/sbin/zoneadm"
ZONECFG="/usr/sbin/zonecfg"
THISPROG=$( ${BASENAME} $0 )
COUNT=0
VERBOSE=0
ZONE="global"
E_SUCCESS=0
E_WARNING=1
E_CRITICAL=2
E_UNKNOWN=3
function print_error {
${ECHO} "Error: $@" >&2
}
function printv {
(( VERBOSE )) && {
${ECHO} "--> $@"
}
}
function print_usage {
{
${ECHO} "Usage: ${THISPROG} [-hv] [-z <zonename>] -s <service_fmri> [ -p -w <warn> -c <crit> ]"
${ECHO} " -c Specify critical threshold for number of processes (use with -p)"
${ECHO} " -h Display this usage message"
${ECHO} " -p Check number of processes"
${ECHO} " -s FMRI of target service"
${ECHO} " -v Verbose mode"
${ECHO} " -w Specify warning threshold for number of processes (use with -p)"
${ECHO} " -z Specify zonename (default is global)"
} >&2
}
function check_usage {
if [ -z "${FMRI}" ]; then
${ECHO} "UNKNOWN: -s option mandatory"
exit ${E_UNKNOWN}
fi
if [ "${COUNT}" -gt "0" ]; then
if [ -z "${WARN}" ]; then
${ECHO} "UNKNOWN: -w mandatory with -p"
exit ${E_UNKNOWN}
fi
if [ -z "${CRIT}" ]; then
${ECHO} "UNKNOWN: -c mandatory with -p"
exit ${E_UNKNOWN}
fi
${ECHO} "${WARN}" | ${GREP} -E -q '^[0-9]+$'
if [ "$?" -ne "0" ]; then
${ECHO} "UNKNOWN: -w should have an integer value"
exit ${E_UNKNOWN}
fi
${ECHO} "${CRIT}" | ${GREP} -E -q '^[0-9]+$'
if [ "$?" -ne "0" ]; then
${ECHO} "UNKNOWN: -c should have an integer value"
exit ${E_UNKNOWN}
fi
if [ "${CRIT}" -le "${WARN}" ]; then
${ECHO} "UNKNOWN: -c should be >= -w"
exit ${E_UNKNOWN}
fi
fi
}
function check_valid_zone {
if [ "${ZONE}" = "global" ]; then
return
fi
ZONELIST=$( ${SUDO} ${ZONEADM} list -cp )
if [ "$?" -ne "0" ]; then
${ECHO} "UNKNOWN: Could not get zone list"
exit ${E_UNKNOWN}
fi
ZONESTATE=$( ${ECHO} "${ZONELIST}" | ${GREP} -E "^[0-9-]+:${ZONE}:" )
if [ "$?" -ne "0" ]; then
${ECHO} "UNKNOWN: ${ZONE} is not a valid zone"
exit ${E_UNKNOWN}
fi
}
function check_zone_runstate {
if [ "${ZONE}" = "global" ]; then
return
fi
STATE=$( ${ECHO} "${ZONESTATE}" | ${SED} 's/^[^:]*:[^:]*:\([^:]*\):.*$/\1/' )
if [ "${STATE}" != "running" ]; then
# We only output a warning, as the check_zone plugin monitors zone state
${ECHO} "WARNING: ${ZONE} in state ${STATE}"
exit ${E_WARNING}
fi
}
function check_service {
if [ "${ZONE}" = "global" ]; then
RESULT=$( ${SVCS} -H ${FMRI} 2>&1 )
${ECHO} "${RESULT}" | ${GREP} -q 'Pattern.*doesn.t match any'
if [ "$?" -eq "0" ]; then
${ECHO} "CRITICAL: Service ${FMRI} not present on global zone"
exit ${E_CRITICAL}
fi
else
RESULT=$( ${SUDO} ${ZLOGIN} ${ZONE} svcs -H ${FMRI} 2>&1 )
${ECHO} "${RESULT}" | ${GREP} -q 'Pattern.*doesn.t match any'
if [ "$?" -eq "0" ]; then
${ECHO} "CRITICAL: Service ${FMRI} not present on ${ZONE}"
exit ${E_CRITICAL}
fi
fi
if [ "${COUNT}" -eq "0" ]; then
SVCSTATE=$( ${ECHO} "${RESULT}" | ${AWK} '{print $1}' )
if [ "${SVCSTATE}" = "online" ]; then
${ECHO} "OK: Service ${FMRI} is online [Zone: ${ZONE}]"
exit ${E_OK}
elif [ "${SVCSTATE}" = "disabled" ]; then
${ECHO} "WARNING: Service ${FMRI} has been disabled [Zone: ${ZONE}]"
exit ${E_WARNING}
else
${ECHO} "CRITICAL: Service ${FMRI} is in state: ${SVCSTATE} [Zone: ${ZONE}]"
exit ${E_CRITICAL}
fi
else
if [ "${ZONE}" = "global" ]; then
SVCPROCS=$( ${SVCS} -H -p ${FMRI} )
SVCSTATE=$( ${ECHO} "${SVCPROCS}" | ${AWK} 'NR==1 {print $1}' )
PROCCOUNT=$( ${ECHO} "${SVCPROCS}" | ${SED} '1d' | ${WC} -l | ${AWK} '{print $1}' )
if [ "${SVCSTATE}" = "online" ]; then
if [ "${PROCCOUNT}" -ge "${CRIT}" ]; then
${ECHO} "CRITICAL: ${PROCCOUNT} ${CRIT} processes for ${FMRI} [Zone: ${ZONE}]"
exit ${E_CRITICAL}
elif [ "${PROCCOUNT}" -ge "${WARN}" ]; then
${ECHO} "WARNING: ${PROCCOUNT} processes for ${FMRI} [Zone: ${ZONE}]"
exit ${E_WARNING}
else
${ECHO} "OK: ${PROCCOUNT} processes for ${FMRI} [Zone: ${ZONE}]"
exit ${E_OK}
fi
elif [ "${SVCSTATE}" = "disabled" ]; then
${ECHO} "WARNING: Service ${FMRI} has been disabled [Zone: ${ZONE}]"
exit ${E_WARNING}
else
${ECHO} "CRITICAL: Service ${FMRI} is in state: ${SVCSTATE} [Zone: ${ZONE}]"
exit ${E_CRITICAL}
fi
else
SVCPROCS=$( ${SUDO} ${ZLOGIN} ${ZONE} svcs -H -p ${FMRI} )
SVCSTATE=$( ${ECHO} "${SVCPROCS}" | ${AWK} 'NR==1 {print $1}' )
PROCCOUNT=$( ${ECHO} "${SVCPROCS}" | ${SED} '1d' | ${WC} -l | ${AWK} '{print $1}' )
if [ "${SVCSTATE}" = "online" ]; then
if [ "${PROCCOUNT}" -ge "${CRIT}" ]; then
${ECHO} "CRITICAL: ${PROCCOUNT} ${CRIT} processes for ${FMRI} [Zone: ${ZONE}]"
exit ${E_CRITICAL}
elif [ "${PROCCOUNT}" -ge "${WARN}" ]; then
${ECHO} "WARNING: ${PROCCOUNT} processes for ${FMRI} [Zone: ${ZONE}]"
exit ${E_WARNING}
else
${ECHO} "OK: ${PROCCOUNT} processes for ${FMRI} [Zone: ${ZONE}]"
exit ${E_OK}
fi
elif [ "${SVCSTATE}" = "disabled" ]; then
${ECHO} "WARNING: Service ${FMRI} has been disabled [Zone: ${ZONE}]"
exit ${E_WARNING}
else
${ECHO} "CRITICAL: Service ${FMRI} is in state: ${SVCSTATE} [Zone: ${ZONE}]"
exit ${E_CRITICAL}
fi
fi
fi
}
function tmp_warn {
if [ "${COUNT}" -eq "1" ]; then
echo "not yet implemented..."
exit 127
fi
}
#
# main()
#
while getopts ":c:hps:vw:z:" OPTION; do
case ${OPTION} in
"c") CRIT="${OPTARG}" ;;
"h") print_usage && exit 0 ;;
"p") COUNT=1 ;;
"s") FMRI="${OPTARG}" ;;
"v") VERBOSE=1 ;;
"w") WARN="${OPTARG}" ;;
"z") ZONE="${OPTARG}" ;;
* ) print_usage && exit 1 ;;
esac
done
shift $(( ${OPTIND} - 1 ))
if [ "$#" -ne "0" ]; then
print_usage && exit 1
fi
check_usage
#tmp_warn
check_valid_zone
check_zone_runstate
check_service
${ECHO} "UNKNOWN: Should never be reached"
exit ${E_UNKNOWN}