Implement PBX device boot-strapping.

agranig/peering-route
Andreas Granig 13 years ago
parent fdc1f9514a
commit b4949f1a48

@ -12,10 +12,12 @@ use NGCP::Panel::Form::Customer::PbxExtensionSubscriber;
use NGCP::Panel::Form::Customer::PbxGroupBase;
use NGCP::Panel::Form::Customer::PbxGroup;
use NGCP::Panel::Form::Customer::PbxFieldDevice;
use NGCP::Panel::Form::Customer::PbxFieldDeviceSync;
use NGCP::Panel::Utils::Message;
use NGCP::Panel::Utils::Navigation;
use NGCP::Panel::Utils::DateTime;
use NGCP::Panel::Utils::Subscriber;
use Template;
=head1 NAME
@ -710,6 +712,63 @@ sub pbx_device_delete :Chained('pbx_device_base') :PathPart('delete') :Args(0) {
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for_action('/customer/details', $c->req->captures));
}
sub pbx_device_sync :Chained('pbx_device_base') :PathPart('sync') :Args(0) {
my ($self, $c) = @_;
my $form = NGCP::Panel::Form::Customer::PbxFieldDeviceSync->new;
my $posted = ($c->req->method eq 'POST');
# TODO: if registered, we could try taking the ip from location?
my $params = {};
$form->process(
posted => $posted,
params => $c->req->params,
item => $params,
);
if($posted && $form->validated) {
NGCP::Panel::Utils::Navigation::back_or($c, $c->uri_for_action('/customer/details', $c->req->captures));
}
my $dev = $c->stash->{pbx_device};
my $t = Template->new;
my $conf = {
client => {
ip => '__NGCP_CLIENT_IP__',
},
server => {
uri => $c->uri_for_action('/device/dev_field_config'),
},
};
my ($sync_uri, $real_sync_uri) = ("", "");
$sync_uri = $dev->profile->config->device->sync_uri;
$t->process(\$sync_uri, $conf, \$real_sync_uri);
my ($sync_params_field, $real_sync_params) = ("", "");
$sync_params_field = $dev->profile->config->device->sync_params;
my @sync_params = ();
if($sync_params_field) {
$t->process(\$sync_params_field, $conf, \$real_sync_params);
foreach my $p(split /\s*\,\s*/, $real_sync_params) {
my ($k, $v) = split /=/, $p;
if(defined $k && defined $v) {
push @sync_params, { key => $k, value => $v };
} elsif(defined $k) {
push @sync_params, { key => $k, value => 0 };
}
}
}
$c->stash(
form => $form,
devsync_flag => 1,
autoprov_uri => $real_sync_uri,
autoprov_method => $dev->profile->config->device->sync_method,
autoprov_params => \@sync_params,
);
}
=head1 AUTHOR

@ -808,9 +808,17 @@ sub devprof_edit :Chained('devprof_base') :PathPart('edit') :Args(0) {
);
}
sub dev_field_config :Chained('/') :PathPart('device/autoprov') :Args(1) {
sub dev_field_config :Chained('/') :PathPart('device/autoprov') :Args() {
my ($self, $c, $id) = @_;
unless($id) {
$c->response->content_type('text/plain');
$c->response->body("404 - device not found");
$c->response->status(404);
return;
}
$id =~ s/^([^\=]+)\=0$/$1/;
my $dev = $c->model('DB')->resultset('autoprov_field_devices')->find({
identifier => $id
});

@ -0,0 +1,41 @@
package NGCP::Panel::Form::Customer::PbxFieldDeviceSync;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';
use Moose::Util::TypeConstraints;
use HTML::FormHandler::Widget::Block::Bootstrap;
has '+widget_wrapper' => ( default => 'Bootstrap' );
sub build_render_list {[qw/fields actions/]}
sub build_form_element_class {[qw(form-horizontal)]}
has_field 'ip' => (
type => 'Text',
required => 1,
label => 'IP Address',
);
has_field 'sync' => (
type => 'Button',
value => 'Push Provisioning URL',
element_class => [qw/btn btn-primary/],
label => '',
);
has_block 'fields' => (
tag => 'div',
class => [qw/modal-body/],
render_list => [qw/ip/],
);
has_block 'actions' => (
tag => 'div',
class => [qw/modal-footer/],
render_list => [qw/sync/],
);
sub build_form_element_attr { { id => 'devsyncform' } }
1;
# vim: set tabstop=4 expandtab:

@ -38,6 +38,31 @@ has_field 'mac_image' => (
max_size => '67108864', # 64MB
);
has_field 'sync_uri' => (
type => 'Text',
required => 0,
label => 'Bootstrap Sync URI',
default => 'http://[% client.ip %]/admin/resync',
);
has_field 'sync_method' => (
type => 'Select',
required => 0,
label => 'Bootstrap Sync HTTP Method',
options => [
{ label => 'GET', value => 'GET' },
{ label => 'POST', value => 'POST' },
],
default => 'GET',
);
has_field 'sync_params' => (
type => 'Text',
required => 0,
label => 'Bootstrap Sync Parameters',
default => '[% server.uri %]/$MA',
);
has_field 'save' => (
type => 'Submit',
value => 'Save',
@ -48,7 +73,7 @@ has_field 'save' => (
has_block 'fields' => (
tag => 'div',
class => [qw/modal-body/],
render_list => [qw/vendor model front_image mac_image/],
render_list => [qw/vendor model front_image mac_image sync_uri sync_method sync_params/],
);
has_block 'actions' => (

@ -16,12 +16,6 @@ has_field 'reseller' => (
not_nullable => 1,
);
has_field 'model' => (
type => 'Text',
required => 1,
label => 'Model',
);
has_field 'save' => (
type => 'Submit',
value => 'Save',
@ -32,7 +26,7 @@ has_field 'save' => (
has_block 'fields' => (
tag => 'div',
class => [qw/modal-body/],
render_list => [qw/reseller vendor model front_image mac_image/],
render_list => [qw/reseller vendor model front_image mac_image sync_uri sync_method sync_params/],
);
has_block 'actions' => (

@ -273,6 +273,7 @@
[% UNLESS c.user.readonly -%]
<a class="btn btn-secondary btn-small" href="[% c.uri_for_action("/customer/pbx_device_delete", [contract.id, dev.id])%]" data-confirm="Delete"><i class="icon-remove"></i> Delete</a>
<a class="btn btn-primary btn-small" href="[% c.uri_for_action("/customer/pbx_device_edit", [contract.id, dev.id]) %]"><i class="icon-edit"></i> Edit</a>
<a class="btn btn-primary btn-small" href="[% c.uri_for_action("/customer/pbx_device_sync", [contract.id, dev.id]) %]"><i class="icon-edit"></i> Sync Device</a>
[% END -%]
</div>
</td>
@ -426,6 +427,82 @@
modal_footer();
modal_script(m.close_target = close_target);
-%]
[% ELSIF devsync_flag == 1 -%]
[%
PROCESS "helpers/modal.tt";
modal_header(m.create_flag=0,
m.name = "Sync Device");
form.render;
modal_footer();
modal_script(m.close_target = close_target);
-%]
<script>
$('input#sync').click(function(e) {
var timer; var loaded = 0;
var ip = $('form#devsyncform input#ip').val();
$('form#devsyncform .form_messages').empty();
// Add the iframe with a unique name
var iframe = document.createElement("iframe");
var uniqueString = "spa_autoconf_post";
document.body.appendChild(iframe);
iframe.style.display = "none";
iframe.contentWindow.name = uniqueString;
iframe.onload = function(e) {
$('input#ip').removeAttr("disabled");
clearTimeout(timer);
if(!loaded) {
loaded = 1;
$('form#devsyncform .form_messages').prepend('<div class="alert alert-success" style="margin:10px">Successfully pushed provisioning settings to device</div>');
} else {
console.log("iframe loaded after timer");
}
}
// construct a form with hidden inputs, targeting the iframe
if(!ip.length) {
return 0;
}
var autoprov_uri = "[% autoprov_uri %]";
console.log("before uri: " + autoprov_uri);
autoprov_uri = autoprov_uri.replace('__NGCP_CLIENT_IP__', ip);
console.log("after uri: " + autoprov_uri);
$('form#devsyncform').attr('target', uniqueString);
$('form#devsyncform').attr('action', autoprov_uri);
$('form#devsyncform').attr('method', "[% autoprov_method %]");
console.log("method=[% autoprov_method %], uri=" + autoprov_uri);
[% FOR p IN autoprov_params -%]
var input = document.createElement("input");
input.type = "hidden";
input.name = "[% p.key %]";
[%# IF p.value.defined -%]
input.value = "[% p.value %]";
[%# END -%]
$('form#devsyncform').append(input);
[% END -%]
timer = setTimeout(function() {
console.log("timeout hit");
$('input#ip').removeAttr("disabled");
if(loaded) {
console.log("iframe already loaded, we're fine?");
} else {
$('form#devsyncform .form_messages').prepend('<div class="alert alert-error" style="margin:10px">Failed to push provisioning settings to device. Is the IP Address reachable from your browser?</div>');
}
loaded = 1;
// TODO: get iframe by id
var iframes = document.getElementsByTagName('iframe');
for (var i = 0; i < iframes.length; i++) {
iframes[i].parentNode.removeChild(iframes[i]);
}
}, 5000);
$('form#devsyncform').submit(function() {
$('input#ip').attr("disabled", "disabled");
});
});
</script>
[% END -%]
[% # vim: set tabstop=4 syntax=html expandtab: -%]

Loading…
Cancel
Save