HTTP = 3
IPAL = 4
- TELNET_TIMEOUT = 60
+ TELNET_TIMEOUT = 120
def __init__(self, type, verbose):
self.type = type
if self.transport != None:
output = self.transport.read_until(expected, self.TELNET_TIMEOUT)
if output.find(expected) == -1:
+ print "OUTPUT: --%s--" % output
raise ErrorClass, "'%s' not found" % expected
else:
self.transport.write(buffer + "\r\n")
class PCUControl(Transport,PCUModel,PCURecord):
+
+ supported_ports = []
+
def __init__(self, plc_pcu_record, verbose, supported_ports=[]):
PCUModel.__init__(self, plc_pcu_record)
PCURecord.__init__(self, plc_pcu_record)
import traceback
traceback.print_exc()
return "EOF connection reset" + str(err)
-
+
+class IPMI(PCUControl):
+
+ supported_ports = [80,443,623]
+
+ # TODO: get exit codes to determine success or failure...
+ def run(self, node_port, dryrun):
+
+ if not dryrun:
+ cmd = "ipmitool -I lanplus -H %s -U %s -P '%s' power cycle"
+ p = os.popen(cmd % ( self.host, self.username, self.password) )
+ result = p.read()
+ print "RESULT: ", result
+ else:
+ cmd = "ipmitool -I lanplus -H %s -U %s -P '%s' user list"
+ p = os.popen(cmd % ( self.host, self.username, self.password) )
+ result = p.read()
+ print "RESULT: ", result
+
+ if "Error" in result:
+ return result
+ else:
+ return 0
+
class IPAL(PCUControl):
"""
This now uses a proprietary format for communicating with the PCU. I
prefer it to Telnet, and Web access, since it's much lighter weight
and, more importantly, IT WORKS!! HHAHHHAHAHAHAHAHA!
"""
+ supported_ports = [23,80,9100]
def format_msg(self, data, cmd):
esc = chr(int('1b',16))
return ret
def run(self, node_port, dryrun):
+ if self.type == Transport.IPAL:
+ return self.run_ipal(node_port, dryrun)
+ elif self.type == Transport.TELNET:
+ return self.run_telnet(node_port, dryrun)
+ else:
+ raise Exception("Unimplemented Transport for IPAL")
+
+ def run_telnet(self, node_port, dryrun):
+ # TELNET version of protocol...
+ self.open(self.host)
+ ## XXX Some iPals require you to hit Enter a few times first
+ self.ifThenSend("Password >", "\r\n\r\n", ExceptionNotFound)
+ # Login
+ self.ifThenSend("Password >", self.password, ExceptionPassword)
+ self.transport.write("\r\n\r\n")
+ if not dryrun: # P# - Pulse relay
+ print "node_port %s" % node_port
+ self.ifThenSend("Enter >",
+ "P7", # % node_port,
+ ExceptionNotFound)
+ print "send newlines"
+ self.transport.write("\r\n\r\n")
+ print "after new lines"
+ # Get the next prompt
+ print "wait for enter"
+ self.ifElse("Enter >", ExceptionTimeout)
+ print "closing "
+ self.close()
+ return 0
+
+ def run_ipal(self, node_port, dryrun):
import errno
power_on = False
if ret == '':
raise Exception("Status returned 'another session already open' %s : %s" % (node_port, ret))
-
if node_port < len(ret):
status = ret[node_port]
s.close()
return 0
-# TELNET version of protocol...
-# #self.open(self.host)
-# ## XXX Some iPals require you to hit Enter a few times first
-# #self.ifThenSend("Password >", "\r\n\r\n", ExceptionNotFound)
-# # Login
-# self.ifThenSend("Password >", self.password, ExceptionPassword)
-# self.transport.write("\r\n\r\n")
-# if not dryrun: # P# - Pulse relay
-# print "node_port %s" % node_port
-# self.ifThenSend("Enter >",
-# "P7", # % node_port,
-# ExceptionNotFound)
-# print "send newlines"
-# self.transport.write("\r\n\r\n")
-# print "after new lines"
-# # Get the next prompt
-# print "wait for enter"
-# self.ifElse("Enter >", ExceptionTimeout)
-# print "closing "
-# self.close()
-# return 0
class APCEurope(PCUControl):
def run(self, node_port, dryrun):
return 0
class APCMaster(PCUControl):
+ supported_ports = [22,23]
def run(self, node_port, dryrun):
print "Rebooting %s" % self.host
self.open(self.host, self.username)
return ret
class IntelAMT(PCUControl):
+ supported_ports = [16992]
+
def run(self, node_port, dryrun):
cmd = command.CMD()
- #[cmd_str = "IntelAMTSDK/Samples/RemoteControl/remoteControl"
- cmd_str = "cmdamt/remoteControl"
+ # TODO: need to make this path universal; not relative to pwd.
+ cmd_str = "pcucontrol/models/intelamt/remoteControl"
if dryrun:
# NOTE: -p checks the power state of the host.
return 0
class DRAC(PCUControl):
+ supported_ports = [22,443,5869]
def run(self, node_port, dryrun):
self.open(self.host, self.username)
self.sendPassword(self.password)
return 0
class HPiLO(PCUControl):
+ supported_ports = [22,443]
def run(self, node_port, dryrun):
self.open(self.host, self.username)
self.sendPassword(self.password)
class HPiLOHttps(PCUControl):
+ supported_ports = [22,443]
def run(self, node_port, dryrun):
locfg = command.CMD()
return 0
class BayTech(PCUControl):
+ supported_ports = [22,23]
def run(self, node_port, dryrun):
self.open(self.host, self.username)
self.sendPassword(self.password)
return 0
class WTIIPS4(PCUControl):
+ supported_ports = [23]
def run(self, node_port, dryrun):
self.open(self.host)
self.sendPassword(self.password, "Enter Password:")
return 0
class ePowerSwitch(PCUControl):
+ supported_ports = [80]
def run(self, node_port, dryrun):
self.url = "http://%s:%d/" % (self.host,80)
uri = "%s:%d" % (self.host,80)
self.close()
return 0
+class ManualPCU(PCUControl):
+ supported_ports = [22,23,80,443,9100,16992]
+
+ def run(self, node_port, dryrun):
+ if not dryrun:
+ # TODO: send email message to monitor admin requesting manual
+ # intervention. This should always be an option for ridiculous,
+ # custom jobs.
+ pass
+ return 0
### rebooting european BlackBox PSE boxes
# Thierry Parmentelat - May 11 2005
# curl --http1.0 --basic --user <username>:<password> --data P<port>=r \
# http://<hostname>:<http_port>/cmd.html && echo OK
+# log in:
+
+## BB PSMaverick
+class BlackBoxPSMaverick(PCUControl):
+ supported_ports = [80]
+
+ def run(self, node_port, dryrun):
+ if not dryrun:
+ # send reboot signal.
+ cmd = "curl -s --data 'P%s=r' --anyauth --user '%s:%s' http://%s/config/home_f.html" % ( node_port, self.username, self.password, self.host)
+ else:
+ # else, just try to log in
+ cmd = "curl -s --anyauth --user '%s:%s' http://%s/config/home_f.html" % ( self.username, self.password, self.host)
+
+ p = os.popen(cmd)
+ result = p.read()
+ print "RESULT: ", result
+
+ if len(result.split()) > 3:
+ return 0
+ else:
+ return result
+
def bbpse_reboot (pcu_ip,username,password,port_in_pcu,http_port, dryrun):
global verbose
print "return true"
return True
+class Unknown(PCUControl):
+ supported_ports = [22,23,80,443,5869,9100,16992]
+
+def model_to_object(modelname):
+ if "AMT" in modelname:
+ return IntelAMT
+ elif "DS4-RPC" in modelname:
+ return BayTech
+ elif "ilo2" in modelname:
+ return HPiLO
+ elif "IP-41x" in modelname:
+ return IPAL
+ elif "AP79xx" in modelname or "Masterswitch" in modelname:
+ return APCMaster
+ elif "DRAC" in modelname:
+ return DRAC
+ elif "WTI" in modelname:
+ return WTIIPS4
+ elif "ePowerSwitch" in modelname:
+ return ePowerSwitch
+ elif "ipmi" in modelname:
+ return IPMI
+ elif "bbsemaverick" in modelname:
+ return BlackBoxPSMaverick
+ else:
+ return Unknown
+
def reboot_test(nodename, values, continue_probe, verbose, dryrun):
rb_ret = ""
if 'plc_pcu_stats' in values:
apc = APCBrazil(values, verbose, ['22', '23'])
rb_ret = apc.reboot(values[nodename], dryrun)
- elif values['pcu_id'] in [1221,1225,1220]:
+ elif values['pcu_id'] in [1221,1225,1220,1192]:
apc = APCBerlin(values, verbose, ['22', '23'])
rb_ret = apc.reboot(values[nodename], dryrun)
- elif values['pcu_id'] in [1173,1240,47]:
+ elif values['pcu_id'] in [1173,1240,47,1363,1405,1401,1372,1371]:
apc = APCFolsom(values, verbose, ['22', '23'])
rb_ret = apc.reboot(values[nodename], dryrun)
amt = IntelAMT(values, verbose, ['16992'])
rb_ret = amt.reboot(values[nodename], dryrun)
- # BlackBox PSExxx-xx (e.g. PSE505-FR)
+ elif continue_probe and values['model'].find("bbsemaverick") >=0:
+ print "TRYING BlackBoxPSMaverick"
+ bbe = BlackBoxPSMaverick(values, verbose, ['80'])
+ rb_ret = bbe.reboot(values[nodename], dryrun)
+
+ elif continue_probe and values['model'].find("ipmi") >=0:
+
+ print "TRYING IPMI"
+ ipmi = IPMI(values, verbose, ['80', '443', '623'])
+ rb_ret = ipmi.reboot(values[nodename], dryrun)
+
elif continue_probe and values['model'].find("ePowerSwitch") >=0:
# TODO: allow a different port than http 80.
if values['pcu_id'] in [1089, 1071, 1046, 1035, 1118]: