From 5a1ed2e31354e27a14913a14f4da432fba2b2c54 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Thu, 13 Nov 2014 21:44:33 +0000 Subject: [PATCH 01/16] [#160] Job Queue fatal error on num_slots --- Netdisco/Changes | 3 ++- Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm | 7 +++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 07025b6c..2b564b34 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,9 +1,10 @@ -2.029013 - +2.029013_001 - 2014-11-13 [BUG FIXES] * Fix for latest DBIx::Class (deploy) * Fix for latest Dancer (YAML::XS) + * [#160] Job Queue fatal error on num_slots 2.029012 - 2014-10-09 diff --git a/Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm b/Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm index 02d77d3a..e9838228 100644 --- a/Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm +++ b/Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm @@ -27,17 +27,16 @@ our %EXPORT_TAGS = ( all => \@EXPORT_OK ); sub jq_getsome { my ($num_slots, $prio) = @_; - return () if defined $num_slots and $num_slots eq '0'; - $num_slots ||= 1; + return () if ((!defined $num_slots) or ($num_slots < 1)); $prio ||= 'normal'; - my @returned = (); my $rs = schema('netdisco')->resultset('Admin') ->search( {status => 'queued', action => { -in => setting('job_prio')->{$prio} } }, - {order_by => 'random()', rows => ($num_slots || 1)}, + {order_by => 'random()', rows => $num_slots}, ); + my @returned = (); while (my $job = $rs->next) { push @returned, App::Netdisco::Daemon::Job->new({ $job->get_columns }); } From bf27489a87877806f45d2119bde8dc91e2f81140 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Thu, 13 Nov 2014 21:49:49 +0000 Subject: [PATCH 02/16] [#157] Device Port Log being emptied by device discover --- Netdisco/Changes | 1 + Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 2b564b34..7ac33d69 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -5,6 +5,7 @@ * Fix for latest DBIx::Class (deploy) * Fix for latest Dancer (YAML::XS) * [#160] Job Queue fatal error on num_slots + * [#157] Device Port Log being emptied by device discover 2.029012 - 2014-10-09 diff --git a/Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm b/Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm index 91ee2682..4b471617 100644 --- a/Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm +++ b/Netdisco/lib/App/Netdisco/DB/ResultSet/DevicePort.pm @@ -157,7 +157,6 @@ sub delete { DevicePortVlan DevicePortWireless DevicePortSsid - DevicePortLog /) { $schema->resultset($set)->search( { ip => { '-in' => $ports->as_query }}, From e3f5022caabba5c65395dbb330cbb34aa91833e2 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Thu, 13 Nov 2014 23:42:24 +0000 Subject: [PATCH 03/16] [#156] Only delete node_ip and node_nbt when no active nodes reference I'm a bit wary that this will slow things down horribly. --- Netdisco/Changes | 1 + .../lib/App/Netdisco/DB/ResultSet/Node.pm | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/Netdisco/Changes b/Netdisco/Changes index 7ac33d69..a6a64b32 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -6,6 +6,7 @@ * Fix for latest Dancer (YAML::XS) * [#160] Job Queue fatal error on num_slots * [#157] Device Port Log being emptied by device discover + * [#156] Only delete node_ip and node_nbt when no active nodes reference 2.029012 - 2014-10-09 diff --git a/Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm b/Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm index 3a143243..4b9c4b5b 100644 --- a/Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm +++ b/Netdisco/lib/App/Netdisco/DB/ResultSet/Node.pm @@ -109,9 +109,30 @@ sub delete { return 0E0; } else { + # for node_ip and node_nbt *only* delete if there are no longer + # any active nodes referencing the IP or NBT (hence 2nd IN clause). foreach my $set (qw/ NodeIp NodeNbt + /) { + $schema->resultset($set)->search({ + '-and' => [ + 'me.mac' => { '-in' => $nodes->as_query }, + 'me.mac' => { '-in' => $schema->resultset($set)->search({ + -bool => 'nodes.active', + }, + { + columns => 'mac', + join => 'nodes', + group_by => 'me.mac', + having => \[ 'count(nodes.mac) = 0' ], + })->as_query, + }, + ], + })->delete; + } + + foreach my $set (qw/ NodeMonitor NodeWireless /) { From 51fa835e166c44062261a4b3d92beac705d18ab7 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Thu, 13 Nov 2014 23:46:03 +0000 Subject: [PATCH 04/16] [#169] Remove ref to force install of Dancer and DBIC --- Netdisco/Changes | 1 + Netdisco/lib/App/Netdisco.pm | 4 ---- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index a6a64b32..2fe1fb62 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -7,6 +7,7 @@ * [#160] Job Queue fatal error on num_slots * [#157] Device Port Log being emptied by device discover * [#156] Only delete node_ip and node_nbt when no active nodes reference + * [#169] Remove ref to force install of Dancer and DBIC 2.029012 - 2014-10-09 diff --git a/Netdisco/lib/App/Netdisco.pm b/Netdisco/lib/App/Netdisco.pm index 38ae6be4..3a97858f 100644 --- a/Netdisco/lib/App/Netdisco.pm +++ b/Netdisco/lib/App/Netdisco.pm @@ -123,7 +123,6 @@ install Netdisco and its dependencies into the C user's home area su - netdisco curl -L http://cpanmin.us/ | perl - --notest --local-lib ~/perl5 App::Netdisco - ~/bin/localenv cpanm --notest --force Dancer@1.3126 DBIx::Class@0.08270 Link some of the newly installed apps into a handy location: @@ -203,9 +202,6 @@ Notes|App::Netdisco::Manual::ReleaseNotes>. Then, the process is as follows: # upgrade Netdisco ~/bin/localenv cpanm --notest App::Netdisco - # workaround for current upstream bug - ~/bin/localenv cpanm --notest --force Dancer@1.3126 DBIx::Class@0.08270 - # apply database schema updates ~/bin/netdisco-deploy From f58e7c1753c786560b2e2efc5400adfe42f393ed Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Thu, 13 Nov 2014 23:51:10 +0000 Subject: [PATCH 05/16] [#161] Updated IOS-XR SSHCollector --- Netdisco/Changes | 4 +++ .../Netdisco/SSHCollector/Platform/IOSXR.pm | 28 ++++++------------- 2 files changed, 13 insertions(+), 19 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 2fe1fb62..9bba371c 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,5 +1,9 @@ 2.029013_001 - 2014-11-13 + [ENHANCEMENTS] + + * [#161] Updated IOS-XR SSHCollector + [BUG FIXES] * Fix for latest DBIx::Class (deploy) diff --git a/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm index 9e893d93..e101c765 100644 --- a/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm +++ b/Netdisco/lib/App/Netdisco/SSHCollector/Platform/IOSXR.pm @@ -8,7 +8,7 @@ App::Netdisco::SSHCollector::Platform::IOSXR =head1 DESCRIPTION -Collect ARP entries from Cisco IOS XR devices. +Collect ARP entries from Cisco IOSXR devices. =cut @@ -16,7 +16,6 @@ use strict; use warnings; use Dancer ':script'; -use Expect; use Moo; =head1 PUBLIC METHODS @@ -36,28 +35,19 @@ sub arpnip { my ($self, $hostlabel, $ssh, @args) = @_; debug "$hostlabel $$ arpnip()"; + my @data = $ssh->capture("show arp vrf all"); - my ($pty, $pid) = $ssh->open2pty or die "unable to run remote command"; - my $expect = Expect->init($pty); - - my ($pos, $error, $match, $before, $after); - my $prompt = qr/#/; - - ($pos, $error, $match, $before, $after) = $expect->expect(10, -re, $prompt); - - $expect->send("terminal length 0\n"); - ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); - + chomp @data; my @arpentries; - $expect->send("show arp vrf all\n"); - ($pos, $error, $match, $before, $after) = $expect->expect(5, -re, $prompt); - # 0.0.0.0 00:00:00 0000.0000.0000 Dynamic ARPA GigabitEthernet0/0/0/0 - for (split(/\n/, $before)){ + foreach (@data) { + my ($ip, $age, $mac, $state, $t, $iface) = split(/\s+/); - if ($ip =~ m/(\d{1,3}\.){3}\d{1,3}/ && $mac =~ m/[0-9a-f.]+/i) { - push(@arpentries, { ip => $ip, mac => $mac }); + + if ($ip =~ m/(\d{1,3}\.){3}\d{1,3}/ + && $mac =~ m/([0-9a-f]{4}\.){2}[0-9a-f]{4}/i) { + push(@arpentries, { ip => $ip, mac => $mac }); } } From 016d090d26c420196afd61fe82b7f7d64792e8af Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Thu, 13 Nov 2014 23:53:06 +0000 Subject: [PATCH 06/16] [#165] Mention system clock in docs --- Netdisco/Changes | 1 + Netdisco/lib/App/Netdisco.pm | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 9bba371c..ea92759b 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -3,6 +3,7 @@ [ENHANCEMENTS] * [#161] Updated IOS-XR SSHCollector + * [#165] Mention system clock in docs [BUG FIXES] diff --git a/Netdisco/lib/App/Netdisco.pm b/Netdisco/lib/App/Netdisco.pm index 3a97858f..f1236f42 100644 --- a/Netdisco/lib/App/Netdisco.pm +++ b/Netdisco/lib/App/Netdisco.pm @@ -75,7 +75,8 @@ On Fedora/Red-Hat: root:~# yum install perl-core perl-DBD-Pg net-snmp-perl make automake gcc -With those installed, we can proceed... +With those installed, next check that your system's clock is correct. Then, we +can proceed... Create a user on your system called C if one does not already exist. We'll install Netdisco and its dependencies into this user's home area, which From ebb5adc6eeb7eda8cec92714e1a6dbbbbe66d13d Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Fri, 14 Nov 2014 00:11:09 +0000 Subject: [PATCH 07/16] [#164] Workers should restart periodically They restart once a day, if the worker completes a job at least every hour. The worker ID is compared to the hour of day and if the modulus matches, then it exits (and is restarted by MCE). Should do the trick with memory usage. --- Netdisco/Changes | 1 + Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/Netdisco/Changes b/Netdisco/Changes index ea92759b..e1e39f3a 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -4,6 +4,7 @@ * [#161] Updated IOS-XR SSHCollector * [#165] Mention system clock in docs + * [#164] Workers should restart periodically [BUG FIXES] diff --git a/Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm b/Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm index 437be666..ff232cc7 100644 --- a/Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm +++ b/Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm @@ -38,6 +38,13 @@ sub worker_body { }; $self->close_job($job); + + # restart worker once a day. + # relies on the worker seeing a job at least every hour. + my $hour = [localtime()]->[2]; + if ($wid and (($wid % 24) == $hour)) { + $self->exit(0, "recycling worker $wid"); + } } } From db9775780bac6f94424df5e54e06d88d92745107 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Fri, 14 Nov 2014 00:14:31 +0000 Subject: [PATCH 08/16] release 2.029013_001 --- Netdisco/META.yml | 2 +- Netdisco/lib/App/Netdisco.pm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Netdisco/META.yml b/Netdisco/META.yml index d06d270b..37cac2d4 100644 --- a/Netdisco/META.yml +++ b/Netdisco/META.yml @@ -91,4 +91,4 @@ resources: homepage: http://netdisco.org/ license: http://opensource.org/licenses/bsd-license.php repository: git://git.code.sf.net/p/netdisco/netdisco-ng -version: 2.029012 +version: 2.029013_001 diff --git a/Netdisco/lib/App/Netdisco.pm b/Netdisco/lib/App/Netdisco.pm index f1236f42..c61ee7c6 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.029012'; +our $VERSION = '2.029013_001'; use App::Netdisco::Configuration; use Module::Find (); From 445d26bb318e99e5d8746573cb40d2e7ca8e9607 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Fri, 14 Nov 2014 21:44:48 +0000 Subject: [PATCH 09/16] fix worker restart to happen once per hour per day --- Netdisco/Changes | 2 +- Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index e1e39f3a..a5c60637 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,4 +1,4 @@ -2.029013_001 - 2014-11-13 +2.029013_002 - 2014-11-14 [ENHANCEMENTS] diff --git a/Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm b/Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm index ff232cc7..4b217d2c 100644 --- a/Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm +++ b/Netdisco/lib/App/Netdisco/Daemon/Worker/Common.pm @@ -10,6 +10,8 @@ use namespace::clean; use App::Netdisco::JobQueue qw/jq_defer jq_complete/; +sub worker_begin { (shift)->{started} = time } + sub worker_body { my $self = shift; my $wid = $self->wid; @@ -42,7 +44,8 @@ sub worker_body { # restart worker once a day. # relies on the worker seeing a job at least every hour. my $hour = [localtime()]->[2]; - if ($wid and (($wid % 24) == $hour)) { + if ($wid and (time >= ($self->{started} + 86400)) + and ($hour == ($wid % 24))) { $self->exit(0, "recycling worker $wid"); } } From 87a09b09739a11aca74465dcbacfefe8ebded2d0 Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Fri, 14 Nov 2014 22:20:10 +0000 Subject: [PATCH 10/16] [#168] Jobs requested via web UI are treated as high priority --- Netdisco/Changes | 1 + .../lib/App/Netdisco/JobQueue/PostgreSQL.pm | 27 ++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index a5c60637..7b6fcc6f 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -5,6 +5,7 @@ * [#161] Updated IOS-XR SSHCollector * [#165] Mention system clock in docs * [#164] Workers should restart periodically + * [#168] Jobs requested via web UI are treated as high priority [BUG FIXES] diff --git a/Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm b/Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm index e9838228..c4989792 100644 --- a/Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm +++ b/Netdisco/lib/App/Netdisco/JobQueue/PostgreSQL.pm @@ -25,15 +25,15 @@ our @EXPORT_OK = qw/ /; our %EXPORT_TAGS = ( all => \@EXPORT_OK ); -sub jq_getsome { - my ($num_slots, $prio) = @_; +sub _getsome { + my ($num_slots, $where) = @_; return () if ((!defined $num_slots) or ($num_slots < 1)); - $prio ||= 'normal'; + return () if ((!defined $where) or (ref {} ne ref $where)); my $rs = schema('netdisco')->resultset('Admin') ->search( - {status => 'queued', action => { -in => setting('job_prio')->{$prio} } }, - {order_by => 'random()', rows => $num_slots}, + { status => 'queued', %$where }, + { order_by => 'random()', rows => $num_slots }, ); my @returned = (); @@ -43,7 +43,22 @@ sub jq_getsome { return @returned; } -sub jq_getsomep { return jq_getsome(shift, 'high') } +sub jq_getsome { + return _getsome(shift, + { action => { -in => setting('job_prio')->{'normal'} } } + ); +} + +sub jq_getsomep { + return _getsome(shift, { + -or => [{ + username => { '!=' => undef }, + action => { -in => setting('job_prio')->{'normal'} }, + },{ + action => { -in => setting('job_prio')->{'high'} }, + }], + }); +} sub jq_locked { my $fqdn = hostfqdn || 'localhost'; From e4c668fb12f2388f6af4c708301eed3ebf57afeb Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Fri, 14 Nov 2014 22:26:03 +0000 Subject: [PATCH 11/16] Add "Run Expire Job" to the Admin Menu --- Netdisco/Changes | 1 + Netdisco/share/views/layouts/main.tt | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/Netdisco/Changes b/Netdisco/Changes index 7b6fcc6f..9d9b91af 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -6,6 +6,7 @@ * [#165] Mention system clock in docs * [#164] Workers should restart periodically * [#168] Jobs requested via web UI are treated as high priority + * Add "Run Expire Job" to the Admin Menu [BUG FIXES] diff --git a/Netdisco/share/views/layouts/main.tt b/Netdisco/share/views/layouts/main.tt index f2e51218..6cb1ddd9 100644 --- a/Netdisco/share/views/layouts/main.tt +++ b/Netdisco/share/views/layouts/main.tt @@ -119,6 +119,11 @@ +
  • +
    + +
    +
  • [% IF settings._admin_tasks.size %]
  • [% FOREACH ai IN settings._admin_order %] From a308d1a1770b93743844c6e752e2a1bd0d995c8b Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Fri, 14 Nov 2014 22:49:07 +0000 Subject: [PATCH 12/16] [#162] Change from Net::MAC to NetAddr::MAC Note that IEEE and Microsoft are the WRONG WAY ROUND in NetAddr::MAC. I've emailed the author about this. A dirty hack is in place to deal with it. --- Netdisco/Changes | 1 + Netdisco/META.yml | 2 +- Netdisco/Makefile.PL | 6 +++--- Netdisco/lib/App/Netdisco/Core/Discover.pm | 16 ++++++++-------- .../lib/App/Netdisco/DB/Result/DevicePort.pm | 6 +++--- Netdisco/lib/App/Netdisco/DB/Result/Node.pm | 6 +++--- Netdisco/lib/App/Netdisco/DB/Result/NodeIp.pm | 6 +++--- Netdisco/lib/App/Netdisco/DB/Result/NodeNbt.pm | 6 +++--- .../lib/App/Netdisco/DB/Result/NodeWireless.pm | 6 +++--- Netdisco/lib/App/Netdisco/Manual/Developing.pod | 6 +++--- Netdisco/lib/App/Netdisco/Util/Node.pm | 16 ++++++++-------- Netdisco/lib/App/Netdisco/Web/Device.pm | 3 +-- .../lib/App/Netdisco/Web/Plugin/Search/Node.pm | 8 ++++---- Netdisco/share/views/sidebar/device/ports.tt | 7 ++++--- Netdisco/share/views/sidebar/search/node.tt | 7 ++++--- 15 files changed, 52 insertions(+), 50 deletions(-) diff --git a/Netdisco/Changes b/Netdisco/Changes index 9d9b91af..5e9377da 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -6,6 +6,7 @@ * [#165] Mention system clock in docs * [#164] Workers should restart periodically * [#168] Jobs requested via web UI are treated as high priority + * [#162] Change from Net::MAC to NetAddr::MAC * Add "Run Expire Job" to the Admin Menu [BUG FIXES] diff --git a/Netdisco/META.yml b/Netdisco/META.yml index 37cac2d4..3ba0816c 100644 --- a/Netdisco/META.yml +++ b/Netdisco/META.yml @@ -59,7 +59,7 @@ requires: Net::DNS: 0.72 Net::Domain: 1.23 Net::LDAP: 0 - Net::MAC: 2.103622 + NetAddr::MAC: 0.87 NetAddr::IP: 4.068 Opcode: 1.07 Path::Class: 0.32 diff --git a/Netdisco/Makefile.PL b/Netdisco/Makefile.PL index b4a63df6..3c34f9c8 100644 --- a/Netdisco/Makefile.PL +++ b/Netdisco/Makefile.PL @@ -1,12 +1,12 @@ use inc::Module::Install; - + name 'App-Netdisco'; license 'bsd'; all_from 'lib/App/Netdisco.pm'; test_requires 'Test::More' => 0.88; test_requires 'Env::Path' => 0; - + requires 'Algorithm::Cron' => 0.07; requires 'AnyEvent' => 7.05; requires 'AnyEvent::DNS::EtcHosts' => 0; @@ -38,7 +38,7 @@ requires 'MCE' => 1.515; requires 'Net::Domain' => 1.23; requires 'Net::DNS' => 0.72; requires 'Net::LDAP' => 0; -requires 'Net::MAC' => 2.103622; +requires 'NetAddr::MAC' => 0.87; requires 'NetAddr::IP' => 4.068; requires 'Opcode' => 1.07; requires 'Path::Class' => 0.32; diff --git a/Netdisco/lib/App/Netdisco/Core/Discover.pm b/Netdisco/lib/App/Netdisco/Core/Discover.pm index 29acbac6..94257b15 100644 --- a/Netdisco/lib/App/Netdisco/Core/Discover.pm +++ b/Netdisco/lib/App/Netdisco/Core/Discover.pm @@ -10,7 +10,7 @@ use NetAddr::IP::Lite ':lower'; use List::MoreUtils (); use Encode; use Try::Tiny; -use Net::MAC; +use NetAddr::MAC; use base 'Exporter'; our @EXPORT = (); @@ -754,9 +754,9 @@ sub store_neighbors { $device->ip, $remote_ip, $port, $remote_id; if (!defined $neigh) { - my $mac = Net::MAC->new(mac => $remote_id, 'die' => 0, verbose => 0); - if (not $mac->get_error) { - $neigh = $devices->single({mac => $mac->as_IEEE()}); + my $mac = NetAddr::MAC->new(mac => $remote_id); + if ($mac and not $mac->errstr) { + $neigh = $devices->single({mac => $mac->as_microsoft()}); } } @@ -765,13 +765,13 @@ sub store_neighbors { # "myswitchname(012345-012345)" if (!defined $neigh) { (my $tmpid = $remote_id) =~ s/.([0-9a-f]{6})-([0-9a-f]{6})./$1$2/; - my $mac = Net::MAC->new(mac => $tmpid, 'die' => 0, verbose => 0); + my $mac = NetAddr::MAC->new(mac => $tmpid); - if (not $mac->get_error) { + if ($mac and not $mac->errstr) { info sprintf '[%s] neigh - found neighbor %s by MAC %s', - $device->ip, $remote_id, $mac->as_IEEE(); - $neigh = $devices->single({mac => $mac->as_IEEE()}); + $device->ip, $remote_id, $mac->as_microsoft(); + $neigh = $devices->single({mac => $mac->as_microsoft()}); } } diff --git a/Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm b/Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm index dcb40579..93b94367 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/DevicePort.pm @@ -7,7 +7,7 @@ package App::Netdisco::DB::Result::DevicePort; use strict; use warnings; -use Net::MAC; +use NetAddr::MAC; use MIME::Base64 'encode_base64url'; @@ -339,10 +339,10 @@ sub base64url_port { return encode_base64url((shift)->port) } =head2 net_mac -Returns the C column instantiated into a L object. +Returns the C column instantiated into a L object. =cut -sub net_mac { return Net::MAC->new(mac => (shift)->mac) } +sub net_mac { return NetAddr::MAC->new(mac => (shift)->mac) } 1; diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Node.pm b/Netdisco/lib/App/Netdisco/DB/Result/Node.pm index d71bf24a..88de7544 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/Node.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/Node.pm @@ -7,7 +7,7 @@ package App::Netdisco::DB::Result::Node; use strict; use warnings; -use Net::MAC; +use NetAddr::MAC; use base 'DBIx::Class::Core'; __PACKAGE__->table("node"); @@ -175,10 +175,10 @@ sub time_last_stamp { return (shift)->get_column('time_last_stamp') } =head2 net_mac -Returns the C column instantiated into a L object. +Returns the C column instantiated into a L object. =cut -sub net_mac { return Net::MAC->new(mac => (shift)->mac) } +sub net_mac { return NetAddr::MAC->new(mac => (shift)->mac) } 1; diff --git a/Netdisco/lib/App/Netdisco/DB/Result/NodeIp.pm b/Netdisco/lib/App/Netdisco/DB/Result/NodeIp.pm index 504c2f7f..0a3f6a77 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/NodeIp.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/NodeIp.pm @@ -7,7 +7,7 @@ package App::Netdisco::DB::Result::NodeIp; use strict; use warnings; -use Net::MAC; +use NetAddr::MAC; use base 'DBIx::Class::Core'; __PACKAGE__->table("node_ip"); @@ -221,10 +221,10 @@ sub time_last_stamp { return (shift)->get_column('time_last_stamp') } =head2 net_mac -Returns the C column instantiated into a L object. +Returns the C column instantiated into a L object. =cut -sub net_mac { return Net::MAC->new(mac => (shift)->mac) } +sub net_mac { return NetAddr::MAC->new(mac => (shift)->mac) } 1; diff --git a/Netdisco/lib/App/Netdisco/DB/Result/NodeNbt.pm b/Netdisco/lib/App/Netdisco/DB/Result/NodeNbt.pm index 7790b9ae..e8203dc9 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/NodeNbt.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/NodeNbt.pm @@ -7,7 +7,7 @@ package App::Netdisco::DB::Result::NodeNbt; use strict; use warnings; -use Net::MAC; +use NetAddr::MAC; use base 'DBIx::Class::Core'; __PACKAGE__->table("node_nbt"); @@ -178,10 +178,10 @@ sub time_last_stamp { return (shift)->get_column('time_last_stamp') } =head2 net_mac -Returns the C column instantiated into a L object. +Returns the C column instantiated into a L object. =cut -sub net_mac { return Net::MAC->new(mac => (shift)->mac) } +sub net_mac { return NetAddr::MAC->new(mac => (shift)->mac) } 1; diff --git a/Netdisco/lib/App/Netdisco/DB/Result/NodeWireless.pm b/Netdisco/lib/App/Netdisco/DB/Result/NodeWireless.pm index e43244b3..c2e8aad0 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/NodeWireless.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/NodeWireless.pm @@ -7,7 +7,7 @@ package App::Netdisco::DB::Result::NodeWireless; use strict; use warnings; -use Net::MAC; +use NetAddr::MAC; use base 'DBIx::Class::Core'; __PACKAGE__->table("node_wireless"); @@ -87,10 +87,10 @@ __PACKAGE__->belongs_to( node => 'App::Netdisco::DB::Result::Node', =head2 net_mac -Returns the C column instantiated into a L object. +Returns the C column instantiated into a L object. =cut -sub net_mac { return Net::MAC->new(mac => (shift)->mac) } +sub net_mac { return NetAddr::MAC->new(mac => (shift)->mac) } 1; diff --git a/Netdisco/lib/App/Netdisco/Manual/Developing.pod b/Netdisco/lib/App/Netdisco/Manual/Developing.pod index 61c63a13..37a09a23 100644 --- a/Netdisco/lib/App/Netdisco/Manual/Developing.pod +++ b/Netdisco/lib/App/Netdisco/Manual/Developing.pod @@ -14,10 +14,10 @@ the L. Then: su - netdisco && cd $HOME mkdir git && cd git - + git clone git://git.code.sf.net/p/netdisco/netdisco-ng netdisco-ng cd netdisco-ng/Netdisco - + DBIC_TRACE=1 ~/bin/localenv plackup -R share,lib -p 5001 bin/netdisco-web-fg The above creates you a git clone (change the URL if you're a Netdisco @@ -259,7 +259,7 @@ Compared to the current Netdisco, the handler routines are very small. This is because (a) they don't include any HTML - this is delegated to a template, and (b) they don't include an SQL - this is delegated to DBIx::Class. Small routines are more manageable, and easier to maintain. You'll also notice use -of modules such as L and L to simplify and make +of modules such as L and L to simplify and make more robust the handling of data. In fact, many sections of the web application have been factored out into diff --git a/Netdisco/lib/App/Netdisco/Util/Node.pm b/Netdisco/lib/App/Netdisco/Util/Node.pm index ac87ebe1..44c43bcc 100644 --- a/Netdisco/lib/App/Netdisco/Util/Node.pm +++ b/Netdisco/lib/App/Netdisco/Util/Node.pm @@ -3,7 +3,7 @@ package App::Netdisco::Util::Node; use Dancer qw/:syntax :script/; use Dancer::Plugin::DBIC 'schema'; -use Net::MAC; +use NetAddr::MAC; use App::Netdisco::Util::Permission 'check_acl'; use base 'Exporter'; @@ -66,23 +66,23 @@ 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 $mac = NetAddr::MAC->new(mac => $node); my $devip = (ref $device ? $device->ip : ''); $port_macs ||= {}; # incomplete MAC addresses (BayRS frame relay DLCI, etc) - if ($mac->get_error) { + if (!defined $mac or $mac->errstr) { debug sprintf ' [%s] check_mac - mac [%s] malformed - skipping', $devip, $node; return 0; } else { # lower case, hex, colon delimited, 8-bit groups - $node = lc $mac->as_IEEE; + $node = lc $mac->as_microsoft; } # broadcast MAC addresses - return 0 if $node eq 'ff:ff:ff:ff:ff:ff'; + return 0 if $mac->is_broadcast; # all-zero MAC addresses return 0 if $node eq '00:00:00:00:00:00'; @@ -91,21 +91,21 @@ sub check_mac { return 0 if $node eq '00:00:00:00:00:01'; # multicast - if ($node =~ m/^[0-9a-f](?:1|3|5|7|9|b|d|f):/) { + if ($mac->is_multicast and not $mac->is_msnlb) { debug sprintf ' [%s] check_mac - multicast mac [%s] - skipping', $devip, $node; return 0; } # VRRP - if (index($node, '00:00:5e:00:01:') == 0) { + if ($mac->is_vrrp) { debug sprintf ' [%s] check_mac - VRRP mac [%s] - skipping', $devip, $node; return 0; } # HSRP - if (index($node, '00:00:0c:07:ac:') == 0) { + if ($mac->is_hsrp or $mac->is_hsrp2) { debug sprintf ' [%s] check_mac - HSRP mac [%s] - skipping', $devip, $node; return 0; diff --git a/Netdisco/lib/App/Netdisco/Web/Device.pm b/Netdisco/lib/App/Netdisco/Web/Device.pm index 89e97cfe..23ea7caa 100644 --- a/Netdisco/lib/App/Netdisco/Web/Device.pm +++ b/Netdisco/lib/App/Netdisco/Web/Device.pm @@ -129,8 +129,7 @@ hook 'before_template' => sub { $tokens->{device_ports}->query_param($key, params->{$key}); } - # for Net::MAC method - $tokens->{mac_format_call} = 'as_'. params->{'mac_format'} + $tokens->{mac_format_call} = 'as_'. lc(params->{'mac_format'}) if params->{'mac_format'}; foreach my $col (@{ var('port_columns') }) { diff --git a/Netdisco/lib/App/Netdisco/Web/Plugin/Search/Node.pm b/Netdisco/lib/App/Netdisco/Web/Plugin/Search/Node.pm index 7c312355..a4ef1280 100644 --- a/Netdisco/lib/App/Netdisco/Web/Plugin/Search/Node.pm +++ b/Netdisco/lib/App/Netdisco/Web/Plugin/Search/Node.pm @@ -6,7 +6,7 @@ use Dancer::Plugin::DBIC; use Dancer::Plugin::Auth::Extensible; use NetAddr::IP::Lite ':lower'; -use Net::MAC (); +use NetAddr::MAC (); use App::Netdisco::Web::Plugin; use App::Netdisco::Util::Web 'sql_match'; @@ -20,9 +20,9 @@ ajax '/ajax/content/search/node' => require_login sub { content_type('text/html'); my $agenot = param('age_invert') || '0'; - my ( $start, $end ) = param('daterange') =~ /(\d+-\d+-\d+)/gmx; + my ( $start, $end ) = param('daterange') =~ m/(\d+-\d+-\d+)/gmx; - my $mac = Net::MAC->new(mac => $node, 'die' => 0, verbose => 0); + my $mac = NetAddr::MAC->new(mac => $node); my @active = (param('archived') ? () : (-bool => 'active')); my @times = (); @@ -48,7 +48,7 @@ ajax '/ajax/content/search/node' => require_login sub { my @where_mac = ($using_wildcards ? \['me.mac::text ILIKE ?', $likeval] - : ($mac->get_error ? \'0=1' : ('me.mac' => $mac->as_IEEE)) ); + : ((!defined $mac or $mac->errstr) ? \'0=1' : ('me.mac' => $mac->as_microsoft)) ); my $sightings = schema('netdisco')->resultset('Node') ->search({-and => [@where_mac, @active, @times]}, { diff --git a/Netdisco/share/views/sidebar/device/ports.tt b/Netdisco/share/views/sidebar/device/ports.tt index 5618b3ee..88213dc3 100644 --- a/Netdisco/share/views/sidebar/device/ports.tt +++ b/Netdisco/share/views/sidebar/device/ports.tt @@ -125,9 +125,10 @@
  • MAC address format:
  • [% FOREACH item IN vars.connected_properties %] diff --git a/Netdisco/share/views/sidebar/search/node.tt b/Netdisco/share/views/sidebar/search/node.tt index a73eb989..19368224 100644 --- a/Netdisco/share/views/sidebar/search/node.tt +++ b/Netdisco/share/views/sidebar/search/node.tt @@ -55,9 +55,10 @@
    MAC address format: