1#!/bin/sh 2# 3# External STONITH module for APC Switched Rack PDU 4# 5# Copyright (c) 2008 Sergey Maznichenko <msergeyb@gmail.com> <inbox@it-consultant.su> 6# Version 1.2 7# 8# See http://www.it-consultant.su/rackpdu 9# for additional information 10# 11# This program is free software; you can redistribute it and/or modify 12# it under the terms of version 2 of the GNU General Public License as 13# published by the Free Software Foundation. 14# 15# This program is distributed in the hope that it would be useful, but 16# WITHOUT ANY WARRANTY; without even the implied warranty of 17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 18# 19# Further, this software is distributed without any warranty that it is 20# free of the rightful claim of any third person regarding infringement 21# or the like. Any license provided herein, whether implied or 22# otherwise, applies only to this software file. Patent licenses, if 23# any, provided herein do not apply to combinations of this program with 24# other software, or any other product whatsoever. 25# 26# You should have received a copy of the GNU General Public License 27# along with this program; if not, write the Free Software Foundation, 28# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. 29# 30 31SWITCH_ON="1" 32SWITCH_OFF="2" 33SWITCH_RESET="3" 34 35DEFAULT_NAMES_OID=".1.3.6.1.4.1.318.1.1.12.3.3.1.1.2" 36DEFAULT_COMMAND_OID=".1.3.6.1.4.1.318.1.1.12.3.3.1.1.4" 37 38if [ -z "$oid" ]; then 39 oid=$DEFAULT_COMMAND_OID 40fi 41 42if [ -z "$names_oid" ]; then 43 names_oid=$DEFAULT_NAMES_OID 44fi 45 46if [ -z "$outlet_config" ]; then 47 outlet_config="none" 48fi 49 50GetOutletNumber() { 51 local nodename=$1 52 53 if [ "$outlet_config" != "none" ]; then 54 # Get outlet number from file 55 56 if [ -f "$outlet_config" ]; then 57 local outlet_num=`grep $nodename $outlet_config | tr -d ' ' | cut -f2 -d'='` 58 if [ -z "$outlet_num" ]; then 59 ha_log.sh err "Outlet number not found for node $nodename. Check configuration file $outlet_config" 60 return 0 61 fi 62 return $outlet_num 63 else 64 ha_log.sh err "File $outlet_config not found." 65 return 0 66 fi 67 else 68 # Get outlet number from device 69 70 local outlet_num=1 71 local snmp_result 72 snmp_result=`snmpwalk -v1 -c $community $pduip $names_oid 2>&1` 73 if [ $? -ne 0 ]; then 74 ha_log.sh err "snmpwalk $community $pduip $names_oid failed. Result: $snmp_result" 75 return 0 76 fi 77 78 local names 79 names=`echo "$snmp_result" | cut -f2 -d'"' | tr ' ' '_' | tr '\012' ' '` 80 for name in $names; do 81 if [ "$name" != "$nodename" ]; then 82 local outlet_num=`expr $outlet_num + 1` 83 continue 84 fi 85 86 return $outlet_num 87 done 88 89 ha_log.sh err "Outlet number not found for node $nodename. Result: $snmp_result" 90 return 0 91 fi 92} 93 94SendCommand() { 95 96 local host=$1 97 local command=$2 98 99 GetOutletNumber $host 100 local outlet=$? 101 102 if [ $outlet -gt 0 ]; then 103 local set_result 104 set_result=`snmpset -v1 -c $community $pduip $oid.$outlet i $command 2>&1` 105 if [ $? -ne 0 ]; then 106 ha_log.sh err "Write SNMP to $pduip value $oid.$outlet=$command failed. Result: $set_result" 107 return 1 108 fi 109 if echo "$set_result" | grep -qs "Timeout"; then 110 ha_log.sh err "Write SNMP to $pduip value $oid.$outlet=$command timed out. Result: $set_result" 111 return 1 112 fi 113 return 0 114 else 115 return 1 116 fi 117} 118 119hostlist=`echo $hostlist | tr ',' ' '` 120incommand=$1 121innode=$2 122 123case $incommand in 124gethosts) 125 if [ "$hostlist" = "AUTO" ]; then 126 snmp_result=`snmpwalk -v1 -c $community $pduip $names_oid 2>&1` 127 if [ $? -ne 0 ]; then 128 ha_log.sh err "snmpwalk $community $pduip $names_oid failed. Result: $snmp_result" 129 exit 1 130 fi 131 if echo "$snmp_result" | grep -qs "Timeout"; then 132 ha_log.sh err "snmpwalk $community $pduip $names_oid timed out. Result: $snmp_result" 133 exit 1 134 else 135 hostlist=`echo "$snmp_result" | cut -f2 -d'"' | tr ' ' '_' | tr '\012' ' '` 136 fi 137 fi 138 139 for h in $hostlist ; do 140 echo $h 141 done 142 143 exit 0 144 ;; 145on) 146 if 147 SendCommand $innode $SWITCH_ON 148 then 149 exit 0 150 else 151 exit 1 152 fi 153 ;; 154off) 155 if 156 SendCommand $innode $SWITCH_OFF 157 then 158 exit 0 159 else 160 exit 1 161 fi 162 ;; 163reset) 164 if 165 SendCommand $innode $SWITCH_RESET 166 then 167 exit 0 168 else 169 exit 1 170 fi 171 ;; 172status) 173 if [ -z "$pduip" ]; then 174 exit 1 175 fi 176 177 if ping -w1 -c1 $pduip >/dev/null 2>&1; then 178 exit 0 179 else 180 exit 1 181 fi 182 ;; 183getconfignames) 184 echo "hostlist pduip community" 185 exit 0 186 ;; 187getinfo-devid) 188 echo "rackpdu STONITH device" 189 exit 0 190 ;; 191getinfo-devname) 192 echo "rackpdu STONITH external device" 193 exit 0 194 ;; 195getinfo-devdescr) 196 echo "APC Switched Rack PDU" 197 exit 0 198 ;; 199getinfo-devurl) 200 echo "http://www.apcc.com/products/family/index.cfm?id=30" 201 exit 0 202 ;; 203getinfo-xml) 204 cat << PDUXML 205<parameters> 206 <parameter name="hostlist" unique="1" required="1"> 207 <content type="string" default="AUTO" /> 208 <shortdesc lang="en">Hostlist</shortdesc> 209 <longdesc lang="en"> 210The list of hosts that the STONITH device controls (comma or space separated). 211If you set value of this parameter to AUTO, list of hosts will be get from Rack PDU device. 212 </longdesc> 213 </parameter> 214 215 <parameter name="pduip" unique="1" required="1"> 216 <content type="string" /> 217 <shortdesc lang="en">Name or IP address of Rack PDU device.</shortdesc> 218 <longdesc lang="en">Name or IP address of Rack PDU device.</longdesc> 219 </parameter> 220 221 <parameter name="community" unique="1" required="1"> 222 <content type="string" default="private" /> 223 <shortdesc lang="en">Name of write community.</shortdesc> 224 <longdesc lang="en">Name of write community.</longdesc> 225 </parameter> 226 227 <parameter name="oid" unique="1" required="0"> 228 <content type="string" /> 229 <shortdesc lang="en"> 230 The OID without the outlet number. 231 </shortdesc> 232 <longdesc lang="en"> 233The SNMP OID for the PDU. minus the outlet number. 234Try .1.3.6.1.4.1.318.1.1.12.3.3.1.1.4 (default value) 235or use mib from ftp://ftp.apcc.com/apc/public/software/pnetmib/mib/ 236Varies on different APC hardware and firmware. 237Warning! No dot at the end of OID 238 </longdesc> 239 </parameter> 240 241 <parameter name="names_oid" unique="1" required="0"> 242 <content type="string" /> 243 <shortdesc lang="en">The OID for getting names of outlets.</shortdesc> 244 <longdesc lang="en"> 245The SNMP OID for getting names of outlets. 246It is required to recognize outlet number by nodename. 247Try ".1.3.6.1.4.1.318.1.1.12.3.3.1.1.2" (default value) 248or use mib from ftp://ftp.apcc.com/apc/public/software/pnetmib/mib/ 249Names of nodes must be equal names of outlets, in other way use outlet_config parameter. 250If you set 'names_oid' parameter then parameter outlet_config must not be use. 251Varies on different APC hardware and firmware. 252Warning! No dot at the end of OID 253 </longdesc> 254 </parameter> 255 256 <parameter name="outlet_config" unique="1" required="0"> 257 <content type="string" /> 258 <shortdesc lang="en">Configuration file. Other way to recognize outlet number by nodename.</shortdesc> 259 <longdesc lang="en"> 260Configuration file. Other way to recognize outlet number by nodename. 261Configuration file which contains 262node_name=outlet_number 263strings. 264 265Example: 266server1=1 267server2=2 268 269If you use outlet_config parameter then names_oid parameter can have any value and it is not uses. 270 </longdesc> 271 </parameter> 272 273</parameters> 274PDUXML 275 exit 0 276 ;; 277*) 278 exit 1 279 ;; 280esac 281