Hello all,

It is time to give back - I would like to submit a stonith plugin written in 
perl 
for the netio230A IP Switch device for review and possible inclusion to glue.

See http://www.koukaam.se/showproduct.php?article_id=1504 for info about the 
device.

Thanks,
Martin


#!/usr/bin/perl -w
#
# External STONITH module for netio-230A IP switch devices
#
# Copyright (c) 2011 Martin Dziobek (dziobek at ihr.uni-stuttgart.de)
# 
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Further, this software is distributed without any warranty that it is
# free of the rightful claim of any third person regarding infringement
# or the like. Any license provided herein, whether implied or
# otherwise, applies only to this software file. Patent licenses, if
# any, provided herein do not apply to combinations of this program with
# other software, or any other product whatsoever.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write the Free Software Foundation,
# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
#

# This module talks to netio-230A devices via encrypted telnet interface
# Tested with firmware revision V 2.33
# Settings : All ports manual, watchdog off, port names set to names of
#            the machines to be switched 

use IO::Socket;
use Digest::MD5 qw(md5 md5_hex md5_base64);

my $EX_OK=0;
my $EX_FAIL=1;
my $EX_ERR=3;

# set to 1 for debugging, else 0
my $DBG=0;

# stuff from environment
my $deviceip = '127.0.0.1';
my $deviceport = 1234;
my $devicelogin = 'none';
my $devicepass = 'none';

# handle to netio device
my $remote;
# comm line to netio device
my $line='';
# ports on netio device
my @ports=();

my $target="none";
my $command="none";

# get command
$command = $ARGV[0] if ( defined $ARGV[0] );

# get host to handle on device
$target = $ARGV[1] if ( defined $ARGV[1] );

# get stuff from environment
$deviceip = $ENV{'deviceip'} if ( defined $ENV{'deviceip'} );
$deviceport = $ENV{'deviceport'} if ( defined $ENV{'deviceport'} );
$devicelogin = $ENV{'devicelogin'} if ( defined $ENV{'devicelogin'} );
$devicepass = $ENV{'devicepass'} if ( defined $ENV{'devicepass'} );

print STDERR "$command $target $deviceip $deviceport $devicelogin 
$devicepass\n" if $DBG;

# handle commands which need no connection to
# device first
if ( $command =~ /^getconfignames$/ ) {
    foreach $i ('deviceip','deviceport','devicelogin','devicepass'){
      print "$i\n";
    }
    exit($EX_OK);
} elsif ( $command =~ /^getinfo-devid$/ ) {
    print "netio-230A STONITH device\n";
    exit($EX_OK);    
} elsif ( $command =~ /^getinfo-devname$/ ) {
    print "netio-230A device\n";
    exit($EX_OK);    
} elsif ( $command =~ /^getinfo-devdescr$/ ) {
    print "netio-230A IP power switch device\n";
    exit($EX_OK);    
} elsif ( $command =~ /^getinfo-devurl$/ ) {
    print "http://www.koukaam.se/";;
    exit($EX_OK);
} elsif ( $command =~ /^getinfo-xml$/ ) {
    $metadata = <<END;
<parameters>
<parameter name="deviceip" unique="0" required="0">
<content type="string" />
<shortdesc lang="en">
deviceip
</shortdesc>
<longdesc lang="en">
IP of netio-230A device
</longdesc>
</parameter>
<parameter name="deviceport" unique="0" required="0">
<content type="string" />
<shortdesc lang="en">
deviceport
</shortdesc>
<longdesc lang="en">
Port to use on netio-230A device
</longdesc>
</parameter>
<parameter name="devicelogin" unique="0" required="0">
<content type="string" />
<shortdesc lang="en">
devicelogin 
</shortdesc>
<longdesc lang="en">
Username at the netio-230A device
</longdesc>
</parameter>
<parameter name="devicepass" unique="0" required="0">
<content type="string" />
<shortdesc lang="en">
devicepass
</shortdesc>
<longdesc lang="en">
Password at the netio-230A device
</longdesc>
</parameter>
</parameters>
END
    print $metadata;
    exit($EX_OK);
}

# connect to device
&connect;

if ( $command =~ /^status$/ ) {
    print STDERR "CMD status done\n" if $DBG;
    # if we came here without bailing out, device is ok
    close $remote;
    exit($EX_OK);
}    

# log in and get port info
&login;

# now handle commands which need a connection to the device

if ( $command =~ /^gethosts$/ ) {
    print STDERR "CMD gethosts\n" if $DBG;
    foreach $n (1..4){     
      print $ports[$n]."\n";
     }
    &bye;
}  


# switch commands

if ( $command =~ /^on$/ ) {
    print  STDERR "CMD $target on\n" if $DBG;;
    &switch("ON");
} elsif ( $command =~ /^off$/ ) {
    print  STDERR "CMD $target off\n" if $DBG;
    &switch("OFF");
} elsif ( $command =~ /^reset$/ ) {
    print  STDERR "CMD $target reset\n" if $DBG;
    &switch("RESET");
} else {
    print  STDERR "Command $command: not supported\n" if $DBG;
    $line="Command $command: not supported";
    &bailout;
}

# we should not end up here
close $remote;
exit($EX_OK);

# -----------------------------------------
sub connect{
  $remote = IO::Socket::INET->new( Proto     => "tcp",
                                   PeerAddr  => $deviceip,
                                   PeerPort  => $deviceport,
                                 );
  unless ($remote) { 
      print  STDERR "cannot connect to daemon on $deviceip\n";
      exit($EX_ERR); 
  }
}  
  
sub login{
  
  $remote->autoflush(1);
  
  $line = <$remote>;
  my($stat,undef,$key,undef)=split(' ',$line,4);  
  &bailout unless ($stat == 100);

  my($digest)=md5_hex($devicelogin.$devicepass.$key);
  
  print $remote "clogin $devicelogin $digest\n";
  $line = <$remote>;
  &bailout unless($line=~m/^250 OK/);
  
  foreach $n (1..4){
    print $remote "port setup $n\n";
    $line = <$remote>;
    print  STDERR "$line" if $DBG;
    my($stat,$name,undef,undef,$on)=split(' ',$line,5);
    &bailout unless ($stat == 250);
    $name=~s/\"//g;
    $ports[$n]=$name;
  }
}

sub gethosts{
   foreach $n (1..4){     
    print $ports[$n]." ";
   }
}

sub switch{
    my($stat)=shift;
    foreach $n (1..4){     
       if($target eq $ports[$n]){
         if($stat eq 'ON'){
           print $remote "port $n 1\n";
           $line = <$remote>;
           &bailout unless($line=~m/^250 OK/);
           &bye;
         }elsif($stat eq 'OFF'){
           print $remote "port $n 0\n";
           $line = <$remote>;
           &bailout unless($line=~m/^250 OK/);
           &bye;
         }elsif($stat eq 'RESET'){
           print $remote "port $n 0\n";
           $line = <$remote>;
           &bailout unless($line=~m/^250 OK/);
           sleep 5;
           print $remote "port $n 1\n";
           $line = <$remote>;
           &bailout unless($line=~m/^250 OK/);
           &bye;                 
         }
       }
    }
    $line = "Invalid target\n";
    &bailout; 
}

sub bailout{
  # exit with error condition
  print  STDERR "Bailout on $deviceip Offending line: $line";
  close $remote;
  exit($EX_ERR);
}

sub bye{
  # exit gracefully
  print $remote "quit\n";
  $line = <$remote>;
  &bailout unless($line=~m/^110 BYE/);
  close $remote;
  exit($EX_OK);
}
_______________________________________________________
Linux-HA-Dev: [email protected]
http://lists.linux-ha.org/mailman/listinfo/linux-ha-dev
Home Page: http://linux-ha.org/

Reply via email to