async dns support

This commit is contained in:
Eric A. Miller
2013-10-15 22:55:44 -04:00
parent 325e59bade
commit 8946cf291b
10 changed files with 97 additions and 148 deletions

View File

@@ -10,7 +10,7 @@ use Time::HiRes 'gettimeofday';
use base 'Exporter';
our @EXPORT = ();
our @EXPORT_OK = qw/ do_arpnip store_arp resolve_node_names /;
our @EXPORT_OK = qw/ do_arpnip store_arp /;
our %EXPORT_TAGS = (all => \@EXPORT_OK);
=head1 NAME
@@ -44,9 +44,9 @@ sub do_arpnip {
}
# get v4 arp table
my @v4 = _get_arps($device, $snmp->at_paddr, $snmp->at_netaddr);
my $v4 = _get_arps($device, $snmp->at_paddr, $snmp->at_netaddr);
# get v6 neighbor cache
my @v6 = _get_arps($device, $snmp->ipv6_n2p_mac, $snmp->ipv6_n2p_addr);
my $v6 = _get_arps($device, $snmp->ipv6_n2p_mac, $snmp->ipv6_n2p_addr);
# get directly connected networks
my @subnets = _gather_subnets($device, $snmp);
@@ -58,13 +58,13 @@ sub do_arpnip {
my $now = 'to_timestamp('. (join '.', gettimeofday) .')';
# update node_ip with ARP and Neighbor Cache entries
store_arp(@$_, $now) for @v4;
store_arp(\%$_, $now) for @$v4;
debug sprintf ' [%s] arpnip - processed %s ARP Cache entries',
$device->ip, scalar @v4;
$device->ip, scalar @$v4;
store_arp(@$_, $now) for @v6;
store_arp(\%$_, $now) for @$v6;
debug sprintf ' [%s] arpnip - processed %s IPv6 Neighbor Cache entries',
$device->ip, scalar @v6;
$device->ip, scalar @$v6;
_store_subnet($_, $now) for @subnets;
debug sprintf ' [%s] arpnip - processed %s Subnet entries',
@@ -82,16 +82,24 @@ sub _get_arps {
my $ip = $netaddr->{$arp};
next unless defined $ip;
next unless check_mac($device, $node);
push @arps, [$node, $ip];
push @arps, {
node => $node,
ip => $ip,
dns => undef,
};
}
return @arps;
debug sprintf ' resolving %d aliases with max %d outstanding requests',
scalar @arps, $ENV{'PERL_ANYEVENT_MAX_OUTSTANDING_DNS'};
my $resolved_ips = hostnames_resolve_async(\@arps);
return $resolved_ips;
}
=head2 store_arp( $mac, $ip, $now? )
=head2 store_arp( $mac, $ip, $name, $now? )
Stores a new entry to the C<node_ip> table with the given MAC, and IP (v4 or
v6).
Stores a new entry to the C<node_ip> table with the given MAC, IP (v4 or v6)
and DNS host name.
Will mark old entries for this IP as no longer C<active>.
@@ -101,8 +109,11 @@ C<time_last> timestamp, otherwise the current timestamp (C<now()>) is used.
=cut
sub store_arp {
my ($mac, $ip, $now) = @_;
my ($hash_ref, $now) = @_;
$now ||= 'now()';
my $ip = $hash_ref->{'ip'};
my $mac = $hash_ref->{'node'};
my $name = $hash_ref->{'dns'};
schema('netdisco')->txn_do(sub {
my $current = schema('netdisco')->resultset('NodeIp')
@@ -119,6 +130,7 @@ sub store_arp {
->search({'me.mac' => $mac, 'me.ip' => $ip})
->update_or_create(
{
dns => $name,
active => \'true',
time_last => \$now,
},
@@ -171,39 +183,4 @@ sub _store_subnet {
});
}
=head2 resolve_node_names( $device )
Given a Device database object, resolve Node IP (ARP) entries belonging to
this device into DNS names, and store them in the C<node_ip> database table.
This action is usually queued following C<do_arpip> so that it may run
asynchronously, and/or on another daemon worker node.
=cut
sub resolve_node_names {
my ($device) = @_;
schema('netdisco')->txn_do(sub {
my $nodeips = schema('netdisco')
->resultset('NodeIp')->search(
{
-and => [
-bool => 'me.active',
-bool => 'nodes.active',
],
'nodes.switch' => $device->ip,
},
{
join => 'nodes',
for => 'update',
}
);
while (my $nodeip = $nodeips->next) {
$nodeip->update({dns => hostname_from_ip($nodeip->ip)});
}
});
}
1;

View File

@@ -76,10 +76,14 @@ sub store_device {
alias => $addr,
port => $port,
subnet => $subnet,
dns => hostname_from_ip($addr),
dns => undef,
};
}
debug sprintf ' resolving %d aliases with max %d outstanding requests',
scalar @aliases, $ENV{'PERL_ANYEVENT_MAX_OUTSTANDING_DNS'};
my $resolved_aliases = hostnames_resolve_async(\@aliases);
# VTP Management Domain -- assume only one.
my $vtpdomains = $snmp->vtp_d_name;
my $vtpdomain;
@@ -108,7 +112,7 @@ sub store_device {
debug sprintf ' [%s] device - removed %s aliases',
$device->ip, $gone;
$device->update_or_insert(undef, {for => 'update'});
$device->device_ips->populate(\@aliases);
$device->device_ips->populate($resolved_aliases);
debug sprintf ' [%s] device - added %d new aliases',
$device->ip, scalar @aliases;
});
@@ -547,7 +551,7 @@ sub store_modules {
# build device modules list for DBIC
my @modules;
foreach my $entry (keys %$e_class) {
foreach my $entry (keys %$e_index) {
push @modules, {
index => $e_index->{$entry},
type => $e_type->{$entry},
@@ -670,7 +674,7 @@ sub store_neighbors {
if $remote_type !~ /ip phone/i;
}
else {
$remote_type = '';
$remote_type ||= '';
}
# hack for devices seeing multiple neighbors on the port