diff options
author | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2014-07-23 15:03:01 +0200 |
---|---|---|
committer | Jörg Frings-Fürst <debian@jff-webhosting.net> | 2014-07-23 15:03:01 +0200 |
commit | 777af8a8761d05c30588abec7444b143fe7393f0 (patch) | |
tree | 5a135c37eaa9ac94772819a28ce5beedd18e5c4a /contrib/bmc-snmp-proxy | |
parent | c3445516ecd58e97de483cf4b7fafcc1104890d7 (diff) | |
parent | b32d92e890caac903491116e9d817aa780c0323b (diff) |
Merge tag 'upstream/1.8.14'
Upstream version 1.8.14
Diffstat (limited to 'contrib/bmc-snmp-proxy')
-rw-r--r-- | contrib/bmc-snmp-proxy | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/contrib/bmc-snmp-proxy b/contrib/bmc-snmp-proxy new file mode 100644 index 0000000..1704ef3 --- /dev/null +++ b/contrib/bmc-snmp-proxy @@ -0,0 +1,381 @@ +#!/bin/sh +############################################################################# +# +# bmc-snmp-proxy: Set SNMP proxy to BMC (Baseboard Management Controller) +# +# version: 0.6 +# +# Authors: Charles Rose <charles_rose@dell.com> +# Jordan Hargrave <jordan_hargrave@dell.com> +# +# Description: Script to set snmp proxy to the BMC for certain OID +# See here for details: +# https://fedoraproject.org/wiki/Features/AgentFreeManagement +# +# Assumptions: This script will work only when /etc/snmp/ is writable. +# +############################################################################# +# GLOBALS +############################################################################# +SYSCONF_DIR="/etc/sysconfig" +CONFIG="${SYSCONF_DIR}/bmc-snmp-proxy" + +SNMPD_LOCAL_CONF_DIR="/etc/snmp/bmc" +SNMPD_LOCAL_CONF="${SNMPD_LOCAL_CONF_DIR}/snmpd.local.conf" +TRAPD_LOCAL_CONF="${SNMPD_LOCAL_CONF_DIR}/snmptrapd.local.conf" + +TRAPD_CONF="/etc/snmp/snmptrapd.conf" + +LOCKFILE="/var/lock/subsys/bmc-snmp-proxy" +BMC_INFO="/var/run/bmc-info" + +IPMITOOL=`which ipmitool` + +#Default config +BMC_COMMUNITY="public" +BMC_OID=".1.3.6.1.4.1.674.10892.2" # Dell iDRAC +TRAP_FORWARD="no" +RELOAD_SERVICES="yes" + +############################################################################# + +#TODO: Use inotify and daemonize when $BMC_INFO changes + +# source config +[ -r ${CONFIG} ] && . ${CONFIG} + +. gettext.sh + +SCRIPT_NAME=$(basename $0) +RETVAL=0 + +# Check if bmc-info created by exchange-bmc-os-info +bmc_info_exists() +{ + if [ -r "${BMC_INFO}" ]; then + . ${BMC_INFO} + else + RETVAL=2 + fi + return $RETVAL +} + +check_snmp() +{ + if [ ! -d /etc/snmp ] && [ ! -x /usr/sbin/snmpd ]; then + RETVAL=12 + fi + return $RETVAL +} + +############################################################################# +# configure SNMP proxy +############################################################################# +write_snmp_conf() +{ + # SNMPv3 security: bmcview, bmc_ctx, bmc_sec, bmc_grp, bmc_cmty + printf "###############################################\n" + printf "# Automatically created by %s #\n" "${SCRIPT_NAME}" + printf "###############################################\n" + printf "view bmcview included %s 80\n" "${BMC_OID}" + printf "com2sec -Cn bmc_ctx bmc_sec default bmc_cmty\n" + printf "group bmc_grp v1 bmc_sec\n" + printf "access bmc_grp bmc_ctx any noauth exact bmcview none none\n" + printf "proxy -Cn bmc_ctx -v 1 %s\n" "${PROXY_TOKEN}" + printf "###############################################\n" +} + +valid_ip() +{ + #Thanks to mkyong.com + octet="([01]?[[:digit:]][[:digit:]]?|2[0-4][[:digit:]]|25[0-5])" + + printf -- "%s" "${1}"| grep -Eq \ + "^${octet}\\.${octet}\\.${octet}\\.${octet}$" + return $? +} + +check_vars() +{ + [ -z ${BMC_COMMUNITY} ] && BMC_COMMUNITY="public" + [ -z ${BMC_OID} ] && return 1 + + if [ -n "${BMC_IPv4}" ] && valid_ip ${BMC_IPv4}; then + return 0 + else + return 1 + fi +} + +set_snmp_proxy() +{ + if check_vars; then + PROXY_TOKEN="-c ${BMC_COMMUNITY} ${BMC_IPv4} ${BMC_OID}" + + if [ ! -d ${SNMPD_LOCAL_CONF_DIR} ] && \ + mkdir ${SNMPD_LOCAL_CONF_DIR}; then + write_snmp_conf > ${SNMPD_LOCAL_CONF} + [ $? -ne 0 ] && RETVAL=4 + fi + else + RETVAL=3 + fi +} + + +set_snmpd_conf_path() +{ + for SYSCONF in ${SYSCONF_DIR}/snmp*d; + do + if grep -q "${SNMPD_LOCAL_CONF_DIR}" "${SYSCONF}" > \ + /dev/null 2>&1; then + continue + else + printf "SNMPCONFPATH=%s\n" "${SNMPD_LOCAL_CONF_DIR}" \ + >> ${SYSCONF} || RETVAL=7 + fi + done + return $RETVAL +} + +disable_snmp_proxy() +{ + if [ -f ${SNMPD_LOCAL_CONF} ]; then + rm -f ${SNMPD_LOCAL_CONF} + [ $? -ne 0 ] && RETVAL=5 + fi +} +############################################################################# +# Trap Forwarding +############################################################################# + +pick_alert_dest() +{ + test_ip="$1" + for ALERT_DEST in `seq 1 4` + do + temp_ip=$(${IPMITOOL} lan alert print ${CHANNEL} ${ALERT_DEST}\ + 2>/dev/null| sed -n "s#^Alert IP Address.*: ##p") + + [ "${temp_ip}" = "${test_ip}" ] && return 0 + done + return 1 +} + +set_alert_dest_ip() +{ + ${IPMITOOL} lan alert set ${CHANNEL} ${ALERT_DEST} ipaddr ${1} \ + retry 4 type pet >/dev/null 2>&1 + [ $? -ne 0 ] && RETVAL=8 +} + +bmc_alert_dest() +{ + # Pick the first active LAN channel + for CHANNEL in `seq 1 14` + do + [ $(${IPMITOOL} -I open channel info ${CHANNEL} 2>/dev/null \ + | grep -q "802\.3") ] || break + done + + # If TRAPD_IP is already set as an alert dest, + if pick_alert_dest "${TRAPD_IP}"; then + # reset: reset it if we are called with reset + [ "${1}" = "reset" ] && \ + set_alert_dest_ip "0.0.0.0" + # else, find the next free alert dest, + elif pick_alert_dest "0.0.0.0"; then + [ "${1}" = "reset" ] && \ + return $RETVAL + # set: the TRAPD_IP + set_alert_dest_ip "${TRAPD_IP}" + else + # No free alert destinations + RETVAL=9 + fi + return $RETVAL +} + +set_ipmi_alert() +{ + ${IPMITOOL} lan set ${CHANNEL} alert "${1}" >/dev/null 2>&1 + [ $? -ne 0 ] && RETVAL=10 +} + +get_host_ip() +{ + # Get host's IP that the BMC can reach. + IFACE=$(/usr/sbin/ip -o -f inet address |awk '!/: lo/ {print $2}') + for dev in ${IFACE} + do + ping -c 1 -I ${dev} ${BMC_IPv4} > /dev/null 2>&1 + done +} + +config_bmc_alert() +{ + # Get Host's IP that the BMC can send traps to + TRAPD_IP=$(get_host_ip) + + # Set Host's IP as the alert destination in the BMC + valid_ip ${TRAPD_IP} && bmc_alert_dest "${ACTION}" + + # Enable alerting on the LAN channel + [ $RETVAL -eq 0 ] && set_ipmi_alert "${ACTION}" +} + +write_trapd_conf() +{ + printf "###############################################\n" + printf "# Automatically created by %s #\n" "${SCRIPT_NAME}" + printf "forward %s %s\n" "${BMC_OID}*" "${FORWARD_HOST}" + printf "###############################################\n" +} + +config_trapd() +{ + # Proceed only if snmptrapd is available on the system + if [ -f ${TRAPD_CONF} ]; then + write_trapd_conf > ${TRAPD_LOCAL_CONF} + [ $? -ne 0 ] && RETVAL=11 + else + return 1 + fi +} + +trap_sink_exists() +{ + # TODO: We only set the first match. We should be able to set + # multiple + FORWARD_HOST=$(awk '/^trap.*sink/{print $2}; /^informsink/{print $2}' \ + /etc/snmp/snmpd*conf | head -1) + if [ -z "${FORWARD_HOST}" ]; then + # there is no trapsink setup. + return 1 + else + return 0 + fi +} + +# Forward SNMP traps from the BMC to trapsink. +trap_forward() +{ + NO_TRAP=0 + ACTION=${1} # set or reset + + if [ "${ACTION}" = "set" ]; then + # Get trapd config, + if trap_sink_exists; then + config_trapd && config_bmc_alert + else + # exit silently if there is no sink + NO_TRAP=1 + fi + else + if [ -f ${TRAPD_LOCAL_CONF} ]; then + rm -f ${TRAPD_LOCAL_CONF} >/dev/null 2>&1 + else + NO_TRAP=1 + fi + fi +} + +############################################################################# +service_reload() +{ + #TODO: do this in systemd + if [ ${RETVAL} -eq 0 ] && [ "${RELOAD_SERVICES}" = "yes" ]; then + service $1 reload + [ $? -ne 0 ] && RETVAL=6 + fi + return +} + +############################################################################# +start() +{ + if bmc_info_exists && check_snmp; then + touch ${LOCKFILE} + set_snmpd_conf_path && set_snmp_proxy + [ $RETVAL -eq 0 ] && service_reload snmpd + + if [ "${TRAP_FORWARD}" = "yes" ]; then + trap_forward "set" + [ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \ + service_reload snmptrapd + fi + fi +} + +############################################################################# +stop() +{ + [ ! -f ${LOCKFILE} ] && return + if bmc_info_exists && check_snmp; then + disable_snmp_proxy + [ $RETVAL -eq 0 ] && service_reload snmpd + + if [ "${TRAP_FORWARD}" = "yes" ]; then + trap_forward "reset" + [ $RETVAL -eq 0 ] && [ $NO_TRAP -eq 0 ] && \ + service_reload snmptrapd + fi + rm -f ${LOCKFILE} + fi +} + +############################################################################# +status() +{ + eval_gettext "${SCRIPT_NAME}: snmp proxy to BMC is " + # Checking for lockfile is better. + #if grep -q "^proxy" "${SNMPD_LOCAL_CONF}" > /dev/null 2>&1 ; then + if [ -f ${LOCKFILE} ]; then + eval_gettext "set" + else + eval_gettext "not set" + fi + echo + RETVAL=0 +} + +############################################################################# +usage() +{ + eval_gettext "Usage: $0 {start|stop|status}"; echo 1>&2 + RETVAL=1 +} + +############################################################################# +# MAIN +############################################################################# +case "$1" in + start) start ;; + stop) stop ;; + status) status ;; + *) usage ;; +esac + +case "$RETVAL" in + 0|1) ;; + 2) eval_gettext "${SCRIPT_NAME}: failed to read ${BMC_INFO} " 1>&2 ;; + 3) eval_gettext "${SCRIPT_NAME}: failed to get proxy config." 1>&2 ;; + 4) eval_gettext "${SCRIPT_NAME}: failed to set ${SNMPD_LOCAL_CONF}." 1>&2 ;; + 5) eval_gettext "${SCRIPT_NAME}: failed to disable snmp proxy." 1>&2 ;; + 6) eval_gettext "${SCRIPT_NAME}: failed to reload snmpd." 1>&2 ;; + 7) eval_gettext "${SCRIPT_NAME}: failed to update ${SYSCONF}." 1>&2 ;; + 8) eval_gettext "${SCRIPT_NAME}: failed to set IPMI alert dest." 1>&2 ;; + 9) eval_gettext "${SCRIPT_NAME}: no free IPMI alert dest." 1>&2 ;; + 10) eval_gettext "${SCRIPT_NAME}: failed to set IPMI PEF." 1>&2 ;; + 11) eval_gettext "${SCRIPT_NAME}: failed to write snmptrapd.conf." 1>&2 ;; + 12) eval_gettext "${SCRIPT_NAME}: snmpd not found." 1>&2 ;; + *) eval_gettext "${SCRIPT_NAME}: unknown error." 1>&2 ;; +esac + +if [ ${RETVAL} -gt 1 ]; then + eval_gettext " Return code: ${RETVAL}"; echo +fi +exit ${RETVAL} +############################################################################# +# end of file +############################################################################# |