diff --git a/Netdisco/Changes b/Netdisco/Changes index 3b287820..2d6b4246 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,5 +1,9 @@ 2.033000 - 2015-08 + [NEW FEATURES] + + * [#237] Show IPv4 and/or IPv6 nodes separately in Device Ports table + [ENHANCEMENTS] * Expose the created, last login and note fields for User managment diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Node.pm b/Netdisco/lib/App/Netdisco/DB/Result/Node.pm index 88de7544..87252126 100644 --- a/Netdisco/lib/App/Netdisco/DB/Result/Node.pm +++ b/Netdisco/lib/App/Netdisco/DB/Result/Node.pm @@ -112,6 +112,24 @@ the current Node's. __PACKAGE__->has_many( ips => 'App::Netdisco::DB::Result::NodeIp', { 'foreign.mac' => 'self.mac', 'foreign.active' => 'self.active' } ); +=head2 ip4s + +Same as C but for IPv4 only. + +=cut + +__PACKAGE__->has_many( ip4s => 'App::Netdisco::DB::Result::Virtual::NodeIp4', + { 'foreign.mac' => 'self.mac', 'foreign.active' => 'self.active' } ); + +=head2 ip6s + +Same as C but for IPv6 only. + +=cut + +__PACKAGE__->has_many( ip6s => 'App::Netdisco::DB::Result::Virtual::NodeIp6', + { 'foreign.mac' => 'self.mac', 'foreign.active' => 'self.active' } ); + =head2 netbios Returns the C entry associated with this Node if one exists. That diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodeIp4.pm b/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodeIp4.pm new file mode 100644 index 00000000..66d368f8 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodeIp4.pm @@ -0,0 +1,19 @@ +use utf8; +package App::Netdisco::DB::Result::Virtual::NodeIp4; + +use strict; +use warnings; + +use base 'App::Netdisco::DB::Result::NodeIp'; + +__PACKAGE__->load_components('Helper::Row::SubClass'); +__PACKAGE__->subclass; + +__PACKAGE__->table_class('DBIx::Class::ResultSource::View'); +__PACKAGE__->table("node_ip4"); +__PACKAGE__->result_source_instance->is_virtual(1); +__PACKAGE__->result_source_instance->view_definition(q{ + SELECT * FROM node_ip WHERE family(ip) = 4 +}); + +1; diff --git a/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodeIp6.pm b/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodeIp6.pm new file mode 100644 index 00000000..be3692fb --- /dev/null +++ b/Netdisco/lib/App/Netdisco/DB/Result/Virtual/NodeIp6.pm @@ -0,0 +1,19 @@ +use utf8; +package App::Netdisco::DB::Result::Virtual::NodeIp6; + +use strict; +use warnings; + +use base 'App::Netdisco::DB::Result::NodeIp'; + +__PACKAGE__->load_components('Helper::Row::SubClass'); +__PACKAGE__->subclass; + +__PACKAGE__->table_class('DBIx::Class::ResultSource::View'); +__PACKAGE__->table("node_ip6"); +__PACKAGE__->result_source_instance->is_virtual(1); +__PACKAGE__->result_source_instance->view_definition(q{ + SELECT * FROM node_ip WHERE family(ip) = 6 +}); + +1; diff --git a/Netdisco/lib/App/Netdisco/Web/Device.pm b/Netdisco/lib/App/Netdisco/Web/Device.pm index 2235d7d9..1dc5e2fa 100644 --- a/Netdisco/lib/App/Netdisco/Web/Device.pm +++ b/Netdisco/lib/App/Netdisco/Web/Device.pm @@ -48,12 +48,13 @@ hook 'before' => sub { # view settings for port connected devices var('connected_properties' => [ - { name => 'n_age', label => 'Age Stamp', default => '' }, - { name => 'n_ip', label => 'IP Address', default => 'on' }, - { name => 'n_netbios', label => 'NetBIOS', default => 'on' }, - { name => 'n_ssid', label => 'SSID', default => 'on' }, - { name => 'n_vendor', label => 'Vendor', default => '' }, - { name => 'n_archived', label => 'Archived Data', default => '' }, + { name => 'n_age', label => 'Age Stamp', default => '' }, + { name => 'n_ip4', label => 'IPv4 Addresses', default => 'on' }, + { name => 'n_ip6', label => 'IPv6 Addresses', default => 'on' }, + { name => 'n_netbios', label => 'NetBIOS', default => 'on' }, + { name => 'n_ssid', label => 'SSID', default => 'on' }, + { name => 'n_vendor', label => 'Vendor', default => '' }, + { name => 'n_archived', label => 'Archived Data', default => '' }, ]); return unless (request->path eq uri_for('/device')->path diff --git a/Netdisco/lib/App/Netdisco/Web/Plugin/Device/Ports.pm b/Netdisco/lib/App/Netdisco/Web/Plugin/Device/Ports.pm index be8eb8f5..40431ece 100644 --- a/Netdisco/lib/App/Netdisco/Web/Plugin/Device/Ports.pm +++ b/Netdisco/lib/App/Netdisco/Web/Plugin/Device/Ports.pm @@ -136,25 +136,29 @@ get '/ajax/content/device/ports' => require_login sub { # what kind of nodes are we interested in? my $nodes_name = (param('n_archived') ? 'nodes' : 'active_nodes'); - $nodes_name .= '_with_age' if param('c_nodes') and param('n_age'); - $set = $set->search_rs({}, { order_by => ["${nodes_name}.vlan", "${nodes_name}.mac", "ips.ip"] }) - if param('c_nodes'); + $nodes_name .= '_with_age' if param('n_age'); - # retrieve active/all connected nodes, if asked for - $set = $set->search_rs({}, { prefetch => [{$nodes_name => 'ips'}] }) - if param('c_nodes'); + if (param('c_nodes')) { + my $ips = ((param('n_ip4') and param('n_ip6')) ? 'ips' + : param('n_ip4') ? 'ip4s' + : 'ip6s'); - # retrieve wireless SSIDs, if asked for - $set = $set->search_rs({}, { prefetch => [{$nodes_name => 'wireless'}] }) - if param('c_nodes') && param('n_ssid'); + # retrieve active/all connected nodes, if asked for + $set = $set->search_rs({}, { prefetch => [{$nodes_name => $ips}] }); + $set = $set->search_rs({}, { order_by => ["${nodes_name}.vlan", "${nodes_name}.mac", "${ips}.ip"] }); - # retrieve NetBIOS, if asked for - $set = $set->search_rs({}, { prefetch => [{$nodes_name => 'netbios'}] }) - if param('c_nodes') && param('n_netbios'); + # retrieve wireless SSIDs, if asked for + $set = $set->search_rs({}, { prefetch => [{$nodes_name => 'wireless'}] }) + if param('n_ssid'); - # retrieve vendor, if asked for - $set = $set->search_rs({}, { prefetch => [{$nodes_name => 'oui'}] }) - if param('c_nodes') && param('n_vendor'); + # retrieve NetBIOS, if asked for + $set = $set->search_rs({}, { prefetch => [{$nodes_name => 'netbios'}] }) + if param('n_netbios'); + + # retrieve vendor, if asked for + $set = $set->search_rs({}, { prefetch => [{$nodes_name => 'oui'}] }) + if param('n_vendor'); + } # retrieve SSID, if asked for $set = $set->search({}, { prefetch => 'ssid' }) if param('c_ssid'); diff --git a/Netdisco/share/views/ajax/device/ports.tt b/Netdisco/share/views/ajax/device/ports.tt index c899dc07..1862da99 100644 --- a/Netdisco/share/views/ajax/device/ports.tt +++ b/Netdisco/share/views/ajax/device/ports.tt @@ -331,8 +331,19 @@ ) [% END %] [% ' (' _ node.time_last_age _ ')' IF params.n_age %] - [% IF params.n_ip %] - [% FOREACH ip IN node.ips %] + [% IF params.n_ip4 %] + [% FOREACH ip IN node.ip4s %] +
  [% '  ' IF NOT ip.active %] + [% SET dns = ip.dns %] + [% IF dns %] + [% dns %] ([% ip.ip | html_entity %]) + [% ELSE %] + [% ip.ip | html_entity %] + [% END %] + [% END %] + [% END %] + [% IF params.n_ip6 %] + [% FOREACH ip IN node.ip6s %]
  [% '  ' IF NOT ip.active %] [% SET dns = ip.dns %] [% IF dns %] diff --git a/Netdisco/share/views/ajax/device/ports_csv.tt b/Netdisco/share/views/ajax/device/ports_csv.tt index 343aba46..76790a50 100644 --- a/Netdisco/share/views/ajax/device/ports_csv.tt +++ b/Netdisco/share/views/ajax/device/ports_csv.tt @@ -11,9 +11,9 @@ [% headers.push('Node MAC') %] [% headers.push('Archived Node') %] [% headers.push('Age Stamp') IF params.n_age %] - [% headers.push('Node IP') IF params.n_ip %] - [% headers.push('Node DNS') IF params.n_ip %] - [% headers.push('Archived IP') IF params.n_ip %] + [% headers.push('Node IP') IF params.n_ip4 OR params.n_ip6 %] + [% headers.push('Node DNS') IF params.n_ip4 OR params.n_ip6 %] + [% headers.push('Archived IP') IF params.n_ip4 OR params.n_ip6 %] [% ELSIF item.name == 'c_duplex' %] [% headers.push('Duplex Setting') %] [% headers.push('Duplex') %] @@ -132,9 +132,9 @@ [% myport.push('') %] [% myport.push('') %] [% myport.push('') IF params.n_age %] - [% myport.push('') IF params.n_ip %] - [% myport.push('') IF params.n_ip %] - [% myport.push('') IF params.n_ip %] + [% myport.push('') IF params.n_ip4 OR params.n_ip6 %] + [% myport.push('') IF params.n_ip4 OR params.n_ip6 %] + [% myport.push('') IF params.n_ip4 OR params.n_ip6 %] [% END %] [% IF params.c_neighbors %] @@ -184,21 +184,36 @@ [% CALL mynode.push(node.time_last_age) IF params.n_age %] - [% IF params.n_ip %] + [% IF params.n_ip4 OR params.n_ip6 %] [% mynode.push('') %] [% mynode.push('') %] [% mynode.push('') %] [% SET has_ips = 0 %] - [% FOREACH ip IN node.ips %] - [% SET has_ips = 1 %] + [% IF params.n_ip4 %] + [% FOREACH ip IN node.ip4s %] + [% SET has_ips = 1 %] - [% CALL mynode.splice(-3, 1, ip.ip) %] - [% CALL mynode.splice(-2, 1, ip.dns) %] - [% CALL mynode.splice(-1, 1, (ip.active ? 'No' : 'Yes')) %] + [% CALL mynode.splice(-3, 1, ip.ip) %] + [% CALL mynode.splice(-2, 1, ip.dns) %] + [% CALL mynode.splice(-1, 1, (ip.active ? 'No' : 'Yes')) %] - [% CALL myport.splice(c_nodes_pos, mynode.size, mynode) %] - [% CSV.dump(myport) %] + [% CALL myport.splice(c_nodes_pos, mynode.size, mynode) %] + [% CSV.dump(myport) %] + [% END %] + [% END %] + + [% IF params.n_ip6 %] + [% FOREACH ip IN node.ip6s %] + [% SET has_ips = 1 %] + + [% CALL mynode.splice(-3, 1, ip.ip) %] + [% CALL mynode.splice(-2, 1, ip.dns) %] + [% CALL mynode.splice(-1, 1, (ip.active ? 'No' : 'Yes')) %] + + [% CALL myport.splice(c_nodes_pos, mynode.size, mynode) %] + [% CSV.dump(myport) %] + [% END %] [% END %] [% CSV.dump(myport) IF NOT has_ips %]