From dafb8e9f1b0c0d7cfe092ddb467a7650109efb51 Mon Sep 17 00:00:00 2001 From: James Date: Mon, 17 Mar 2014 11:20:42 +0000 Subject: fish --- INF/APC.pm | 504 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 504 insertions(+) create mode 100644 INF/APC.pm (limited to 'INF/APC.pm') diff --git a/INF/APC.pm b/INF/APC.pm new file mode 100644 index 0000000..f740543 --- /dev/null +++ b/INF/APC.pm @@ -0,0 +1,504 @@ +#!/usr/bin/env perl + +package INF::APC; + +use SNMP::MIB::Compiler; +use Net::SNMP qw(oid_lex_sort); + +use Data::Dumper; + +sub get_mib() { + + my $compiled_dir = "/usr/local/share/inf/mibs/compiled"; + my $mibname = 'PowerNet-MIB'; + + mkdir $compiled_dir; + + my $mib = new SNMP::MIB::Compiler; + $mib->add_path('/usr/local/share/inf/mibs'); + $mib->add_extension('.mib'); + $mib->repository($compiled_dir); + $mib->{'accept_smiv1'} = 1; + $mib->{'accept_smiv2'} = 1; + $mib->{'make_dump'} = 1; + $mib->{'use_dump'} = 1; + $mib->{'do_imports'} = 1; + die "can't load" unless $mib->compile($mibname); + + return $mib; +} + +my $mib = get_mib(); + +sub name_to_oid(@) { + + my (@name) = (@_); + + my @ocmp = (); + + for my $cmp (@name) { + push @ocmp, $mib->resolve_oid($cmp); + } + + return join( '.', @ocmp ); +} + +sub oid_to_name($) { + my $oid = shift; + + $mib->convert_oid($oid); +} + +sub get_snmp($$) { + my ( $host, $cmty ) = @_; + + my ( $session, $error ) = Net::SNMP->session( + -hostname => $host, + -community => $cmty, + -port => 161, + -localport => 32130 + ); + + if ( !defined($session) ) { + printf( "ERROR: %s.\n", $error ); + exit 1; + } + + return $session; +} + +sub short_name($) { + my $name = shift; + my @s = split( /\./, $name ); + my @n = (); + + do { + $node = pop @s; + unshift @n, $node; + return $toid unless ( defined $node ); + } until ( defined $mib->{nodes}->{$node} ); + + return join( '.', @n ); +} + +sub expand_enum($$) { + my ( $oid_name, $value ) = @_; + my @s = split( /\./, $oid_name ); + + do { + $node = pop @s; + return $value unless ( defined $node ); + } until ( defined $mib->{nodes}->{$node} ); + + return $value unless ( $mib->{nodes}->{$node}->{type} eq 'OBJECT-TYPE' ); + + return $value + unless ( $mib->{nodes}->{$node}->{syntax}->{type} eq 'INTEGER' ); + + return $value + unless ( defined $mib->{'nodes'}->{$node}->{syntax}->{values}->{$value} ); + return $mib->{'nodes'}->{$node}->{syntax}->{values}->{$value}; + +} + +sub lookup_enum($$) { + my ( $oid_name, $value ) = @_; + my @s = split( /\./, $oid_name ); + + do { + $node = pop @s; + return $value unless ( defined $node ); + } until ( defined $mib->{nodes}->{$node} ); + + return $value unless ( $mib->{nodes}->{$node}->{type} eq 'OBJECT-TYPE' ); + + return $value + unless ( $mib->{nodes}->{$node}->{syntax}->{type} eq 'INTEGER' ); + + for my $i ( keys %{ $mib->{'nodes'}->{$node}->{syntax}->{values} } ) { + return $i + if ( $mib->{'nodes'}->{$node}->{syntax}->{values}->{$i} =~ /$value/ ); + } + return $value; + +} + +sub show_results($) { + my ($result) = @_; + my $v = undef; + + for my $oid ( oid_lex_sort( keys( %{$result} ) ) ) { + my $name = oid_to_name($oid); + $v = expand_enum( $name, $result->{$oid} ); + + # print "oid=$oid\n"; + print short_name($name); + print " => "; + print $v; + print "\n"; + } + return $v; +} + +my $mib = get_mib(); + +sub get { + my $self = shift; + + # print "Getting ",join('.',@_),"\n"; + + my $oid = name_to_oid(@_); + + my $name = oid_to_name($oid); + + my $result = $self->{snmp}->get_request( -varbindlist => [$oid] ); + + my @keys = keys %$result; + + if ( scalar(@keys) != 1 ) { + return undef; + } + + my $value = $result->{ $keys[0] }; + + $value = expand_enum( $name, $value ); + + return $value; +} + +sub set { + my $self = shift; + my $value = shift; + my $type = shift; + + my $oid = name_to_oid(@_); + my $vbl = [ ( $oid, $type, $value ) ]; + + # print Dumper($vbl),oid_to_name($oid),"\n"; + + my $result = $self->{snmp}->set_request( -varbindlist => $vbl ); + + return $result; +} + +sub show { + my $self = shift; + + my $oid = name_to_oid(@_); + + my $name = oid_to_name($oid); + + my $result = $self->{snmp}->get_request( -varbindlist => [$oid] ); + + show_results($result); +} + +sub name_get($) { + my $self = shift; + my $ret; + + if ( $self->{vmunit} ) { + return $self->get( 'sPDUMasterConfigVMName', $self->{vmunit} ); + } + + for my $node ('rPDUIdentName') { + $ret = $self->get( $node, '0' ); + return $ret if ( defined $ret ); + } + return undef; +} + +sub name_set($$) { + my ( $self, $name ) = @_; + + if ( $self->{vmunit} ) { + return $self->set( $name, Net::SNMP::OCTET_STRING, + 'sPDUMasterConfigVMName', $self->{vmunit} ); + } + + for my $node ('rPDUIdentName') { + $ret = $self->get( $node, '0' ); + if ( defined $ret ) { + return $self->set( $name, Net::SNMP::OCTET_STRING, $node, '0' ); + } + } + return undef; + +} + +sub port_count($) { + my $self = shift; + my $ret; + + if ( $self->{vmunit} ) { + return $self->get( 'sPDUMasterStatusVMOutletCount', $self->{vmunit} ); + } + + for my $node ( 'sPDUOutletConfigTableSize', 'rPDUOutletDevNumCntrlOutlets' ) + { + $ret = $self->get( $node, '0' ); + return $ret if ( defined $ret ); + } + + return 8; +} + +sub port_id_get_by_number($) { + my ( $self, $i ) = @_; + return $i; +} + +sub port_name_get($$) { + my ( $self, $i ) = @_; + my $ret; + + if ( $self->{vmunit} ) { + return $self->get( 'sPDUOutletConfigVMOutletName', $self->{vmunit}, 1, + $i ); + } + + for my $node ( 'rPDUOutletConfigOutletName', 'sPDUOutletName' ) { + $ret = $self->get( $node, $i ); + return $ret if ( defined $ret ); + } + return undef; +} + +sub port_name_set($$$) { + my ( $self, $i, $name ) = @_; + + if ( $self->{vmunit} ) { + return $self->set( $name, Net::SNMP::OCTET_STRING, + 'sPDUOutletConfigVMOutletName', + $self->{vmunit}, 1, $i ); + } + + for my $node ( 'rPDUOutletConfigOutletName', 'sPDUOutletName' ) { + $ret = $self->get( $node, $i ); + if ( defined $ret ) { + return $self->set( $name, Net::SNMP::OCTET_STRING, $node, $i ); + } + } + return undef; +} + +sub port_state_get_no_cache($$) { + + my ( $self, $i ) = @_; + my $ret; + + if ( $self->{vmunit} ) { + return $self->get( 'sPDUOutletStatusVMOutletState', $self->{vmunit}, 1, + $i ); + } + + for my $node ( 'rPDUOutletStatusOutletState', 'sPDUOutletCtl' ) { + $ret = $self->get( $node, $i ); + return $ret if ( defined $ret ); + } + return undef; +} + +sub port_state_get($$) { + my ( $self, $i ) = @_; + return $self->port_state_get_no_cache($i); +} + +sub port_state_set($$$) { + my ( $self, $i, $state ) = @_; + + my $ret; + + if ( $self->{vmunit} ) { + my $ret = $self->get( 'sPDUOutletControlVMOutletCommand', + $self->{vmunit}, 1, $i ); + my $oid = name_to_oid( 'sPDUOutletControlVMOutletCommand', + $self->{vmunit}, 1, $i ); + my $name = oid_to_name($oid); + + if ( defined $ret ) { + my $v = lookup_enum( $name, $state ); + return undef if ( not defined $v ); + return undef if ( int($v) ne $v ); + return $self->set( $v, Net::SNMP::INTEGER, + 'sPDUOutletControlVMOutletCommand', + $self->{vmunit}, 1, $i ); + } + + return undef; + } + + for my $node ( 'rPDUOutletControlOutletCommand', 'sPDUOutletCtl' ) { + my $ret = $self->get( $node, $i ); + my $oid = name_to_oid( $node, $i ); + my $name = oid_to_name($oid); + + if ( defined $ret ) { + my $v = lookup_enum( $name, $state ); + + # print "lookup of state=$state gave value=$v\n"; + return undef if ( not defined $v ); + return undef if ( int($v) ne $v ); + return $self->set( $v, Net::SNMP::INTEGER, $node, $i ); + } + + } + return undef; +} + +sub port_cycle($$) { + my ( $self, $i ) = @_; + my $ret; + + for my $cmd ( 'immediateReboot', 'outletReboot', 'immediateRebootVM' ) { + $ret = $self->set_outlet_state( $i, $cmd ); + return $ret if ( defined $ret ); + } + return undef; +} + +sub port_off($$) { + my ( $self, $i ) = @_; + my $ret; + + for my $cmd ( 'immediateOff', 'outletOff', 'immediateOffVM' ) { + $ret = $self->set_outlet_state( $i, $cmd ); + return $ret if ( defined $ret ); + } + return undef; +} + +sub port_on($$) { + my ( $self, $i ) = @_; + my $ret; + + for my $cmd ( 'immediateOn', 'outletOn', 'immediateOnVM' ) { + $ret = $self->set_outlet_state( $i, $cmd ); + return $ret if ( defined $ret ); + } + return undef; + +} + +sub pdu_load_get($) { + my $self = shift; + my $l; + + if ( $self->{vmunit} ) { + $l = $self->get( 'sPDUMasterStatusVMCurrentLoad', $self->{vmunit} ); + } + else { + $l = $self->get( 'rPDULoadStatusLoad', '1' ); + } + return undef unless ( defined $l ); + return ( 1.0 * $l ) / 10.0; +} + +sub psu_status($) { + my $self = shift; + + my $v; + my @vr = (); + my $ok = 'Ok'; + my $unk = 'Unknown'; + + $v = $self->get( 'rPDUPowerSupply1Status', '0' ); + if ( defined $v ) { + $ok = 'Sick' if ( $v ne 'powerSupplyOneOk' ); + push @vr, $v; + $unk = undef; + } + + $v = $self->get( 'rPDUPowerSupply2Status', '0' ); + if ( defined $v ) { + $ok = 'Sick' if ( $v ne 'powerSupplyTwoOk' ); + push @vr, $v; + $unk = undef; + } + + $v = $self->get( 'rPDUPowerSupplyAlarm', '0' ); + if ( defined $v ) { + $ok = 'Sick' if ( $v ne 'allAvailablePowerSuppliesOK' ); + push @vr, $v; + $unk = undef; + } + + return $unk if ( defined $unk ); + + return $ok . "(" . join( ' ', @vr ) . ")"; + +} + +sub show_oid { + my $self = shift; + my $baseoid = name_to_oid(@_); + + my $result = $self->{snmp}->get_table( -baseoid => $baseoid ); + + show_results($result); +} + +sub show_all($) { + my $self = shift; + + $self->show_oid('apc'); + +} + +# my ( $mib, $snmp, $basename ) = @_; +# +# $baseoid=resolve($mib,$basename); +# +# my $result = $snmp->get_table( -baseoid => $baseoid ); +# +# results($mib,$result); +#} + +#sub status_show($) { +# my $self = shift; +# +# $n = $self->get_n_outlets(); +# +# print $self->{host}, " thinks it's called ", $self->get_name(), "\n"; +# print "has ", $n, " outlets\n"; +# +# for ( my $i = 1 ; $i <= $n ; ++$i ) { +# print "outlet $i is called ", $self->get_outlet_name($i), " and is ", +# $self->get_outlet_status($i), "\n"; +# } +# +# my $l = $self->get_load; +# if ( defined $l ) { +# $l = $l . ' Amps'; +# } +# else { +# $l = 'Unknown'; +# } +# +# print "load ", $l, "\n"; +# +# print "PSU status ", $self->get_psu_status(), "\n"; +# +#} + +sub new ($;$) { + my ( $class, $parm ) = @_; + my $self; + + $self->{host} = $parm->{host} || "redbus-ms20.mythic-beasts.com"; + $self->{community} = $parm->{community} || "private"; + + if ( $self->{host} =~ /^(.*):(.*)$/ ) { + $self->{iphost} = $1; + $self->{vmunit} = $2; + } + else { + $self->{iphost} = $self->{host}; + } + + $self->{snmp} = get_snmp( $self->{iphost}, $self->{community} ); + + return bless $self, $class; +} + +1; -- cgit v1.2.3