1package App::Netdisco::Web::Plugin::Search::Port; 2 3use Dancer ':syntax'; 4use Dancer::Plugin::DBIC; 5use Dancer::Plugin::Auth::Extensible; 6 7use App::Netdisco::Web::Plugin; 8use App::Netdisco::Util::Web 'sql_match'; 9 10use Regexp::Common 'net'; 11use NetAddr::MAC (); 12 13register_search_tab({ 14 tag => 'port', 15 label => 'Port', 16 provides_csv => 1, 17 api_endpoint => 1, 18 api_parameters => [ 19 q => { 20 description => 'Port name or VLAN or MAC address', 21 required => 1, 22 }, 23 partial => { 24 description => 'Search for a partial match on parameter "q"', 25 type => 'boolean', 26 default => 'true', 27 }, 28 uplink => { 29 description => 'Include uplinks in results', 30 type => 'boolean', 31 default => 'false', 32 }, 33 ethernet => { 34 description => 'Only Ethernet type interfaces in results', 35 type => 'boolean', 36 default => 'true', 37 }, 38 ], 39}); 40 41# device ports with a description (er, name) matching 42get '/ajax/content/search/port' => require_login sub { 43 my $q = param('q'); 44 send_error( 'Missing query', 400 ) unless $q; 45 my $rs; 46 47 if ($q =~ m/^[0-9]+$/ and $q < 4096) { 48 $rs = schema('netdisco')->resultset('DevicePort') 49 ->columns( [qw/ ip port name up up_admin speed /] )->search({ 50 "port_vlans.vlan" => $q, 51 ( param('uplink') ? () : (-or => [ 52 {-not_bool => "me.is_uplink"}, 53 {"me.is_uplink" => undef}, 54 ]) ), 55 ( param('ethernet') ? ("me.type" => 'ethernetCsmacd') : () ), 56 },{ '+columns' => [qw/ device.dns device.name port_vlans.vlan /], 57 join => [qw/ port_vlans device /] 58 } 59 )->with_times; 60 } 61 else { 62 my ( $likeval, $likeclause ) = sql_match($q); 63 my $mac = NetAddr::MAC->new(mac => ($q || '')); 64 65 undef $mac if 66 ($mac and $mac->as_ieee 67 and (($mac->as_ieee eq '00:00:00:00:00:00') 68 or ($mac->as_ieee !~ m/$RE{net}{MAC}/))); 69 70 $rs = schema('netdisco')->resultset('DevicePort') 71 ->columns( [qw/ ip port name up up_admin speed /] ) 72 ->search({ 73 -and => [ 74 -or => [ 75 { "me.name" => ( param('partial') ? $likeclause : $q ) }, 76 ( ((!defined $mac) or $mac->errstr) 77 ? \[ 'me.mac::text ILIKE ?', $likeval ] 78 : { 'me.mac' => $mac->as_ieee } 79 ), 80 ( param('uplink') ? ( 81 { "me.remote_id" => $likeclause }, 82 { "me.remote_type" => $likeclause }, 83 ) : () ), 84 ], 85 ( param('uplink') ? () : (-or => [ 86 {-not_bool => "me.is_uplink"}, 87 {"me.is_uplink" => undef}, 88 ]) ), 89 ( param('ethernet') ? ("me.type" => 'ethernetCsmacd') : () ), 90 ] 91 }, 92 { '+columns' => [qw/ device.dns device.name port_vlans.vlan /], 93 join => [qw/ port_vlans device /] 94 } 95 )->with_times; 96 } 97 98 my @results = $rs->hri->all; 99 return unless scalar @results; 100 101 if ( request->is_ajax ) { 102 my $json = to_json( \@results ); 103 template 'ajax/search/port.tt', { results => $json }; 104 } 105 else { 106 header( 'Content-Type' => 'text/comma-separated-values' ); 107 template 'ajax/search/port_csv.tt', { results => \@results }; 108 } 109}; 110 1111; 112