add rest of POD and fixes for Device helper renaming
This commit is contained in:
@@ -82,9 +82,44 @@ __PACKAGE__->set_primary_key("ip");
|
|||||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:671/XuuvsO2aMB1+IRWFjg
|
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:671/XuuvsO2aMB1+IRWFjg
|
||||||
|
|
||||||
|
=head1 RELATIONSHIPS
|
||||||
|
|
||||||
|
=head2 device_ips
|
||||||
|
|
||||||
|
Returns rows from the C<device_ip> table which relate to this Device. That is,
|
||||||
|
all the interface IP aliases configured on the Device.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->has_many( device_ips => 'Netdisco::DB::Result::DeviceIp', 'ip' );
|
__PACKAGE__->has_many( device_ips => 'Netdisco::DB::Result::DeviceIp', 'ip' );
|
||||||
|
|
||||||
|
=head2 vlans
|
||||||
|
|
||||||
|
Returns the C<device_vlan> entries for this Device. That is, the list of VLANs
|
||||||
|
configured on or known by this Device.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->has_many( vlans => 'Netdisco::DB::Result::DeviceVlan', 'ip' );
|
__PACKAGE__->has_many( vlans => 'Netdisco::DB::Result::DeviceVlan', 'ip' );
|
||||||
|
|
||||||
|
=head2 ports
|
||||||
|
|
||||||
|
Returns the set of ports on this Device.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->has_many( ports => 'Netdisco::DB::Result::DevicePort', 'ip' );
|
__PACKAGE__->has_many( ports => 'Netdisco::DB::Result::DevicePort', 'ip' );
|
||||||
|
|
||||||
|
=head2 port_vlans
|
||||||
|
|
||||||
|
Returns the set of VLANs known to be configured on Ports on this Device,
|
||||||
|
either tagged or untagged.
|
||||||
|
|
||||||
|
The JOIN is of type "RIGHT" meaning that the results are constrained to VLANs
|
||||||
|
only on Ports on this Device.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->has_many(
|
__PACKAGE__->has_many(
|
||||||
port_vlans => 'Netdisco::DB::Result::DevicePortVlan',
|
port_vlans => 'Netdisco::DB::Result::DevicePortVlan',
|
||||||
'ip', { join_type => 'RIGHT' }
|
'ip', { join_type => 'RIGHT' }
|
||||||
@@ -93,4 +128,57 @@ __PACKAGE__->has_many(
|
|||||||
# helper which assumes we've just RIGHT JOINed to Vlans table
|
# helper which assumes we've just RIGHT JOINed to Vlans table
|
||||||
sub vlan { return (shift)->vlans->first }
|
sub vlan { return (shift)->vlans->first }
|
||||||
|
|
||||||
|
=head1 ADDITIONAL COLUMNS
|
||||||
|
|
||||||
|
=head2 uptime_age
|
||||||
|
|
||||||
|
Formatted version of the C<uptime> field.
|
||||||
|
|
||||||
|
The format is in "X days/months/years" style, similar to:
|
||||||
|
|
||||||
|
1 year 4 months 05:46:00
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub uptime_age { return (shift)->get_column('uptime_age') }
|
||||||
|
|
||||||
|
=head2 last_discover_stamp
|
||||||
|
|
||||||
|
Formatted version of the C<last_discover> field, accurate to the minute.
|
||||||
|
|
||||||
|
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||||
|
between the date stamp and time stamp. That is:
|
||||||
|
|
||||||
|
2012-02-06 12:49
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub last_discover_stamp { return (shift)->get_column('last_discover_stamp') }
|
||||||
|
|
||||||
|
=head2 last_macsuck_stamp
|
||||||
|
|
||||||
|
Formatted version of the C<last_macsuck> field, accurate to the minute.
|
||||||
|
|
||||||
|
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||||
|
between the date stamp and time stamp. That is:
|
||||||
|
|
||||||
|
2012-02-06 12:49
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub last_macsuck_stamp { return (shift)->get_column('last_macsuck_stamp') }
|
||||||
|
|
||||||
|
=head2 last_arpnip_stamp
|
||||||
|
|
||||||
|
Formatted version of the C<last_arpnip> field, accurate to the minute.
|
||||||
|
|
||||||
|
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||||
|
between the date stamp and time stamp. That is:
|
||||||
|
|
||||||
|
2012-02-06 12:49
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub last_arpnip_stamp { return (shift)->get_column('last_arpnip_stamp') }
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -34,7 +34,23 @@ __PACKAGE__->set_primary_key("ip", "alias");
|
|||||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/ugGtBSGyrJ7s6yqJ9bclQ
|
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/ugGtBSGyrJ7s6yqJ9bclQ
|
||||||
|
|
||||||
|
=head1 RELATIONSHIPS
|
||||||
|
|
||||||
|
=head2 device
|
||||||
|
|
||||||
|
Returns the entry from the C<device> table to which this IP alias relates.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->belongs_to( device => 'Netdisco::DB::Result::Device', 'ip' );
|
__PACKAGE__->belongs_to( device => 'Netdisco::DB::Result::Device', 'ip' );
|
||||||
|
|
||||||
|
=head2 device_port
|
||||||
|
|
||||||
|
Returns the Port on which this IP address is configured (typically a loopback,
|
||||||
|
routed port or virtual interface).
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->belongs_to( device_port => 'Netdisco::DB::Result::DevicePort',
|
__PACKAGE__->belongs_to( device_port => 'Netdisco::DB::Result::DevicePort',
|
||||||
{ 'foreign.port' => 'self.port', 'foreign.ip' => 'self.ip' } );
|
{ 'foreign.port' => 'self.port', 'foreign.ip' => 'self.ip' } );
|
||||||
|
|
||||||
|
|||||||
@@ -39,10 +39,34 @@ __PACKAGE__->set_primary_key("ip", "port", "vlan");
|
|||||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/3KLjJ3D18pGaPEaw9EU5w
|
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:/3KLjJ3D18pGaPEaw9EU5w
|
||||||
|
|
||||||
|
=head1 RELATIONSHIPS
|
||||||
|
|
||||||
|
=head2 device
|
||||||
|
|
||||||
|
Returns the entry from the C<device> table which hosts the Port on which this
|
||||||
|
VLAN is configured.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->belongs_to( device => 'Netdisco::DB::Result::Device', 'ip' );
|
__PACKAGE__->belongs_to( device => 'Netdisco::DB::Result::Device', 'ip' );
|
||||||
|
|
||||||
|
=head2 port
|
||||||
|
|
||||||
|
Returns the entry from the C<port> table on which this VLAN is configured.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->belongs_to( port => 'Netdisco::DB::Result::DevicePort', {
|
__PACKAGE__->belongs_to( port => 'Netdisco::DB::Result::DevicePort', {
|
||||||
'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port',
|
'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port',
|
||||||
});
|
});
|
||||||
|
|
||||||
|
=head2 vlan
|
||||||
|
|
||||||
|
Returns the entry from the C<device_vlan> table describing this VLAN in
|
||||||
|
detail, typically in order that the C<name> can be retrieved.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->belongs_to( vlan => 'Netdisco::DB::Result::DeviceVlan', {
|
__PACKAGE__->belongs_to( vlan => 'Netdisco::DB::Result::DeviceVlan', {
|
||||||
'foreign.ip' => 'self.ip', 'foreign.vlan' => 'self.vlan',
|
'foreign.ip' => 'self.ip', 'foreign.vlan' => 'self.vlan',
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -37,7 +37,22 @@ __PACKAGE__->set_primary_key("ip", "vlan");
|
|||||||
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
# Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02
|
||||||
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hBJRcdzOic4d3u4pD1m8iA
|
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:hBJRcdzOic4d3u4pD1m8iA
|
||||||
|
|
||||||
|
=head1 RELATIONSHIPS
|
||||||
|
|
||||||
|
=head2 device
|
||||||
|
|
||||||
|
Returns the entry from the C<device> table on which this VLAN entry was discovered.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->belongs_to( device => 'Netdisco::DB::Result::Device', 'ip' );
|
__PACKAGE__->belongs_to( device => 'Netdisco::DB::Result::Device', 'ip' );
|
||||||
|
|
||||||
|
=head2 port_vlans_tagged
|
||||||
|
|
||||||
|
Link relationship for C<tagging_ports>, see below.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->has_many( port_vlans_tagged => 'Netdisco::DB::Result::DevicePortVlan',
|
__PACKAGE__->has_many( port_vlans_tagged => 'Netdisco::DB::Result::DevicePortVlan',
|
||||||
{
|
{
|
||||||
'foreign.ip' => 'self.ip',
|
'foreign.ip' => 'self.ip',
|
||||||
@@ -47,6 +62,13 @@ __PACKAGE__->has_many( port_vlans_tagged => 'Netdisco::DB::Result::DevicePortVla
|
|||||||
where => { -not_bool => 'me.native' },
|
where => { -not_bool => 'me.native' },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
=head2 port_vlans_native
|
||||||
|
|
||||||
|
Link relationship to support C<native_ports>, see below.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->has_many( port_vlans_native => 'Netdisco::DB::Result::DevicePortVlan',
|
__PACKAGE__->has_many( port_vlans_native => 'Netdisco::DB::Result::DevicePortVlan',
|
||||||
{
|
{
|
||||||
'foreign.ip' => 'self.ip',
|
'foreign.ip' => 'self.ip',
|
||||||
@@ -56,7 +78,22 @@ __PACKAGE__->has_many( port_vlans_native => 'Netdisco::DB::Result::DevicePortVla
|
|||||||
where => { -bool => 'me.native' },
|
where => { -bool => 'me.native' },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
=head2 tagging_ports
|
||||||
|
|
||||||
|
Returns the set of Device Ports on which this VLAN is configured to be tagged.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->many_to_many( tagging_ports => 'port_vlans_tagged', 'port' );
|
__PACKAGE__->many_to_many( tagging_ports => 'port_vlans_tagged', 'port' );
|
||||||
|
|
||||||
|
=head2 native_ports
|
||||||
|
|
||||||
|
Returns the set of Device Ports on which this VLAN is the native VLAN (that
|
||||||
|
is, untagged).
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->many_to_many( native_ports => 'port_vlans_native', 'port' );
|
__PACKAGE__->many_to_many( native_ports => 'port_vlans_native', 'port' );
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -5,52 +5,132 @@ use strict;
|
|||||||
use warnings FATAL => 'all';
|
use warnings FATAL => 'all';
|
||||||
use NetAddr::IP::Lite ':lower';
|
use NetAddr::IP::Lite ':lower';
|
||||||
|
|
||||||
# override the built-in so we can munge some columns
|
=head1 ADDITIONAL METHODS
|
||||||
sub find {
|
|
||||||
my ($set, $ip, $attr) = @_;
|
|
||||||
$attr ||= {};
|
|
||||||
|
|
||||||
return $set->SUPER::find($ip,
|
=head2 with_times
|
||||||
{
|
|
||||||
%$attr,
|
This is a modifier for any C<search()> (including the helpers below) which
|
||||||
'+select' => [
|
will add the following additional synthesized columns to the result set:
|
||||||
\"replace(age(timestamp 'epoch' + uptime / 100 * interval '1 second', timestamp '1970-01-01 00:00:00-00')::text, 'mon', 'month')",
|
|
||||||
\"to_char(last_discover, 'YYYY-MM-DD HH24:MI')",
|
=over 4
|
||||||
\"to_char(last_macsuck, 'YYYY-MM-DD HH24:MI')",
|
|
||||||
\"to_char(last_arpnip, 'YYYY-MM-DD HH24:MI')",
|
=item uptime_age
|
||||||
],
|
|
||||||
'+as' => [qw/ uptime last_discover last_macsuck last_arpnip /],
|
=item last_discover_stamp
|
||||||
}
|
|
||||||
);
|
=item last_macsuck_stamp
|
||||||
|
|
||||||
|
=item last_arpnip_stamp
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub with_times {
|
||||||
|
my ($rs, $cond, $attrs) = @_;
|
||||||
|
$cond ||= {};
|
||||||
|
$attrs ||= {};
|
||||||
|
|
||||||
|
return $rs
|
||||||
|
->search_rs($cond, $attrs)
|
||||||
|
->search({},
|
||||||
|
{
|
||||||
|
'+select' => [
|
||||||
|
\"replace(age(timestamp 'epoch' + uptime / 100 * interval '1 second',
|
||||||
|
timestamp '1970-01-01 00:00:00-00')::text, 'mon', 'month')",
|
||||||
|
\"to_char(last_discover, 'YYYY-MM-DD HH24:MI')",
|
||||||
|
\"to_char(last_macsuck, 'YYYY-MM-DD HH24:MI')",
|
||||||
|
\"to_char(last_arpnip, 'YYYY-MM-DD HH24:MI')",
|
||||||
|
],
|
||||||
|
'+as' => [qw/
|
||||||
|
uptime_age
|
||||||
|
last_discover_stamp
|
||||||
|
last_macsuck_stamp
|
||||||
|
last_arpnip_stamp
|
||||||
|
/],
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
# finds distinct values of a col for use in form selections
|
=head2 search_by_field( \%cond, \%attrs? )
|
||||||
sub get_distinct {
|
|
||||||
my ($set, $col) = @_;
|
|
||||||
return $set unless $col;
|
|
||||||
|
|
||||||
return $set->search({},
|
This variant of the standard C<search()> method returns a ResultSet of Device
|
||||||
{
|
entries. It is written to support web forms which accept fields that match and
|
||||||
columns => [$col],
|
locate Devices in the database.
|
||||||
order_by => $col,
|
|
||||||
distinct => 1
|
The hashref parameter should contain fields from the Device table which will
|
||||||
}
|
be intelligently used in a search query.
|
||||||
)->get_column($col)->all;
|
|
||||||
}
|
In addition, you can provide the key C<matchall> which, given a True or False
|
||||||
|
value, controls whether fields must all match or whether any can match, to
|
||||||
|
select a row.
|
||||||
|
|
||||||
|
Supported keys:
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item matchall
|
||||||
|
|
||||||
|
If a True value, fields must all match to return a given row of the Device
|
||||||
|
table, otherwise any field matching will cause the row to be included in
|
||||||
|
results.
|
||||||
|
|
||||||
|
=item name
|
||||||
|
|
||||||
|
Can match the C<name> field as a substring.
|
||||||
|
|
||||||
|
=item location
|
||||||
|
|
||||||
|
Can match the C<location> field as a substring.
|
||||||
|
|
||||||
|
=item description
|
||||||
|
|
||||||
|
Can match the C<description> field as a substring (usually this field contains
|
||||||
|
a description of the vendor operating system).
|
||||||
|
|
||||||
|
=item model
|
||||||
|
|
||||||
|
Will match exactly the C<model> field.
|
||||||
|
|
||||||
|
=item os_ver
|
||||||
|
|
||||||
|
Will match exactly the C<os_ver> field, which is the operating sytem software version.
|
||||||
|
|
||||||
|
=item vendor
|
||||||
|
|
||||||
|
Will match exactly the C<vendor> (manufacturer).
|
||||||
|
|
||||||
|
=item dns
|
||||||
|
|
||||||
|
Can match any of the Device IP address aliases as a substring.
|
||||||
|
|
||||||
|
=item ip
|
||||||
|
|
||||||
|
Can be a string IP or a NetAddr::IP object, either way being treated as an
|
||||||
|
IPv4 or IPv6 prefix within which the device must have one IP address alias.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub search_by_field {
|
||||||
|
my ($rs, $p, $attrs) = @_;
|
||||||
|
|
||||||
|
die "condition parameter to search_by_field must be hashref\n"
|
||||||
|
if ref {} ne ref $p or 0 == scalar keys %$p;
|
||||||
|
$attrs ||= {};
|
||||||
|
|
||||||
sub by_field {
|
|
||||||
my ($set, $p) = @_;
|
|
||||||
return $set unless ref {} eq ref $p;
|
|
||||||
my $op = $p->{matchall} ? '-and' : '-or';
|
my $op = $p->{matchall} ? '-and' : '-or';
|
||||||
|
|
||||||
# this is a bit of an ungraceful backflip to catch junk entry
|
# this is a bit of an inelegant trick to catch junk data entry,
|
||||||
# whilst avoiding returning all devices in the DB
|
# whilst avoiding returning *all* entries in the table
|
||||||
my $ip = ($p->{ip} ?
|
if (exists $p->{ip} and defined $p->{ip} and 'NetAddr::IP::Lite' ne ref $p->{ip}) {
|
||||||
(NetAddr::IP::Lite->new($p->{ip}) || NetAddr::IP::Lite->new('255.255.255.255'))
|
$p->{ip} = ( NetAddr::IP::Lite->new($p->{ip})
|
||||||
: undef);
|
|| NetAddr::IP::Lite->new('255.255.255.255') );
|
||||||
|
}
|
||||||
|
|
||||||
return $set->search(
|
return $rs
|
||||||
{
|
->search_rs({}, $attrs)
|
||||||
|
->search({
|
||||||
$op => [
|
$op => [
|
||||||
($p->{name} ? ('me.name' =>
|
($p->{name} ? ('me.name' =>
|
||||||
{ '-ilike' => "\%$p->{name}\%" }) : ()),
|
{ '-ilike' => "\%$p->{name}\%" }) : ()),
|
||||||
@@ -58,22 +138,25 @@ sub by_field {
|
|||||||
{ '-ilike' => "\%$p->{location}\%" }) : ()),
|
{ '-ilike' => "\%$p->{location}\%" }) : ()),
|
||||||
($p->{description} ? ('me.description' =>
|
($p->{description} ? ('me.description' =>
|
||||||
{ '-ilike' => "\%$p->{description}\%" }) : ()),
|
{ '-ilike' => "\%$p->{description}\%" }) : ()),
|
||||||
|
|
||||||
($p->{model} ? ('me.model' =>
|
($p->{model} ? ('me.model' =>
|
||||||
{ '-in' => $p->{model} }) : ()),
|
{ '-in' => $p->{model} }) : ()),
|
||||||
($p->{os_ver} ? ('me.os_ver' =>
|
($p->{os_ver} ? ('me.os_ver' =>
|
||||||
{ '-in' => $p->{os_ver} }) : ()),
|
{ '-in' => $p->{os_ver} }) : ()),
|
||||||
($p->{vendor} ? ('me.vendor' =>
|
($p->{vendor} ? ('me.vendor' =>
|
||||||
{ '-in' => $p->{vendor} }) : ()),
|
{ '-in' => $p->{vendor} }) : ()),
|
||||||
|
|
||||||
($p->{dns} ? (
|
($p->{dns} ? (
|
||||||
-or => [
|
-or => [
|
||||||
'me.dns' => { '-ilike' => "\%$p->{dns}\%" },
|
'me.dns' => { '-ilike' => "\%$p->{dns}\%" },
|
||||||
'device_ips.dns' => { '-ilike' => "\%$p->{dns}\%" },
|
'device_ips.dns' => { '-ilike' => "\%$p->{dns}\%" },
|
||||||
]) : ()),
|
]) : ()),
|
||||||
($ip ? (
|
|
||||||
-or => [
|
($p->{ip} ? (
|
||||||
'me.ip' => { '<<=' => $ip->cidr },
|
-or => [
|
||||||
'device_ips.alias' => { '<<=' => $ip->cidr },
|
'me.ip' => { '<<=' => $p->{ip}->cidr },
|
||||||
]) : ()),
|
'device_ips.alias' => { '<<=' => $p->{ip}->cidr },
|
||||||
|
]) : ()),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -84,9 +167,38 @@ sub by_field {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub by_any {
|
=head2 search_fuzzy( $value )
|
||||||
my ($set, $q) = @_;
|
|
||||||
return $set unless $q;
|
This method accepts a single parameter only and returns a ResultSet of rows
|
||||||
|
from the Device table where one field matches the passed parameter.
|
||||||
|
|
||||||
|
The following fields are inspected for a match:
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item contact
|
||||||
|
|
||||||
|
=item serial
|
||||||
|
|
||||||
|
=item location
|
||||||
|
|
||||||
|
=item name
|
||||||
|
|
||||||
|
=item description
|
||||||
|
|
||||||
|
=item dns
|
||||||
|
|
||||||
|
=item ip (including aliases)
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub search_fuzzy {
|
||||||
|
my ($rs, $q) = @_;
|
||||||
|
|
||||||
|
die "missing param to search_by_field\n"
|
||||||
|
unless $q;
|
||||||
$q = "\%$q\%" if $q !~ m/\%/;
|
$q = "\%$q\%" if $q !~ m/\%/;
|
||||||
|
|
||||||
# basic IP check is a string match
|
# basic IP check is a string match
|
||||||
@@ -104,7 +216,7 @@ sub by_any {
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return $set->search(
|
return $rs->search(
|
||||||
{
|
{
|
||||||
-or => [
|
-or => [
|
||||||
'me.contact' => { '-ilike' => $q },
|
'me.contact' => { '-ilike' => $q },
|
||||||
@@ -127,39 +239,123 @@ sub by_any {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub carrying_vlan {
|
=head2 carrying_vlan( \%cond, \%attrs? )
|
||||||
my ($set, $vlan) = @_;
|
|
||||||
return $set unless $vlan and $vlan =~ m/^\d+$/;
|
|
||||||
|
|
||||||
return $set->search(
|
my $set = $rs->carrying_vlan({ vlan => 123 });
|
||||||
{
|
|
||||||
'vlans.vlan' => $vlan,
|
Like C<search()>, this returns a ResultSet of matching rows from the Device
|
||||||
'port_vlans.vlan' => $vlan,
|
table.
|
||||||
},
|
|
||||||
{
|
The returned devices each are aware of the given Vlan and have at least one
|
||||||
order_by => [qw/ me.dns me.ip /],
|
Port configured in the Vlan (either tagged, or not).
|
||||||
columns => [qw/ me.ip me.dns me.model me.os me.vendor /],
|
|
||||||
join => 'port_vlans',
|
=over 4
|
||||||
prefetch => 'vlans',
|
|
||||||
},
|
=item *
|
||||||
);
|
|
||||||
|
The C<cond> parameter must be a hashref containing a key C<vlan> with
|
||||||
|
the value to search for.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Results are ordered by the Device DNS and IP fields.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Related rows from the C<device_vlan> table will be prefetched.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub carrying_vlan {
|
||||||
|
my ($rs, $cond, $attrs) = @_;
|
||||||
|
|
||||||
|
die "vlan number required for carrying_vlan\n"
|
||||||
|
if ref {} ne ref $cond or !exists $cond->{vlan};
|
||||||
|
|
||||||
|
$cond->{'vlans.vlan'} = $cond->{vlan};
|
||||||
|
$cond->{'port_vlans.vlan'} = delete $cond->{vlan};
|
||||||
|
$attrs ||= {};
|
||||||
|
|
||||||
|
return $rs
|
||||||
|
->search_rs($cond,
|
||||||
|
{
|
||||||
|
order_by => [qw/ me.dns me.ip /],
|
||||||
|
columns => [qw/ me.ip me.dns me.model me.os me.vendor /],
|
||||||
|
join => 'port_vlans',
|
||||||
|
prefetch => 'vlans',
|
||||||
|
})
|
||||||
|
->search({}, $attrs);
|
||||||
}
|
}
|
||||||
|
|
||||||
sub carrying_vlan_name {
|
=head2 carrying_vlan_name( \%cond, \%attrs? )
|
||||||
my ($set, $name) = @_;
|
|
||||||
return $set unless $name;
|
|
||||||
$name = "\%$name\%" if $name !~ m/\%/;
|
|
||||||
|
|
||||||
return $set->search(
|
my $set = $rs->carrying_vlan_name({ name => 'Branch Office' });
|
||||||
{
|
|
||||||
'vlans.description' => { '-ilike' => $name },
|
Like C<search()>, this returns a ResultSet of matching rows from the Device
|
||||||
},
|
table.
|
||||||
{
|
|
||||||
|
The returned devices each are aware of the named Vlan and have at least one
|
||||||
|
Port configured in the Vlan (either tagged, or not).
|
||||||
|
|
||||||
|
=over 4
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
The C<cond> parameter must be a hashref containing a key C<name> with
|
||||||
|
the value to search for. The value may optionally include SQL wildcard
|
||||||
|
characters.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Results are ordered by the Device DNS and IP fields.
|
||||||
|
|
||||||
|
=item *
|
||||||
|
|
||||||
|
Related rows from the C<device_vlan> table will be prefetched.
|
||||||
|
|
||||||
|
=back
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub carrying_vlan_name {
|
||||||
|
my ($rs, $cond, $attrs) = @_;
|
||||||
|
|
||||||
|
die "vlan name required for carrying_vlan_name\n"
|
||||||
|
if ref {} ne ref $cond or !exists $cond->{name};
|
||||||
|
|
||||||
|
$cond->{'vlans.description'} = { '-ilike' => $cond->{name} };
|
||||||
|
$attrs ||= {};
|
||||||
|
|
||||||
|
return $rs
|
||||||
|
->search_rs({}, {
|
||||||
order_by => [qw/ me.dns me.ip /],
|
order_by => [qw/ me.dns me.ip /],
|
||||||
columns => [qw/ me.ip me.dns me.model me.os me.vendor /],
|
columns => [qw/ me.ip me.dns me.model me.os me.vendor /],
|
||||||
prefetch => 'vlans',
|
prefetch => 'vlans',
|
||||||
},
|
})
|
||||||
);
|
->search($cond, $attrs);
|
||||||
|
}
|
||||||
|
|
||||||
|
=head2 get_distinct( $column )
|
||||||
|
|
||||||
|
Returns an asciibetical sorted list of the distinct values in the given column
|
||||||
|
of the Device table. This is useful for web forms when you want to provide a
|
||||||
|
drop-down list of possible options.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub get_distinct {
|
||||||
|
my ($rs, $col) = @_;
|
||||||
|
return $rs unless $col;
|
||||||
|
|
||||||
|
return $rs->search({},
|
||||||
|
{
|
||||||
|
columns => [$col],
|
||||||
|
order_by => $col,
|
||||||
|
distinct => 1
|
||||||
|
}
|
||||||
|
)->get_column($col)->all;
|
||||||
}
|
}
|
||||||
|
|
||||||
1;
|
1;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use warnings FATAL => 'all';
|
|||||||
|
|
||||||
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55'});
|
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55'});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
DevicePort table.
|
DevicePort table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
@@ -55,7 +55,7 @@ sub search_by_mac {
|
|||||||
|
|
||||||
my $set = $rs->search_by_ip({ip => '192.0.2.1'});
|
my $set = $rs->search_by_ip({ip => '192.0.2.1'});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
DevicePort table.
|
DevicePort table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
@@ -103,7 +103,7 @@ sub search_by_ip {
|
|||||||
|
|
||||||
my $set = $rs->search_by_name({name => 'sniffer'});
|
my $set = $rs->search_by_name({name => 'sniffer'});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
DevicePort table.
|
DevicePort table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
@@ -141,7 +141,7 @@ sub search_by_name {
|
|||||||
|
|
||||||
my $set = $rs->search_by_vlan({vlan => 123});
|
my $set = $rs->search_by_vlan({vlan => 123});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
DevicePort table.
|
DevicePort table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
@@ -179,7 +179,7 @@ sub search_by_vlan {
|
|||||||
|
|
||||||
my $set = $rs->search_by_port({port => 'FastEthernet0/23'});
|
my $set = $rs->search_by_port({port => 'FastEthernet0/23'});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
DevicePort table.
|
DevicePort table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use warnings FATAL => 'all';
|
|||||||
|
|
||||||
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
|
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the Node
|
Like C<search()>, this returns a ResultSet of matching rows from the Node
|
||||||
table.
|
table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ column.
|
|||||||
=cut
|
=cut
|
||||||
|
|
||||||
sub has_dns_col {
|
sub has_dns_col {
|
||||||
my $set = shift;
|
my $rs = shift;
|
||||||
return $set->result_source->has_column('dns');
|
return $rs->result_source->has_column('dns');
|
||||||
}
|
}
|
||||||
|
|
||||||
my $search_attr = {
|
my $search_attr = {
|
||||||
@@ -37,7 +37,7 @@ my $search_attr = {
|
|||||||
|
|
||||||
my $set = $rs->search_by_ip({ip => '192.0.2.1', active => 1});
|
my $set = $rs->search_by_ip({ip => '192.0.2.1', active => 1});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
NodeIp table.
|
NodeIp table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
@@ -96,7 +96,7 @@ sub search_by_ip {
|
|||||||
|
|
||||||
my $set = $rs->search_by_name({dns => 'foo.example.com', active => 1});
|
my $set = $rs->search_by_name({dns => 'foo.example.com', active => 1});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
NodeIp table.
|
NodeIp table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
@@ -152,7 +152,7 @@ sub search_by_dns {
|
|||||||
|
|
||||||
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
|
my $set = $rs->search_by_mac({mac => '00:11:22:33:44:55', active => 1});
|
||||||
|
|
||||||
Like C<search()>, this returns a C<$resultset> of matching rows from the
|
Like C<search()>, this returns a ResultSet of matching rows from the
|
||||||
NodeIp table.
|
NodeIp table.
|
||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ ajax '/ajax/content/device/addresses' => sub {
|
|||||||
my $ip = param('q');
|
my $ip = param('q');
|
||||||
return unless $ip;
|
return unless $ip;
|
||||||
|
|
||||||
my $set = schema('netdisco')->resultset('DeviceIp')->search({ip => $ip}, { order_by => 'alias' });
|
my $set = schema('netdisco')->resultset('DeviceIp')
|
||||||
|
->search({ip => $ip}, { order_by => 'alias' });
|
||||||
return unless $set->count;
|
return unless $set->count;
|
||||||
|
|
||||||
content_type('text/html');
|
content_type('text/html');
|
||||||
@@ -71,17 +72,19 @@ ajax '/ajax/content/device/ports' => sub {
|
|||||||
my $ip = param('q');
|
my $ip = param('q');
|
||||||
return unless $ip;
|
return unless $ip;
|
||||||
|
|
||||||
my $set = schema('netdisco')->resultset('DevicePort')->search_by_ip({ip => $ip});
|
my $set = schema('netdisco')->resultset('DevicePort')
|
||||||
|
->search_by_ip({ip => $ip});
|
||||||
|
|
||||||
# refine by ports if requested
|
# refine by ports if requested
|
||||||
my $q = param('f');
|
my $q = param('f');
|
||||||
if ($q) {
|
if ($q) {
|
||||||
if ($q =~ m/^\d+$/) {
|
if ($q =~ m/^\d+$/) {
|
||||||
$set = $set->by_vlan($q);
|
$set = $set->search_by_vlan({vlan => $q});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my $c = schema('netdisco')->resultset('DevicePort')
|
my $c = schema('netdisco')->resultset('DevicePort')
|
||||||
->search_by_ip({ip => $ip})->search_by_port({port => $q});
|
->search_by_ip({ip => $ip})
|
||||||
|
->search_by_port({port => $q});
|
||||||
if ($c->count) {
|
if ($c->count) {
|
||||||
$set = $set->search_by_port({port => $q});
|
$set = $set->search_by_port({port => $q});
|
||||||
}
|
}
|
||||||
@@ -115,7 +118,8 @@ ajax '/ajax/content/device/details' => sub {
|
|||||||
my $ip = param('q');
|
my $ip = param('q');
|
||||||
return unless $ip;
|
return unless $ip;
|
||||||
|
|
||||||
my $device = schema('netdisco')->resultset('Device')->find($ip);
|
my $device = schema('netdisco')->resultset('Device')
|
||||||
|
->with_times()->find($ip);
|
||||||
return unless $device;
|
return unless $device;
|
||||||
|
|
||||||
content_type('text/html');
|
content_type('text/html');
|
||||||
|
|||||||
@@ -42,13 +42,13 @@ ajax '/ajax/content/search/device' => sub {
|
|||||||
my $set;
|
my $set;
|
||||||
|
|
||||||
if ($has_opt) {
|
if ($has_opt) {
|
||||||
$set = schema('netdisco')->resultset('Device')->by_field(scalar params);
|
$set = schema('netdisco')->resultset('Device')->search_by_field(scalar params);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
my $q = param('q');
|
my $q = param('q');
|
||||||
return unless $q;
|
return unless $q;
|
||||||
|
|
||||||
$set = schema('netdisco')->resultset('Device')->by_any($q);
|
$set = schema('netdisco')->resultset('Device')->search_fuzzy($q);
|
||||||
}
|
}
|
||||||
return unless $set->count;
|
return unless $set->count;
|
||||||
|
|
||||||
@@ -136,15 +136,15 @@ ajax '/ajax/content/search/node' => sub {
|
|||||||
|
|
||||||
# devices carrying vlan xxx
|
# devices carrying vlan xxx
|
||||||
ajax '/ajax/content/search/vlan' => sub {
|
ajax '/ajax/content/search/vlan' => sub {
|
||||||
my $vlan = param('q');
|
my $q = param('q');
|
||||||
return unless $vlan;
|
return unless $q;
|
||||||
my $set;
|
my $set;
|
||||||
|
|
||||||
if ($vlan =~ m/^\d+$/) {
|
if ($q =~ m/^\d+$/) {
|
||||||
$set = schema('netdisco')->resultset('Device')->carrying_vlan($vlan);
|
$set = schema('netdisco')->resultset('Device')->carrying_vlan({vlan => $q});
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$set = schema('netdisco')->resultset('Device')->carrying_vlan_name($vlan);
|
$set = schema('netdisco')->resultset('Device')->carrying_vlan_name({name => $q});
|
||||||
}
|
}
|
||||||
return unless $set->count;
|
return unless $set->count;
|
||||||
|
|
||||||
@@ -208,9 +208,8 @@ get '/search' => sub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if ($s->resultset('Device')->search({
|
if ($s->resultset('Device')
|
||||||
dns => { '-ilike' => "\%$q\%" },
|
->search({dns => { '-ilike' => "\%$q\%" }})->count) {
|
||||||
})->count) {
|
|
||||||
params->{'tab'} = 'device';
|
params->{'tab'} = 'device';
|
||||||
}
|
}
|
||||||
elsif ($s->resultset('DevicePort')
|
elsif ($s->resultset('DevicePort')
|
||||||
|
|||||||
Reference in New Issue
Block a user