diff --git a/Netdisco/lib/Netdisco/DB/Result/NodeIp.pm b/Netdisco/lib/Netdisco/DB/Result/NodeIp.pm index 326daa90..afd5fe64 100644 --- a/Netdisco/lib/Netdisco/DB/Result/NodeIp.pm +++ b/Netdisco/lib/Netdisco/DB/Result/NodeIp.pm @@ -39,15 +39,25 @@ __PACKAGE__->set_primary_key("mac", "ip"); # Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:9+CuvuVWH88WxAf6IBij8g -__PACKAGE__->has_many( nodeips => 'Netdisco::DB::Result::NodeIp', +__PACKAGE__->belongs_to( oui => 'Netdisco::DB::Result::Oui', + sub { + my $args = shift; + return { + "$args->{foreign_alias}.oui" => + { '=' => \"substring(cast($args->{self_alias}.mac as varchar) for 8)" } + }; + } +); + +__PACKAGE__->has_many( node_ips => 'Netdisco::DB::Result::NodeIp', { 'foreign.mac' => 'self.mac' } ); __PACKAGE__->has_many( nodes => 'Netdisco::DB::Result::Node', { 'foreign.mac' => 'self.mac' } ); -sub tidy_nodeips { +sub ip_aliases { my ($row, $archive) = @_; - return $row->nodeips( + return $row->node_ips( { ip => { '!=' => $row->ip }, ($archive ? () : (active => 1)), @@ -64,7 +74,7 @@ sub tidy_nodeips { ); } -sub tidy_nodes { +sub node_sightings { my ($row, $archive) = @_; return $row->nodes( diff --git a/Netdisco/lib/Netdisco/DB/ResultSet/NodeIp.pm b/Netdisco/lib/Netdisco/DB/ResultSet/NodeIp.pm index ada6536b..7d48ba8f 100644 --- a/Netdisco/lib/Netdisco/DB/ResultSet/NodeIp.pm +++ b/Netdisco/lib/Netdisco/DB/ResultSet/NodeIp.pm @@ -1,24 +1,46 @@ package Netdisco::DB::ResultSet::NodeIp; use base 'DBIx::Class::ResultSet'; +my $search_attr = { + order_by => {'-desc' => 'time_last'}, + columns => [qw/ mac ip dns active oui.company /], + '+select' => [ + \"to_char(time_first, 'YYYY-MM-DD HH24:MI')", + \"to_char(time_last, 'YYYY-MM-DD HH24:MI')", + ], + '+as' => [qw/ time_first time_last /], + join => 'oui' +}; + sub by_ip { - my ($set, $ip, $archive) = @_; + my ($set, $archive, $ip) = @_; return $set unless $ip; + my $op = '='; + if ('NetAddr::IP::Lite' eq ref $ip) { + $op = '<<=' if $ip->num > 1; + $ip = $ip->cidr; + } + return $set->search( { - ip => $ip, + ip => { $op => $ip }, ($archive ? () : (active => 1)), }, + $search_attr, + ); +} + +sub by_name { + my ($set, $archive, $name) = @_; + return $set unless $name; + + return $set->search( { - order_by => {'-desc' => 'time_last'}, - columns => [qw/ mac ip dns active /], - '+select' => [ - \"to_char(time_first, 'YYYY-MM-DD HH24:MI')", - \"to_char(time_last, 'YYYY-MM-DD HH24:MI')", - ], - '+as' => [qw/ time_first time_last /], + dns => { '-ilike' => $name }, + ($archive ? () : (active => 1)), }, + $search_attr, ); } diff --git a/Netdisco/lib/Netdisco/Web.pm b/Netdisco/lib/Netdisco/Web.pm index 1868406a..873b5b97 100644 --- a/Netdisco/lib/Netdisco/Web.pm +++ b/Netdisco/lib/Netdisco/Web.pm @@ -3,7 +3,11 @@ package Netdisco::Web; use Dancer ':syntax'; use Dancer::Plugin::Ajax; use Dancer::Plugin::DBIC; + use Digest::MD5 (); +use Socket6 (); +use NetAddr::IP::Lite ':lower'; +use Regexp::Common 'net'; hook 'before' => sub { if (! session('user') && request->path !~ m{^/login}) { @@ -11,6 +15,16 @@ hook 'before' => sub { #var(requested_path => request->path); #request->path_info('/'); } + + # set up default search options for each type + if (not param('tab') or param('tab') ne 'node') { + params->{'stamps'} = 'checked'; + } + + # set up query string defaults for templates + var('query_defaults' => { map { ($_ => "tab=$_") } qw/node/ }); + var('query_defaults')->{node} .= "\&$_=". (param($_) || '') + for qw/stamps vendor archived partial/; }; get '/' => sub { @@ -26,15 +40,35 @@ ajax '/ajax/content/search/:thing' => sub { ajax '/ajax/content/search/node' => sub { my $node = param('q'); return unless $node; + my $set; - my $set = schema('netdisco')->resultset('NodeIp') - ->by_ip($node, param('archived')); - return unless $set->count; + # if mac + # search on mac + # try to make ip + # search on ip + # text search for node dns - content_type('text/html'); - template 'ajax/node.tt', { - results => $set, - }, { layout => undef }; + if ($node =~ m/^$RE{net}{MAC}$/) { + } + else { + if (my $ip = NetAddr::IP::Lite->new($node)) { + # by_ip() will extract cidr notation if necessary + $set = schema('netdisco')->resultset('NodeIp') + ->by_ip(param('archived'), $ip); + return unless $set->count; + } + else { + $node = "\%$node\%" if param('partial'); + $set = schema('netdisco')->resultset('NodeIp') + ->by_name(param('archived'), $node); + return unless $set->count; + } + + content_type('text/html'); + template 'ajax/node.tt', { + results => $set, + }, { layout => undef }; + } }; # devices carrying vlan xxx @@ -48,27 +82,10 @@ ajax '/ajax/content/search/vlan' => sub { content_type('text/html'); template 'ajax/vlan.tt', { results => $set, - columns => [ - { key => 'dns', label => 'Device' }, - { key => 'vlan.description', label => 'Description' }, - { key => 'model', label => 'Model' }, - { key => 'os', label => 'OS' }, - { key => 'vendor', label => 'Vendor' }, - ], - hyperlink => sub { - my $row = shift; - return '/device?q='. $row->ip .'&vlan='. $vlan; - }, }, { layout => undef }; }; get '/search' => sub { - # set up default search options for each type - if (not param('tab') or param('tab') ne 'node') { - params->{'stamps'} = 'checked'; - params->{'vendor'} = 'checked'; - } - my $q = param('q'); if ($q and not param('tab')) { # pick most likely tab for initial results diff --git a/Netdisco/views/ajax/node.tt b/Netdisco/views/ajax/node.tt index ff2a810b..a19a5c64 100644 --- a/Netdisco/views/ajax/node.tt +++ b/Netdisco/views/ajax/node.tt @@ -2,6 +2,9 @@ MAC + [% IF params.vendor %] + Vendor + [% END %] Match Device or Node [% IF params.stamps %] @@ -13,10 +16,14 @@ [% WHILE (row = results.next) %] - [% row.mac %] + [% row.mac %] + [% IF params.vendor %] + [% row.oui.company %] + [% END %] IP → MAC - [% row.ip %] - [% ' (' _ row.dns _ ')' IF row.dns %] + [% row.ip %] + [% ' (' _ row.dns.remove(settings.domain_suffix) _ ')' IF row.dns %] [% ' a' IF NOT row.active %] [% IF params.stamps %] @@ -24,12 +31,15 @@ [% row.time_last %] [% END %] - [% FOREACH node IN row.tidy_nodes(params.archived) %] + [% FOREACH node IN row.node_sightings(params.archived) %]   + [% IF params.vendor %] +   + [% END %] Switch Port [% node.switch %] [ [% node.port %] ] - [% ' (' _ node.device.dns _ ')' IF node.device.dns %] + [% ' (' _ node.device.dns.remove(settings.domain_suffix) _ ')' IF node.device.dns %] [% ' a' IF NOT node.active %] [% IF params.stamps %] @@ -38,12 +48,15 @@ [% END %] [% END %] - [% FOREACH nodeip IN row.tidy_nodeips(params.archived) %] + [% FOREACH nodeip IN row.ip_aliases(params.archived) %]   + [% IF params.vendor %] +   + [% END %] MAC → IP - [% nodeip.ip %] - [% ' (' _ nodeip.dns _ ')' IF nodeip.dns %] + [% nodeip.ip %] + [% ' (' _ nodeip.dns.remove(settings.domain_suffix) _ ')' IF nodeip.dns %] [% ' a' IF NOT nodeip.active %] [% IF params.stamps %] diff --git a/Netdisco/views/ajax/vlan.tt b/Netdisco/views/ajax/vlan.tt index 11da0c21..870bfbdb 100644 --- a/Netdisco/views/ajax/vlan.tt +++ b/Netdisco/views/ajax/vlan.tt @@ -1,21 +1,26 @@ - [% FOREACH col IN columns %] - - [% END %] + + + + + [% WHILE (row = results.next) %] - [% FOREACH col IN columns %] - [% SET val = row %] - [% FOREACH method IN col.key.split('\.') %] - [% SET val = val.$method %] - [% END %] - - [% END %] + + + + + [% END %] diff --git a/Netdisco/views/inc/search/node.tt b/Netdisco/views/inc/search/node.tt index b6036690..0b938118 100644 --- a/Netdisco/views/inc/search/node.tt +++ b/Netdisco/views/inc/search/node.tt @@ -24,3 +24,11 @@ Archived Data a +
+ + +
[% col.label %]DeviceDescriptionModelOSVendor
[% val %][% row.dns %][% row.vlan.description %][% row.model %][% row.os %][% row.vendor %]