diff options
author | Jonathan Prykop <jonathan@freeside.biz> | 2015-12-09 23:39:52 -0600 |
---|---|---|
committer | Jonathan Prykop <jonathan@freeside.biz> | 2015-12-09 23:39:52 -0600 |
commit | 3a02a1bce4190ce0d94883709e0a6c362bcb0af3 (patch) | |
tree | 055961d63c00774effa2890a5ce20d8965418fdd | |
parent | af0bf1fd5b9cb1316d6e34bff0ed41061e14443d (diff) |
RT#39115: View SNMP info on svc_broadband service
-rw-r--r-- | FS/FS/part_export/broadband_snmp_get.pm | 113 | ||||
-rw-r--r-- | httemplate/edit/elements/part_export/broadband_snmp.html | 8 | ||||
-rw-r--r-- | httemplate/edit/elements/part_export/broadband_snmp_get.html | 77 | ||||
-rw-r--r-- | httemplate/elements/broadband_snmp_get-dialog.html | 68 | ||||
-rw-r--r-- | httemplate/misc/select-mib-popup.html (renamed from httemplate/elements/select-mib-popup.html) | 0 | ||||
-rw-r--r-- | httemplate/misc/xmlhttp-broadband_snmp_get.cgi | 35 | ||||
-rw-r--r-- | httemplate/view/svc_broadband.cgi | 1 |
7 files changed, 299 insertions, 3 deletions
diff --git a/FS/FS/part_export/broadband_snmp_get.pm b/FS/FS/part_export/broadband_snmp_get.pm new file mode 100644 index 000000000..faa51ed06 --- /dev/null +++ b/FS/FS/part_export/broadband_snmp_get.pm @@ -0,0 +1,113 @@ +package FS::part_export::broadband_snmp_get; + +use strict; +use vars qw(%info $DEBUG); +use base 'FS::part_export'; +use SNMP; +use Tie::IxHash; + +tie my %snmp_version, 'Tie::IxHash', + v1 => '1', + v2c => '2c' + # v3 unimplemented +; + +tie my %options, 'Tie::IxHash', + 'snmp_version' => { + label=>'SNMP version', + type => 'select', + options => [ keys %snmp_version ], + }, + 'snmp_community' => { 'label'=>'Community', 'default'=>'public' }, + 'snmp_timeout' => { label=>'Timeout (seconds)', 'default'=>1 }, + 'snmp_oid' => { label=>'Object ID', multiple=>1 }, +; + +%info = ( + 'svc' => 'svc_broadband', + 'desc' => 'Enable interface display of realtime SNMP get requests to service IP address', + 'config_element' => '/edit/elements/part_export/broadband_snmp_get.html', + 'options' => \%options, + 'no_machine' => 1, + 'notes' => <<'END', +Use this export to configure the community and object ids for displaying realtime +SNMP data from the service IP address when viewing a provisioned service. Timeout is +per object, and should be small enough for realtime use. This export takes no action +during provisioning itself; it is expected that snmp will be separately +configured on the service machine. +END +); + +sub export_insert { ''; } +sub export_replace { ''; } +sub export_delete { ''; } +sub export_suspend { ''; } +sub export_unsuspend { ''; } + +=pod + +=head1 NAME + +FS::part_export::broadband_snmp_get + +=head1 SYNOPSIS + +Configuration for realtime snmp requests to svc_broadband IP address + +=head1 METHODS + +=cut + +=over 4 + +=item snmp_results SVC + +Request statistics from SVC ip address. Returns an array of hashes with keys + +objectID + +label + +value + +error - error when attempting to load this object + +=cut + +sub snmp_results { + my ($self, $svc) = @_; + my $host = $svc->ip_addr; + my $comm = $self->option('snmp_community'); + my $vers = $self->option('snmp_version'); + my $time = ($self->option('snmp_timeout') || 1) * 1000; + my @oids = split("\n", $self->option('snmp_oid')); + my %connect = ( + 'DestHost' => $host, + 'Community' => $comm, + 'Version' => $vers, + 'Timeout' => $time, + ); + my $snmp = new SNMP::Session(%connect); + return { 'error' => 'Error creating SNMP session' } unless $snmp; + return { 'error' => $snmp->{'ErrorStr'} } if $snmp->{'ErrorStr'}; + my @out; + foreach my $oid (@oids) { + $oid = $SNMP::MIB{$oid}->{'objectID'} if $SNMP::MIB{$oid}; + my $value = $snmp->get($oid.'.0'); + if ($snmp->{'ErrorStr'}) { + push @out, { 'error' => $snmp->{'ErrorStr'} }; + next; + } + my %result = map { $_ => $SNMP::MIB{$oid}{$_} } qw( objectID label value ); + $result{'value'} = $value; + push @out, \%result; + } + return @out; +} + +=back + +=cut + +1; + diff --git a/httemplate/edit/elements/part_export/broadband_snmp.html b/httemplate/edit/elements/part_export/broadband_snmp.html index ebb765dee..b4d57edd5 100644 --- a/httemplate/edit/elements/part_export/broadband_snmp.html +++ b/httemplate/edit/elements/part_export/broadband_snmp.html @@ -11,7 +11,7 @@ <& /elements/tr-input-text.html, label => 'Community', field => 'community', - curr_value => $part_export->option('community'), + curr_value => $part_export->option('community') || $opt{'export_info'}->{'options'}->{'community'}->{'default'}, &> <& /elements/tr-checkbox.html, label => 'Send IP address changes to new address', @@ -30,7 +30,7 @@ function open_select_mib(obj) { nd(1); // if there's already one open, close it var rownum = obj.rownum; var curr_oid = obj.form.elements['oid' + rownum].value || ''; - var url = '<%$fsurl%>/elements/select-mib-popup.html?' + + var url = '<%$fsurl%>misc/select-mib-popup.html?' + 'callback=receive_mib;' + 'arg=' + rownum + ';curr_value=' + curr_oid; @@ -45,8 +45,10 @@ function open_select_mib(obj) { function receive_mib(obj, rownum) { //console.log(JSON.stringify(obj)); // we don't really need the numeric OID or any of the other properties - document.getElementById('oid'+rownum).value = obj.fullname; + var oidfield = document.getElementById('oid'+rownum); + oidfield.value = obj.fullname; document.getElementById('datatype'+rownum).value = obj.type; + oidfield.onchange(); //should be same as datatype, only need to run one } </script> diff --git a/httemplate/edit/elements/part_export/broadband_snmp_get.html b/httemplate/edit/elements/part_export/broadband_snmp_get.html new file mode 100644 index 000000000..8b8717c29 --- /dev/null +++ b/httemplate/edit/elements/part_export/broadband_snmp_get.html @@ -0,0 +1,77 @@ +<%doc> +Quite a bit of false laziness with edit/elements/part_export/broadband_snmp.html +</%doc> +<& head.html, %opt &> +<INPUT TYPE="hidden" NAME="options" VALUE="snmp_community,snmp_version,snmp_timeout"> +<& /elements/tr-select.html, + label => 'SNMP version', + field => 'snmp_version', + options => [ '1', '2c' ], + curr_value => $part_export->option('version') +&> +<& /elements/tr-input-text.html, + label => 'Community', + field => 'snmp_community', + curr_value => $part_export->option('community') || $opt{'export_info'}->{'options'}->{'snmp_community'}->{'default'}, +&> +<& /elements/tr-input-text.html, + label => 'Timeout (seconds)', + field => 'snmp_timeout', + curr_value => $part_export->option('timeout') || $opt{'export_info'}->{'options'}->{'snmp_timeout'}->{'default'}, +&> +</TABLE> +<script type="text/javascript"> +function open_select_mib_get(obj) { + nd(1); // if there's already one open, close it + var rownum = obj.rownum; + var curr_oid = obj.form.elements['snmp_oid' + rownum].value || ''; + var url = '<%$fsurl%>misc/select-mib-popup.html?' + + 'callback=receive_mib_get;' + + 'arg=' + rownum + + ';curr_value=' + curr_oid; + overlib( + OLiframeContent(url, 550, 450, '<% $popup_name %>', 0, 'auto'), + CAPTION, 'Select MIB object', STICKY, AUTOSTATUSCAP, + MIDX, 0, MIDY, 0, DRAGGABLE, CLOSECLICK, + BGCOLOR, '#333399', CGCOLOR, '#333399', + CLOSETEXT, 'Close' + ); +} +function receive_mib_get(obj, rownum) { + var oidfield = document.getElementById('snmp_oid'+rownum); + oidfield.value = obj.fullname; + oidfield.onchange(); +} +</script> + +<table bgcolor="#cccccc" border=0 cellspacing=3> +<TR><TH>Object ID</TH></TR> +<TR id="broadband_snmp_get_template"> + <TD> + <INPUT NAME="oid" ID="oid" SIZE="54"> + <INPUT TYPE="button" VALUE="..." ID="openselector" onclick="open_select_mib_get(this)"> + </TD> +</TR> +<& /elements/auto-table.html, + template_row => 'broadband_snmp_get_template', + fieldorder => ['oid'], + data => \@data, + table => 'snmp', +&> +<INPUT TYPE="hidden" NAME="multi_options" VALUE="snmp_oid"> +<& foot.html, %opt &> +<%init> +my %opt = @_; + +my $part_export = $opt{part_export} || FS::part_export->new; + +my @oids = split("\n", $part_export->option('snmp_oid')); + +my @data; +while (@oids) { + my @thisrow = (shift(@oids)); + push @data, \@thisrow if grep length($_), @thisrow; +} + +my $popup_name = 'popup-'.time."-$$-".rand() * 2**32; +</%init> diff --git a/httemplate/elements/broadband_snmp_get-dialog.html b/httemplate/elements/broadband_snmp_get-dialog.html new file mode 100644 index 000000000..61bb9c763 --- /dev/null +++ b/httemplate/elements/broadband_snmp_get-dialog.html @@ -0,0 +1,68 @@ +<%doc> +Adds a link to display snmp statistics based on broadband_snmp_get export config. +Performs necessary checks such that, if no such exports are configured for the passed +service, returns blank space (ie may be safely invoked even if no exports are configured.) + + <& '/elements/broadband_snmp_get-dialog.html', svc => $svc &> + +</%doc> +% if (@snmp) { +<& '/elements/xmlhttp.html', + 'url' => $fsurl.'misc/xmlhttp-broadband_snmp_get.cgi', + 'subs' => [ 'broadband_snmp_get_request' ] + &> +<SCRIPT> +function broadband_snmp_get (svcnum) { + var jqd = $( '#broadband_snmp_get_dialog' ); + if (!jqd.dialog( 'isOpen' )) { + jqd.dialog( 'open' ); + } + document.getElementById('broadband_snmp_get_dialog').innerHTML = '<B>Loading...</B>'; + broadband_snmp_get_request('svcnum',svcnum, + function (result) { + var objects = JSON.parse(result) || []; + if (objects.length) { + var table = document.createElement('table'); + for (i = 0; i < objects.length; i++) { + var row = document.createElement('tr'); + var obj = objects[i]; + if (obj.error) { + var cell = document.createElement('td'); + cell.colSpan = '2'; + cell.innerHTML = obj['error']; + row.appendChild(cell); + } else { + var cell = document.createElement('td'); + cell.innerHTML = obj['label']; + row.appendChild(cell); + cell = document.createElement('td'); + cell.innerHTML = obj['value']; + row.appendChild(cell); + } + table.appendChild(row); + } + var dialog = document.getElementById('broadband_snmp_get_dialog'); + dialog.innerHTML = ''; + dialog.appendChild(table); + } // if objects.length + } // function + ); // broadband_snmp_get_request +} // broadband_snmp_get +</SCRIPT> +<SPAN ID="broadband_snmp_get_dialog"></SPAN> +<SPAN ID="broadband_snmp_get_link"> +<A HREF="javascript: void(0)" onclick="broadband_snmp_get('<% $svcnum %>')">(snmp)</A> +</SPAN> +<SCRIPT> +$( '#broadband_snmp_get_dialog' ).dialog({ + position: { my: "left top", at: "left top", of: "#broadband_snmp_get_link" }, + autoOpen: false, + title: 'SNMP', +}); +</SCRIPT> +% } #if @snmp +<%init> +my(%opt) = @_; +my @snmp = $opt{'svc'}->cust_svc->part_svc->part_export('broadband_snmp_get'); +my $svcnum = $opt{'svc'}->svcnum; +</%init> diff --git a/httemplate/elements/select-mib-popup.html b/httemplate/misc/select-mib-popup.html index f95ce2b97..f95ce2b97 100644 --- a/httemplate/elements/select-mib-popup.html +++ b/httemplate/misc/select-mib-popup.html diff --git a/httemplate/misc/xmlhttp-broadband_snmp_get.cgi b/httemplate/misc/xmlhttp-broadband_snmp_get.cgi new file mode 100644 index 000000000..a6f926722 --- /dev/null +++ b/httemplate/misc/xmlhttp-broadband_snmp_get.cgi @@ -0,0 +1,35 @@ +<%doc> +Requires arg $svcnum. Returns JSON-encoded realtime snmp results +for configured broadband_snmp_get exports. +</%doc> +<% encode_json(\@result) %>\ +<%init> + +# access/agent permissions lifted from /view/elements/svc_Common.html + +die "access denied" + unless $FS::CurrentUser::CurrentUser->access_right('View customer services'); + +my %arg = $cgi->param('arg'); +my $svc = qsearchs({ + 'select' => 'svc_broadband.*', + 'table' => 'svc_broadband', + 'addl_from' => ' LEFT JOIN cust_svc USING ( svcnum ) '. + ' LEFT JOIN cust_pkg USING ( pkgnum ) '. + ' LEFT JOIN cust_main USING ( custnum ) ', + 'hashref' => { 'svcnum' => $arg{'svcnum'} }, + 'extra_sql' => ' AND '. $FS::CurrentUser::CurrentUser->agentnums_sql( + 'null_right' => 'View/link unlinked services' + ), +}) or die "Unknown svcnum ".$arg{'svcnum'}." in svc_broadband table\n"; + +my @part_export = $svc->cust_svc->part_svc->part_export('broadband_snmp_get'); + +my @result; +foreach my $part_export (@part_export) { + push @result, $part_export->snmp_results($svc); +} + +</%init> + + diff --git a/httemplate/view/svc_broadband.cgi b/httemplate/view/svc_broadband.cgi index 4935a1096..bc272e844 100644 --- a/httemplate/view/svc_broadband.cgi +++ b/httemplate/view/svc_broadband.cgi @@ -72,6 +72,7 @@ sub ip_addr { my $out = $ip_addr; $out .= ' (' . include('/elements/popup_link-ping.html', ip => $ip_addr) . ')' if $ip_addr; + $out .= include('/elements/broadband_snmp_get-dialog.html', svc => $svc); if ($svc->cust_svc->part_svc->part_export('cacti')) { $out .= ' (<A HREF="' . popurl(2) |