diff --git a/Changes b/Changes index d0b33097..bdf4eff5 100644 --- a/Changes +++ b/Changes @@ -1,3 +1,17 @@ +2.040000 - 2018-05 + + [ENHANCEMENTS] + + * #408 improvements to MakeRancidConf (earendilfr) + * #410 improvements to Undiscovered Neighbors report + * device port search will match on Description as well as Port + * issue DB schema statements each within savepoints + + [BUG FIXES] + + * #414 clicking discover button with empty field causes crash + * #415 neighbors map display is blank + 2.039028 - 2018-05-05 [BUG FIXES] diff --git a/lib/App/Netdisco/DB.pm b/lib/App/Netdisco/DB.pm index 9bb97495..008b5369 100644 --- a/lib/App/Netdisco/DB.pm +++ b/lib/App/Netdisco/DB.pm @@ -11,7 +11,7 @@ __PACKAGE__->load_namespaces( ); our # try to hide from kwalitee - $VERSION = 52; # schema version used for upgrades, keep as integer + $VERSION = 53; # schema version used for upgrades, keep as integer use Path::Class; use File::ShareDir 'dist_dir'; @@ -20,7 +20,7 @@ our $schema_versions_dir = Path::Class::Dir->new( dist_dir('App-Netdisco') ) ->subdir('schema_versions')->stringify; __PACKAGE__->load_components(qw/ - Schema::Versioned + +App::Netdisco::DB::SchemaVersioned +App::Netdisco::DB::ExplicitLocking /); diff --git a/lib/App/Netdisco/DB/Result/Virtual/UndiscoveredNeighbors.pm b/lib/App/Netdisco/DB/Result/Virtual/UndiscoveredNeighbors.pm index 427e716d..1fe1c1d5 100644 --- a/lib/App/Netdisco/DB/Result/Virtual/UndiscoveredNeighbors.pm +++ b/lib/App/Netdisco/DB/Result/Virtual/UndiscoveredNeighbors.pm @@ -11,28 +11,32 @@ __PACKAGE__->table_class('DBIx::Class::ResultSource::View'); __PACKAGE__->table('undiscovered_neighbors'); __PACKAGE__->result_source_instance->is_virtual(1); __PACKAGE__->result_source_instance->view_definition(<<'ENDSQL'); - SELECT DISTINCT ON (p.remote_ip) d.ip, - d.name, - d.dns, - p.port, - p.remote_ip, - p.remote_id, - p.remote_type, - p.remote_port, - a.log, - a.finished - FROM device_port p - JOIN device d - ON d.ip = p.ip - LEFT JOIN admin a - ON (p.remote_ip = a.device AND a.action = 'discover') - WHERE - (p.remote_ip NOT IN (SELECT alias FROM device_ip)) - OR - ((p.remote_ip IS NULL) AND p.is_uplink) - ORDER BY - p.remote_ip ASC, - a.finished DESC + SELECT DISTINCT ON (p.remote_ip, p.port) + d.ip, d.name, d.dns, + p.port, p.name AS port_description, + p.remote_ip, p.remote_id, p.remote_type, p.remote_port, + l.log AS comment, + a.log, a.finished + + FROM device_port p + + INNER JOIN device d USING (ip) + LEFT OUTER JOIN device_skip ds + ON ('discover' = ANY(ds.actionset) AND p.remote_ip = ds.device) + LEFT OUTER JOIN device_port_log l USING (ip, port) + LEFT OUTER JOIN admin a + ON (p.remote_ip = a.device AND a.action = 'discover') + + WHERE + ds.device IS NULL + AND ((p.remote_ip NOT IN (SELECT alias FROM device_ip)) + OR ((p.remote_ip IS NULL) AND p.is_uplink)) + + ORDER BY + p.remote_ip ASC, + p.port ASC, + l.creation DESC, + a.finished DESC ENDSQL __PACKAGE__->add_columns( @@ -44,6 +48,8 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 1 }, "port", { data_type => "text", is_nullable => 0 }, + "port_description", + { data_type => "text", is_nullable => 0 }, "remote_ip", { data_type => "inet", is_nullable => 1 }, "remote_port", @@ -52,6 +58,8 @@ __PACKAGE__->add_columns( { data_type => "text", is_nullable => 1 }, "remote_id", { data_type => "text", is_nullable => 1 }, + "comment", + { data_type => "text", is_nullable => 1 }, "log", { data_type => "text", is_nullable => 1 }, "finished", diff --git a/lib/App/Netdisco/DB/SchemaVersioned.pm b/lib/App/Netdisco/DB/SchemaVersioned.pm new file mode 100644 index 00000000..9e4443cd --- /dev/null +++ b/lib/App/Netdisco/DB/SchemaVersioned.pm @@ -0,0 +1,17 @@ +package App::Netdisco::DB::SchemaVersioned; + +use strict; +use warnings; + +use base 'DBIx::Class::Schema::Versioned'; + +use Try::Tiny; +use DBIx::Class::Carp; + +sub apply_statement { + my ($self, $statement) = @_; + try { $self->storage->txn_do(sub { $self->storage->dbh->do($statement) }) } + catch { carp "SQL was: $statement" if $ENV{DBIC_TRACE} }; +} + +1; diff --git a/lib/App/Netdisco/Web/AdminTask.pm b/lib/App/Netdisco/Web/AdminTask.pm index 944a5f48..7826a6f4 100644 --- a/lib/App/Netdisco/Web/AdminTask.pm +++ b/lib/App/Netdisco/Web/AdminTask.pm @@ -16,7 +16,7 @@ sub add_job { return if ($device and (!$net or $net->num == 0 or $net->addr eq '0.0.0.0')); - my @hostlist = defined $device ? ($net->hostenum) : (undef); + my @hostlist = $device ? ($net->hostenum) : (undef); jq_insert([map {{ ($_ ? (device => $_->addr) : ()), diff --git a/lib/App/Netdisco/Web/Plugin/AdminTask/UndiscoveredNeighbors.pm b/lib/App/Netdisco/Web/Plugin/AdminTask/UndiscoveredNeighbors.pm index 7fb81804..d409d3cb 100644 --- a/lib/App/Netdisco/Web/Plugin/AdminTask/UndiscoveredNeighbors.pm +++ b/lib/App/Netdisco/Web/Plugin/AdminTask/UndiscoveredNeighbors.pm @@ -18,29 +18,28 @@ register_admin_task( get '/ajax/content/admin/undiscoveredneighbors' => require_role admin => sub { my @results - = schema('netdisco')->resultset('Virtual::UndiscoveredNeighbors') - ->order_by('ip')->hri->all; + = schema('netdisco')->resultset('Virtual::UndiscoveredNeighbors')->hri->all; return unless scalar @results; # Don't include devices excluded from discovery by config - # but only if the number of devices is small, as it triggers a - # SELECT per device to check. - if (scalar @results < 50) { - @results - = grep { is_discoverable( $_->{'remote_ip'}, $_->{'remote_type'} ) } - @results; + my @discoverable_results = (); + foreach my $r (@results) { + # create a new row object to avoid hitting the DB in get_device() + my $dev = schema('netdisco')->resultset('Device')->new({ip => $r->{remote_ip}}); + next unless is_discoverable( $dev, $r->{remote_type} ); + push @discoverable_results, $r; } - return unless scalar @results; + return unless scalar @discoverable_results; if ( request->is_ajax ) { template 'ajax/admintask/undiscoveredneighbors.tt', - { results => \@results, }, + { results => \@discoverable_results, }, { layout => undef }; } else { header( 'Content-Type' => 'text/comma-separated-values' ); template 'ajax/admintask/undiscoveredneighbors_csv.tt', - { results => \@results, }, + { results => \@discoverable_results, }, { layout => undef }; } }; diff --git a/lib/App/Netdisco/Web/Plugin/Device/Ports.pm b/lib/App/Netdisco/Web/Plugin/Device/Ports.pm index e6e1b4a9..b5276052 100644 --- a/lib/App/Netdisco/Web/Plugin/Device/Ports.pm +++ b/lib/App/Netdisco/Web/Plugin/Device/Ports.pm @@ -63,11 +63,12 @@ get '/ajax/content/device/ports' => require_login sub { } if (($prefer eq 'port') or not $prefer and - $set->search({'me.port' => $f})->count) { + $set->search({-or => ['me.port' => $f, 'me.descr' => $f]})->count) { $set = $set->search({ -or => [ 'me.port' => $f, + 'me.descr' => $f, 'me.slave_of' => $f, ], }); diff --git a/share/schema_versions/App-Netdisco-DB-52-53-PostgreSQL.sql b/share/schema_versions/App-Netdisco-DB-52-53-PostgreSQL.sql new file mode 100644 index 00000000..8a6501cd --- /dev/null +++ b/share/schema_versions/App-Netdisco-DB-52-53-PostgreSQL.sql @@ -0,0 +1,13 @@ +BEGIN; + +ALTER TABLE netmap_positions DROP CONSTRAINT "netmap_positions_device_groups_vlan_key"; + +ALTER TABLE netmap_positions RENAME COLUMN device_groups TO host_groups; + +ALTER TABLE netmap_positions ALTER COLUMN host_groups SET DEFAULT '{}'; + +ALTER TABLE netmap_positions ADD COLUMN "device" inet; + +ALTER TABLE netmap_positions ADD COLUMN "locations" text[] DEFAULT '{}' NOT NULL; + +COMMIT; diff --git a/share/views/ajax/admintask/undiscoveredneighbors.tt b/share/views/ajax/admintask/undiscoveredneighbors.tt index 5bcfb7af..c8ec1624 100644 --- a/share/views/ajax/admintask/undiscoveredneighbors.tt +++ b/share/views/ajax/admintask/undiscoveredneighbors.tt @@ -1,31 +1,29 @@
| Observing Device | +Observing Interface | Undiscovered Neighbor | -Last Discovery Attempt | -Last Discovery Log | +Neighbor ID | +Last Discovery | |
|---|---|---|---|---|---|---|---|
| - [% row.dns || row.name || row.ip | html_entity %] ( [% row.port | html_entity %] ) | -
- [% IF row.remote_ip %]
-
- [% row.remote_ip | html_entity %]
- ([% row.remote_port | html_entity %])
- [% ' ' IF row.remote_id or row.remote_type %] - [% ' id: '_ row.remote_id IF row.remote_id %] - [% ' type: '_ row.remote_type IF row.remote_type %] - [% ELSE %] - Known Device's MAC Address seen on this Port during Macsuck - [% END %] + |
+ [% row.dns || row.name || row.ip | html_entity %] + + [% row.port | html_entity %] + [% IF row.port_description %] [% row.port_description | html_entity %][% END %] + [% IF row.comment %] "[% row.comment | html_entity %]"[% END %] |
- [% row.finished | html_entity %] | -[% row.log | html_entity %] | +
+ [% row.remote_ip | html_entity %] + [% row.remote_port | html_entity %] |
+ [% row.remote_id | html_entity %] + [% row.remote_type | remove('(?:(?:C|c)opyright\s+)?\(c\).*') | remove('Technical Support: http://.*') | html_entity | html_line_break %] |
+ [% row.finished | html_entity %] [% row.log | html_entity %] |