ngcp-panel/t/lib/NGCP/TestFramework/Client.pm

192 lines
4.7 KiB

package NGCP::TestFramework::Client;
use strict;
use warnings;
use Data::Dumper;
use Digest::MD5 qw/md5_hex/;
use IO::Uncompress::Unzip;
use LWP::UserAgent;
use Moose;
use Time::HiRes qw/gettimeofday tv_interval/;
has 'username' => (
isa => 'Str',
is => 'ro',
default => sub {
$ENV{API_USER} // 'administrator';
}
);
has 'password' => (
isa => 'Str',
is => 'ro',
default => sub {
$ENV{API_PASS} // 'administrator';
}
);
has 'role' => (
isa => 'Str',
is => 'ro',
default => 'admin',
);
has 'uri' => (
isa => 'Str',
is => 'ro',
default => sub { $ENV{CATALYST_SERVER}; },
);
has 'sub_uri' => (
isa => 'Str',
is => 'ro',
default => sub { $ENV{CATALYST_SERVER_SUB}; },
);
has '_uri' => (
isa => 'Maybe[Str]',
is => 'rw',
);
has 'verify_ssl' => (
isa => 'Int',
is => 'ro',
default => 0,
);
has 'log_debug' => (
isa => 'Bool',
is => 'rw',
default => 0,
);
has '_crt_path' => (
is => 'ro',
isa => 'Str',
lazy => 1,
default => sub {
my ($self) = @_;
return '/tmp/' . md5_hex($self->username) . ".crt";
}
);
has 'last_rtt' => (
is => 'rw',
isa => 'Num',
default => 0,
);
has '_ua' => (
isa => 'LWP::UserAgent',
is => 'ro',
lazy => 1,
builder => '_build_ua'
);
sub _build_ua {
my $self = shift;
my $ua = LWP::UserAgent->new(keep_alive => 1);
my $uri;
if($self->role eq "admin" || $self->role eq "reseller") {
$uri = $self->uri;
} else {
$uri = $self->sub_uri;
}
$self->_uri($uri);
$self->debug("client using uri $uri\n");
$uri =~ s/^https?:\/\///;
$self->debug("client using ip:port $uri\n");
my $realm;
if($self->role eq 'admin' || $self->role eq 'reseller') {
$realm = 'api_admin_http';
} elsif($self->role eq 'subscriber') {
$realm = 'api_subscriber_http';
}
$self->debug("client using realm $realm with user=" . $self->username . " and pass " . $self->password . "\n");
$ua->credentials($uri, $realm, $self->username, $self->password);
unless($self->verify_ssl) {
$ua->ssl_opts(
verify_hostname => 0,
SSL_verify_mode => 0,
);
}
if($self->role eq "admin" || $self->role eq "reseller") {
unless(-f $self->_crt_path) {
# we have to setup a new connection here, because if we're already connected,
# the connection will be re-used, thus no cert is used
my $tmpua = LWP::UserAgent->new;
$tmpua->credentials($uri, $realm, $self->username, $self->password);
unless($self->verify_ssl) {
$tmpua->ssl_opts(
verify_hostname => 0,
SSL_verify_mode => 0,
);
}
my $res = $tmpua->post(
$self->_uri . '/api/admincerts/',
Content_Type => 'application/json',
Content => '{}'
);
unless($res->is_success) {
die "Failed to fetch client certificate: " . $res->status_line . "\n";
}
my $zip = $res->decoded_content;
my $z = IO::Uncompress::Unzip->new(\$zip, MultiStream => 0, Append => 1);
my $data;
while(!$z->eof() && (my $hdr = $z->getHeaderInfo())) {
unless($hdr->{Name} =~ /\.pem$/) {
# wrong file, just read stream, clear buffer and try next
while($z->read($data) > 0) {}
$data = undef;
$z->nextStream();
next;
}
while($z->read($data) > 0) {}
last;
}
$z->close();
unless($data) {
die "Failed to find PEM file in client certificate zip file\n";
}
open my $fh, ">:raw", $self->_crt_path
or die "Failed to open " . $self->_crt_path . ": $!\n";
print $fh $data;
close $fh;
}
$ua->ssl_opts(
SSL_cert_file => $self->_crt_path,
SSL_key_file => $self->_crt_path,
);
}
return $ua;
}
sub perform_request {
my ($self, $req) = @_;
my $t0 = [gettimeofday];
$self->debug("content of " . $req->method . " request to " . $req->uri . ":\n");
$self->debug($req->content || "<empty request>");
$self->debug("\n");
my $res = $self->_ua->request($req);
my $rtt = tv_interval($t0);
$self->last_rtt($rtt);
$self->debug("content of response:\n");
$self->debug($res->decoded_content || "<empty response>");
$self->debug("\n");
return $res;
}
sub debug {
my ($self, $msg) = @_;
if($self->log_debug) {
print $msg;
}
}
1;