diff --git a/Netdisco/lib/Netdisco/DB/ResultSet/Device.pm b/Netdisco/lib/Netdisco/DB/ResultSet/Device.pm index fefb7efb..8d7333ab 100644 --- a/Netdisco/lib/Netdisco/DB/ResultSet/Device.pm +++ b/Netdisco/lib/Netdisco/DB/ResultSet/Device.pm @@ -3,6 +3,23 @@ use base 'DBIx::Class::ResultSet'; use NetAddr::IP::Lite ':lower'; +# override the built-in so we can munge some columns +sub find { + my ($set, $ip) = @_; + + return $set->SUPER::find($ip, + { + '+select' => [ + \"replace(age(timestamp 'epoch' + uptime / 100 * interval '1 second', timestamp '1970-01-01 00:00:00-00')::text, 'mons', 'months')", + \"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 last_discover last_macsuck last_arpnip /], + } + ); +} + # finds distinct values of a col for use in form selections sub get_distinct { my ($set, $col) = @_; diff --git a/Netdisco/lib/Netdisco/Web.pm b/Netdisco/lib/Netdisco/Web.pm index fced281b..11ce7908 100644 --- a/Netdisco/lib/Netdisco/Web.pm +++ b/Netdisco/lib/Netdisco/Web.pm @@ -6,6 +6,7 @@ use Dancer::Plugin::DBIC; use Digest::MD5 (); use Socket6 (); # to ensure dependency is met +use HTML::Entities (); # to ensure dependency is met use NetAddr::IP::Lite ':lower'; use Net::MAC (); use List::MoreUtils (); @@ -32,6 +33,49 @@ hook 'before' => sub { for qw/stamps vendor archived partial/; }; +ajax '/ajax/content/device/:thing' => sub { + return "
Hello ". param('thing') ."
"; +}; + +# device ports with a description (er, name) matching +ajax '/ajax/content/device/details' => sub { + my $ip = param('ip'); + return unless $ip; + + my $device = schema('netdisco')->resultset('Device')->find($ip); + return unless $device; + + content_type('text/html'); + template 'ajax/device/details.tt', { + d => $device, + }, { layout => undef }; +}; + +get '/device' => sub { + my $ip = NetAddr::IP::Lite->new(param('ip')); + if (! $ip) { + redirect '/?nosuchdevice=1'; + return; + } + + my $device = schema('netdisco')->resultset('Device')->find($ip->addr); + if (! $device) { + redirect '/?nosuchdevice=1'; + return; + } + + # list of tabs + var('tabs' => [ + { id => 'details', label => 'Details' }, + { id => 'ports', label => 'Ports' }, + { id => 'modules', label => 'Modules' }, + { id => 'addresses', label => 'Addresses' }, + ]); + + params->{'tab'} ||= 'details'; + template 'device', { d => $device }; +}; + # device with various properties or a default match-all ajax '/ajax/content/search/device' => sub { my $has_opt = List::MoreUtils::any {param($_)} @@ -50,7 +94,7 @@ ajax '/ajax/content/search/device' => sub { return unless $set->count; content_type('text/html'); - template 'ajax/device.tt', { + template 'ajax/search/device.tt', { results => $set, }, { layout => undef }; }; @@ -74,7 +118,7 @@ ajax '/ajax/content/search/node' => sub { my $ports = schema('netdisco')->resultset('DevicePort') ->by_mac($mac->as_IEEE); - template 'ajax/node_by_mac.tt', { + template 'ajax/search/node_by_mac.tt', { ips => $ips, sightings => $sightings, ports => $ports, @@ -95,7 +139,7 @@ ajax '/ajax/content/search/node' => sub { } return unless $set->count; - template 'ajax/node_by_ip.tt', { + template 'ajax/search/node_by_ip.tt', { results => $set, }, { layout => undef }; } @@ -116,7 +160,7 @@ ajax '/ajax/content/search/vlan' => sub { return unless $set->count; content_type('text/html'); - template 'ajax/vlan.tt', { + template 'ajax/search/vlan.tt', { results => $set, }, { layout => undef }; }; @@ -130,7 +174,7 @@ ajax '/ajax/content/search/port' => sub { return unless $set->count; content_type('text/html'); - template 'ajax/port.tt', { + template 'ajax/search/port.tt', { results => $set, }, { layout => undef }; }; diff --git a/Netdisco/views/ajax/device/details.tt b/Netdisco/views/ajax/device/details.tt new file mode 100644 index 00000000..eaf0bf19 --- /dev/null +++ b/Netdisco/views/ajax/device/details.tt @@ -0,0 +1,69 @@ +| System Name | +[% d.name %] | +
| Location | ++ [% d.location %] | +
| Contact | +[% d.contact %] | +
| Model | ++ [% d.model %] | +
| OS / Version | +[% d.os %] / + [% d.os_ver %] + | +
| Serial Number | +[% d.serial %] | +
| Description | +[% d.description.replace(', ',", ") %] |
+
| Uptime | +[% d.uptime %] | +
| Last Discover | +[% d.last_discover %] | +
| Last Arpnip | +[% d.last_arpnip %] | +
| Last Macsuck | +[% d.last_macsuck %] | +
| Hardware Status | +Fan: [% d.fan %]
+ PS1 [[% d.ps1_type %]]: [% d.ps1_status %] + PS2 [[% d.ps2_type %]]: [% d.ps2_status %] |
+
| MAC Address | +[% d.mac %] | +
| VTP Domain | +[% d.vtp_domain %] | +
You are now logged out.