fence-agents: master - fence_ibmblade: Rewrite of agent under Python unified library

Jan Friesse honzaf@fedoraproject.org
Wed Mar 11 12:36:00 GMT 2009


Gitweb:        http://git.fedorahosted.org/git/fence-agents.git?p=fence-agents.git;a=commitdiff;h=f9ced2a62b7d6006471438532be1237bd03cd3ef
Commit:        f9ced2a62b7d6006471438532be1237bd03cd3ef
Parent:        adf955182ce928c67d5479fa5e14920a575881c6
Author:        Jan Friesse <jfriesse@redhat.com>
AuthorDate:    Wed Mar 11 13:36:23 2009 +0100
Committer:     Jan Friesse <jfriesse@redhat.com>
CommitterDate: Wed Mar 11 13:36:23 2009 +0100

fence_ibmblade: Rewrite of agent under Python unified library

Main functionality should be kept and has some new
features, like list, metadata, ...
---
 fence/agents/ibmblade/fence_ibmblade.pl |  273 -------------------------------
 fence/agents/ibmblade/fence_ibmblade.py |   75 +++++++++
 fence/man/fence_ibmblade.8              |  111 ++++++++++---
 3 files changed, 166 insertions(+), 293 deletions(-)

diff --git a/fence/agents/ibmblade/fence_ibmblade.pl b/fence/agents/ibmblade/fence_ibmblade.pl
deleted file mode 100644
index adf7548..0000000
--- a/fence/agents/ibmblade/fence_ibmblade.pl
+++ /dev/null
@@ -1,273 +0,0 @@
-#!/usr/bin/perl
-
-use Getopt::Std;
-use Net::SNMP; 
-
-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 = $_;
-
-my $sleep_time = 5; 
-my $snmp_timeout = 10;
-$opt_o = "reboot";
-$opt_u = 161;
-
-my $oid_powerState =  ".1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.4";    # remoteControlBladePowerState
-my $oid_powerChange = ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7";    # powerOnOffBlade
-my $oid_resetPower =  ".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.8";    # restartBlade
-
-# WARNING!! Do not add code bewteen "#BEGIN_VERSION_GENERATION" and
-# "#END_VERSION_GENERATION"  It is generated by the Makefile
-
-#BEGIN_VERSION_GENERATION
-$RELEASE_VERSION="";
-$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 BladeCenter\n";
-    print "  -h               usage\n";
-    print "  -c <community>   SNMP Community\n";
-    print "  -n <num>         Port number to disable\n";
-    print "  -o <string>      Action:  Reboot (default), On or Off\n";
-    print "  -u <udpport>     UDP port to use (default: 161)\n"; 
-    print "  -q               quiet mode\n";
-    print "  -t               test power state\n"; 
-    print "  -V               version\n";
-
-    exit 0;
-}
-
-sub fail_usage
-{
-  ($msg)=@_;
-  print STDERR $msg."\n" if $msg;
-  print STDERR "Please use '-h' for usage.\n";
-  exit 1;
-}
-
-sub fail
-{
-  ($msg) = @_;
-  print $msg."\n" unless defined $opt_q;
-  $t->close if defined $t;
-  exit 1;
-}
-
-sub version
-{
-  print "$pname $RELEASE_VERSION $BUILD_DATE\n";
-  print "$REDHAT_COPYRIGHT\n" if ( $REDHAT_COPYRIGHT );
-
-  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 "community" ) 
-	{
-            $opt_c = $val;
-        } 
-
-        elsif ($name eq "option" )
-        {
-            $opt_o = $val;
-        }
-	elsif ($name eq "port" ) 
-	{
-            $opt_n = $val;
-        }
-	elsif ($name eq "udpport" )
-	{
-	    $opt_u = $val; 
-	}
-
-        # FIXME should we do more error checking?  
-        # Excess name/vals will be eaten for now
-	else 
-	{
-           fail "parse error: unknown option \"$opt\"";
-        }
-    }
-}
-
-# ---------------------------- MAIN --------------------------------
-
-if (@ARGV > 0) {
-   getopts("a:hc:n:o:qu:tV") || 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 '-c' flag specified." unless defined $opt_c;
-   fail_usage "Unrecognised action '$opt_o' for '-o' flag"
-      unless $opt_o =~ /^(reboot|on|off)$/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 SNMP community" unless defined $opt_c;
-   fail "failed: unrecognised action: $opt_o"
-      unless $opt_o =~ /^(reboot|on|off)$/i;
-}
-
-my ($snmpsess, $error) = Net::SNMP->session ( 
-	-hostname   => $opt_a, 
-	-version    => "snmpv1", 
-	-port       => $opt_u, 
-	-community  => $opt_c,
-	-timeout    => $snmp_timeout); 
-
-if (!defined ($snmpsess)) { 
-	printf("$RELEASE_VERSION ERROR: %s.\n", $error);
-	exit 1; 
-};
-
-# first check in what state are we now
-my $oid = $oid_powerState . "." . $opt_n;
-my $oid_val = ""; 
-my $result = $snmpsess->get_request ( 
-	-varbindlist => [$oid]
-);
-if (!defined($result)) {
-	printf("$RELEASE_VERSION ERROR: %s.\n", $snmpsess->error);
-	$snmpsess->close;
-	exit 1;
-}
-
-if (defined ($opt_t)) { 
-	printf ("$RELEASE_VERSION STATE: Port %d on %s returned %d\n", $opt_n, $opt_a, $result->{$oid}); 
-	exit 1; 
-};
-
-if ($opt_o =~ /^(reboot|off)$/i) { 
-	if ($result->{$oid} == "0") { 
-		printf ("$RELEASE_VERSION WARNING: Port %d on %s already down.\n", $opt_n, $opt_a); 
-		$snmpsess->close; 
-		exit 0; 
-	}; 
-} else { 
-	if ($result->{$oid} == "1") { 
-		printf ("$RELEASE_VERSION WARNING: Port %d on %s already up.\n", $opt_n, $opt_a); 
-		$snmpsess->close; 
-		exit 0; 
-	};
-};
-
-# excellent, now change the state 
-if ($opt_o =~ /^reboot$/i) { 
-	# reboot
-	$oid = $oid_resetPower . "." . $opt_n;
-	$oid_val = "1"; 
-} elsif ($opt_o =~ /^on$/i) { 
-	# power on
-	$oid = $oid_powerChange . "." . $opt_n; 
-	$oid_val = "1"; 
-} else { 
-	# power down
-	$oid = $oid_powerChange . "." . $opt_n; 
-	$oid_val = "0"; 
-};
-
-$result = $snmpsess->set_request (
-	-varbindlist => [$oid, INTEGER, $oid_val]
-); 
-
-if (!defined ($result)) { 
-	# ignore this for now, seems like IBM BladeCenter has a broken SNMPd
-	# it almost always timeouts
-}; 
-
-# now, wait a bit and see if we have done it
-sleep($sleep_time); 
-
-$oid = $oid_powerState . "." . $opt_n;
-
-undef $result; 
-$result = $snmpsess->get_request ( 
-	-varbindlist => [$oid]
-);
-
-if (!defined($result)) {
-	# this is a real error
-	printf("$RELEASE_VERSION ERROR: %s.\n", $snmpsess->error);
-	$snmpsess->close;
-	exit 1;
-}; 
-
-if ($opt_o =~ /^(off)$/i) { 
-	if ($result->{$oid} == "1") { 
-		printf ("$RELEASE_VERSION ERROR: Port %d on %s still up.\n", $opt_n, $opt_a); 
-		$snmpsess->close; 
-		exit 1; 
-	}; 
-} else { 
-	if ($result->{$oid} == "0") { 
-		printf ("$RELEASE_VERSION ERROR: Port %d on %s still down.\n", $opt_n, $opt_a); 
-		$snmpsess->close; 
-		exit 1; 
-	};
-};
-
-# everything's a ok :) 
-$snmpsess->close; 
-
-printf ("$RELEASE_VERSION SUCCESS: Port %d on %s changed state to %s\n", $opt_n, $opt_a, $opt_o) unless defined $opt_q;
-exit 0; 
-
diff --git a/fence/agents/ibmblade/fence_ibmblade.py b/fence/agents/ibmblade/fence_ibmblade.py
new file mode 100644
index 0000000..3c9ecf1
--- /dev/null
+++ b/fence/agents/ibmblade/fence_ibmblade.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+
+import sys, re, pexpect
+from fencing import *
+from fencing_snmp import *
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION="IBM Blade SNMP fence agent"
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+### CONSTANTS ###
+# From fence_ibmblade.pl
+STATUSES_OID=".1.3.6.1.4.1.2.3.51.2.22.1.5.1.1.4" # remoteControlBladePowerState
+CONTROL_OID=".1.3.6.1.4.1.2.3.51.2.22.1.6.1.1.7" # powerOnOffBlade
+
+# Status constants returned as value from SNMP
+STATUS_DOWN=0
+STATUS_UP=1
+
+# Status constants to set as value to SNMP
+STATUS_SET_OFF=0
+STATUS_SET_ON=1
+
+### FUNCTIONS ###
+
+def get_power_status(conn,options):
+	(oid,status)=conn.get("%s.%s"%(STATUSES_OID,options["-n"]))
+	return (status==str(STATUS_UP) and "on" or "off")
+
+def set_power_status(conn, options):
+	conn.set("%s.%s"%(CONTROL_OID,options["-n"]),(options["-o"]=="on" and STATUS_SET_ON or STATUS_SET_OFF))
+
+def get_outlets_status(conn, options):
+	result={}
+
+	res_blades=conn.walk(STATUSES_OID,30)
+
+	for x in res_blades:
+		port_num=x[0].split('.')[-1]
+
+		port_alias=""
+		port_status=(x[1]==str(STATUS_UP) and "on" or "off")
+
+		result[port_num]=(port_alias,port_status)
+
+	return result
+
+# Define new options
+def ibmblade_define_defaults():
+	all_opt["snmp_version"]["default"]="1"
+
+# Main agent method
+def main():
+	global port_oid
+
+	device_opt = [ "help", "version", "agent", "quiet", "verbose", "debug",
+		       "action", "ipaddr", "login", "passwd", "passwd_script",
+		       "test", "port", "separator", "no_login", "no_password",
+		       "snmp_version", "community", "snmp_auth_prot", "snmp_sec_level",
+		       "snmp_priv_prot", "snmp_priv_passwd", "snmp_priv_passwd_script",
+		       "udpport"]
+
+	atexit.register(atexit_handler)
+
+	ibmblade_define_defaults()
+
+	options=check_input(device_opt,process_input(device_opt))
+
+	# Operate the fencing device
+	fence_action(FencingSnmp(options), options, set_power_status, get_power_status, get_outlets_status)
+
+if __name__ == "__main__":
+	main()
diff --git a/fence/man/fence_ibmblade.8 b/fence/man/fence_ibmblade.8
index ba364c6..fb573af 100644
--- a/fence/man/fence_ibmblade.8
+++ b/fence/man/fence_ibmblade.8
@@ -1,7 +1,7 @@
 .TH fence_ibmblade 8
 
 .SH NAME
-fence_ibmblade - I/O Fencing agent for IBM BladeCenter 
+fence_ibmblade - I/O Fencing agent for IBM BladeCenter
 
 .SH SYNOPSIS
 .B
@@ -14,28 +14,62 @@ chassis. It issues SNMP Set request to BladeCenter chassis, rebooting, powering
 up or down the specified Blade Server. 
 
 fence_ibmblade accepts options on the command line as well as from stdin.
-fenced sends parameters through stdin when it execs the agent.  fence_ibmblade 
-can be run by itself with command line options which is useful for testing.
+Fenced sends parameters through stdin when it execs the agent.  fence_ibmblade 
+can be run by itself with command line options.  This is useful for testing.
 
 .SH OPTIONS
 .TP
-\fB-a\fP \fIIPaddress\fP
-IP address of the BladeCenter chassis. 
+\fB-a\fP \fIIPaddress\fR
+IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
 .TP
 \fB-h\fP
 Print out a help message describing available options, then exit.
 .TP
-\fB-c\fP \fIcommunity\fP
-SNMP community string to use.
+\fB-c\fP \fIcommunity\fR
+The read/write community string to be used in the request.
 .TP
-\fB-n\fP \fIport\fP
-The Blade port number to disable.
+\fB-n\fP \fIname\fR
+Name of port to fence or ifIndex.
 .TP
-\fB-o\fP \fIaction\fP
-The action required.  This can be reboot (default), on or off.
+\fB-p\fP \fIpassword\fR
+Password for login for SNMP v3 (authentication protocol pass phrase).
 .TP
-\fB-q\fP
-Quiet mode: print only error messages.
+\fB-P\fP \fIpassword\fR
+Password for privacy for SNMP v3 (privacy protocol password).
+.TP
+\fB-S\fP \fIscript\fR
+Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
+.TP
+\fB-R\fP \fIscript\fR
+Script to run to retrieve privacy for SNMP v3 (privacy protocol password).
+.TP
+\fB-l\fP \fIlogin\fR
+Login name for SNMP v3 (security name).
+.TP
+\fB-d\fP \fIversion\fR
+SNMP version (1,2c,3). Default is 1.
+.TP
+\fB-b\fP \fIauth_protocol\fR
+SNMP authentication protocol (MD5|SHA).
+.TP
+\fB-E\fP \fIsec_level\fR
+SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
+.TP
+\fB-B\fP \fIpriv_protocol\fR
+SNMP privacy protocol (DES|AES).
+.TP
+\fB-u\fP \fIudp_port\fR
+UDP/TCP port to use.
+.TP
+\fB-o\fP \fIaction\fR
+The action required.  off (default), on, status, list or monitor. Deprecated
+options (enable -> on and disable -> off) can be used too.
+.TP
+\fB-v\fP
+Verbose. Record session to stdout, or debug file if specified (see -D).
+.TP
+\fB-D\fP
+Specifies file, where will be written debug messages from session.
 .TP
 \fB-V\fP
 Print out a version message, then exit.
@@ -45,17 +79,54 @@ Print out a version message, then exit.
 \fIagent = < param >\fR
 This option is used by fence_node(8) and is ignored by fence_ibmblade.
 .TP
-\fIipaddr = < hostname | ip >\fR
-IP address or hostname of the switch.
+\fIipaddr = < param >\fR
+IP address or hostname of the SNMP device. Can be used any syntax supported by snmpget.
 .TP
 \fIcommunity = < param >\fR
-SNMP community.
-.TP
-\fIoption = < param >\fR
-The action required.  reboot (default), on or off.
+The read/write community string to be used in the request.
 .TP
 \fIport = < param >\fR
-The Blade port number to disable.
+Name of port to fence or ifIndex.
+.TP
+\fIpasswd = < param >\fR
+Password for login for SNMP v3 (authentication protocol pass phrase).
+.TP
+\fIsnmp_priv_passwd\fR
+Password for privacy for SNMP v3 (privacy protocol password).
+.TP
+\fIpasswd_script = < param >\fR
+Script to run to retrieve password for login for SNMP v3 (authentication protocol pass phrase).
+.TP
+\fIsnmp_priv_passwd_script = < param>\fR
+Password for privacy for SNMP v3 (privacy protocol password).
+.TP
+\fIlogin = < param >\fR
+Login name for SNMP v3 (security name).
+.TP
+\fIsnmp_version = < param >\fR
+SNMP version (1,2c,3). Default is 1.
+.TP
+\fIsnmp_auth_prot = < param >\fR
+SNMP authentication protocol (MD5|SHA).
+.TP
+\fIsnmp_sec_level = < param >\fR
+SNMP security level (noAuthNoPriv|authNoPriv|authPriv).
+.TP
+\fIsnmp_priv_prot = < param >\fR
+SNMP privacy protocol (DES|AES).
+.TP
+\fIudpport = < param >\fR
+UDP/TCP port to use.
+.TP
+\fIaction = < param >\fR
+The action required.  off (default), on, status, list or monitor. Deprecated
+options (enable -> on and disable -> off) can be used too.
+.TP
+\fIverbose = < param >\fR
+Verbose.  Record session to stdout, or debug file if specified (see debug).
+.TP
+\fIdebug = < param >\fR
+Specifies file, where will be written debug messages from session.
 
 .SH SEE ALSO
 fence(8), fence_node(8)



More information about the Cluster-cvs mailing list