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 +++++++++++++++++++++++++++++++++++++++++++++ INF/DSRx020.pm | 635 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1139 insertions(+) create mode 100644 INF/APC.pm create mode 100644 INF/DSRx020.pm (limited to 'INF') 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; diff --git a/INF/DSRx020.pm b/INF/DSRx020.pm new file mode 100644 index 0000000..591f367 --- /dev/null +++ b/INF/DSRx020.pm @@ -0,0 +1,635 @@ +#!/usr/bin/env perl + +IO::Socket::SSL::set_ctx_defaults( SSL_verify_mode => SSL_VERIFY_NONE ); + +package INF::DSRx020; + +use IO::Socket::SSL qw(); +use HTML::TreeBuilder; +use HTTP::Request::Common; +use LWP::UserAgent; +use URI::Escape; +use File::Temp qw/ tempfile tempdir /; +use XML::Simple; +use Data::Dumper; + +my $prefix = "/usr/local/share/inf/avocent/"; + +my $jars = [ + $prefix . "avctLinuxLib.jar", + $prefix . "avctMacOSXLib.jar", + $prefix . "avctSolarisLib.jar", + $prefix . "avctVideo.jar", + $prefix . "avctVM.jar", + $prefix . "avctWin32Lib.jar", + $prefix . "avmLinuxLib.jar", + $prefix . "avmMacOSXLib.jar", + $prefix . "avmSolarisLib.jar", + $prefix . "avmWin32Lib.jar", + $prefix . "jpcscdll.jar", + $prefix . "jpcscso.jar" +]; + +sub trim($) { + my $s = shift; + + if ( defined $s ) { + $s =~ s/a^\s+//g; + $s =~ s/\s+$//g; + } + + return $s; +} + +sub flush($) { + my $self = shift; + delete $self->{names}; + delete $self->{ports}; + delete $self->{statuses}; +} + +sub login($) { + my $self = shift; + + my $post = POST( + $self->{kvm_url} . 'file=login', + [ + action => "SAVE", + saveParms => "login", + filename => "login", + spcDevice => "(NULL)", + spcSocket => "(NULL)", + spcInlet => "(NULL)", + userindex => "(NULL)", + id => "(NULL)", + index => "(NULL)", + loginUsername => $self->{user}, + loginPassword => $self->{password}, + htmlLanguage => '0' + ] + ); + + my $res = $self->{ua}->request($post); + + unless ( $res->is_success ) { + print STDERR "Login failed - did not get 200\n"; + $self->{uid} = undef; + return -1; + } + my $content = $res->content; + + if ( $content =~ /errorMsg/ ) { + print STDERR "Login failed - invalid password\n"; + $self->{uid} = undef; + return -1; + } + + my $refresh = $res->headers->header('refresh'); + + unless ( $refresh =~ /userid=(\d+)$/i ) { + print STDERR "Login failed - no uid found\n"; + $self->{uid} = undef; + return -1; + } + + $self->{uid} = $1; + + # print "userid = ", $self->{uid}, "\n"; + + return 0; +} + +sub do_get($$) { + my ( $self, $args ) = @_; + my @uea; + my $url; + + do { + + $url = $self->{kvm_url}; + @uea = (); + + for my $key ( keys %$args ) { + push @uea, $key . '=' . uri_escape( $args->{$key} ); + } + push @uea, 'userID=' . $self->{uid}; + + $url .= join( '&', @uea ); + + # print STDERR "get from url=$url\n"; + + my $get = GET($url); + + my $res = $self->{ua}->request($get); + + return undef unless $res->is_success; + + return $res unless $res->content =~ /form name="loginForm"/; + + return undef if $self->login; + + } while (1); + +} + +sub do_post($$$) { + my ( $self, $args, $postargs ) = @_; + my @uea; + my $url; + + do { + + $url = $self->{kvm_url}; + @uea = (); + + for my $key ( keys %$args ) { + push @uea, $key . '=' . uri_escape( $args->{$key} ); + } + push @uea, 'userID=' . $self->{uid}; + + $url .= join( '&', @uea ); + + # print STDERR "post to url=$url\n"; + + my $post = POST( $url, [ @{$postargs}, userID => $self->{uid} ] ); + + my $res = $self->{ua}->request($post); + + return undef unless $res->is_success; + + return $res unless $res->content =~ /form name="loginForm"/; + + return undef if $self->login; + + } while (1); + +} + +sub spc_set_power($$$$) { + my ( $self, $spc, $socket, $action ) = @_; + + my $res = $self->do_post( + { file => 'overview-spc', spcDevice => $spc, spcSocket => $socket }, + [ + file => 'overview-spc', + saveParms => 'overview-spc', + spcDevice => $spc, + spcSocket => $socket, + action => $action, + ] + ); + + $self->flush(); + + #name=>Test+power+port + #oids=>','.$socket + + return undef unless $res->is_success; + + return "Success"; +} + +sub port_cycle($$) { + my ( $self, $port ) = @_; + + if ( $port =~ /P(\d+)\.(\d+)/ ) { + return $self->spc_set_power( $1, $2, 'POWER_CYCLE' ); + } + else { + return undef; + } +} + +sub port_on($$) { + my ( $self, $port ) = @_; + + if ( $port =~ /P(\d+)\.(\d+)/ ) { + return $self->spc_set_power( $1, $2, 'POWER_ON' ); + } + else { + return undef; + } +} + +sub port_off($$) { + my ( $self, $port ) = @_; + + if ( $port =~ /P(\d+)\.(\d+)/ ) { + return $self->spc_set_power( $1, $2, 'POWER_OFF' ); + } + else { + return undef; + } +} + +sub spc_get_state($$$) { + my ( $self, $spc, $socket ) = @_; + + my $res = $self->do_get( + { file => 'overview-spc', spcDevice => $spc, spcSocket => $socket } ); + + return undef unless defined $res; + + my $tree = HTML::TreeBuilder->new; + + $tree->parse( $res->content ); + + my $thing = $tree->look_down( 'id' => 'status-label-power-1' ); + + if ( not defined $thing ) { + $tree->delete; + return undef; + } + + my $ret = ""; + for my $c ( $thing->content_list ) { + $ret .= $c unless ref $c; + } + + $tree->delete; + + $ret = trim($ret); + + return $ret; +} + +sub spc_get_name($$$) { + my ( $self, $spc, $socket ) = @_; + + my $res = $self->do_get( + { file => 'overview-spc', spcDevice => $spc, spcSocket => $socket } ); + + return undef unless defined $res; + + my $tree = HTML::TreeBuilder->new; + + $tree->parse( $res->content ); + + my $thing = $tree->look_down( 'name' => 'spcsocketname' ); + + if ( not defined $thing ) { + $tree->delete; + return undef; + } + + my $ret = $thing->attr('value'); + + print "ret=$ret\n"; + + $tree->delete; + + $ret = trim($ret); + + return $ret; +} + +sub spc_set_name($$$$) { + my ( $self, $spc, $socket, $name ) = @_; + + my ( $self, $spc, $socket, $action ) = @_; + + my $res = $self->do_post( + { file => 'overview-spc', spcDevice => $spc, spcSocket => $socket }, + [ + file => 'overview-spc', + saveParms => 'overview-spc', + spcDevice => $spc, + spcSocket => $socket, + spcsocketname => $name, + action => 'SAVE', + ] + ); + + $self->flush(); + + return undef unless $res->is_success; + + return "Success"; +} + +sub elm_to_txt($) { + my $e = shift; + my $ret = ""; + for my $c ( $e->content_list ) { + $ret .= $c unless ref $c; + } + + return $ret; +} + +sub elm_to_txt_with_spaces($) { + my $e = shift; + my $ret = ""; + for my $c ( $e->content_list ) { + $ret .= $c unless ref $c; + $ret .= " "; + } + return $ret; +} + +sub get_names($) { + my $self = shift; + + my $res = $self->do_get( { file => 'view-units-by-target-devices' } ); + + return -1 unless defined $res; + + my $tree = HTML::TreeBuilder->new; + + $tree->parse( $res->content ); + + $self->{ports} = []; + $self->{names} = {}; + $self->{statuses} = {}; + + for my $thing ( + $tree->look_down( + 'title' => +'Unique name of target device. Clicking moves to the Unit Overview window for the TD.' + ) + ) + { + + my $p = $thing->parent(); + my $tr = $p->parent->parent; + my $href = $p->attr('href'); + + my $status = ""; + my $name = elm_to_txt($thing); + + for my $span ( + $tr->look_down( sub { $_[0]->attr('id') =~ /status-label-unit/ } ) ) + { + $status .= elm_to_txt_with_spaces($span); + } + + $name = trim($name); + $status = trim($status); + + $status =~ s/Idle/On/; + + #print "href=$href name=$name\n"; + #$p->dump(); + + if ( $href =~ /file=overview-spc.*spcDevice=(\d+)&spcSocket=(\d+)/ ) { + my $port = 'P' . $1 . '.' . $2; + push @{ $self->{ports} }, $port; + $self->{names}->{$port} = $name; + $self->{statuses}->{$port} = $status; + } + + if ( $href =~ /file=overview-dsr.*index=(\d+)/ ) { + my $port = 'K' . $1; + push @{ $self->{ports} }, $port; + $self->{names}->{$port} = $name; + $self->{statuses}->{$port} = $status; + } + + } + + $tree->delete; + + return 0; +} + +sub port_name_set($$$) { + my ( $self, $port, $name ) = @_; + + if ( $port =~ /P(\d+)\.(\d+)/ ) { + return $self->spc_set_name( $1, $2, $name ); + } + else { + return undef; + } +} + +sub port_state_get_no_cache($$) { + my ( $self, $port ) = @_; + + if ( $port =~ /P(\d+)\.(\d+)/ ) { + return $self->spc_get_state( $1, $2 ); + } + else { + return "Unknown"; + } +} + +sub port_state_get($$) { + my ( $self, $port ) = @_; + return $self->{statuses}->{$port} if defined $self->{statuses}; + return $self->port_state_get_no_cache($port); +} + +sub port_name_get($$) { + my ( $self, $port ) = @_; + + return $self->{names}->{$port} if defined $self->{ports}; + $self->get_names(); + return $self->{names}->{$port}; +} + +sub port_id_get_by_number($$) { + my ( $self, $n ) = @_; + return $self->{ports}->[ $n - 1 ]; +} + +sub port_count($) { + my $self = shift; + + return scalar( @{ $self->{ports} } ) if defined $self->{ports}; + + $self->get_names(); + return scalar( @{ $self->{ports} } ); +} + +sub view($$) { + my ( $self, $port ) = @_; + + return unless $port =~ /K(\d+)/; + + my $res = $self->do_get( + { + file => 'jnlp', + index => $1 + } + ); + + return undef unless defined $res; + + my $xml = new XML::Simple; + + my $c = $res->content; + + $c =~ s/^[\s\n\r]+//s; + + my $data = $xml->XMLin($c); + + return undef unless defined $data->{'application-desc'}; + + my $args = $data->{'application-desc'}->{'argument'}; + + return undef unless defined $args; + + my $cp = join( ':', @$jars ); + + mkdir $ENV{HOME} . "/.avocent_kvm"; + chdir $ENV{HOME} . "/.avocent_kvm"; + +#print join( ' ', ( "java", "-cp", $cp, "com.avocent.video.Stingray", @$args ) ), "\n"; + + system( "java", "-cp", $cp, "com.avocent.video.Stingray", @$args ); + +} + +sub pdu_load_get($) { + + my $self = shift; + my $ret = []; + my $res = $self->do_get( { file => 'view-spcs' } ); + + return undef unless defined $res; + + my $tree = HTML::TreeBuilder->new; + $tree->parse( $res->content ); + + my $t1 = $tree->look_down( 'class' => 'list-filter-row' ); + return undef unless defined $t1; + my $div = $t1->parent; + return undef unless defined $div; + + my $tables = []; + for my $t ( $div->content_list ) { + next unless ref $t; + push @$tables, $t if $t->tag eq 'table'; + } + + my $t2 = $tables->[1]; + return undef unless defined $t2; + my $t3 = [ $t2->look_down( "_tag" => 'table' ) ]; + + return undef unless scalar(@$t3) > 1; + + my $table = $t3->[1]; + + return undef unless defined $table; + + my $rows = [ $table->look_down( "_tag" => 'tr' ) ]; + return undef unless scalar(@$rows) > 1; + + my $r1 = [ $rows->[0]->look_down( "_tag" => 'td' ) ]; + my $r2 = [ $rows->[1]->look_down( "_tag" => 'td' ) ]; + + for ( my $i = 0 ; $i < scalar(@$r1) ; ++$i ) { + + my $title = $r1->[$i]; + my $value = $r2->[$i]; + + next unless defined $title; + next unless defined $value; + + $title = elm_to_txt($title); + $value = elm_to_txt($value); + + trim($value); + + push @$ret, $value . " " if $title =~ /current/i; + } + + return join( ",", @$ret ); +} + +sub psu_status($) { + return undef; +} + +sub name_get($) { + my $self = shift; + + my $res = $self->do_get( { file => 'appliance-overview' } ); + + return undef unless defined $res; + + my $tree = HTML::TreeBuilder->new; + + $tree->parse( $res->content ); + + my $thing = $tree->look_down( 'name' => 'appliancename' ); + + return undef unless defined $thing; + my $ret = $thing->attr('value'); + + $tree->delete; + + $ret = trim($ret); + + return $ret; +} + +sub name_set($$) { + my ( $self, $name ) = @_; + + my $res = $self->do_post( + { file => 'appliance-overview' }, + [ + file => 'appliance-overview', + saveParms => 'appliance-overview', + appliancename => $name, + spcSocket => $socket, + action => 'SAVE', + ] + ); + + #name=>Test+power+port + #oid=>'148737', + #oids=>'' + + return -1 unless $res->is_success; + + return 0; +} + +sub new ($;$) { + my ( $class, $parm ) = @_; + my $self; + + $self->{ua} = my $ua = LWP::UserAgent->new; + + $self->{host} = $parm->{host} || "127.0.0.1"; + + $self->{user} = $parm->{user} || "Admin"; + $self->{password} = $parm->{password} || ""; + + $self->{kvm_url} = $parm->{kvm_url} + || 'https://' . $self->{host} . '/cgi-bin/kvm.cgi?&'; + $self->{userid} = undef; + + $self->{ua}->ssl_opts( + SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, + verify_hostname => 0, + ); + + return bless $self, $class; + +} + +1; + +#my $dsr = new DSRx020( +# { +# # host => 'https://freyja-brisingamen.uk.bromium.net', +# #host => 'http://localhost:81', +# host => 'https://10.32.95.20', +# user => 'Admin', +# password=>'Woow7See' +# } +#); +# +##$dsr->login(); +# +##print "1.8 is called ", $dsr->spc_get_name( 1, 8 ), "\n"; +##print "1.8 is state ", $dsr->spc_get_state( 1, 8 ), "\n"; +##print "1.8 power off: ", $dsr->spc_power_off( 1, 8 ), "\n"; +##print "1.8 is state ", $dsr->spc_get_state( 1, 8 ), "\n"; +# +#$dsr->get_names(); + -- cgit v1.2.3