233 lines
5.0 KiB
Perl
233 lines
5.0 KiB
Perl
package App::Netdisco::DB::ResultSet::NodeIp;
|
|
use base 'App::Netdisco::DB::ResultSet';
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
__PACKAGE__->load_components(qw/
|
|
+App::Netdisco::DB::ExplicitLocking
|
|
/);
|
|
|
|
my $search_attr = {
|
|
order_by => {'-desc' => 'time_last'},
|
|
'+columns' => [
|
|
'oui.company',
|
|
'oui.abbrev',
|
|
{ time_first_stamp => \"to_char(time_first, 'YYYY-MM-DD HH24:MI')" },
|
|
{ time_last_stamp => \"to_char(time_last, 'YYYY-MM-DD HH24:MI')" },
|
|
],
|
|
join => 'oui'
|
|
};
|
|
|
|
=head1 with_times
|
|
|
|
This is a modifier for any C<search()> (including the helpers below) which
|
|
will add the following additional synthesized columns to the result set:
|
|
|
|
=over 4
|
|
|
|
=item time_first_stamp
|
|
|
|
=item time_last_stamp
|
|
|
|
=back
|
|
|
|
=cut
|
|
|
|
sub with_times {
|
|
my ($rs, $cond, $attrs) = @_;
|
|
|
|
return $rs
|
|
->search_rs({}, $search_attr)
|
|
->search($cond, $attrs);
|
|
}
|
|
|
|
=head1 search_by_ip( \%cond, \%attrs? )
|
|
|
|
my $set = $rs->search_by_ip({ip => '192.0.2.1', active => 1});
|
|
|
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
|
NodeIp table.
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
The C<cond> parameter must be a hashref containing a key C<ip> with the value
|
|
to search for. Value can either be a simple string of IPv4 or IPv6, or a
|
|
L<NetAddr::IP::Lite> object in which case all results within the CIDR/Prefix
|
|
will be retrieved.
|
|
|
|
=item *
|
|
|
|
Results are ordered by time last seen.
|
|
|
|
=item *
|
|
|
|
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
|
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
|
|
|
=item *
|
|
|
|
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
|
|
|
=back
|
|
|
|
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
|
|
|
=cut
|
|
|
|
sub search_by_ip {
|
|
my ($rs, $cond, $attrs) = @_;
|
|
|
|
die "ip address required for search_by_ip\n"
|
|
if ref {} ne ref $cond or !exists $cond->{ip};
|
|
|
|
# handle either plain text IP or NetAddr::IP (/32 or CIDR)
|
|
my ($op, $ip) = ('=', delete $cond->{ip});
|
|
|
|
if ('NetAddr::IP::Lite' eq ref $ip and $ip->num > 1) {
|
|
$op = '<<=';
|
|
$ip = $ip->cidr;
|
|
}
|
|
$cond->{ip} = { $op => $ip };
|
|
|
|
return $rs
|
|
->search_rs({}, $search_attr)
|
|
->search($cond, $attrs);
|
|
}
|
|
|
|
=head1 search_by_dns( \%cond, \%attrs? )
|
|
|
|
my $set = $rs->search_by_dns({dns => 'foo.example.com', active => 1});
|
|
|
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
|
NodeIp table.
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
The NodeIp table must have a C<dns> column for this search to work. Typically
|
|
this column is the IP's DNS PTR record, cached at the time of Netdisco Arpnip.
|
|
|
|
=item *
|
|
|
|
The C<cond> parameter must be a hashref containing a key C<dns> with the value
|
|
to search for. The value may optionally include SQL wildcard characters.
|
|
|
|
=item *
|
|
|
|
The C<cond> parameter may optionally have a suffix parameter which is a
|
|
regular expression of domain names that must also match the results.
|
|
|
|
=item *
|
|
|
|
Results are ordered by time last seen.
|
|
|
|
=item *
|
|
|
|
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
|
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
|
|
|
=item *
|
|
|
|
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
|
|
|
=back
|
|
|
|
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
|
|
|
=cut
|
|
|
|
sub search_by_dns {
|
|
my ($rs, $cond, $attrs) = @_;
|
|
|
|
die "dns field required for search_by_dns\n"
|
|
if ref {} ne ref $cond or !exists $cond->{dns};
|
|
|
|
(my $suffix = (delete $cond->{suffix} || ''))
|
|
=~ s|^\Q(?^\E|***:(?|;
|
|
|
|
$cond->{dns} = [ -and =>
|
|
{ '-ilike' => delete $cond->{dns} },
|
|
{ '~*' => "$suffix" },
|
|
];
|
|
|
|
return $rs
|
|
->search_rs({}, $search_attr)
|
|
->search($cond, $attrs);
|
|
}
|
|
|
|
=head1 search_by_mac( \%cond, \%attrs? )
|
|
|
|
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
|
|
|
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
|
NodeIp table.
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
The C<cond> parameter must be a hashref containing a key C<mac> with the value
|
|
to search for.
|
|
|
|
=item *
|
|
|
|
Results are ordered by time last seen.
|
|
|
|
=item *
|
|
|
|
Additional columns C<time_first_stamp> and C<time_last_stamp> provide
|
|
preformatted timestamps of the C<time_first> and C<time_last> fields.
|
|
|
|
=item *
|
|
|
|
A JOIN is performed on the OUI table and the OUI C<company> column prefetched.
|
|
|
|
=back
|
|
|
|
To limit results only to active IPs, set C<< {active => 1} >> in C<cond>.
|
|
|
|
=cut
|
|
|
|
sub search_by_mac {
|
|
my ($rs, $cond, $attrs) = @_;
|
|
|
|
die "mac address required for search_by_mac\n"
|
|
if ref {} ne ref $cond or !exists $cond->{mac};
|
|
|
|
return $rs
|
|
->search_rs({}, $search_attr)
|
|
->search($cond, $attrs);
|
|
}
|
|
|
|
=head2 ip_version( $version )
|
|
|
|
my $rset = $rs->ip_version(4);
|
|
|
|
This predefined C<search()> returns a ResultSet of matching rows from the
|
|
NodeIp table of nodes with addresses of the supplied IP version.
|
|
|
|
=over 4
|
|
|
|
=item *
|
|
|
|
The C<version> parameter must be an integer either 4 or 6.
|
|
|
|
=back
|
|
|
|
=cut
|
|
|
|
sub ip_version {
|
|
my ( $rs, $version ) = @_;
|
|
|
|
die "ip_version input must be either 4 or 6\n"
|
|
unless $version && ( $version == 4 || $version == 6 );
|
|
|
|
return $rs->search_rs( \[ 'family(me.ip) = ?', $version ] );
|
|
}
|
|
|
|
1;
|