Change-Id: Ib10c44dce69ce7a1f7c1017ce25b85c6590f9b0cchanges/56/25756/18
parent
759ce4e9ab
commit
ea25662c18
@ -0,0 +1,189 @@
|
|||||||
|
package NGCP::Panel::Utils::DeviceBootstrap::SipwiseProfile;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use URI::Escape;
|
||||||
|
use Moo;
|
||||||
|
use Types::Standard qw(Str);
|
||||||
|
use JSON qw/encode_json decode_json/;
|
||||||
|
use MIME::Base64;
|
||||||
|
|
||||||
|
extends 'NGCP::Panel::Utils::DeviceBootstrap::VendorREST';
|
||||||
|
|
||||||
|
sub rpc_server_params {
|
||||||
|
my $self = shift;
|
||||||
|
my $cfg = {
|
||||||
|
proto => 'https',
|
||||||
|
host => 'api.eds.sipwise.com',
|
||||||
|
port => '443',
|
||||||
|
path => 'api',
|
||||||
|
};
|
||||||
|
$self->{rpc_server_params} = $cfg;
|
||||||
|
return $self->{rpc_server_params};
|
||||||
|
}
|
||||||
|
|
||||||
|
sub register_model {
|
||||||
|
my($self) = @_;
|
||||||
|
$self->rpc_server_params;
|
||||||
|
my $c = $self->params->{c};
|
||||||
|
|
||||||
|
$c->log->error("++++ SipwiseProfile register_model");
|
||||||
|
|
||||||
|
my $cfg = $self->{rpc_server_params};
|
||||||
|
my $redirect_url = $self->get_config_uri();
|
||||||
|
|
||||||
|
# first, fetch profile from eds
|
||||||
|
my $url = "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/profiles?q=ngcp";
|
||||||
|
$c->log->debug("SipwiseProfile check profile '$url'");
|
||||||
|
my $req = HTTP::Request->new(GET => $url);
|
||||||
|
$req->header(%{$self->get_basic_authorization($self->params->{credentials})});
|
||||||
|
my $res = $self->_ua->request($req);
|
||||||
|
my $prof;
|
||||||
|
|
||||||
|
if ($res->is_success) {
|
||||||
|
$c->log->debug("SipwiseProfile check profile query successful, data: " . $res->decoded_content);
|
||||||
|
my $data = decode_json($res->decoded_content);
|
||||||
|
if (ref $data eq 'HASH' && exists $data->{data} && ref $data->{data} eq 'ARRAY' && @{ $data->{data} }) {
|
||||||
|
# profile exists, nothing to do
|
||||||
|
$prof = shift @{ $data->{data} };
|
||||||
|
} elsif (ref $data eq 'HASH' && exists $data->{data} && ref $data->{data} eq 'ARRAY' && @{ $data->{data} } == 0) {
|
||||||
|
# profile does not exist, create it
|
||||||
|
$c->log->debug("SipwiseProfile ngcp profile not available for this reseller, create it");
|
||||||
|
|
||||||
|
# first we need to create the blob containing the
|
||||||
|
# server's ca cert
|
||||||
|
my $cert = $c->model('CA')->get_server_ca_cert($c);
|
||||||
|
$c->log->debug("SipwiseProfile got ca cert, encode");
|
||||||
|
my $cacert = encode_base64($cert);
|
||||||
|
$c->log->debug("SipwiseProfile got encoded ca cert, send");
|
||||||
|
$url = "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/blobs";
|
||||||
|
$c->log->debug("SipwiseProfile create blob '$url'");
|
||||||
|
my $req = HTTP::Request->new(POST => $url);
|
||||||
|
$req->header(%{$self->get_basic_authorization($self->params->{credentials})});
|
||||||
|
$req->content(encode_json({ data => { name => 'ngcp-ca-cert.pem', b64body => $cacert, content_type => 'application/octet-stream' } }));
|
||||||
|
$req->content_type('application/json');
|
||||||
|
$res = $self->_ua->request($req);
|
||||||
|
if ($res->is_success) {
|
||||||
|
$c->log->debug("SipwiseProfile create blob query successful");
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile create blob query failed (" . $res->status_line . "): " . $res->decoded_content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
# now create the profile, referring to the blob and the
|
||||||
|
# server's provisioning url
|
||||||
|
my $profile_body = "<settings><setting override=\"true\" value=\"https:\/\/dev.eds.sipwise.com\/dev\/blob\/\$EDS{MAC}\/ngcp-ca-cert.pem\" id=\"ThirdPartyCAUrl\"\/><setting override=\"true\" value=\"$redirect_url\" id=\"EdsEnetcfgDmUrl\"\/><\/settings>";
|
||||||
|
|
||||||
|
$url = "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/profiles";
|
||||||
|
$c->log->debug("SipwiseProfile create profile '$url'");
|
||||||
|
$req = HTTP::Request->new(POST => $url);
|
||||||
|
$req->header(%{$self->get_basic_authorization($self->params->{credentials})});
|
||||||
|
$req->content(encode_json({ data => { body => $profile_body, content_type => 'text/xml', description => 'ngcp' } }));
|
||||||
|
$req->content_type('application/json');
|
||||||
|
$res = $self->_ua->request($req);
|
||||||
|
if ($res->is_success) {
|
||||||
|
$c->log->debug("SipwiseProfile create profile query successful, data: " . $res->decoded_content);
|
||||||
|
$data = decode_json($res->decoded_content);
|
||||||
|
if (ref $data eq 'HASH' && exists $data->{data} && ref $data->{data} eq 'HASH') {
|
||||||
|
$prof = $data->{data};
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile create profile query failed with invalid data: " . $res->decoded_content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile create profile query failed (" . $res->status_line . "): " . $res->decoded_content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile check profile query failed due to invalid body");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile fetch profile query failed (" . $res->status_line . "): " . $res->decoded_content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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};
|
||||||
|
|
||||||
|
$self->{rpc_server_params} //= $self->rpc_server_params;
|
||||||
|
my $cfg = $self->{rpc_server_params};
|
||||||
|
|
||||||
|
$c->log->debug("SipwiseProfile prepare request for action $action");
|
||||||
|
|
||||||
|
if ($action eq 'register_content') {
|
||||||
|
|
||||||
|
# first, fetch profile from eds
|
||||||
|
my $url = "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/profiles?q=ngcp";
|
||||||
|
$c->log->debug("SipwiseProfile check profile '$url'");
|
||||||
|
my $req = HTTP::Request->new(GET => $url);
|
||||||
|
$req->header(%{$self->get_basic_authorization($self->params->{credentials})});
|
||||||
|
my $res = $self->_ua->request($req);
|
||||||
|
my $prof;
|
||||||
|
|
||||||
|
if ($res->is_success) {
|
||||||
|
$c->log->debug("SipwiseProfile check profile query successful, data: " . $res->decoded_content);
|
||||||
|
my $data = decode_json($res->decoded_content);
|
||||||
|
if (ref $data eq 'HASH' && exists $data->{data} && ref $data->{data} eq 'ARRAY' && @{ $data->{data} }) {
|
||||||
|
# profile exists, nothing to do
|
||||||
|
$prof = shift @{ $data->{data} };
|
||||||
|
} elsif (ref $data eq 'HASH' && exists $data->{data} && ref $data->{data} eq 'ARRAY' && @{ $data->{data} } == 0) {
|
||||||
|
$c->log->error("SipwiseProfile ngcp profile does not exist");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile check profile query failed due to invalid body");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$ret = {
|
||||||
|
method =>'POST',
|
||||||
|
url => "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/devices",
|
||||||
|
body => { data => { mac => $new_mac, profile_id => $prof->{id}, url => undef} },
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile unregister 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
|
||||||
|
my $url = "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/devices?q=$old_mac";
|
||||||
|
$c->log->debug("SipwiseProfile unregister via url '$url'");
|
||||||
|
my $req = HTTP::Request->new(GET => $url);
|
||||||
|
$req->header(%{$self->get_basic_authorization($self->params->{credentials})});
|
||||||
|
my $res = $self->_ua->request($req);
|
||||||
|
if ($res->is_success) {
|
||||||
|
$c->log->debug("SipwiseProfile unregister query successful, data: " . $res->decoded_content);
|
||||||
|
my $data = decode_json($res->decoded_content);
|
||||||
|
my $dev;
|
||||||
|
if (ref $data eq 'HASH' && exists $data->{data} && ref $data->{data} eq 'ARRAY' && @{ $data->{data} }) {
|
||||||
|
$dev = shift @{ $data->{data} };
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile unregister query failed due to invalid body");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$ret = {
|
||||||
|
method =>'DELETE',
|
||||||
|
url => "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/devices/$$dev{id}",
|
||||||
|
body => undef,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseProfile unregister query failed (" . $res->status_line . "): " . $res->decoded_content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
@ -0,0 +1,76 @@
|
|||||||
|
package NGCP::Panel::Utils::DeviceBootstrap::SipwiseRedirect;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use URI::Escape;
|
||||||
|
use Moo;
|
||||||
|
use Types::Standard qw(Str);
|
||||||
|
use JSON qw/encode_json decode_json/;
|
||||||
|
|
||||||
|
extends 'NGCP::Panel::Utils::DeviceBootstrap::VendorREST';
|
||||||
|
|
||||||
|
sub rpc_server_params {
|
||||||
|
my $self = shift;
|
||||||
|
my $cfg = {
|
||||||
|
proto => 'https',
|
||||||
|
host => 'api.eds.sipwise.com',
|
||||||
|
port => '443',
|
||||||
|
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 $redirect_url = $self->get_bootstrap_uri();
|
||||||
|
|
||||||
|
$self->{rpc_server_params} //= $self->rpc_server_params;
|
||||||
|
my $cfg = $self->{rpc_server_params};
|
||||||
|
|
||||||
|
if ($action eq 'register_content') {
|
||||||
|
$ret = {
|
||||||
|
method =>'POST',
|
||||||
|
url => "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/devices",
|
||||||
|
body => { data => { mac => $new_mac, profile_id => undef, url => $redirect_url} },
|
||||||
|
};
|
||||||
|
} elsif ($action eq 'unregister_content') {
|
||||||
|
# we've to fetch the id first before constructing the delete request
|
||||||
|
my $url = "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/devices?q=$old_mac";
|
||||||
|
$c->log->debug("SipwiseRedirect unregister via url '$url'");
|
||||||
|
my $req = HTTP::Request->new(GET => $url);
|
||||||
|
$req->header(%{$self->get_basic_authorization($self->params->{credentials})});
|
||||||
|
my $res = $self->_ua->request($req);
|
||||||
|
if ($res->is_success) {
|
||||||
|
$c->log->debug("SipwiseRedirect unregister query successful, data: " . $res->decoded_content);
|
||||||
|
my $data = decode_json($res->decoded_content);
|
||||||
|
my $dev;
|
||||||
|
if (ref $data eq 'HASH' && exists $data->{data} && ref $data->{data} eq 'ARRAY' && @{ $data->{data} }) {
|
||||||
|
$dev = shift @{ $data->{data} };
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseRedirect unregister query failed due to invalid body");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$ret = {
|
||||||
|
method =>'DELETE',
|
||||||
|
url => "$$cfg{proto}://$$cfg{host}:$$cfg{port}/$$cfg{path}/devices/$$dev{id}",
|
||||||
|
body => undef,
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
$c->log->error("SipwiseRedirect unregister query failed (" . $res->status_line . "): " . $res->decoded_content);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
@ -0,0 +1,43 @@
|
|||||||
|
package NGCP::Panel::Utils::DeviceBootstrap::VendorREST;
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use Moo;
|
||||||
|
use HTTP::Request;
|
||||||
|
use JSON qw/encode_json decode_json/;
|
||||||
|
extends 'NGCP::Panel::Utils::DeviceBootstrap::VendorRPC';
|
||||||
|
|
||||||
|
sub redirect_server_call {
|
||||||
|
my ($self, $action) = @_;
|
||||||
|
my $c = $self->params->{c};
|
||||||
|
$self->init_content_params();
|
||||||
|
|
||||||
|
$c->log->debug("Performing VendorREST call for action '$action'");
|
||||||
|
|
||||||
|
my $method = $action.'_content';
|
||||||
|
my $data = $self->rest_prepare_request($method);
|
||||||
|
unless ($data) {
|
||||||
|
$c->log->debug("VendorREST call for action '$action' failed due to missing data");
|
||||||
|
return "No bootstrap data from redirect service";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $req = HTTP::Request->new($data->{method} => $data->{url});
|
||||||
|
$req->header(%{$self->get_basic_authorization($self->params->{credentials})});
|
||||||
|
if (defined $data->{body}) {
|
||||||
|
$req->content(encode_json($data->{body}));
|
||||||
|
$req->content_type('application/json');
|
||||||
|
}
|
||||||
|
my $res = $self->_ua->request($req);
|
||||||
|
if ($res->is_success) {
|
||||||
|
$c->log->info("Performing VendorREST for action '$action' succeeded");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
$c->log->error("Performing VendorREST for action '$action' failed (" . $res->status_line . "): " . $res->decoded_content);
|
||||||
|
return "Failed to perform redirect service action";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
|
|
||||||
|
# vim: set tabstop=4 expandtab:
|
Loading…
Reference in new issue