You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
5.3 KiB
206 lines
5.3 KiB
package NGCP::Panel::Utils::DeviceBootstrap::VendorRPC;
|
|
|
|
use strict;
|
|
use URI::Escape;
|
|
use MIME::Base64 qw/encode_base64/;
|
|
use Net::HTTPS::Any qw/https_post/;
|
|
use RPC::XML::ParserFactory 'XML::LibXML';
|
|
use RPC::XML;
|
|
use Data::Dumper;
|
|
use Moose;
|
|
|
|
has 'params' => (
|
|
is => 'rw',
|
|
isa => 'HashRef',
|
|
);
|
|
has 'content_params' => (
|
|
is => 'rw',
|
|
isa => 'HashRef',
|
|
);
|
|
has 'rpc_server_params' => (
|
|
is => 'rw',
|
|
isa => 'HashRef',
|
|
accessor => '_rpc_server_params',
|
|
);
|
|
has 'register_content' => (
|
|
is => 'rw',
|
|
isa => 'Str',
|
|
accessor => '_register_content',
|
|
);
|
|
has 'unregister_content' => (
|
|
is => 'rw',
|
|
isa => 'Str',
|
|
accessor => '_unregister_content',
|
|
);
|
|
|
|
sub redirect_server_call{
|
|
my ($self, $action) = @_;
|
|
my $c = $self->params->{c};
|
|
$self->init_content_params();
|
|
my($content,$response_value,$ret);
|
|
my $method = $action.'_content';
|
|
if($self->can($method)){
|
|
$content = $self->$method();
|
|
}else{
|
|
$ret = "Unknown method: $action";
|
|
}
|
|
if($content){
|
|
$response_value = $self->rpc_https_call($content);
|
|
$ret = $self->extract_response_description($response_value);
|
|
}
|
|
return $ret;
|
|
}
|
|
|
|
sub rpc_https_call{
|
|
my($self, $content, $cfg) = @_;
|
|
$cfg //= $self->rpc_server_params;
|
|
my $c = $self->params->{c};
|
|
$c->log->debug( "rpc_https_call: host=$cfg->{host}; port=$cfg->{port}; path=$cfg->{path}; content=$content;" );
|
|
#$c->log->debug( Dumper($cfg->{headers}) );
|
|
my( $page, $response_code, %reply_headers, $response_value );
|
|
eval {
|
|
local $SIG{ALRM} = sub { die "Connection timeout\n" };
|
|
alarm(25);
|
|
( $page, $response_code, %reply_headers ) = https_post({
|
|
'host' => $cfg->{host},
|
|
'port' => $cfg->{port},
|
|
'path' => $cfg->{path},
|
|
'headers' => $cfg->{headers},
|
|
'Content-Type' => 'text/xml',
|
|
'content' => $content,
|
|
},);
|
|
alarm(0);
|
|
};
|
|
alarm(0);
|
|
if ($@ && !$page) {
|
|
$c->log->debug( "eval error: $@;" );
|
|
if ($@ =~ /Connection timeout/) {
|
|
$response_value = 'Connection timeout';
|
|
}
|
|
}
|
|
$c->log->info( "response=$response_code; page=$page;" );
|
|
if($page){
|
|
my $rpc_response = $self->parse_rpc_response_page($page);
|
|
$response_value = $self->parse_rpc_response($rpc_response);
|
|
}
|
|
return $response_value;
|
|
}
|
|
|
|
sub parse_rpc_response_page{
|
|
my($self, $page) = @_;
|
|
my $parser = RPC::XML::ParserFactory->new();
|
|
return $parser->parse($page);
|
|
}
|
|
sub parse_rpc_response{
|
|
my($self,$rpc_response) = @_;
|
|
return $rpc_response->value->value;
|
|
}
|
|
|
|
sub extract_response_description{
|
|
my($self,$response_value) = @_;
|
|
|
|
if(('HASH' eq ref $response_value) && $response_value->{faultString}){
|
|
return $response_value->{faultString};
|
|
} else {
|
|
return;
|
|
}
|
|
}
|
|
sub init_content_params{
|
|
my($self) = @_;
|
|
$self->{content_params} ||= {};
|
|
$self->content_params->{uri} = $self->get_bootstrap_uri();
|
|
|
|
$self->content_params->{mac} = normalize_mac($self->params->{mac});
|
|
if(defined $self->params->{mac_old}) {
|
|
$self->content_params->{mac_old} = normalize_mac($self->params->{mac_old});
|
|
}
|
|
}
|
|
sub normalize_mac {
|
|
my ($mac) = @_;
|
|
return unless($mac);
|
|
$mac =~s/[^A-F0-9]//gi;
|
|
$mac = uc($mac);
|
|
return $mac;
|
|
}
|
|
|
|
sub get_basic_authorization{
|
|
my($self) = @_;
|
|
my $authorization = encode_base64(join(':',@{$self->params->{credentials}}{qw/user password/}));
|
|
$authorization =~s/[ \s]//gis;
|
|
return { 'Authorization' => 'Basic '.$authorization };
|
|
}
|
|
sub get_bootstrap_uri{
|
|
my ($self) = @_;
|
|
my $uri = $self->params->{redirect_uri};
|
|
my $uri_params = $self->params->{redirect_params}->{sync_params} || '';
|
|
if(!$uri){
|
|
my $cfg = $self->bootstrap_uri_conf();
|
|
$uri = "$cfg->{schema}://$cfg->{host}:$cfg->{port}/device/autoprov/bootstrap/";
|
|
}
|
|
$uri .= $uri_params;
|
|
return $self->process_bootstrap_uri($uri);
|
|
}
|
|
|
|
sub process_bootstrap_uri{
|
|
my($self,$uri) = @_;
|
|
$uri = $self->bootstrap_uri_protocol($uri);
|
|
return $uri;
|
|
}
|
|
|
|
sub bootstrap_uri_protocol{
|
|
my($self,$uri) = @_;
|
|
if($uri !~/^(?:https?|t?ftp):\/\//i ){
|
|
$uri = 'http://'.$uri;
|
|
}
|
|
return $uri;
|
|
}
|
|
sub bootstrap_uri_mac{
|
|
my($self, $uri) = @_;
|
|
if ($uri !~/\{MAC\}$/){
|
|
if ($uri !~/\/$/){
|
|
$uri .= '/' ;
|
|
}
|
|
$uri .= '{MAC}' ;
|
|
}
|
|
return $uri;
|
|
}
|
|
#separated as this logic also used in other places, so can be moved to other utils module
|
|
sub bootstrap_uri_conf{
|
|
my ($self) = @_;
|
|
my $c = $self->params->{c};
|
|
my $cfg = {
|
|
#schema => $c->config->{deviceprovisioning}->{secure} ? 'https' : 'http',
|
|
schema => 'http', # for bootstrapping, we always use http
|
|
host => $c->config->{deviceprovisioning}->{host} // $c->req->uri->host,
|
|
port => $c->config->{deviceprovisioning}->{bootstrap_port} // 1445,
|
|
};
|
|
return $cfg;
|
|
}
|
|
1;
|
|
|
|
=head1 NAME
|
|
|
|
NGCP::Panel::Utils::DeviceBootstrap
|
|
|
|
=head1 DESCRIPTION
|
|
|
|
Make API requests to configure remote redirect servers for requested MAC with autorpov uri.
|
|
|
|
=head1 METHODS
|
|
|
|
=head2 bootstrap
|
|
|
|
Dispatch to proper vendor API call.
|
|
|
|
=head1 AUTHOR
|
|
|
|
Irina Peshinskaya C<< <ipeshinskaya@sipwise.com> >>
|
|
|
|
=head1 LICENSE
|
|
|
|
This library is free software. You can redistribute it and/or modify
|
|
it under the same terms as Perl itself.
|
|
|
|
=cut
|
|
# vim: set tabstop=4 expandtab:
|