diff --git a/Netdisco/lib/Netdisco/DB/Result/Node.pm b/Netdisco/lib/Netdisco/DB/Result/Node.pm index b680ab99..de6c3e15 100644 --- a/Netdisco/lib/Netdisco/DB/Result/Node.pm +++ b/Netdisco/lib/Netdisco/DB/Result/Node.pm @@ -48,6 +48,11 @@ __PACKAGE__->set_primary_key("mac", "switch", "port"); # Created by DBIx::Class::Schema::Loader v0.07015 @ 2012-01-07 14:20:02 # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:sGGyKEfUkoIFVtmj1wnH7A +__PACKAGE__->belongs_to( device => 'Netdisco::DB::Result::Device', + { 'foreign.ip' => 'self.switch' } ); +__PACKAGE__->belongs_to( device_port => 'Netdisco::DB::Result::DevicePort', + { 'foreign.ip' => 'self.switch', 'foreign.port' => 'self.port' } ); +__PACKAGE__->has_many( ips => 'Netdisco::DB::Result::NodeIp', + { 'foreign.mac' => 'self.mac' } ); -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/Netdisco/lib/Netdisco/DB/Result/NodeIp.pm b/Netdisco/lib/Netdisco/DB/Result/NodeIp.pm index 4b680e32..326daa90 100644 --- a/Netdisco/lib/Netdisco/DB/Result/NodeIp.pm +++ b/Netdisco/lib/Netdisco/DB/Result/NodeIp.pm @@ -39,6 +39,49 @@ __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', + { 'foreign.mac' => 'self.mac' } ); +__PACKAGE__->has_many( nodes => 'Netdisco::DB::Result::Node', + { 'foreign.mac' => 'self.mac' } ); + +sub tidy_nodeips { + my ($row, $archive) = @_; + + return $row->nodeips( + { + ip => { '!=' => $row->ip }, + ($archive ? () : (active => 1)), + }, + { + 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 /], + }, + ); +} + +sub tidy_nodes { + my ($row, $archive) = @_; + + return $row->nodes( + { + ($archive ? () : (active => 1)), + }, + { + order_by => {'-desc' => 'time_last'}, + columns => [qw/ mac switch port oui active device.dns /], + '+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 => 'device', + }, + ); +} -# You can replace this text with custom code or comments, and it will be preserved on regeneration 1; diff --git a/Netdisco/lib/Netdisco/DB/ResultSet/Device.pm b/Netdisco/lib/Netdisco/DB/ResultSet/Device.pm index 9c6cad72..e28b1d96 100644 --- a/Netdisco/lib/Netdisco/DB/ResultSet/Device.pm +++ b/Netdisco/lib/Netdisco/DB/ResultSet/Device.pm @@ -11,10 +11,10 @@ sub carrying_vlan { 'port_vlans.vlan' => $vlan, }, { - join => [qw/ port_vlans vlans /], - prefetch => 'vlans', order_by => [qw/ me.dns me.ip /], columns => [qw/ me.ip me.dns me.model me.os me.vendor /], + join => 'port_vlans', + prefetch => 'vlans', }, ); } diff --git a/Netdisco/lib/Netdisco/DB/ResultSet/NodeIp.pm b/Netdisco/lib/Netdisco/DB/ResultSet/NodeIp.pm new file mode 100644 index 00000000..ada6536b --- /dev/null +++ b/Netdisco/lib/Netdisco/DB/ResultSet/NodeIp.pm @@ -0,0 +1,25 @@ +package Netdisco::DB::ResultSet::NodeIp; +use base 'DBIx::Class::ResultSet'; + +sub by_ip { + my ($set, $ip, $archive) = @_; + return $set unless $ip; + + return $set->search( + { + ip => $ip, + ($archive ? () : (active => 1)), + }, + { + 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 /], + }, + ); +} + +1; diff --git a/Netdisco/lib/Netdisco/Web.pm b/Netdisco/lib/Netdisco/Web.pm index a1501993..c43b4f05 100644 --- a/Netdisco/lib/Netdisco/Web.pm +++ b/Netdisco/lib/Netdisco/Web.pm @@ -22,6 +22,21 @@ ajax '/ajax/content/search/:thing' => sub { return '

Hello '. param('thing') .'.

'; }; +# nodes matching the param as an IP or DNS hostname or MAC +ajax '/ajax/content/search/node' => sub { + my $node = param('q'); + return unless $node; + + my $set = schema('netdisco')->resultset('NodeIp') + ->by_ip($node, param('archived')); + return unless $set->count; + + content_type('text/html'); + template 'content/node.tt', { + results => $set, + }, { layout => undef }; +}; + # devices carrying vlan xxx ajax '/ajax/content/search/vlan' => sub { my $vlan = param('q'); @@ -48,6 +63,12 @@ ajax '/ajax/content/search/vlan' => sub { }; 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 @@ -55,7 +76,35 @@ get '/search' => sub { params->{'tab'} = 'vlan'; } else { - params->{'tab'} = 'device'; + my $s = schema('netdisco'); + if ($q =~ m/^[a-f0-9.:]+$/i) { + if ($s->resultset('Device')->find($q)) { + params->{'tab'} = 'device'; + } + else { + # this will match for MAC addresses + # and partial IPs (subnets?) + params->{'tab'} = 'node'; + } + } + else { + if ($s->resultset('Device')->search({ + dns => { '-ilike' => "\%$q\%" }, + })->count) { + params->{'tab'} = 'device'; + } + elsif ($s->resultset('NodeIp')->search({ + dns => { '-ilike' => "\%$q\%" }, + })->count) { + params->{'tab'} = 'node'; + } + elsif ($s->resultset('DevicePort')->search({ + name => { '-ilike' => "\%$q\%" }, + })->count) { + params->{'tab'} = 'port'; + } + } + params->{'tab'} ||= 'device'; } } elsif (not $q) { @@ -63,12 +112,6 @@ get '/search' => sub { return; } - # set up default search options for each type - if (param('tab') and param('tab') ne 'node') { - params->{'stamps'} = 'checked'; - params->{'vendor'} = 'checked'; - } - # list of tabs var('tabs' => [ { id => 'device', label => 'Device' }, diff --git a/Netdisco/public/css/style.css b/Netdisco/public/css/style.css index eeac062c..fa34c431 100644 --- a/Netdisco/public/css/style.css +++ b/Netdisco/public/css/style.css @@ -3,6 +3,14 @@ body { padding-top: 50px; } +.well { + margin-right: 15px; +} + +.nd_content { + margin-left: 225px !important; +} + .nd_loginalert { margin-top: -40px; } @@ -34,13 +42,23 @@ body { vertical-align: top; } +.nd_legendlabel { + float: right; + line-height: 1.2; + margin-top: 2px; + margin-right: 3px; +} + .nd_search { margin-top: 15px; } -.nd_linkcell { +.nd_stealthlink { text-decoration: none !important; color: #404040; +} + +.nd_linkcell { display: block; padding: 0px; height: 100%; diff --git a/Netdisco/views/content/node.tt b/Netdisco/views/content/node.tt new file mode 100644 index 00000000..ff2a810b --- /dev/null +++ b/Netdisco/views/content/node.tt @@ -0,0 +1,57 @@ + + + + + + + [% IF params.stamps %] + + + [% END %] + + + + [% WHILE (row = results.next) %] + + + + + [% IF params.stamps %] + + + [% END %] + + [% FOREACH node IN row.tidy_nodes(params.archived) %] + + + + + [% IF params.stamps %] + + + [% END %] + + [% END %] + [% FOREACH nodeip IN row.tidy_nodeips(params.archived) %] + + + + + [% IF params.stamps %] + + + [% END %] + + [% END %] + [% END %] + +
MACMatchDevice or NodeFirst SeenLast Seen
[% row.mac %]IP → MAC[% row.ip %] + [% ' (' _ row.dns _ ')' IF row.dns %] + [% ' a' IF NOT row.active %] + [% row.time_first %][% row.time_last %]
 Switch Port[% node.switch %] [ [% node.port %] ] + [% ' (' _ node.device.dns _ ')' IF node.device.dns %] + [% ' a' IF NOT node.active %] + [% node.time_first %][% node.time_last %]
 MAC → IP[% nodeip.ip %] + [% ' (' _ nodeip.dns _ ')' IF nodeip.dns %] + [% ' a' IF NOT nodeip.active %] + [% nodeip.time_first %][% nodeip.time_last %]
diff --git a/Netdisco/views/content/vlan.tt b/Netdisco/views/content/vlan.tt index 576b0778..11da0c21 100644 --- a/Netdisco/views/content/vlan.tt +++ b/Netdisco/views/content/vlan.tt @@ -14,7 +14,7 @@ [% FOREACH method IN col.key.split('\.') %] [% SET val = val.$method %] [% END %] - [% val %] + [% val %] [% END %] [% END %] diff --git a/Netdisco/views/inc/search/node.tt b/Netdisco/views/inc/search/node.tt index 5d6148e9..b6036690 100644 --- a/Netdisco/views/inc/search/node.tt +++ b/Netdisco/views/inc/search/node.tt @@ -1,6 +1,5 @@

Node Search Options

-
diff --git a/Netdisco/views/search.tt b/Netdisco/views/search.tt index 15ca563d..2f24a370 100644 --- a/Netdisco/views/search.tt +++ b/Netdisco/views/search.tt @@ -24,7 +24,7 @@ -
+