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 App::Netdisco::DB::ExplicitLocking ':modes'; | ||||
| use App::Netdisco::Util::PortMAC ':all'; | ||||
| use App::Netdisco::Util::DNS ':all'; | ||||
| use NetAddr::IP::Lite ':lower'; | ||||
| use Time::HiRes 'gettimeofday'; | ||||
| @@ -27,11 +28,13 @@ subroutines. | ||||
|  | ||||
| =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 | ||||
| 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 | ||||
|  | ||||
| sub do_arpnip { | ||||
| @@ -43,7 +46,7 @@ sub do_arpnip { | ||||
|   } | ||||
|  | ||||
|   my (@v4, @v6); | ||||
|   my $port_macs = _get_port_macs($device, $snmp); | ||||
|   my $port_macs = get_port_macs($device); | ||||
|  | ||||
|   # get v4 arp table | ||||
|   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 | ||||
|   foreach my $cidr (@subnets) { | ||||
|       schema('netdisco')->txn_do(sub { | ||||
|           # update_or_create doesn't seem to lock the row | ||||
|           schema('netdisco')->resultset('Subnet')->find( | ||||
|             {net => $cidr}, {for => 'update'}, | ||||
|           ); | ||||
|           schema('netdisco')->resultset('Subnet')->update_or_create({ | ||||
|           schema('netdisco')->resultset('Subnet')->update_or_create( | ||||
|           { | ||||
|             net => $cidr, | ||||
|             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', | ||||
| @@ -200,25 +202,4 @@ sub _gather_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; | ||||
|   | ||||
| @@ -106,7 +106,7 @@ sub store_device { | ||||
|     my $gone = $device->device_ips->delete; | ||||
|     debug sprintf ' [%s] device - removed %s aliases', | ||||
|       $device->ip, $gone; | ||||
|     $device->update_or_insert; | ||||
|     $device->update_or_insert({}, {for => 'update'}); | ||||
|     $device->device_ips->populate(\@aliases); | ||||
|     debug sprintf ' [%s] device - added %d new aliases', | ||||
|       $device->ip, scalar @aliases; | ||||
| @@ -253,7 +253,7 @@ sub store_interfaces { | ||||
|     my $gone = $device->ports->delete; | ||||
|     debug sprintf ' [%s] interfaces - removed %s interfaces', | ||||
|       $device->ip, $gone; | ||||
|     $device->update_or_insert; | ||||
|     $device->update_or_insert({}, {for => 'update'}); | ||||
|     $device->ports->populate(\@interfaces); | ||||
|     debug sprintf ' [%s] interfaces - added %d new 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