start on macsuck; tweak update locking
This commit is contained in:
@@ -4,6 +4,7 @@ use Dancer qw/:syntax :script/;
|
|||||||
use Dancer::Plugin::DBIC 'schema';
|
use Dancer::Plugin::DBIC 'schema';
|
||||||
|
|
||||||
use App::Netdisco::DB::ExplicitLocking ':modes';
|
use App::Netdisco::DB::ExplicitLocking ':modes';
|
||||||
|
use App::Netdisco::Util::PortMAC ':all';
|
||||||
use App::Netdisco::Util::DNS ':all';
|
use App::Netdisco::Util::DNS ':all';
|
||||||
use NetAddr::IP::Lite ':lower';
|
use NetAddr::IP::Lite ':lower';
|
||||||
use Time::HiRes 'gettimeofday';
|
use Time::HiRes 'gettimeofday';
|
||||||
@@ -27,11 +28,13 @@ subroutines.
|
|||||||
|
|
||||||
=head1 EXPORT_OK
|
=head1 EXPORT_OK
|
||||||
|
|
||||||
=head2 arpnip( $device, $snmp )
|
=head2 do_arpnip( $device, $snmp )
|
||||||
|
|
||||||
Given a Device database object, and a working SNMP connection, connect to a
|
Given a Device database object, and a working SNMP connection, connect to a
|
||||||
device and discover its ARP cache for IPv4 and Neighbor cache for IPv6.
|
device and discover its ARP cache for IPv4 and Neighbor cache for IPv6.
|
||||||
|
|
||||||
|
Will also discover subnets in use on the device and update the Subnets table.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
sub do_arpnip {
|
sub do_arpnip {
|
||||||
@@ -43,7 +46,7 @@ sub do_arpnip {
|
|||||||
}
|
}
|
||||||
|
|
||||||
my (@v4, @v6);
|
my (@v4, @v6);
|
||||||
my $port_macs = _get_port_macs($device, $snmp);
|
my $port_macs = get_port_macs($device);
|
||||||
|
|
||||||
# get v4 arp table
|
# get v4 arp table
|
||||||
push @v4, _get_arps($device, $port_macs, $snmp->at_paddr, $snmp->at_netaddr);
|
push @v4, _get_arps($device, $port_macs, $snmp->at_paddr, $snmp->at_netaddr);
|
||||||
@@ -77,14 +80,13 @@ sub do_arpnip {
|
|||||||
# update subnets with new networks
|
# update subnets with new networks
|
||||||
foreach my $cidr (@subnets) {
|
foreach my $cidr (@subnets) {
|
||||||
schema('netdisco')->txn_do(sub {
|
schema('netdisco')->txn_do(sub {
|
||||||
# update_or_create doesn't seem to lock the row
|
schema('netdisco')->resultset('Subnet')->update_or_create(
|
||||||
schema('netdisco')->resultset('Subnet')->find(
|
{
|
||||||
{net => $cidr}, {for => 'update'},
|
|
||||||
);
|
|
||||||
schema('netdisco')->resultset('Subnet')->update_or_create({
|
|
||||||
net => $cidr,
|
net => $cidr,
|
||||||
last_discover => \"to_timestamp($now)",
|
last_discover => \"to_timestamp($now)",
|
||||||
});
|
},
|
||||||
|
# update_or_create doesn't seem to lock the row
|
||||||
|
{ for => 'update'});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
debug sprintf ' [%s] arpnip - processed %s Subnet entries',
|
debug sprintf ' [%s] arpnip - processed %s Subnet entries',
|
||||||
@@ -200,25 +202,4 @@ sub _gather_subnets {
|
|||||||
return @subnets;
|
return @subnets;
|
||||||
}
|
}
|
||||||
|
|
||||||
# returns table of MACs used by device's interfaces so that we don't bother to
|
|
||||||
# macsuck them.
|
|
||||||
sub _get_port_macs {
|
|
||||||
my ($device, $snmp) = @_;
|
|
||||||
my $port_macs;
|
|
||||||
|
|
||||||
my $dp_macs = schema('netdisco')->resultset('DevicePort')
|
|
||||||
->search({ mac => { '!=' => undef} });
|
|
||||||
while (my $r = $dp_macs->next) {
|
|
||||||
$port_macs->{ $r->mac } = $r->ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
my $d_macs = schema('netdisco')->resultset('Device')
|
|
||||||
->search({ mac => { '!=' => undef} });
|
|
||||||
while (my $r = $d_macs->next) {
|
|
||||||
$port_macs->{ $r->mac } = $r->ip;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $port_macs;
|
|
||||||
}
|
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ sub store_device {
|
|||||||
my $gone = $device->device_ips->delete;
|
my $gone = $device->device_ips->delete;
|
||||||
debug sprintf ' [%s] device - removed %s aliases',
|
debug sprintf ' [%s] device - removed %s aliases',
|
||||||
$device->ip, $gone;
|
$device->ip, $gone;
|
||||||
$device->update_or_insert;
|
$device->update_or_insert({}, {for => 'update'});
|
||||||
$device->device_ips->populate(\@aliases);
|
$device->device_ips->populate(\@aliases);
|
||||||
debug sprintf ' [%s] device - added %d new aliases',
|
debug sprintf ' [%s] device - added %d new aliases',
|
||||||
$device->ip, scalar @aliases;
|
$device->ip, scalar @aliases;
|
||||||
@@ -253,7 +253,7 @@ sub store_interfaces {
|
|||||||
my $gone = $device->ports->delete;
|
my $gone = $device->ports->delete;
|
||||||
debug sprintf ' [%s] interfaces - removed %s interfaces',
|
debug sprintf ' [%s] interfaces - removed %s interfaces',
|
||||||
$device->ip, $gone;
|
$device->ip, $gone;
|
||||||
$device->update_or_insert;
|
$device->update_or_insert({}, {for => 'update'});
|
||||||
$device->ports->populate(\@interfaces);
|
$device->ports->populate(\@interfaces);
|
||||||
debug sprintf ' [%s] interfaces - added %d new interfaces',
|
debug sprintf ' [%s] interfaces - added %d new interfaces',
|
||||||
$device->ip, scalar @interfaces;
|
$device->ip, scalar @interfaces;
|
||||||
|
|||||||
57
Netdisco/lib/App/Netdisco/Util/Macsuck.pm
Normal file
57
Netdisco/lib/App/Netdisco/Util/Macsuck.pm
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package App::Netdisco::Util::Macsuck;
|
||||||
|
|
||||||
|
use Dancer qw/:syntax :script/;
|
||||||
|
use Dancer::Plugin::DBIC 'schema';
|
||||||
|
|
||||||
|
use App::Netdisco::DB::ExplicitLocking ':modes';
|
||||||
|
use App::Netdisco::Util::PortMAC ':all';
|
||||||
|
use NetAddr::IP::Lite ':lower';
|
||||||
|
use Time::HiRes 'gettimeofday';
|
||||||
|
use Net::MAC;
|
||||||
|
|
||||||
|
use base 'Exporter';
|
||||||
|
our @EXPORT = ();
|
||||||
|
our @EXPORT_OK = qw/ do_macsuck /;
|
||||||
|
our %EXPORT_TAGS = (all => \@EXPORT_OK);
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
App::Netdisco::Util::Macsuck
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
Helper subroutine to support parts of the Netdisco application.
|
||||||
|
|
||||||
|
There are no default exports, however the C<:all> tag will export all
|
||||||
|
subroutines.
|
||||||
|
|
||||||
|
=head1 EXPORT_OK
|
||||||
|
|
||||||
|
=head2 do_macsuck( $device, $snmp )
|
||||||
|
|
||||||
|
Given a Device database object, and a working SNMP connection, connect to a
|
||||||
|
device and discover the MAC addresses listed against each physical port
|
||||||
|
without a neighbor.
|
||||||
|
|
||||||
|
If the device has VLANs, C<do_macsuck> will walk each VALN to get the MAC
|
||||||
|
addresses from there.
|
||||||
|
|
||||||
|
It will also gather wireless client information if C<store_wireless_client>
|
||||||
|
configuration setting is enabled.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub do_macsuck {
|
||||||
|
my ($device, $snmp) = @_;
|
||||||
|
|
||||||
|
unless ($device->in_storage) {
|
||||||
|
debug sprintf ' [%s] macsuck - skipping device not yet discovered', $device->ip;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $port_macs = get_port_macs($device);
|
||||||
|
my $ports = $device->ports;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
56
Netdisco/lib/App/Netdisco/Util/PortMAC.pm
Normal file
56
Netdisco/lib/App/Netdisco/Util/PortMAC.pm
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
package App::Netdisco::Util::PortMAC;
|
||||||
|
|
||||||
|
use Dancer qw/:syntax :script/;
|
||||||
|
use Dancer::Plugin::DBIC 'schema';
|
||||||
|
|
||||||
|
use base 'Exporter';
|
||||||
|
our @EXPORT = ();
|
||||||
|
our @EXPORT_OK = qw/ get_port_macs /;
|
||||||
|
our %EXPORT_TAGS = (all => \@EXPORT_OK);
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
App::Netdisco::Util::PortMAC
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
Helper subroutine to support parts of the Netdisco application.
|
||||||
|
|
||||||
|
There are no default exports, however the C<:all> tag will export all
|
||||||
|
subroutines.
|
||||||
|
|
||||||
|
=head1 EXPORT_OK
|
||||||
|
|
||||||
|
=head2 get_port_macs( $device )
|
||||||
|
|
||||||
|
Returns a Hash reference of C<< { MAC => IP } >> for all interface MAC
|
||||||
|
addresses on a device.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub get_port_macs {
|
||||||
|
my $device = shift;
|
||||||
|
my $port_macs = {};
|
||||||
|
|
||||||
|
unless ($device->in_storage) {
|
||||||
|
debug sprintf ' [%s] get_port_macs - skipping device not yet discovered',
|
||||||
|
$device->ip;
|
||||||
|
return $port_macs;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $dp_macs = schema('netdisco')->resultset('DevicePort')
|
||||||
|
->search({ mac => { '!=' => undef} });
|
||||||
|
while (my $r = $dp_macs->next) {
|
||||||
|
$port_macs->{ $r->mac } = $r->ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $d_macs = schema('netdisco')->resultset('Device')
|
||||||
|
->search({ mac => { '!=' => undef} });
|
||||||
|
while (my $r = $d_macs->next) {
|
||||||
|
$port_macs->{ $r->mac } = $r->ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $port_macs;
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
Reference in New Issue
Block a user