1package App::Netdisco::Web::Plugin::Report::PortMultiNodes; 2 3use Dancer ':syntax'; 4use Dancer::Plugin::DBIC; 5use Dancer::Plugin::Auth::Extensible; 6 7use App::Netdisco::Web::Plugin; 8 9register_report( 10 { category => 'Port', 11 tag => 'portmultinodes', 12 label => 'Ports with multiple nodes attached', 13 provides_csv => 1, 14 api_endpoint => 1, 15 api_parameters => [ 16 vlan => { 17 description => 'Filter by VLAN', 18 type => 'integer', 19 }, 20 ], 21 } 22); 23 24get '/ajax/content/report/portmultinodes' => require_login sub { 25 my @results = schema('netdisco')->resultset('Device')->search( 26 { 'ports.remote_ip' => undef, 27 (param('vlan') ? 28 ('ports.vlan' => param('vlan'), 'nodes.vlan' => param('vlan')) : ()), 29 'nodes.active' => 1, 30 'wireless.port' => undef 31 }, 32 { select => [ 'ip', 'dns', 'name' ], 33 join => { 'ports' => [ 'wireless', 'nodes' ] }, 34 '+columns' => [ 35 { 'port' => 'ports.port' }, 36 { 'description' => 'ports.name' }, 37 { 'mac_count' => { count => 'nodes.mac' } }, 38 ], 39 group_by => [qw/me.ip me.dns me.name ports.port ports.name/], 40 having => \[ 'count(nodes.mac) > ?', [ count => 1 ] ], 41 order_by => { -desc => [qw/count/] }, 42 } 43 )->hri->all; 44 45 return unless scalar @results; 46 47 if ( request->is_ajax ) { 48 my $json = to_json (\@results); 49 template 'ajax/report/portmultinodes.tt', { results => $json }; 50 } 51 else { 52 header( 'Content-Type' => 'text/comma-separated-values' ); 53 template 'ajax/report/portmultinodes_csv.tt', 54 { results => \@results, }; 55 } 56}; 57 581; 59