#1001 support for FQDN node search while domain_suffix is set; add fallback to IPv4 host lookup search
This commit is contained in:
@@ -122,8 +122,9 @@ to search for. The value may optionally include SQL wildcard characters.
|
|||||||
|
|
||||||
=item *
|
=item *
|
||||||
|
|
||||||
The C<cond> parameter may optionally have a C<suffix> parameter which is a
|
If C<dns> is a plain string, then the C<cond> parameter may optionally have a
|
||||||
regular expression of domain names - one of which must match the results.
|
C<suffix> parameter which is a regular expression of domain names - one of
|
||||||
|
which must match the results.
|
||||||
|
|
||||||
=item *
|
=item *
|
||||||
|
|
||||||
@@ -150,14 +151,37 @@ sub search_by_dns {
|
|||||||
die "dns field required for search_by_dns\n"
|
die "dns field required for search_by_dns\n"
|
||||||
if ref {} ne ref $cond or !exists $cond->{dns};
|
if ref {} ne ref $cond or !exists $cond->{dns};
|
||||||
|
|
||||||
(my $suffix = (delete $cond->{suffix} || ''))
|
my $dns_field = delete $cond->{dns};
|
||||||
|
|
||||||
|
(my $suffix = ($cond->{suffix} || ''))
|
||||||
=~ s|\Q(?^\E[-xismu]*|(?|g;
|
=~ s|\Q(?^\E[-xismu]*|(?|g;
|
||||||
|
|
||||||
$cond->{dns} = [ -and =>
|
if (q{} eq ref $dns_field and exists $cond->{suffix}) {
|
||||||
{ '-ilike' => delete $cond->{dns} },
|
(my $stripped_dns_field = $dns_field) =~ s/\.\%$//;
|
||||||
{ '~*' => "***:$suffix" },
|
(my $fqdn_field = $stripped_dns_field) .= '%';
|
||||||
];
|
$stripped_dns_field =~ s/$cond->{suffix}$// if $cond->{suffix};
|
||||||
|
$stripped_dns_field .= '.%';
|
||||||
|
|
||||||
|
$cond->{dns} = [ -or =>
|
||||||
|
[ -and =>
|
||||||
|
{ '-ilike' => $stripped_dns_field },
|
||||||
|
{ '~*' => "***:$suffix" },
|
||||||
|
],
|
||||||
|
[ -and =>
|
||||||
|
{ '-ilike' => $dns_field },
|
||||||
|
{ '~*' => "***:$suffix" },
|
||||||
|
],
|
||||||
|
{ '-ilike' => $fqdn_field },
|
||||||
|
];
|
||||||
|
}
|
||||||
|
elsif (q{} ne ref $dns_field) {
|
||||||
|
$cond->{dns} = $dns_field;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$cond->{dns} = { '-ilike' => $dns_field };
|
||||||
|
}
|
||||||
|
|
||||||
|
delete $cond->{suffix};
|
||||||
return $rs
|
return $rs
|
||||||
->search_rs({}, $order_by_time_last_and_join_oui)
|
->search_rs({}, $order_by_time_last_and_join_oui)
|
||||||
->search($cond, $attrs);
|
->search($cond, $attrs);
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ use NetAddr::MAC ();
|
|||||||
use POSIX qw/strftime/;
|
use POSIX qw/strftime/;
|
||||||
|
|
||||||
use App::Netdisco::Web::Plugin;
|
use App::Netdisco::Web::Plugin;
|
||||||
|
use App::Netdisco::Util::DNS 'ipv4_from_hostname';
|
||||||
use App::Netdisco::Util::Web 'sql_match';
|
use App::Netdisco::Util::Web 'sql_match';
|
||||||
|
|
||||||
register_search_tab({
|
register_search_tab({
|
||||||
@@ -208,42 +209,57 @@ get '/ajax/content/search/node' => require_login sub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
my $have_rows = 0;
|
||||||
my $set = schema(vars->{'tenant'})->resultset('NodeNbt')
|
my $set = schema(vars->{'tenant'})->resultset('NodeNbt')
|
||||||
->search_by_name({nbname => $likeval, @active, @times});
|
->search_by_name({nbname => $likeval, @active, @times});
|
||||||
|
++$have_rows if $set->has_rows;
|
||||||
|
|
||||||
unless ( $set->has_rows ) {
|
unless ( $have_rows ) {
|
||||||
if ($node =~ m{^(?:$RE{net}{IPv4}|$RE{net}{IPv6})(?:/\d+)?$}i
|
if ($node =~ m{^(?:$RE{net}{IPv4}|$RE{net}{IPv6})(?:/\d+)?$}i
|
||||||
and my $ip = NetAddr::IP::Lite->new($node)) {
|
and my $ip = NetAddr::IP::Lite->new($node)) {
|
||||||
|
|
||||||
# search_by_ip() will extract cidr notation if necessary
|
# search_by_ip() will extract cidr notation if necessary
|
||||||
$set = schema(vars->{'tenant'})->resultset('NodeIp')
|
$set = schema(vars->{'tenant'})->resultset('NodeIp')
|
||||||
->search_by_ip({ip => $ip, @active, @times});
|
->search_by_ip({ip => $ip, @active, @times});
|
||||||
|
++$have_rows if $set->has_rows;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$set = schema(vars->{'tenant'})->resultset('NodeIp')
|
$set = schema(vars->{'tenant'})->resultset('NodeIp')
|
||||||
->search_by_dns({
|
->search_by_dns({
|
||||||
($using_wildcards ? (dns => $likeval) :
|
($using_wildcards ? (dns => $likeval) :
|
||||||
(dns => "${likeval}.\%",
|
(dns => "${likeval}.\%", suffix => setting('domain_suffix'))),
|
||||||
suffix => setting('domain_suffix'))),
|
|
||||||
@active,
|
@active,
|
||||||
@times,
|
@times,
|
||||||
});
|
});
|
||||||
|
++$have_rows if $set->has_rows;
|
||||||
|
|
||||||
|
# try DNS lookup as fallback
|
||||||
|
if (not $using_wildcards and not $have_rows) {
|
||||||
|
my $resolved_ip = ipv4_from_hostname($node);
|
||||||
|
|
||||||
|
if ($resolved_ip) {
|
||||||
|
$set = schema(vars->{'tenant'})->resultset('NodeIp')
|
||||||
|
->search_by_ip({ip => $resolved_ip, @active, @times});
|
||||||
|
++$have_rows if $set->has_rows;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# if the user selects Vendor search opt, then
|
# if the user selects Vendor search opt, then
|
||||||
# we'll try the OUI company name as a fallback
|
# we'll try the OUI company name as a fallback
|
||||||
|
|
||||||
if (param('show_vendor') and not $set->has_rows) {
|
if (param('show_vendor') and not $have_rows) {
|
||||||
$set = schema(vars->{'tenant'})->resultset('NodeIp')
|
$set = schema(vars->{'tenant'})->resultset('NodeIp')
|
||||||
->with_times
|
->with_times
|
||||||
->search(
|
->search(
|
||||||
{'oui.company' => { -ilike => ''.sql_match($node)}, @times},
|
{'oui.company' => { -ilike => ''.sql_match($node)}, @times},
|
||||||
{'prefetch' => 'oui'},
|
{'prefetch' => 'oui'},
|
||||||
);
|
);
|
||||||
|
++$have_rows if $set->has_rows;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return unless $set and $set->has_rows;
|
return unless $set and ($have_rows or $set->has_rows);
|
||||||
$set = $set->search_rs({}, { order_by => 'me.mac' });
|
$set = $set->search_rs({}, { order_by => 'me.mac' });
|
||||||
|
|
||||||
return template 'ajax/search/node_by_ip.tt', {
|
return template 'ajax/search/node_by_ip.tt', {
|
||||||
|
|||||||
Reference in New Issue
Block a user