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.
198 lines
7.6 KiB
198 lines
7.6 KiB
package NGCP::Panel::Utils::DeviceBootstrap::ALE;
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
use URI::Escape;
|
|
use Moo;
|
|
use Types::Standard qw(Str);
|
|
use JSON qw/encode_json decode_json/;
|
|
use MIME::Base64;
|
|
use Digest::MD5 qw/md5_hex/;
|
|
|
|
extends 'NGCP::Panel::Utils::DeviceBootstrap::VendorREST';
|
|
|
|
sub rpc_server_params{
|
|
my $self = shift;
|
|
my $cfg = {
|
|
proto => 'https',
|
|
host => 'api.rps.ce.al-enterprise.com',
|
|
path => 'api',
|
|
};
|
|
$self->{rpc_server_params} = $cfg;
|
|
return $self->{rpc_server_params};
|
|
}
|
|
|
|
sub rest_prepare_request {
|
|
my ($self, $action) = @_;
|
|
my $c = $self->params->{c};
|
|
my $ret;
|
|
my $new_mac = $self->content_params->{mac};
|
|
my $old_mac = $self->content_params->{mac_old};
|
|
my $param_servername = $self->content_params->{server_name};
|
|
my $param_uri = $self->content_params->{uri};
|
|
my $token;
|
|
|
|
$self->{rpc_server_params} //= $self->rpc_server_params;
|
|
my $cfg = $self->{rpc_server_params};
|
|
|
|
$c->log->debug("ALE prepare request for action $action");
|
|
|
|
# first, generate token
|
|
my $url = "$$cfg{proto}://$$cfg{host}/$$cfg{path}/bp_user/generate/token";
|
|
$c->log->debug("ALE generate token '$url'");
|
|
my $req = HTTP::Request->new(GET => $url);
|
|
$req->header(':api_user_name' => $self->params->{credentials}->{user});
|
|
$req->header(':api_password' => $self->params->{credentials}->{password});
|
|
my $res = $self->_ua->request($req);
|
|
|
|
my $data = decode_json($res->decoded_content);
|
|
if ($res->is_success && $data->{success}) {
|
|
$c->log->debug("Token generation successful, data: " . $res->decoded_content);
|
|
$token = $data->{data}->{token};
|
|
} else {
|
|
$c->log->error("Token generation failed (" . $res->status_line . "): " . $res->decoded_content);
|
|
return;
|
|
}
|
|
|
|
if ($action eq 'register_content') {
|
|
# fetch server
|
|
$url = "$$cfg{proto}://$$cfg{host}/$$cfg{path}/servers";
|
|
$c->log->debug("ALE check server '$url'");
|
|
$req = HTTP::Request->new(GET => $url);
|
|
$req->header(token => $token);
|
|
$res = $self->_ua->request($req);
|
|
|
|
my $server_id;
|
|
$data = decode_json($res->decoded_content);
|
|
if ($res->is_success && $data->{success}) {
|
|
$c->log->debug("ALE check server query successful, data: " . $res->decoded_content);
|
|
my ($server) = grep {$_->{server_url} eq $param_uri} @{$data->{data}->{server_list}};
|
|
if ($server) {
|
|
$server_id = $server->{server_id};
|
|
}
|
|
else {
|
|
#server does not exist, create it
|
|
$c->log->debug("ALE create server '$url'");
|
|
$req = HTTP::Request->new(POST => $url);
|
|
$req->header(token => $token);
|
|
$req->content_type('application/json');
|
|
$req->content(encode_json({
|
|
server_name => $param_servername,
|
|
server_url => $param_uri,
|
|
})
|
|
);
|
|
$res = $self->_ua->request($req);
|
|
$data = decode_json($res->decoded_content);
|
|
if ($res->is_success && $data->{success}) {
|
|
$c->log->debug("ALE create server query successful, data: " . $res->decoded_content);
|
|
$server_id = $data->{data}->{server_id};
|
|
}
|
|
else{
|
|
$c->log->error("ALE create server query failed (" . $res->status_line . "): " . $res->decoded_content);
|
|
return;
|
|
}
|
|
}
|
|
} else {
|
|
$c->log->error("ALE check server query failed (" . $res->status_line . "): " . $res->decoded_content);
|
|
return;
|
|
}
|
|
|
|
# fetch profile
|
|
$url = "$$cfg{proto}://$$cfg{host}/$$cfg{path}/profiles";
|
|
$c->log->debug("ALE check server '$url'");
|
|
$req = HTTP::Request->new(GET => $url);
|
|
$req->header(token => $token);
|
|
$res = $self->_ua->request($req);
|
|
|
|
$data = decode_json($res->decoded_content);
|
|
if ($res->is_success && $data->{success}) {
|
|
$c->log->debug("ALE check profile query successful, data: " . $res->decoded_content);
|
|
my $profile_id;
|
|
my ($profile) = grep {$_->{server_id} == $server_id} @{$data->{data}->{profile_list}};
|
|
if ($profile) {
|
|
$profile_id = $profile->{profile_id};
|
|
}
|
|
else {
|
|
#profile does not exist, create it
|
|
$c->log->debug("ALE create profile '$url'");
|
|
$req = HTTP::Request->new(POST => $url);
|
|
$req->header(token => $token);
|
|
$req->content_type('application/json');
|
|
$req->content(encode_json({
|
|
profile_name => $param_servername,
|
|
server_id => $server_id,
|
|
})
|
|
);
|
|
$res = $self->_ua->request($req);
|
|
$data = decode_json($res->decoded_content);
|
|
if ($res->is_success && $data->{success}) {
|
|
$c->log->debug("ALE create profile query successful, data: " . $res->decoded_content);
|
|
$profile_id = $data->{data}->{profile_id};
|
|
}
|
|
else{
|
|
$c->log->error("ALE create profile query failed (" . $res->status_line . "): " . $res->decoded_content);
|
|
return;
|
|
}
|
|
}
|
|
|
|
$ret = {
|
|
method =>'POST',
|
|
url => "$$cfg{proto}://$$cfg{host}/$$cfg{path}/devices",
|
|
body => { macs => [{mac =>$new_mac}], profile_id => $profile_id},
|
|
token => $token,
|
|
};
|
|
} else {
|
|
$c->log->error("ALE check profile query failed (" . $res->status_line . "): " . $res->decoded_content);
|
|
return;
|
|
}
|
|
} elsif ($action eq 'unregister_content') {
|
|
# we've to fetch the id first before constructing the delete request
|
|
$url = "$$cfg{proto}://$$cfg{host}/$$cfg{path}/devices";
|
|
$c->log->debug("ALE check devices '$url'");
|
|
$req = HTTP::Request->new(GET => $url);
|
|
$req->header(token => $token);
|
|
$res = $self->_ua->request($req);
|
|
$data = decode_json($res->decoded_content);
|
|
if ($res->is_success && $data->{success}) {
|
|
$c->log->debug("ALE check devices query successful, data: " . $res->decoded_content);
|
|
my $device_id;
|
|
my ($device) = grep {$_->{mac} == $old_mac} @{$data->{data}->{device_list}};
|
|
if ($device) {
|
|
$device_id = $device->{device_id};
|
|
}
|
|
$c->log->debug("ALE unregister query successful, data: " . $res->decoded_content);
|
|
$data = decode_json($res->decoded_content);
|
|
$ret = {
|
|
method =>'DELETE',
|
|
url => "$$cfg{proto}://$$cfg{host}/$$cfg{path}/devices/$device_id",
|
|
body => undef,
|
|
token => $token,
|
|
};
|
|
} else {
|
|
$c->log->error("ALE unregister query failed (" . $res->status_line . "): " . $res->decoded_content);
|
|
return;
|
|
}
|
|
}
|
|
|
|
return $ret;
|
|
}
|
|
|
|
around 'process_bootstrap_uri' => sub {
|
|
my($orig_method, $self, $uri) = @_;
|
|
$uri = $self->$orig_method($uri);
|
|
$self->content_params->{uri} = $uri;
|
|
$self->bootstrap_uri_server_name($uri);
|
|
return $self->content_params->{uri};
|
|
};
|
|
|
|
sub bootstrap_uri_server_name{
|
|
my($self,$uri) = @_;
|
|
$uri ||= $self->content_params->{uri};
|
|
#http://stackoverflow.com/questions/4826403/hash-algorithm-with-alphanumeric-output-of-20-characters-max
|
|
$self->content_params->{server_name} ||= substr(md5_hex($uri),0,20);
|
|
return $self->content_params->{server_name};
|
|
}
|
|
|
|
1;
|