Node DNS names resolved in their own job
This commit is contained in:
@@ -1,10 +1,11 @@
|
||||
2.017001_001 -
|
||||
2.017001_002 -
|
||||
|
||||
[NEW FEATURES]
|
||||
|
||||
* Add VLAN Inventory Report
|
||||
* Add Wireless SSID Inventory Report
|
||||
* Add Device Inventory by Location Report
|
||||
* Node DNS names resolved in their own job - see nodenames_no and nodenames_only
|
||||
|
||||
[ENHANCEMENTS]
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use Time::HiRes 'gettimeofday';
|
||||
|
||||
use base 'Exporter';
|
||||
our @EXPORT = ();
|
||||
our @EXPORT_OK = qw/ do_arpnip store_arp /;
|
||||
our @EXPORT_OK = qw/ do_arpnip store_arp resolve_node_names /;
|
||||
our %EXPORT_TAGS = (all => \@EXPORT_OK);
|
||||
|
||||
=head1 NAME
|
||||
@@ -82,16 +82,16 @@ sub _get_arps {
|
||||
my $ip = $netaddr->{$arp};
|
||||
next unless defined $ip;
|
||||
next unless check_mac($device, $node);
|
||||
push @arps, [$node, $ip, hostname_from_ip($ip)];
|
||||
push @arps, [$node, $ip];
|
||||
}
|
||||
|
||||
return @arps;
|
||||
}
|
||||
|
||||
=head2 store_arp( $mac, $ip, $name, $now? )
|
||||
=head2 store_arp( $mac, $ip, $now? )
|
||||
|
||||
Stores a new entry to the C<node_ip> table with the given MAC, IP (v4 or v6)
|
||||
and DNS host name.
|
||||
Stores a new entry to the C<node_ip> table with the given MAC, and IP (v4 or
|
||||
v6).
|
||||
|
||||
Will mark old entries for this IP as no longer C<active>.
|
||||
|
||||
@@ -101,7 +101,7 @@ C<time_last> timestamp, otherwise the current timestamp (C<now()>) is used.
|
||||
=cut
|
||||
|
||||
sub store_arp {
|
||||
my ($mac, $ip, $name, $now) = @_;
|
||||
my ($mac, $ip, $now) = @_;
|
||||
$now ||= 'now()';
|
||||
|
||||
schema('netdisco')->txn_do(sub {
|
||||
@@ -119,7 +119,6 @@ sub store_arp {
|
||||
->search({'me.mac' => $mac, 'me.ip' => $ip})
|
||||
->update_or_create(
|
||||
{
|
||||
dns => $name,
|
||||
active => \'true',
|
||||
time_last => \$now,
|
||||
},
|
||||
@@ -172,4 +171,39 @@ 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;
|
||||
|
||||
@@ -22,7 +22,7 @@ sub capacity_for {
|
||||
debug "checking local capacity for action $action";
|
||||
|
||||
my $action_map = {
|
||||
Poller => [qw/discoverall discover arpwalk arpnip macwalk macsuck/],
|
||||
Poller => [qw/discoverall discover arpwalk arpnip nodenames macwalk macsuck/],
|
||||
Interactive => [qw/location contact portcontrol portname vlan power/],
|
||||
};
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ my $fqdn = hostfqdn || 'localhost';
|
||||
|
||||
my $role_map = {
|
||||
(map {$_ => 'Poller'}
|
||||
qw/discoverall discover arpwalk arpnip macwalk macsuck/),
|
||||
qw/discoverall discover arpwalk arpnip nodenames macwalk macsuck/),
|
||||
(map {$_ => 'Interactive'}
|
||||
qw/location contact portcontrol portname vlan power/)
|
||||
};
|
||||
|
||||
@@ -1,9 +1,17 @@
|
||||
package App::Netdisco::Daemon::Worker::Poller::Arpnip;
|
||||
|
||||
use Dancer::Plugin::DBIC 'schema';
|
||||
|
||||
use App::Netdisco::Core::Arpnip 'do_arpnip';
|
||||
use App::Netdisco::Util::Device 'is_arpnipable';
|
||||
use App::Netdisco::Util::Device qw/get_device is_arpnipable can_nodenames/;
|
||||
|
||||
use App::Netdisco::Core::Arpnip 'resolve_node_names';
|
||||
use App::Netdisco::Daemon::Util ':all';
|
||||
|
||||
use NetAddr::IP::Lite ':lower';
|
||||
|
||||
use Role::Tiny;
|
||||
use Class::Method::Modifiers;
|
||||
use namespace::clean;
|
||||
|
||||
with 'App::Netdisco::Daemon::Worker::Poller::Common';
|
||||
@@ -15,4 +23,43 @@ sub arpnip_layer { 3 }
|
||||
sub arpwalk { (shift)->_walk_body('arpnip', @_) }
|
||||
sub arpnip { (shift)->_single_body('arpnip', @_) }
|
||||
|
||||
after 'arpnip' => sub {
|
||||
my ($self, $job) = @_;
|
||||
|
||||
my $host = NetAddr::IP::Lite->new($job->device);
|
||||
my $device = get_device($host->addr);
|
||||
my $jobqueue = schema('netdisco')->resultset('Admin');
|
||||
|
||||
schema('netdisco')->txn_do(sub {
|
||||
$jobqueue->create({
|
||||
device => $device->ip,
|
||||
action => 'nodenames',
|
||||
status => 'queued',
|
||||
username => $job->username,
|
||||
userip => $job->userip,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
# run a nodenames job for one device
|
||||
sub nodenames {
|
||||
my ($self, $job) = @_;
|
||||
|
||||
my $host = NetAddr::IP::Lite->new($job->device);
|
||||
my $device = get_device($host->addr);
|
||||
my $jobqueue = schema('netdisco')->resultset('Admin');
|
||||
|
||||
if ($device->ip eq '0.0.0.0') {
|
||||
return job_error("nodenames failed: no device param (need -d ?)");
|
||||
}
|
||||
|
||||
unless (can_nodenames($device->ip)) {
|
||||
return job_defer("nodenames deferred: cannot run for $host");
|
||||
}
|
||||
|
||||
resolve_node_names($device);
|
||||
|
||||
return job_done("Ended nodenames for ". $host->addr);
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
@@ -444,6 +444,22 @@ Value: Number. Default: 0.
|
||||
Sets the minimum amount of time in seconds which must elapse between any two
|
||||
arpnip jobs for a device.
|
||||
|
||||
=head3 C<nodenames_no>
|
||||
|
||||
Value: List of Network Identifiers or Device Properties. Default: Empty List.
|
||||
|
||||
Devices in the list will not have their Node IPs resolved to names using the
|
||||
DNS. You can include hostnames, IP addresses and subnets (IPv4 or IPv6) in the
|
||||
list.
|
||||
|
||||
=head3 C<nodenames_only>
|
||||
|
||||
Value: List of Network Identifiers or Device Properties. Default: Empty List.
|
||||
|
||||
Only thos devices in the list will have their Node IPs resolved to names using
|
||||
the DNS. You can include hostnames, IP addresses and subnets (IPv4 or IPv6) in
|
||||
the list.
|
||||
|
||||
=head3 C<store_wireless_clients>
|
||||
|
||||
Value: Boolean. Default: C<true>.
|
||||
|
||||
@@ -35,15 +35,20 @@ but they are backwards compatible.
|
||||
|
||||
=back
|
||||
|
||||
=head1 2.017001_001
|
||||
=head1 2.017001_002
|
||||
|
||||
=head2 General Notices
|
||||
|
||||
The previous mentioned bug in Macsuck is now fixed.
|
||||
|
||||
During Arpnip, Node IPs are no longer resolved to DNS hostnames in real-time.
|
||||
In the next release, another job will be queued to perform this action for the
|
||||
device.
|
||||
Another job is queued to perform this action for the device. You can therefore
|
||||
control using the new C<nodenames_no> and C<nodenames_only> config parameters
|
||||
which daemons run this job.
|
||||
|
||||
The idea here is to support sites where the SNMP polling node has no useful
|
||||
DNS, but another system can update the DNS entries for nodes (yet do no
|
||||
polling).
|
||||
|
||||
=head1 2.017000
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ our @EXPORT_OK = qw/
|
||||
check_no
|
||||
is_discoverable
|
||||
is_arpnipable
|
||||
can_nodenames
|
||||
is_macsuckable
|
||||
/;
|
||||
our %EXPORT_TAGS = (all => \@EXPORT_OK);
|
||||
@@ -195,6 +196,32 @@ sub is_arpnipable {
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 can_nodenames( $ip )
|
||||
|
||||
Given an IP address, returns C<true> if Netdisco on this host is permitted by
|
||||
the local configuration to resolve Node IPs to DNS names for the device.
|
||||
|
||||
The configuration items C<nodenames_no> and C<nodenames_only> are checked
|
||||
against the given IP.
|
||||
|
||||
Returns false if the host is not permitted to do this job for the target
|
||||
device.
|
||||
|
||||
=cut
|
||||
|
||||
sub can_nodenames {
|
||||
my $ip = shift;
|
||||
my $device = get_device($ip) or return 0;
|
||||
|
||||
return _bail_msg("can_nodenames device matched nodenames_no")
|
||||
if check_no($device, 'nodenames_no');
|
||||
|
||||
return _bail_msg("can_nodenames: device failed to match nodenames_only")
|
||||
if check_no($device, 'nodenames_only');
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
=head2 is_macsuckable( $ip )
|
||||
|
||||
Given an IP address, returns C<true> if Netdisco on this host is permitted by
|
||||
|
||||
@@ -86,6 +86,8 @@ macsuck_min_age: 0
|
||||
arpnip_no: []
|
||||
arpnip_only: []
|
||||
arpnip_min_age: 0
|
||||
nodenames_no: []
|
||||
nodenames_only: []
|
||||
store_wireless_clients: true
|
||||
store_modules: true
|
||||
ignore_interfaces:
|
||||
|
||||
Reference in New Issue
Block a user