First commit of lavapdu code
diff --git a/apcdrivers.py b/apcdrivers.py
new file mode 100644
index 0000000..b7e882f
--- /dev/null
+++ b/apcdrivers.py
@@ -0,0 +1,130 @@
+__author__ = 'matt'
+
+from driver import PDUDriver
+
+class apc7952(PDUDriver):
+ def _pdu_logout(self):
+ self._back_to_main()
+ print("Logging out")
+ self.connection.send("4\r")
+
+ def _back_to_main(self):
+ print("Returning to main menu")
+ self.connection.expect('>')
+ for i in range(1,20):
+ #print("Sending escape character")
+ self.connection.send("\x1B")
+ self.connection.send("\r")
+ res = self.connection.expect(["4- Logout","> "])
+ if res == 0:
+ print("Back at main menu")
+ break
+ #self.connection.send("\r")
+ #self.connection.expect("4- Logout")
+ #self.connection.expect("> ")
+
+ def _enter_outlet(self, outlet):
+ self.connection.expect("Press <ENTER> to continue...")
+ self.connection.send("\r")
+ self.connection.expect("> ")
+ self.connection.send(outlet)
+ self.connection.send("\r")
+
+ def _port_interaction(self, command, port_number):
+ print("Attempting command: %s port: %i" % (command, port_number))
+ ### make sure in main menu here
+ self._back_to_main()
+ self.connection.send("\r")
+ self.connection.expect("1- Device Manager")
+ self.connection.expect("> ")
+ self.connection.send("1\r")
+ res = self.connection.expect(["3- Outlet Control/Configuration","2- Outlet Control","2- Outlet Management"])
+ if res == 0:
+ self.connection.send("3\r")
+ self._enter_outlet(port_number)
+ elif res == 1:
+ self.connection.send("2\r")
+ self._enter_outlet(port_number)
+ elif res == 2:
+ self.connection.send("2\r")
+ res = self.connection.expect(["1- Control Outlet", "1- Outlet Control/Configuration"])
+ self.connection.expect("> ")
+ self.connection.send("1\r")
+ res = self.connection.expect(["> ","Press <ENTER> to continue..."])
+ if res == 1:
+ print("Stupid paging thingmy detected, pressing enter")
+ self.connection.send("\r")
+ print("We should now be at the outlet list")
+ self.connection.send("%s\r" % port_number)
+ self.connection.send("1\r")
+ self.connection.expect("3- Immediate Reboot")
+ self.connection.expect("> ")
+ if command == "reboot":
+ self.connection.send("3\r")
+ self.connection.expect("Immediate Reboot")
+ self._do_it()
+ elif command == "delayed":
+ self.connection.send("6\r")
+ self.connection.expect("Delayed Reboot")
+ self._do_it()
+ elif command == "on":
+ self.connection.send("1\r")
+ self.connection.expect("Immediate On")
+ self._do_it()
+ elif command == "off":
+ self.connection.send("2\r")
+ self.connection.expect("Immediate Off")
+ self._do_it()
+ else:
+ print("Unknown command!")
+
+ def _do_it(self):
+ self.connection.expect("Enter 'YES' to continue or <ENTER> to cancel :")
+ self.connection.send("YES\r")
+ self.connection.expect("Press <ENTER> to continue...")
+ self.connection.send("\r")
+
+ def port_delayed(self, port_number):
+ self._port_interaction("delayed", port_number)
+
+ def port_on(self, port_number):
+ self._port_interaction("on", port_number)
+
+ def port_off(self, port_number):
+ self._port_interaction("off", port_number)
+
+ def port_reboot(self, port_number):
+ self._port_interaction("reboot", port_number)
+
+class apc8959(PDUDriver):
+ connection = None
+
+ def _pdu_logout(self):
+ print("logging out")
+ self.connection.send("\r")
+ self.connection.send("exit")
+ self.connection.send("\r")
+ print("done")
+
+ def _pdu_get_to_prompt(self):
+ self.connection.send("\r")
+ self.connection.expect ('apc>')
+
+ def _port_interaction(self, command, port_number):
+ print("Attempting %s on port %i" % (command, port_number))
+ self._pdu_get_to_prompt()
+ self.connection.sendline(self.pdu_commands[command] + (" %i" % port_number))
+ self.connection.expect("E000: Success")
+ print("done")
+
+ def port_delayed(self, port_number):
+ self._port_interaction("delayed", port_number)
+
+ def port_on(self, port_number):
+ self._port_interaction("on", port_number)
+
+ def port_off(self, port_number):
+ self._port_interaction("off", port_number)
+
+ def port_reboot(self, port_number):
+ self._port_interaction("reboot", port_number)
\ No newline at end of file
diff --git a/driver.py b/driver.py
new file mode 100644
index 0000000..ca840be
--- /dev/null
+++ b/driver.py
@@ -0,0 +1,9 @@
+__author__ = 'matt'
+
+class PDUDriver():
+ connection = None
+ pdu_commands = {"off":"olOff","on":"olOn","reboot":"olReboot","delayed":"olDlyReboot"}
+
+ def __init__(self, connection):
+ self.connection = connection
+
diff --git a/engine.py b/engine.py
new file mode 100644
index 0000000..4f18c2e
--- /dev/null
+++ b/engine.py
@@ -0,0 +1,65 @@
+import pexpect
+import sys
+import os
+from apcdrivers import apc8959
+from apcdrivers import apc7952
+
+class PDUEngine():
+ connection = None
+ pdu_commands = {"off":"olOff","on":"olOn","reboot":"olReboot","delayed":"olDlyReboot"}
+ prompt = 0
+ driver = None
+
+ def __init__(self, pdu_hostname, pdu_telnetport = 23):
+ self.connection = pexpect.spawn("/usr/bin/telnet %s %d" % (pdu_hostname, pdu_telnetport))
+ #self.connection.logfile_read = sys.stdout
+ self._pdu_login("apc","apc")
+ if self.prompt == 0:
+ print("Found a v5 prompt")
+ self.driver = apc8959(self.connection)
+ elif self.prompt == 1:
+ print("Found a v3 prompt")
+ self.driver = apc7952(self.connection)
+ else:
+ print("Unknown prompt!")
+
+ def is_busy(self):
+ if os.path.exists("/proc/%i" % self.connection.pid):
+ return True
+ return False
+
+ def close(self):
+ self.driver._pdu_logout()
+ self.connection.close(True)
+
+ def _pdu_login(self, username, password):
+ print("attempting login with username %s, password %s" % (username,password))
+ self.connection.send("\r")
+ self.connection.expect ("User Name :")
+ self.connection.send("apc\r")
+ self.connection.expect("Password :")
+ self.connection.send("apc\r")
+ self.prompt = self.connection.expect(["apc>", ">"])
+ #print("prompt: %s" % self.prompt)
+
+
+if __name__ == "__main__":
+ pe1 = PDUEngine("pdu15")
+ pe1.driver.port_off(22)
+ pe1.driver.port_on(22)
+ pe1.close()
+ pe2 = PDUEngine("pdu14")
+ pe2.driver.port_off(6)
+ pe2.driver.port_on(6)
+ pe2.close()
+ pe3 = PDUEngine("pdu01")
+ pe3.driver.port_reboot(1)
+ pe3.driver.port_off(1)
+ pe3.driver.port_on(1)
+ pe3.close()
+ pe4 = PDUEngine("pdu02")
+ pe4.driver.port_reboot(8)
+ pe4.driver.port_off(8)
+ pe4.driver.port_on(8)
+ pe4.close()
+
diff --git a/pdurunner.py b/pdurunner.py
new file mode 100644
index 0000000..28a9d6e
--- /dev/null
+++ b/pdurunner.py
@@ -0,0 +1,45 @@
+import sqlite3
+import time
+from engine import PDUEngine
+
+
+conn = sqlite3.connect('pdu.db', check_same_thread = False)
+c = conn.cursor()
+
+class PDURunner():
+ def get_one(self):
+ c.execute("SELECT * FROM pdu_queue ORDER BY id asc limit 1")
+ res = c.fetchone()
+ if res:
+ id,hostname,port,request = res
+ print(id, hostname, request, port)
+ res = self.do_job(hostname,port,request)
+ self.delete_row(id)
+
+ def delete_row(self, id):
+ print("deleting row %i" % id)
+ c.execute("delete from pdu_queue where id=%i" % id)
+ conn.commit()
+
+ def do_job(self, hostname, port, request):
+ pe = PDUEngine(hostname, 23)
+ if request == "reboot":
+ pe.driver.port_reboot(port)
+ elif request == "on":
+ pe.driver.port_on(port)
+ elif request == "off":
+ pe.driver.port_off(port)
+ elif request == "delayed":
+ pe.driver.port_delayed(port)
+ else:
+ print("Unknown request type: %s" % request)
+
+ def run_me(self):
+ print("Starting up the PDURunner")
+ while 1:
+ self.get_one()
+ time.sleep(1)
+
+if __name__ == "__main__":
+ p = PDURunner()
+ p.run_me()
\ No newline at end of file
diff --git a/socketserver.py b/socketserver.py
new file mode 100644
index 0000000..bf72fd7
--- /dev/null
+++ b/socketserver.py
@@ -0,0 +1,57 @@
+import SocketServer
+import sqlite3
+import logging
+
+logging.basicConfig(level=logging.DEBUG)
+log = logging.getLogger(__name__)
+conn=sqlite3.connect('pdu.db', check_same_thread = False)
+c=conn.cursor()
+
+class ListenerServer():
+ HOST='0.0.0.0'
+ PORT=16421
+
+ def __init__(self):
+ ### read loglevel here
+ self.server = TCPServer((self.HOST, self.PORT), TCPRequestHandler)
+ log.info("listening on %s:%s" % (self.HOST, self.PORT))
+ self.create_db()
+
+ def create_db(self):
+ sql = "create table if not exists pdu_queue (id integer primary key, hostname text, port int, request text)"
+ log.debug("Creating pdu_queue table: %s" % sql)
+ c.execute(sql)
+ conn.commit()
+
+ def start(self):
+ print("Starting the ListenerServer")
+ self.server.serve_forever()
+
+class TCPRequestHandler(SocketServer.BaseRequestHandler):
+ "One instance per connection. Override handle(self) to customize action."
+ def insert_request(self, data):
+ array = data.split(" ")
+ hostname = array[0]
+ port = int(array[1])
+ request = array[2]
+ sql = "insert into pdu_queue values (NULL,'%s',%i,'%s')" % (hostname,port,request)
+ log.debug("executing sql: %s" % sql)
+ c.execute(sql)
+ conn.commit()
+
+ def handle(self):
+ data = self.request.recv(4096).strip()
+ #write to sql db here
+ log.debug("got request: %s" % data)
+ self.insert_request(data)
+ self.request.sendall("ack\n")
+ self.request.close()
+
+class TCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
+ allow_reuse_address = True
+ daemon_threads = True
+ pass
+
+if __name__ == "__main__":
+ ss = ListenerServer()
+ ss.start()
\ No newline at end of file