Commit 6d4939ce authored by Mac Newbold's avatar Mac Newbold

Break power control into its own snmpit module...

parent 79fdd87e
......@@ -25,7 +25,7 @@ LIBEXEC_STUFF = mkprojdir rmproj mkacct-ctrl rmacct-ctrl \
webstartexp webendexp webbatchexp webkillbatchexp
LIB_STUFF = libtbsetup.pm libtestbed.pm snmpit_intel.pm \
snmpit_cisco.pm snmpit_lib.pm
snmpit_cisco.pm snmpit_lib.pm snmpit_apc.pm
#
# Force dependencies on the scripts so that they will be rerun through
......
......@@ -188,6 +188,9 @@ if (@OkNodes > 0) {
push (@OkNodes,"lights");
print "machines= ",join(" ",@machines),"\n" if $verbose;
print "oknodes= ",join(" ",@OkNodes),"\n" if $verbose;
foreach $node ( sort @machines) {
my $Approved = 0;
foreach $ok (sort @OkNodes) {
......
......@@ -21,6 +21,7 @@ use English;
#Uncomment this when we really need to be able to handle intel switches
#use snmpit_intel;
use snmpit_cisco;
use snmpit_apc;
use snmpit_lib;
snmpit_lib::init($DBNAME);
......@@ -67,33 +68,16 @@ sub myMain {
my $v = 0; #Verbose (bool) !Must default quiet; switch only turns on!
#power control
my $on=0;
my $off=0;
my $cyc=0;
my $all=0;
my $powerop=0;
my @outlets=();
&ParseArgs(\@ARGV,\$i,\@p,\$d,\$e,\$a,\$dup,\$spd,\$s,\$f,\$l,\$m,\@vlan,
\@r,\$u,\$b,\$c,\$v,\$g,
\$on,\$off,\$cyc,\$all,\@outlets);
\$powerop,\@outlets);
# print "\ni=$i p=",@p," d=$d e=$e a=$a dup=$dup spd=$spd s=$s f=$f l=$l",
# "m=$m vlan=",@vlan," r=",@r,"u=$u b=$b c=$c v=$v g=$g on=$on ",
# "off=$off cyc=$cyc all=$all device=$device\n" if $debug;
my $sess2;
if ($device eq "APC") {
use SNMP;
$SNMP::debugging = ($debug - 5) if $debug > 5;
&SNMP::addMibDirs('/usr/local/share/snmp/mibs');
&SNMP::addMibFiles('/usr/local/share/snmp/mibs/PowerNet-MIB.txt');
$SNMP::save_descriptions = 1; # must be set prior to mib initialization
SNMP::initMib(); # parses default list of Mib modules
$SNMP::use_enums = 1; #use enum values instead of only ints
print "Opening SNMP session to $i..." if $debug;
$sess2 =new SNMP::Session(DestHost => $i, Community => 'private');
print "".(defined $sess2 ? "Succeeded" : "Failed")."\n" if $debug;
}
#
# Port Level Control
#
......@@ -144,15 +128,11 @@ sub myMain {
}
if (@r) {
if ($device ne "APC") {
$device->vlanLock;
foreach my $x (sort num @r) {
$device->removeVlan($x);
}
$device->vlanUnlock;
} else {
die("Invalid option 'remove VLAN' for device of type $device.\n");
$device->vlanLock;
foreach my $x (sort num @r) {
$device->removeVlan($x);
}
$device->vlanUnlock;
}
#List VLANs is always last so that changes made are reflected
......@@ -161,28 +141,9 @@ sub myMain {
#
# Power Control
#
if ($off || $on || $cyc) {
my $CtlOID = ".1.3.6.1.4.1.318.1.1.4.4.2.1.3";
my $op = "";
#disable confirmation, and go to blocking mode...
$c = 0;
$b = 0;
if ($all) {
my $AllOID = ".1.3.6.1.4.1.318.1.1.4.2.1";
@outlets = ( 0 );
if ($on) { $op = "turnAllOnSequence";}
elsif ($off) { $op = "turnAllOffNow"; }
else { $op = "rebootAllSequence";}
if (! &UpdateField(\$sess2,$AllOID,\@outlets,$op,\$b,\$c,\$v)) {
print STDERR "Outlet control failed.\n";
}
} else {
if ($on) { $op = "outletOn"; }
elsif ($off) { $op = "outletOff"; }
else { $op = "outletReboot";}
if (! &UpdateField(\$sess2,\$CtlOID,\@outlets,\$op,\$b,\$c,\$v)) {
print STDERR "Outlet #@outlets control failed.\n";
}
if ($powerop) {
foreach $outlet (@outlets) {
$device->power($powerop,$outlet);
}
}
}
......@@ -207,33 +168,9 @@ sub AutoVLANConfig {
}
sub UpdateField {
local(*session,*OID,*ports,*val,*b,*c,*v)= @_;
print "sess=$session $OID '",join(" ",@ports),"' $val $b $c $v\n" if $debug;
my $Status = 0;
my $retval;
my $i = $session->{DestHost};
foreach my $port (@ports) {
print "Checking port $port of $i for $val..." if $v;
$Status = $session->get([[$OID,$port]]);
if (!defined $Status) {
print STDERR "Port $port, change to $val: No answer from device\n";
} else {
print "Okay.\nPort $port was $Status\n" if $v;
if ($Status ne $val) {
print "Setting $port to $val..." if $v;
$retval = $session->set([[$OID,$port,$val,"INTEGER"]]);
print "Set returned '$retval'" if $v;
}
}
}
1;
}
sub ParseArgs {
local(*CMDS,*i,*p,*d,*e,*a,*dup,*spd,*s,*f,*l,*m,*vlan,*r,*u,*b,*c,*v,*g,
*on,*off,*cyc,*all,*outlets) = @_;
*powerop,*outlets) = @_;
my $help=0;
if (@main::CMDS < 1) {$help = 1; }
print "Command line was: snmpit ",join(" ",@ARGV),"\n" if $debug;
......@@ -260,14 +197,15 @@ sub ParseArgs {
while (@CMDS>0 && ! ($CMDS[0] =~ /^(-|\+)(.*)/ ) );
}
elsif (/^-debug(.*)/) {
if (!($CMDS[0] =~ /^-/)) { shift (@CMDS); } # possibly ignore number
if ( defined($CMDS[0]) && !($CMDS[0] =~ /^-/)) {
shift (@CMDS); # possibly ignore number
}
$v=1; # debug is already set, so don't do it here
}
elsif (/^-h(.*)/) {$help = 2;}
elsif (/^-off(.*)/) {$off = 1;}
elsif (/^-on(.*)/) {$on = 1;}
elsif (/^-cyc(.*)/) {$cyc = 1;}
elsif (/^-all(.*)/) {$all = 1;}
elsif (/^-off(.*)/) {$powerop = "off";}
elsif (/^-on(.*)/) {$powerop = "on";}
elsif (/^-cyc(.*)/) {$powerop = "cyc";}
elsif (/^-a(.*)/) {$a="disable";}
elsif (/^\+a(.*)/) {$a="enable";}
elsif (/^-dup(.*)/) {$dup = ($1 ? $1 : shift(@CMDS));}
......@@ -303,9 +241,9 @@ sub ParseArgs {
elsif (/^-([1-8])$/) { push(@outlets, $1);}
else {die("Unknown Option: $_\n");}
}
#print "Done\ni=$i p=",@p," d=$d e=$e a=$a dup=$dup s=$spd s=$s f=$f l=$l",
#"m=$m vlan=",@vlan," r=",@r,"u=$u b=$b c=$c v=$v g=$g on=$on ",
#"off=$off cyc=$cyc all=$all\n" if $debug;
print "Done\ni=$i p=",@p," d=$d e=$e a=$a dup=$dup s=$spd s=$s f=$f l=$l",
"m=$m vlan=",@vlan," r=",@r,"u=$u b=$b c=$c v=$v g=$g ".
"powerop=$powerop\n" if $debug;
if ($help) {
print
"snmpit - A general purpose SNMP Tool - Version 1.1\n",
......@@ -317,7 +255,7 @@ sub ParseArgs {
"\t[-d|-e] [+a|-a] [-spd<speed>] [-dup<duplex>]\n";
# Hidden Power control functionality
#,
# "\t[ [-on|-off|-cyc] [-all] | [-<n>] ]\n";
# "\t[ [-on|-off|-cyc] | [-<n>] ]\n";
}
if ($help > 1) {
print
......@@ -349,7 +287,6 @@ sub ParseArgs {
# " -on Turn on outlets\n",
# " -off Turn off outlets\n",
# " -cyc Power Cycle outlets\n",
# " -all All outlets\n",
# " -(n) Outlet #(n) (n=1-8)\n";
}
#Unused letters of the alphabet:
......@@ -361,7 +298,7 @@ sub ParseArgs {
#Now die on any combinations that don't make sense...
die("What shall I do?\n")
if (!($d||$e||$a||$spd||$dup||$s||$g||@vlan||$f||$t||@r||$l
||$on||$off||$cyc));
||$powerop));
if (!defined($i)||!$i||$i eq "") { $i = "cisco"; }
if ( defined Dev($i) ) {
......@@ -373,14 +310,12 @@ sub ParseArgs {
(Dev($i),"debug=$debug","block=$b","confirm=$c","verbose=$v");
# } elsif ($i =~ /intel/ || Dev($i) =~ /intel/) {
# $device = new snmpit_intel;
} else { $device="APC"; }
} else {
$device = new snmpit_apc
($i,"debug=$debug","block=$b","confirm=$c","verbose=$v");
}
} else {
die ("\"$i\" is not a known device.\n");
# my $str= "\"$i\" is not a known device:\nPossible completions are:\n";
# foreach $name (sort keys %Dev) {
# if ($name =~ /[a-zA-Z]/) { $str .= "$name/".Dev($name)."\n"; }
# }
# die($str);
}
# A useful snippet of code for finding out what device we've got...
......@@ -391,10 +326,10 @@ sub ParseArgs {
if ( $i =~ /[a-zA-Z]/) { $i = Dev($i); }
die("\"$i\" is not a switch. Illegal operation requested.\n")
if ( ($device eq "APC" ) &&
if ( ($device->isa(snmpit_apc) ) &&
($d||$e||$a||$spd||$dup||$s||$g||@vlan||$f||@r||$l));
die("\"$i\" is not a power controller.\n")
if ( $device ne "APC" && ($on||$off||$cyc) );
if (! $device->isa(snmpit_apc) && ($powerop || @outlets) );
die("Can't enable and disable at the same time.\n") if ($d && $e);
die("Can't use auto with duplex or speed.\n") if(($a=~/en/)&&($dup||$spd));
my $n=0;
......@@ -469,7 +404,7 @@ sub ParseArgs {
}
}
}
if ($on || $off || $cyc) {
if ($powerop) {
$n=0;
while(@outlets != 0 && $n < @outlets) {
die("Invalid Outlet \"",$outlets[$n],"\": Must be 1 to 8.\n")
......
#!/usr/local/bin/perl -w
#
# snmpit module for APC MasterSwitch power controllers
#
# supports new(ip), power(on|off|cyc[le],port)
#
package snmpit_apc;
$| = 1; # Turn off line buffering on output
local $debug = 0;
local $verbose = 0 + $debug;
use snmpit_lib;
use SNMP;
my $sess;
my $ip;
sub new {
my $classname = shift;
$ip = shift;
while ($arg = shift ) {
my ($var,$val) = split("=",$arg);
${$var} = $val;
print "$var=${$var}\n" if $debug || $verbose;
}
if ($debug) {
print "snmpit_apm module initializing... debug level $debug\n";
}
$SNMP::debugging = ($debug - 5) if $debug > 5;
&SNMP::addMibDirs('/usr/local/share/snmp/mibs');
&SNMP::addMibFiles('/usr/local/share/snmp/mibs/PowerNet-MIB.txt');
$SNMP::save_descriptions = 1; # must be set prior to mib initialization
SNMP::initMib(); # parses default list of Mib modules
$SNMP::use_enums = 1; #use enum values instead of only ints
print "Opening SNMP session to $ip..." if $debug;
$sess =new SNMP::Session(DestHost => $ip, Community => 'private');
print "".(defined $sess ? "Succeeded" : "Failed")."\n" if $debug;
my $obj = [$sess];
bless($obj);
return $obj;
}
sub power {
shift;
my $op = shift;
my $port = shift;
my $CtlOID = ".1.3.6.1.4.1.318.1.1.4.4.2.1.3";
if ($op eq "on") { $op = "outletOn"; }
elsif ($op eq "off") { $op = "outletOff"; }
elsif ($op =~ /cyc/) { $op = "outletReboot";}
if (&UpdateField(\$CtlOID,\$port,\$op)) {
print STDERR "Outlet #$port control failed.\n";
}
}
sub UpdateField {
local(*OID,*port,*val)= @_;
print "sess=$sess $OID $port $val\n" if $debug > 1;
my $Status = 0;
my $retval;
print "Checking port $port of $ip for $val..." if $verbose;
$Status = $sess->get([[$OID,$port]]);
if (!defined $Status) {
print STDERR "Port $port, change to $val: No answer from device\n";
return 1;
} else {
print "Okay.\nPort $port was $Status\n" if $verbose;
if ($Status ne $val) {
print "Setting $port to $val..." if $verbose;
$retval = $sess->set([[$OID,$port,$val,"INTEGER"]]);
print "Set returned '$retval'" if $verbose;
if ($retval) { return 0; } else { return 1; }
}
return 0;
}
}
# End with true
1;
......@@ -30,13 +30,11 @@ does, and have snmpit be able to use this info.
Features supported in snmpit itself:
- auto vlan config from file or from db
- Power control
- device type discovery and command dispatch
Note: Power control should probably be moved out into its own module
too, but right now it wasn't important. Its so different from the
switches that there would be a lot of special cases anyway. But its
something that could be done for increased generality.
Power control has also been moved into its own module, snmpit_apc.pm.
It supports new(ip,args) as above, and power(cmd,port) where cmd is
"on", "off", or "cyc[le]" and port is 1-8.
snmpit library interface
------------------------
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment