diff --git a/Netdisco/Changes b/Netdisco/Changes index 1860eb0a..de8f5f24 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,3 +1,9 @@ +2.028009_001 + + [NEW FEATURES] + + * Node Monitor admin panel and netdisco-do action + 2.028008 - 2014-07-22 [BUG FIXES] diff --git a/Netdisco/lib/App/Netdisco.pm b/Netdisco/lib/App/Netdisco.pm index 19d9e6de..c1c51fc1 100644 --- a/Netdisco/lib/App/Netdisco.pm +++ b/Netdisco/lib/App/Netdisco.pm @@ -4,7 +4,7 @@ use strict; use warnings; use 5.010_000; -our $VERSION = '2.028008'; +our $VERSION = '2.028009_001'; use App::Netdisco::Configuration; =head1 NAME diff --git a/Netdisco/lib/App/Netdisco/Util/Node.pm b/Netdisco/lib/App/Netdisco/Util/Node.pm index 6157f472..ac87ebe1 100644 --- a/Netdisco/lib/App/Netdisco/Util/Node.pm +++ b/Netdisco/lib/App/Netdisco/Util/Node.pm @@ -37,7 +37,7 @@ database storage. Returns false, and might log a debug level message, if the checks fail. -Returns a true value if these checks pass: +Returns a true value (the MAC address in IEEE format) if these checks pass: =over 4 @@ -67,12 +67,13 @@ MAC address does not belong to an interface on any known Device sub check_mac { my ($device, $node, $port_macs) = @_; my $mac = Net::MAC->new(mac => $node, 'die' => 0, verbose => 0); + my $devip = (ref $device ? $device->ip : ''); $port_macs ||= {}; # incomplete MAC addresses (BayRS frame relay DLCI, etc) if ($mac->get_error) { debug sprintf ' [%s] check_mac - mac [%s] malformed - skipping', - $device->ip, $node; + $devip, $node; return 0; } else { @@ -92,32 +93,32 @@ sub check_mac { # multicast if ($node =~ m/^[0-9a-f](?:1|3|5|7|9|b|d|f):/) { debug sprintf ' [%s] check_mac - multicast mac [%s] - skipping', - $device->ip, $node; + $devip, $node; return 0; } # VRRP if (index($node, '00:00:5e:00:01:') == 0) { debug sprintf ' [%s] check_mac - VRRP mac [%s] - skipping', - $device->ip, $node; + $devip, $node; return 0; } # HSRP if (index($node, '00:00:0c:07:ac:') == 0) { debug sprintf ' [%s] check_mac - HSRP mac [%s] - skipping', - $device->ip, $node; + $devip, $node; return 0; } # device's own MACs - if (exists $port_macs->{$node}) { + if ($port_macs and exists $port_macs->{$node}) { debug sprintf ' [%s] check_mac - mac [%s] is device port - skipping', - $device->ip, $node; + $devip, $node; return 0; } - return 1; + return $node; } =head2 check_node_no( $ip, $setting_name ) diff --git a/Netdisco/lib/App/Netdisco/Web/Plugin/AdminTask/NodeMonitor.pm b/Netdisco/lib/App/Netdisco/Web/Plugin/AdminTask/NodeMonitor.pm new file mode 100644 index 00000000..f8483b95 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/Web/Plugin/AdminTask/NodeMonitor.pm @@ -0,0 +1,75 @@ +package App::Netdisco::Web::Plugin::AdminTask::NodeMonitor; + +use Dancer ':syntax'; +use Dancer::Plugin::Ajax; +use Dancer::Plugin::DBIC; +use Dancer::Plugin::Auth::Extensible; + +use App::Netdisco::Web::Plugin; +use App::Netdisco::Util::Node 'check_mac'; + +register_admin_task({ + tag => 'nodemonitor', + label => 'Node Monitor', +}); + +sub _sanity_ok { + return 0 unless param('mac') + and check_mac(undef, param('mac')); + + params->{mac} = check_mac(undef, param('mac')); + return 1; +} + +ajax '/ajax/control/admin/nodemonitor/add' => require_role admin => sub { + send_error('Bad Request', 400) unless _sanity_ok(); + + schema('netdisco')->txn_do(sub { + my $monitor = schema('netdisco')->resultset('NodeMonitor') + ->create({ + mac => param('mac'), + active => (param('active') ? \'true' : \'false'), + why => param('why'), + cc => param('cc'), + }); + }); +}; + +ajax '/ajax/control/admin/nodemonitor/del' => require_role admin => sub { + send_error('Bad Request', 400) unless _sanity_ok(); + + schema('netdisco')->txn_do(sub { + schema('netdisco')->resultset('NodeMonitor') + ->find({mac => param('mac')})->delete; + }); +}; + +ajax '/ajax/control/admin/nodemonitor/update' => require_role admin => sub { + send_error('Bad Request', 400) unless _sanity_ok(); + + schema('netdisco')->txn_do(sub { + my $monitor = schema('netdisco')->resultset('NodeMonitor') + ->find({mac => param('mac')}); + return unless $monitor; + + $monitor->update({ + mac => param('mac'), + active => (param('active') ? \'true' : \'false'), + why => param('why'), + cc => param('cc'), + date => \'now()', + }); + }); +}; + +ajax '/ajax/content/admin/nodemonitor' => require_role admin => sub { + my $set = schema('netdisco')->resultset('NodeMonitor') + ->search(undef, { order_by => [qw/active date mac/] }); + + content_type('text/html'); + template 'ajax/admintask/nodemonitor.tt', { + results => $set, + }, { layout => undef }; +}; + +true; diff --git a/Netdisco/share/views/ajax/admintask/nodemonitor.tt b/Netdisco/share/views/ajax/admintask/nodemonitor.tt new file mode 100644 index 00000000..c80419f5 --- /dev/null +++ b/Netdisco/share/views/ajax/admintask/nodemonitor.tt @@ -0,0 +1,92 @@ +
| Date Added | +MAC Address | +Enabled | +Reason | +Action | +|
|---|---|---|---|---|---|
| + | + | + | + | + | + + | +
| [% row.date | html_entity %] | ++ + | ++ + | ++ + | ++ + | + ++ + + + + + | +