????

Your IP : 216.73.216.174


Current Path : /lib/raider/Client/
Upload File :
Current File : //lib/raider/Client/RaidAlarm.pm

use strict;
use warnings;

package Client::RaidAlarm;

use JSON::Tiny qw(decode_json encode_json);
use HTTP::Tiny;
use IO::Socket::INET;

=head1 NAME

Client::RaidAlarm - Simple library for interacting with RaidAlarm.

=head1 DESCRIPTION

=head1 USAGE

use Raider::RaidAlarm;
my $raidalarm = Client::RaidAlarm->new();

=head1 METHODS

=head2 get_deviceids_by_device(string)

where string is:
  3ware|adaptec|fusion|megaraid_sas|megaraid_sata

Returns:
{
  "devices": [
    "9005:0285",
    "9005:028b",
    "9005:028c",
    "9005:028d"
  ]
}

=head2 call(\%args)

call given the method param. If verb is post, you should pass
in the (unencoded) method params in the params key. Dies on
any errors.

Returns:
the raw JSON body the given method returns

=head2 host_up(%args)

Returns perl boolean (0/1) if the api host is accessible on
the given port.

=head2 get_my_ip(%args)

Returns the machines IP by querying RaidAlarm.

=cut

sub new {
  my ($class, %args) = @_;

  my $raider_ver = $args{raider_ver} //= 'forgotten';
  my $timeout = $args{timeout} //= 25;

  my %blessed = (
    api_host => $args{api_host},
    tiny_obj => HTTP::Tiny->new(
                 agent => "RAIDER-$raider_ver",
                 timeout => $timeout,
                ),
  );

  return bless \%blessed, $class;
}

sub host_up {
  my ($self,%args) = @_;
  my %sockArgs = (
    PeerAddr => $self->{api_host},
    Proto => 'tcp',
    Timeout => 5,
    PeerPort => $args{port}
  );
  my $sock = IO::Socket::INET->new(%sockArgs);
  if ($sock) {
    return 1;
  }
  return 0;
}

sub get_my_ip {
  my ($self,%args) = @_;
  my %sockArgs = (
    PeerAddr => $self->{api_host},
    Proto => 'tcp',
    Timeout => 5,
    PeerPort => 80,
  );
  my $sock = IO::Socket::INET->new(%sockArgs);
  if ($sock) {
    return $sock->sockhost;
  }
  return '';
}

sub get_deviceids_by_device {
  my ($self, $device) = @_;

  return $self->call(method => "/api/v1/device-list/$device");
}

sub call {
  my ($self, %args) = @_;

  my ($err_msg,$response);
  foreach my $httpMode (qw(https:// http://)) {

    my $port = 443;
    $port = 80 if ($httpMode eq 'http://');
    if (!$self->host_up(port => $port)) {
      $err_msg .= "Unable to open sock to [$self->{api_host}:$port]\n";
      next;
    }

    my $url = $httpMode . $self->{api_host} . "$args{method}";

    if (!$args{verb}) {
      $response = $self->{tiny_obj}->get($url);
    }
    elsif ($args{verb} eq 'post') {
      my $jsonBody = encode_json($args{params});
      my $reqArgs = {content => $jsonBody, headers => {'content-type' => 'application/json'}};
      $response = $self->{tiny_obj}->request('POST', $url, $reqArgs);
    }
    else {
      die "unsupported verb param [$args{verb}]";
    }

    # 409 is a duplicate, should not be considered an error
    $response->{success} = 1 if ($response->{status} == 409);

    if ($response->{success}) {
      last;
    }
    else {
      $err_msg .= "url [$url] bad HTTP response [$response->{status}]\n$response->{content}\n";
    }
  }

  if ($err_msg && ref($response) ne 'HASH' || ref($response) eq 'HASH' && !$response->{success}) {
    die $err_msg;
  }

  my $data = {};
  if ($response->{content}) {
    eval {
      $data = decode_json($response->{content});
    };
    if (my $e = $@) {
      return {
        raw => $response->{content},
        decode_error => $e
      };
    }
  }
  return $data;
}


1;