summaryrefslogtreecommitdiffstats
path: root/agents/sanbox2/fence_sanbox2.py
diff options
context:
space:
mode:
Diffstat (limited to 'agents/sanbox2/fence_sanbox2.py')
-rw-r--r--agents/sanbox2/fence_sanbox2.py155
1 files changed, 155 insertions, 0 deletions
diff --git a/agents/sanbox2/fence_sanbox2.py b/agents/sanbox2/fence_sanbox2.py
new file mode 100644
index 0000000..179fe0e
--- /dev/null
+++ b/agents/sanbox2/fence_sanbox2.py
@@ -0,0 +1,155 @@
+#!@PYTHON@ -tt
+
+#####
+##
+## The Following Agent Has Been Tested On:
+##
+## Version Firmware
+## +-----------------+---------------------------+
+#####
+
+import sys, re, pexpect
+import logging
+import atexit
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+from fencing import fail, EC_TIMED_OUT, EC_GENERIC_ERROR
+
+def get_power_status(conn, options):
+ status_trans = {
+ 'online' : "on",
+ 'offline' : "off"
+ }
+ try:
+ conn.send_eol("show port " + options["--plug"])
+ conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+ except pexpect.TIMEOUT:
+ try:
+ conn.send_eol("admin end")
+ conn.send_eol("exit")
+ conn.close()
+ except Exception as e:
+ logging.error("Failed: {}".format(str(e)))
+ pass
+ fail(EC_TIMED_OUT)
+
+ status = re.compile(r".*AdminState\s+(online|offline)\s+",
+ re.IGNORECASE | re.MULTILINE).search(conn.before).group(1)
+
+ try:
+ return status_trans[status.lower().strip()]
+ except KeyError:
+ return "PROBLEM"
+
+def set_power_status(conn, options):
+ action = {
+ 'on' : "online",
+ 'off' : "offline"
+ }[options["--action"]]
+
+ try:
+ conn.send_eol("set port " + options["--plug"] + " state " + action)
+ conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
+ except pexpect.TIMEOUT:
+ try:
+ conn.send_eol("admin end")
+ conn.send_eol("exit")
+ conn.close()
+ except Exception as e:
+ logging.error("Failed: {}".format(str(e)))
+ pass
+ fail(EC_TIMED_OUT)
+
+ try:
+ conn.send_eol("set port " + options["--plug"] + " state " + action)
+ conn.log_expect(options["--command-prompt"], int(options["--power-timeout"]))
+ except pexpect.TIMEOUT:
+ try:
+ conn.send_eol("admin end")
+ conn.send_eol("exit")
+ conn.close()
+ except Exception as e:
+ logging.error("Failed: {}".format(str(e)))
+ pass
+ fail(EC_TIMED_OUT)
+
+def get_list_devices(conn, options):
+ outlets = {}
+
+ try:
+ conn.send_eol("show port")
+ conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+
+ list_re = re.compile(r"^\s+(\d+?)\s+(Online|Offline)\s+", re.IGNORECASE)
+ for line in conn.before.splitlines():
+ if list_re.search(line):
+ status = {
+ 'online' : "ON",
+ 'offline' : "OFF"
+ }[list_re.search(line).group(2).lower()]
+ outlets[list_re.search(line).group(1)] = ("", status)
+
+ except pexpect.TIMEOUT:
+ try:
+ conn.send_eol("admin end")
+ conn.send_eol("exit")
+ conn.close()
+ except Exception as e:
+ logging.error("Failed: {}".format(str(e)))
+ pass
+ fail(EC_TIMED_OUT)
+
+ return outlets
+
+def main():
+ device_opt = ["fabric_fencing", "ipaddr", "login", "passwd", "cmd_prompt", \
+ "port", "telnet"]
+
+ atexit.register(atexit_handler)
+
+ all_opt["cmd_prompt"]["default"] = [" #> "]
+
+ options = check_input(device_opt, process_input(device_opt))
+
+ docs = {}
+ docs["shortdesc"] = "Fence agent for QLogic SANBox2 FC switches"
+ docs["longdesc"] = "fence_sanbox2 is an I/O Fencing agent which can be used with \
+QLogic SANBox2 FC switches. It logs into a SANBox2 switch via telnet and disables a specified \
+port. Disabling the port which a machine is connected to effectively fences that machine. \
+Lengthy telnet connections to the switch should be avoided while a GFS cluster is running \
+because the connection will block any necessary fencing actions."
+ docs["vendorurl"] = "http://www.qlogic.com"
+ show_docs(options, docs)
+
+ ##
+ ## Operate the fencing device
+ ##
+ conn = fence_login(options)
+
+ conn.send_eol("admin start")
+ conn.log_expect(options["--command-prompt"], int(options["--shell-timeout"]))
+
+ if re.search(r"\(admin\)", conn.before, re.MULTILINE) == None:
+ ## Someone else is in admin section, we can't enable/disable
+ ## ports so we will rather exit
+ logging.error("Failed: Unable to switch to admin section\n")
+ sys.exit(EC_GENERIC_ERROR)
+
+ result = fence_action(conn, options, set_power_status, get_power_status, get_list_devices)
+
+ ##
+ ## Logout from system
+ ######
+ try:
+ conn.send_eol("admin end")
+ conn.send_eol("exit\n")
+ conn.close()
+ except OSError:
+ pass
+ except pexpect.ExceptionPexpect:
+ pass
+
+ sys.exit(result)
+
+if __name__ == "__main__":
+ main()