diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py index 79cf7e9..471e7e2 100644 --- a/fence/agents/lib/fencing.py.py +++ b/fence/agents/lib/fencing.py.py @@ -70,6 +70,14 @@ all_opt = { "longopt" : "action", "help" : "-o, --action=<action> Action: status, reboot (default), off or on", "order" : 1 }, + "io_fencing" : { + "getopt" : "o:", + "longopt" : "action", + "help" : "-o, --action=<action> Action: status, enable or disable", + "required" : "1", + "shortdesc" : "Fencing Action", + "default" : "disable", + "order" : 1 }, "ipaddr" : { "getopt" : "a:", "longopt" : "ip", @@ -130,6 +138,11 @@ all_opt = { "longopt" : "ribcl-version", "help" : "-r, --ribcl-version=<version> Force ribcl version to use", "order" : 1 }, + "login_eol_lf" : { + "getopt" : "", + "help" : "", + "order" : 1 + }, "cmd_prompt" : { "getopt" : "c:", "longopt" : "command-prompt", @@ -369,6 +382,8 @@ def process_input(avail_opt): name = "ipaddr" elif name == "modulename": name = "module_name" + elif name == "action" and 1 == avail_opt.count("io_fencing"): + name = "io_fencing" ## ###### @@ -404,15 +419,20 @@ def check_input(device_opt, opt): else: options["log"] = LOG_MODE_QUIET - if 0 == options.has_key("-o"): - options["-o"] = "reboot" - # Convert action to lowercase options["-o"]=options["-o"].lower() - if 0 == ["on", "off", "reboot", "status", "list", "monitor"].count(options["-o"].lower()): - fail_usage("Failed: Unrecognised action '" + options["-o"] + "'") - + if 0 == device_opt.count("io_fencing"): + if 0 == options.has_key("-o"): + options["-o"] = "reboot" + if 0 == ["on", "off", "reboot", "status", "list", "monitor"].count(options["-o"].lower()): + fail_usage("Failed: Unrecognised action '" + options["-o"] + "'") + else: + if 0 == options.has_key("-o"): + options["-o"] = "disable" + if 0 == ["enable", "disable", "status", "list", "monitor"].count(options["-o"].lower()): + fail_usage("Failed: Unrecognised action '" + options["-o"] + "'") + if (0 == options.has_key("-l")) and device_opt.count("login") and (device_opt.count("no_login") == 0): fail_usage("Failed: You have to set login name") @@ -511,6 +531,12 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None if status != "on" and status != "off": fail(EC_STATUS) + + if options["-o"] == "enable": + options["-o"] = "on" + if options["-o"] == "disable": + options["-o"] = "off" + if options["-o"] == "on": if status == "on": print "Success: Already ON" @@ -554,6 +580,11 @@ def fence_login(options): if (options.has_key("-4")): force_ipvx="-4 " + if (options["device_opt"].count("login_eol_lf")): + login_eol = "\n" + else: + login_eol = "\r\n" + try: re_login = re.compile("(login: )|(Login Name: )|(username: )|(User Name :)", re.IGNORECASE) re_pass = re.compile("password", re.IGNORECASE) @@ -593,9 +624,9 @@ def fence_login(options): conn.send("set binary\n") conn.send("open %s -%s\n"%(options["-a"], options["-u"])) conn.log_expect(options, re_login, LOGIN_TIMEOUT) - conn.send(options["-l"]+"\r\n") + conn.send(options["-l"] + login_eol) conn.log_expect(options, re_pass, SHELL_TIMEOUT) - conn.send(options["-p"]+"\r\n") + conn.send(options["-p"] + login_eol) conn.log_expect(options, options["-c"], SHELL_TIMEOUT) except pexpect.EOF: fail(EC_LOGIN_DENIED) diff --git a/fence/agents/sanbox2/Makefile b/fence/agents/sanbox2/Makefile index 31b4677..9428344 100644 --- a/fence/agents/sanbox2/Makefile +++ b/fence/agents/sanbox2/Makefile @@ -11,7 +11,7 @@ ############################################################################### ############################################################################### -SOURCE= fence_sanbox2.pl +SOURCE= fence_sanbox2.py TARGET= fence_sanbox2 top_srcdir=../.. diff --git a/fence/agents/sanbox2/fence_sanbox2.pl b/fence/agents/sanbox2/fence_sanbox2.pl deleted file mode 100644 index b93f8da..0000000 --- a/fence/agents/sanbox2/fence_sanbox2.pl +++ /dev/null @@ -1,263 +0,0 @@ -#!/usr/bin/perl - -############################################################################### -############################################################################### -## -## Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. -## Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved. -## -## This copyrighted material is made available to anyone wishing to use, -## modify, copy, or redistribute it subject to the terms and conditions -## of the GNU General Public License v.2. -## -############################################################################### -############################################################################### - -use Getopt::Std; -use Net::Telnet (); - -my $ME = $0; - -END { - defined fileno STDOUT or return; - close STDOUT and return; - warn "$ME: failed to close standard output: $!\n"; - $? ||= 1; -} - -# Get the program name from $0 and strip directory names -$_=$0; -s/.*\///; -my $pname = $_; - -$opt_o = 'disable'; # Default fence action - -# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and -# "#END_VERSION_GENERATION" It is generated by the Makefile - -#BEGIN_VERSION_GENERATION -$FENCE_RELEASE_NAME=""; -$REDHAT_COPYRIGHT=""; -$BUILD_DATE=""; -#END_VERSION_GENERATION - - -sub usage -{ - print "Usage:\n"; - print "\n"; - print "$pname [options]\n"; - print "\n"; - print "Options:\n"; - print " -a <ip> IP address or hostname of switch\n"; - print " -h usage\n"; - print " -l <name> Login name\n"; - print " -n <num> Port number to disable\n"; - print " -o <string> Action: disable (default) or enable\n"; - print " -p <string> Password for login\n"; - print " -S <path> Script to run to retrieve login password\n"; - print " -q quiet mode\n"; - print " -V version\n"; - - exit 0; -} - -sub fail -{ - ($msg) = @_; - print $msg."\n" unless defined $opt_q; - $t->close if defined $t; - exit 1; -} - -sub fail_usage -{ - ($msg)=@_; - print STDERR $msg."\n" if $msg; - print STDERR "Please use '-h' for usage.\n"; - exit 1; -} - -sub version -{ - print "$pname $FENCE_RELEASE_NAME $BUILD_DATE\n"; - print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT ); - - exit 0; -} - - -if (@ARGV > 0) { - getopts("a:hl:n:o:p:S:qV") || fail_usage ; - - usage if defined $opt_h; - version if defined $opt_V; - - fail_usage "Unknown parameter." if (@ARGV > 0); - - fail_usage "No '-a' flag specified." unless defined $opt_a; - fail_usage "No '-n' flag specified." unless defined $opt_n; - fail_usage "No '-l' flag specified." unless defined $opt_l; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail_usage "No '-p' or '-S' flag specified." unless defined $opt_p; - fail_usage "Unrecognised action '$opt_o' for '-o' flag" - unless $opt_o =~ /^(disable|enable)$/i; - -} else { - get_options_stdin(); - - fail "failed: no IP address" unless defined $opt_a; - fail "failed: no plug number" unless defined $opt_n; - fail "failed: no login name" unless defined $opt_l; - - if (defined $opt_S) { - $pwd_script_out = `$opt_S`; - chomp($pwd_script_out); - if ($pwd_script_out) { - $opt_p = $pwd_script_out; - } - } - - fail "failed: no password" unless defined $opt_p; - fail "failed: unrecognised action: $opt_o" - unless $opt_o =~ /^(disable|enable)$/i; -} - - if ( $opt_o =~ /^disable$/i ) -{ - $command = "set port $opt_n state offline"; -} -elsif ( $opt_o =~ /^enable$/i ) -{ - $command = "set port $opt_n state online"; -} - -# -# Set up and log in -# - -$t = new Net::Telnet; - -$t->open($opt_a); - -$t->waitfor('/login:/'); - -$t->print($opt_l); - -$t->waitfor('/assword:/'); - -$t->print($opt_p); - -$t->waitfor('/\>/'); - -# -# Go to admin mode and check if we're really in it -# -$t->print ("admin start"); -($text, $match) = $t->waitfor('/\>/'); -if ($text =~ /Switch is already in Admin Mode/i) { - fail "failed: parallel telnet session\n"; -}; - -# -# Do the command -# -$t->print($command); -print "$command \n"; - -# -# Assume here that the word "error" will appear after errors (bad assumption! see next check) -# - -($text, $match) = $t->waitfor('/\>/'); - -# -# Do a portshow on the port and look for the DISABLED string to verify success -# - -$t->print("show port $opt_n"); -($text, $match) = $t->waitfor('/\>/'); - -if (!((($opt_o =~ /disable/i) && ($text =~ /AdminState\ *Offline/i)) || - (($opt_o =~ /enable/i) && ($text =~ /AdminState\ *Online/i)))) -{ - # Get out of admin mode before failing - $t->print("admin end"); - $t->waitfor('/\>/'); - fail "failed: could not change state to $opt_o\n"; -} - - -print "success: $opt_o $opt_n\n" unless defined $opt_q; -$t->print("admin end"); -$t->waitfor('/\>/'); -$t->print("quit"); - -exit 0; - -sub get_options_stdin -{ - my $opt; - my $line = 0; - while( defined($in = <>) ) - { - $_ = $in; - chomp; - - # strip leading and trailing whitespace - s/^\s*//; - s/\s*$//; - - # skip comments - next if /^#/; - - $line+=1; - $opt=$_; - next unless $opt; - - ($name,$val)=split /\s*=\s*/, $opt; - - if ( $name eq "" ) - { - print STDERR "parse error: illegal name in option $line\n"; - exit 2; - } - - # DO NOTHING -- this field is used by fenced - elsif ($name eq "agent" ) { } - - elsif ($name eq "ipaddr" ) - { - $opt_a = $val; - } - elsif ($name eq "login" ) - { - $opt_l = $val; - } - - elsif ($name eq "option" ) - { - $opt_o = $val; - } - elsif ($name eq "passwd" ) - { - $opt_p = $val; - } - elsif ($name eq "passwd_script" ) - { - $opt_S = $val; - } - elsif ($name eq "port" ) - { - $opt_n = $val; - } - } -} diff --git a/fence/agents/sanbox2/fence_sanbox2.py b/fence/agents/sanbox2/fence_sanbox2.py new file mode 100644 index 0000000..54122a5 --- /dev/null +++ b/fence/agents/sanbox2/fence_sanbox2.py @@ -0,0 +1,154 @@ +#!/usr/bin/python + +##### +## +## The Following Agent Has Been Tested On: +## +## Version Firmware +## +-----------------+---------------------------+ +##### + +import sys, re, pexpect +sys.path.append("@FENCEAGENTSLIBDIR@") +from fencing import * + +#BEGIN_VERSION_GENERATION +RELEASE_VERSION="New Sanbox2 Agent - test release on steroids" +REDHAT_COPYRIGHT="" +BUILD_DATE="March, 2008" +#END_VERSION_GENERATION + +def get_power_status(conn, options): + status_trans = { + 'online' : "on", + 'offline' : "off" + } + try: + conn.send("show port " + options["-n"] + "\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + try: + conn.send("admin end\n") + conn.send("exit\n") + conn.close() + except: + pass + fail(EC_TIMED_OUT) + + status = re.compile(".*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["-o"]] + + try: + conn.send("set port " + options["-n"] + " state " + action + "\n") + conn.log_expect(options, options["-c"], POWER_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + try: + conn.send("admin end\n") + conn.send("exit\n") + conn.close() + except: + pass + fail(EC_TIMED_OUT) + + try: + conn.send("set port " + options["-n"] + " state " + action + "\n") + conn.log_expect(options, options["-c"], POWER_TIMEOUT) + except pexpect.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + try: + conn.send("admin end\n") + conn.send("exit\n") + conn.close() + except: + pass + fail(EC_TIMED_OUT) + +def get_list_devices(conn, options): + outlets = { } + + try: + conn.send("show port" + "\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + + list_re = re.compile("^\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.EOF: + fail(EC_CONNECTION_LOST) + except pexpect.TIMEOUT: + try: + conn.send("admin end\n") + conn.send("exit\n") + conn.close() + except: + pass + fail(EC_TIMED_OUT) + + return outlets + +def main(): + device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug", + "io_fencing", "ipaddr", "login", "passwd", "passwd_script", + "cmd_prompt", "port", "ipport", "login_eol_lf", "separator" ] + + atexit.register(atexit_handler) + + options = check_input(device_opt, process_input(device_opt)) + + ## + ## Fence agent specific defaults + ##### + if 0 == options.has_key("-c"): + options["-c"] = [ " #> " ] + + ## + ## Operate the fencing device + ## + conn = fence_login(options) + + conn.send("admin start\n") + conn.log_expect(options, options["-c"], SHELL_TIMEOUT) + + if (re.search("\(admin\)", conn.before, re.MULTILINE) == None): + ## Someone else is in admin section, we can't enable/disable + ## ports so we will rather exit + sys.stderr.write("Failed: Unable to switch to admin section\n") + sys.exit(EC_GENERIC_ERROR) + + fence_action(conn, options, set_power_status, get_power_status, get_list_devices) + + ## + ## Logout from system + ###### + try: + conn.send("admin end\n") + conn.send("exit\n") + conn.close() + except exceptions.OSError: + pass + except pexpect.ExceptionPexpect: + pass + +if __name__ == "__main__": + main()