From ef393874b4df287089d07f8d49d91972e0c5ca18 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 10 May 2019 22:48:36 +0100 Subject: supermicro support --- INF/SuperMicro.pm | 344 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 344 insertions(+) create mode 100644 INF/SuperMicro.pm (limited to 'INF') diff --git a/INF/SuperMicro.pm b/INF/SuperMicro.pm new file mode 100644 index 0000000..68927c7 --- /dev/null +++ b/INF/SuperMicro.pm @@ -0,0 +1,344 @@ +#!/usr/bin/env perl + +IO::Socket::SSL::set_ctx_defaults( SSL_verify_mode => SSL_VERIFY_NONE ); + +package INF::SuperMicro; + +use HTTP::Status; +use HTTP::Cookies; + +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; +use JSON::PP; + +my $prefix = "/usr/local/share/inf/supermicro/"; + +my $jars = [ $prefix . "iKVM__V1.69.25.0x0.jar" ]; + +sub login($) { + my $self = shift; + + my $post = POST( $self->{bmc_url} . '/cgi/login.cgi' ); + my $form_content = + 'name=' . $self->{user} . '&' . 'pwd=' . $self->{password}; + + $post->header( 'Content-Type' => 'application/x-www-form-urlencoded' ); + $post->header( 'Content-Length' => length($form_content) ); + $post->content($form_content); + + my $res = $self->{ua}->request($post); + + unless ( $res->is_success ) { + print STDERR "Login failed - did not get 200\n"; + + print Dumper($res); + + $self->{logged_in} = undef; + return -1; + } + + $self->{logged_in} = 1; + + #my $json = decode_json( $res->content ); + + #$self->{skey} = $json->{session_key}; + + #print "Session key ".$self->{skey}."\n"; + + return 0; +} + +sub view($) { + my $self = shift; + + $self->login() unless defined $self->{logged_in}; + + my $get = GET( $self->{bmc_url} + . '/cgi/url_redirect.cgi?url_name=ikvm&url_type=jwsk' ); + + my $res = $self->{ua}->request($get); + + unless ( $res->is_success ) { + print STDERR "JWSK frequest failed - did not get 200\n"; + return -1; + } + + 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; + + mkdir $ENV{HOME} . "/.supermicro_kvm"; + chdir $ENV{HOME} . "/.supermicro_kvm"; + + my $cp = join( ':', @$jars ); + + if ( $self->{proxy_host} ) { + system( + "echo", + "java", + "-Djava.net.preferIPv4Stack=true", + "-Djava.net.useSystemProxies=false", + "-DsocksProxyVersion=4", + "-DsocksProxySet=true", + "-DsocksProxyHost=" . $self->{proxy_host}, + "-DsocksProxyPort=" . $self->{proxy_port}, + "-cp", + $cp, + "-Djava.library.path=" . $prefix, + "tw.com.aten.ikvm.KVMMain", + @$args + ); + system( + "java", + "-Djava.net.preferIPv4Stack=true", + "-Djava.net.useSystemProxies=false", + "-DsocksProxyVersion=4", + "-DsocksProxySet=true", + "-DsocksProxyHost=" . $self->{proxy_host}, + "-DsocksProxyPort=" . $self->{proxy_port}, + "-cp", + $cp, + "-Djava.library.path=" . $prefix, + "tw.com.aten.ikvm.KVMMain", + @$args + ); + + } + else { + system( "java", "-cp", $cp, "-Djava.library.path=" . $prefix, + "tw.com.aten.ikvm.KVMMain", @$args ); + } + +} + +# +# unless ( $content =~ /Netscape'\) {(.*)}[\s\n]*else if/s ) { +# print STDERR "returned html doesn't look right\n"; +# return -1; +# } +# +# $content = $1; +# +# #$content=~ s/document.writeln\("(.*)"\);$/\1/m; +# $content =~ s/^\s*document.writeln\("(.*)"\);\s*$/\1/mg; +# $content =~ s/\\//g; +# +# $content =~ s/RCINFO1=.*$/RCINFO1="$self->{skey}"/m; +# $content =~ s/RCINFO6=.*$/RCINFO6="17990"/m; +# $content =~ s/RCINFOLANG=.*$/RCINFOLANG="en"/m; +# $content =~ s%(archive=)(/.*)$%\1$self->{proxy_url}\2%m; +# +# $content = "" . $content . ""; +# +# $self->{java_html} = $content; +# +# my $webserver_pid = fork(); +# +# if ( $webserver_pid == 0 ) { +# $SIG{INT} = sub { kill 'KILL', ( @{ $self->{to_kill} } ); die; }; +# $SIG{TERM} = sub { kill 'KILL', ( @{ $self->{to_kill} } ); die; }; +# +# $self->{server}->start; +# print STDERR "failed to web server"; +# sleep(100000); +# } +# +# push @{ $self->{to_kill} }, $webserver_pid; +# +# $SIG{INT} = sub { kill 'INT', ( @{ $self->{to_kill} } ); die; }; +# $SIG{TERM} = sub { kill 'TERM', ( @{ $self->{to_kill} } ); die; }; +# +# system( +# "appletviewer", +# "-J-Djava.security.manager", +# "-J-Djava.security.policy=/usr/local/share/inf/ilo/mypolicy", +# "-J-Djavax.net.ssl.trustStore=/usr/local/share/inf/ilo/server.jks", +# $self->{proxy_url} . "/html/java_irc.html" +# ); +# +# kill 'TERM', ( @{ $self->{to_kill} } ); +#} +# +sub get_host_power($) { + my ($self) = @_; + + $self->login() unless defined $self->{logged_in}; + + my $post = POST( $self->{bmc_url} . '/cgi/ipmi.cgi' ); + my $form_content = 'op=POWER_INFO.XML&r=(0%2C0)'; + + $post->header( 'Content-Type' => 'application/x-www-form-urlencoded' ); + $post->header( 'Content-Length' => length($form_content) ); + $post->content($form_content); + + my $res = $self->{ua}->request($post); + + unless ( $res->is_success ) { + print STDERR " get host power - did not get 200\n"; + return undef; + } + + 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->{'POWER_INFO'}; + return undef unless defined $data->{'POWER_INFO'}->{'POWER'}; + return undef unless defined $data->{'POWER_INFO'}->{'POWER'}->{'STATUS'}; + + return $data->{'POWER_INFO'}->{'POWER'}->{'STATUS'}; +} + +sub set_host_power($$) { + my ( $self, $what ) = @_; + + $self->login() unless defined $self->{logged_in}; + + my $post = POST( $self->{bmc_url} . '/cgi/ipmi.cgi' ); + my $form_content = 'op=POWER_INFO.XML&r=(1%2C' . $what . ')'; + + $post->header( 'Content-Type' => 'application/x-www-form-urlencoded' ); + $post->header( 'Content-Length' => length($form_content) ); + $post->content($form_content); + + my $res = $self->{ua}->request($post); + + unless ( $res->is_success ) { + print STDERR " get host power - did not get 200\n"; + return 0; + } + + my $xml = new XML::Simple; + + my $c = $res->content; + + $c =~ s/^[\s\n\r]+//s; + + my $data = $xml->XMLin($c); + + return 0 unless defined $data->{'POWER_INFO'}; + return 0 unless defined $data->{'POWER_INFO'}->{'POWER'}; + return 0 unless defined $data->{'POWER_INFO'}->{'POWER'}->{'STATUS'}; + + return 1; +} + +sub reset($) { + my $self = shift; + return $self->set_host_power('0'); +} + +sub port_off($) { + my $self = shift; + return $self->set_host_power('1'); +} + +sub orderly_shutdown($) { + my $self = shift; + return $self->set_host_power('2'); +} + +sub port_on($) { + my $self = shift; + return $self->set_host_power('3'); +} + +sub port_cycle($) { + my $self = shift; + return $self->set_host_power('5'); +} + +sub port_state_get($$) { + my $self = shift; + return $self->get_host_power(); +} + +sub port_name_get($$) { + my $self = shift; + return $self->{name}; +} + +sub name_get($) { + my $self = shift; + return $self->{name}; +} + +sub pdu_load_get($) { + return "N/A"; +} + +sub psu_status($) { + return "N/A"; +} + +sub port_count($) { + return 1; +} + +sub port_id_get_by_number($$) { + return "K0"; +} + +sub logout($) { + my $self = shift; +} + +sub new ($;$) { + my ( $class, $parm ) = @_; + my $self; + + $self->{ua} = my $ua = LWP::UserAgent->new; + $self->{cookie_jar} = HTTP::Cookies->new(); + $self->{ua}->cookie_jar( $self->{cookie_jar} ); + + $self->{host} = $parm->{host} || "127.0.0.1"; + + $self->{user} = $parm->{user} || "ADMIN"; + $self->{password} = $parm->{password} || "ADMIN"; + + $self->{name} = $parm->{name} || $self->{host}; + + $self->{bmc_url} = $parm->{bmc_url} + || 'https://' . $self->{host}; + + $self->{ua}->ssl_opts( + SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE, + verify_hostname => 0, + ); + + if ( defined $parm->{proxy_host} ) { + $self->{ua}->proxy( [qw(http https)] => "socks://" + . $parm->{proxy_host} . ":" + . $parm->{proxy_port} ); + $self->{proxy_host} = $parm->{proxy_host}; + $self->{proxy_port} = $parm->{proxy_port}; + } + + $self->{logged_in} = undef; + + return bless $self, $class; + +} + +1; + -- cgit v1.2.3