Files
netdisco/lib/App/Netdisco/Util/FastResolver.pm
Oliver Gorwits 9355f5c2b9 Refactored ACL support with multi-object compare
Squashed commit of the following:

commit 4081e22202693bd7c4ea00e95daad8e628c6fd5a
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon May 29 21:02:07 2023 +0100

    large rename of check_acl* to acl_matches*

commit 3cfa284ddd24d68765c255578cc5c184afbdcd83
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Fri May 19 20:39:03 2023 +0100

    update permission doc

commit 8c7bb93cc5e9fafb770f98f446e45cbd94b14894
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Wed May 17 21:50:07 2023 +0100

    migrate most check_acl_only to acl_matches_only

commit c47f699f2a22f08f2f3e093ed0f24c891e6f9a82
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Wed May 17 21:39:19 2023 +0100

    rename check_acl* to be acl_matches*

commit a884a22c3ab1f3262118c3a47ed8e25b0b0a7336
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun May 14 16:50:42 2023 +0100

    update macsuck_no_deviceports to use acl_matches

commit 8c256af728721329b64d071fa529dfc844073ac6
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun May 7 22:54:33 2023 +0100

    update hide_deviceports to use acl_matches multi @things

commit cd5d9978aba1da459be4fed4500f395df13f7784
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun May 7 22:53:38 2023 +0100

    check_acl fix to allow all @things to offer a property before fallback to missing as empty string

commit 1a3ab9a7646e9f994f03126d45fc36e9e5a13ed5
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Tue May 2 15:31:17 2023 +0100

    add ignore_deviceports to portproperties discover; improve comments

commit 51385ce89458dc939587dae902fda431719c22c9
Merge: b97c07d2 3f8ffe78
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Tue May 2 15:21:48 2023 +0100

    Merge branch 'master' into og-acl_multidict

commit b97c07d237d750c1d9eb3095d8ff3908512eac2a
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sat Mar 25 14:37:53 2023 +0000

    add support for arrayref of items, and unblessed hash, to check_acl
2023-05-29 21:32:07 +01:00

90 lines
2.3 KiB
Perl

package App::Netdisco::Util::FastResolver;
use strict;
use warnings;
use Dancer ':script';
use AnyEvent::DNS;
use App::Netdisco::Util::Permission 'acl_matches';
use base 'Exporter';
our @EXPORT = ();
our @EXPORT_OK = qw/hostnames_resolve_async/;
our %EXPORT_TAGS = (all => \@EXPORT_OK);
=head1 NAME
App::Netdisco::Util::FastResolver
=head1 DESCRIPTION
A set of helper subroutines 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 hostnames_resolve_async( \@ips, \@timeouts? )
This method uses a fully asynchronous and high-performance pure-perl stub
resolver C<AnyEvent::DNS>.
Given a reference to an array of hashes will resolve the C<IPv4> or C<IPv6>
address in the C<ip>, C<alias>, or C<device> key of each hash into its
hostname which will be inserted in the C<dns> key of the hash.
Optionally provide a set of timeout values in seconds which is also the
number of resolver attempts. The default is C<< [2,5,5] >>.
Returns the supplied reference to an array of hashes with dns values for
addresses which resolved.
=cut
sub hostnames_resolve_async {
my ($ips, $timeouts) = @_;
return [] unless $ips and ref [] eq ref $ips;
$timeouts ||= [2,5,5];
my $skip = setting('dns')->{'no'};
my $ETCHOSTS = setting('dns')->{'ETCHOSTS'};
AnyEvent::DNS::resolver->timeout(@$timeouts);
AnyEvent::DNS::resolver->os_config();
# Set up the condvar
my $done = AE::cv;
$done->begin( sub { shift->send } );
IP: foreach my $hash_ref (@$ips) {
my $ip = $hash_ref->{'ip'} || $hash_ref->{'alias'} || $hash_ref->{'device'};
next IP if acl_matches($ip, $skip);
# check /etc/hosts file and short-circuit if found
foreach my $name (reverse sort keys %$ETCHOSTS) {
if ($ETCHOSTS->{$name}->[0]->[0] eq $ip) {
$hash_ref->{'dns'} = $name;
next IP;
}
}
$done->begin;
AnyEvent::DNS::reverse_lookup $ip,
sub { $hash_ref->{'dns'} = shift; $done->end; };
}
# Decrement the cv counter to cancel out the send declaration
$done->end;
# Wait for the resolver to perform all resolutions
$done->recv;
# Remove reference to resolver so that we close sockets
# and allow return to any instance defaults we have changed
undef $AnyEvent::DNS::RESOLVER if $AnyEvent::DNS::RESOLVER;
return $ips;
}
1;