3 #############################################################################
4 #############################################################################
6 ## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved.
7 ## Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved.
9 ## This copyrighted material is made available to anyone wishing to use,
10 ## modify, copy, or redistribute it subject to the terms and conditions
11 ## of the GNU General Public License v.2.
13 #############################################################################
14 ## This APC Fence script uses snmp to control the APC power
15 ## switch. This script requires that net-snmp-utils be installed
16 ## on all nodes in the cluster, and that the powernet369.mib file be
17 ## located in /usr/share/snmp/mibs/
18 #############################################################################
19 #############################################################################
30 #BEGIN_VERSION_GENERATION
34 #END_VERSION_GENERATION
38 POWER_REBOOT
="outletReboot"
44 print " -a <ip> IP address or hostname of MasterSwitch";
46 print " -l <name> Login name";
47 print " -n <num> Outlet number to change";
48 print " -o <string> Action: Reboot (default), Off or On";
49 print " -p <string> Login password";
50 print " -q quiet mode";
52 print " -v Log to file /tmp/apclog";
60 apc_base
= "enterprises.apc.products.hardware."
61 apc_outletctl
= "masterswitch.sPDUOutletControl.sPDUOutletControlTable.sPDUOutletControlEntry.sPDUOutletCtl."
62 apc_outletstatus
= "masterswitch.sPDUOutletStatus.sPDUOutletStatusMSPTable.sPDUOutletStatusMSPEntry.sPDUOutletStatusMSP."
67 action
= "outletReboot"
71 if not glob('/usr/share/snmp/mibs/powernet*.mib'):
72 sys
.stderr
.write('This APC Fence script uses snmp to control the APC power switch. This script requires that net-snmp-utils be installed on all nodes in the cluster, and that the powernet369.mib file be located in /usr/share/snmp/mibs/\n')
77 opts
, args
= getopt
.getopt(sys
.argv
[1:], "a:hl:p:n:o:vV", ["help", "output="])
78 except getopt
.GetoptError
:
79 #print help info and quit
87 print "%s\n" % FENCE_RELEASE_NAME
88 print "%s\n" % REDHAT_COPYRIGHT
89 print "%s\n" % BUILD_DATE
91 if o
in ("-h", "--help"):
97 lcase
= a
.lower() #Lower case string
102 elif lcase
== "reboot":
103 action
= "outletReboot"
104 elif lcase
== "status":
105 #action = "sPDUOutletStatusMSPOutletState"
122 else: #Get opts from stdin
124 #place params in dict
125 for line
in sys
.stdin
:
126 val
= line
.split("=")
128 params
[val
[0].strip()] = val
[1].strip()
131 address
= params
["ipaddr"]
133 sys
.stderr
.write("FENCE: Missing ipaddr param for fence_apc...exiting")
136 login
= params
["login"]
138 sys
.stderr
.write("FENCE: Missing login param for fence_apc...exiting")
142 passwd
= params
["passwd"]
144 sys
.stderr
.write("FENCE: Missing passwd param for fence_apc...exiting")
148 port
= params
["port"]
150 sys
.stderr
.write("FENCE: Missing port param for fence_apc...exiting")
156 if a
== "Off" or a
== "OFF" or a
== "off":
158 elif a
== "On" or a
== "ON" or a
== "on":
160 elif a
== "Reboot" or a
== "REBOOT" or a
== "reboot":
161 action
= POWER_REBOOT
163 action
= POWER_REBOOT
165 ####End of stdin section
167 apc_command
= apc_base
+ apc_outletctl
+ port
173 args_status
.append("/usr/bin/snmpget")
174 args_status
.append("-Oqu") #sets printing options
175 args_status
.append("-v")
176 args_status
.append("1")
177 args_status
.append("-c")
178 args_status
.append("private")
179 args_status
.append("-m")
180 args_status
.append("ALL")
181 args_status
.append(address
)
182 args_status
.append(apc_command
)
184 args_off
.append("/usr/bin/snmpset")
185 args_off
.append("-Oqu") #sets printing options
186 args_off
.append("-v")
188 args_off
.append("-c")
189 args_off
.append("private")
190 args_off
.append("-m")
191 args_off
.append("ALL")
192 args_off
.append(address
)
193 args_off
.append(apc_command
)
195 args_off
.append("outletOff")
197 args_on
.append("/usr/bin/snmpset")
198 args_on
.append("-Oqu") #sets printing options
202 args_on
.append("private")
204 args_on
.append("ALL")
205 args_on
.append(address
)
206 args_on
.append(apc_command
)
208 args_on
.append("outletOn")
210 cmdstr_status
= ' '.join(args_status
)
211 cmdstr_off
= ' '.join(args_off
)
212 cmdstr_on
= ' '.join(args_on
)
214 ##This section issues the actual commands. Reboot is split into
215 ##Off, then On to make certain both actions work as planned.
217 ##The status command just dumps the outlet status to stdout.
218 ##The status checks that are made when turning an outlet on or off, though,
219 ##use the execWithCaptureStatus so that the stdout from snmpget can be
220 ##examined and the desired operation confirmed.
224 fd
= open("/tmp/apclog", "w")
225 fd
.write("Attempting the following command: %s\n" % cmdstr_status
)
226 strr
= os
.system(cmdstr_status
)
229 fd
.write("Result: %s\n" % strr
)
233 if action
== POWER_OFF
:
235 fd
= open("/tmp/apclog", "w")
236 fd
.write("Attempting the following command: %s\n" % cmdstr_off
)
237 strr
= os
.system(cmdstr_off
)
239 strr
,code
= execWithCaptureStatus("/usr/bin/snmpget",args_status
)
241 fd
.write("Result: %s\n" % strr
)
243 if strr
.find(POWER_OFF
) >= 0:
244 print "Success. Outlet off"
248 fd
.write("Unable to power off apc outlet")
252 elif action
== POWER_ON
:
254 fd
= open("/tmp/apclog", "w")
255 fd
.write("Attempting the following command: %s\n" % cmdstr_on
)
256 strr
= os
.system(cmdstr_on
)
258 strr
,code
= execWithCaptureStatus("/usr/bin/snmpget",args_status
)
259 #strr = os.system(cmdstr_status)
261 fd
.write("Result: %s\n" % strr
)
262 if strr
.find(POWER_ON
) >= 0:
265 print "Success. Outlet On."
268 print "Unable to power on apc outlet"
270 fd
.write("Unable to power on apc outlet")
274 elif action
== POWER_REBOOT
:
276 fd
= open("/tmp/apclog", "w")
277 fd
.write("Attempting the following command: %s\n" % cmdstr_off
)
278 strr
= os
.system(cmdstr_off
)
280 strr
,code
= execWithCaptureStatus("/usr/bin/snmpget",args_status
)
281 #strr = os.system(cmdstr_status)
283 fd
.write("Result: %s\n" % strr
)
284 if strr
.find(POWER_OFF
) < 0:
285 print "Unable to power off apc outlet"
287 fd
.write("Unable to power off apc outlet")
292 fd
.write("Attempting the following command: %s\n" % cmdstr_on
)
293 strr
= os
.system(cmdstr_on
)
295 strr
,code
= execWithCaptureStatus("/usr/bin/snmpget",args_status
)
296 #strr = os.system(cmdstr_status)
298 fd
.write("Result: %s\n" % strr
)
299 if strr
.find(POWER_ON
) >= 0:
302 print "Success: Outlet Rebooted."
305 print "Unable to power on apc outlet"
307 fd
.write("Unable to power on apc outlet")
311 def execWithCaptureStatus(command
, argv
, searchPath
= 0, root
= '/', stdin
= 0,
312 catchfd
= 1, closefd
= -1):
314 if not os
.access (root
+ command
, os
.X_OK
):
315 raise RuntimeError, command
+ " cannot be run"
317 (read
, write
) = os
.pipe()
321 if (root
and root
!= '/'): os
.chroot (root
)
322 if isinstance(catchfd
, tuple):
326 os
.dup2(write
, catchfd
)
338 os
.execvp(command
, argv
)
340 os
.execv(command
, argv
)
349 select
.select([read
], [], [])
350 s
= os
.read(read
, 1000)
358 (pid
, status
) = os
.waitpid(childpid
, 0)
359 except OSError, (errno
, msg
):
360 print __name__
, "waitpid:", msg
362 if os
.WIFEXITED(status
) and (os
.WEXITSTATUS(status
) == 0):
363 status
= os
.WEXITSTATUS(status
)
369 if __name__
== "__main__":