LAG support.

Also, archive disappeared nodes from device after macsuck.

Squashed commit of the following:

commit 6d16cddaab
Merge: 37d9bda 3fdf780
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 19 15:48:41 2014 +0000

    Merge branch 'master' of ssh://git.code.sf.net/p/netdisco/netdisco-ng into og-agg

commit 37d9bda2bb
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 18:50:22 2014 +0000

    release 2.021000_004

commit 3939a2a51c
Merge: cf23636 571d57d
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 18:45:14 2014 +0000

    Merge branch 'og-agg' of ssh://olly_g@git.code.sf.net/p/netdisco/netdisco-ng into og-agg

commit cf23636ddf
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 18:43:59 2014 +0000

    archive disappeared nodes from device - really important!

commit 571d57dcc7
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 18:20:51 2014 +0000

    release 2.021000_003

commit 444bc1e81d
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 17:51:54 2014 +0000

    protect sprintf from undefined remote_type

commit 5b875c4641
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 17:49:40 2014 +0000

    tidy connected device+node layout

commit c09dddb7d1
Merge: 4f5501c 95fc6b1
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 17:46:39 2014 +0000

    Merge branch 'og-agg' of ssh://olly_g@git.code.sf.net/p/netdisco/netdisco-ng into og-agg

commit 4f5501c613
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 17:46:23 2014 +0000

    allow sanity checks on lag member before moving node

commit 95fc6b18dc
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 14:02:19 2014 +0000

    release 2.021000_002

commit 8b809c445f
Merge: 04d486e fe3e8e3
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 13:58:31 2014 +0000

    Merge branch 'og-agg' of ssh://git.code.sf.net/p/netdisco/netdisco-ng into og-agg

commit fe3e8e3ef2
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 13:57:31 2014 +0000

    do not set master neigh if master is a slave

commit 04d486e433
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 13:38:45 2014 +0000

    display remote ip if only remote ip

commit 14f9eb01ad
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 13:35:54 2014 +0000

    show all members of lag when searching for lag master

commit 5b2a0a0a4b
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 13:35:16 2014 +0000

    fix copy of remote master to local master remote_port

commit 86a9854f39
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 10:00:13 2014 +0000

    show both link and device type icons

commit 88510552e5
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 09:57:29 2014 +0000

    hide neighbor device ID and add sidebar option to show

commit 29da3097cb
Merge: 8bca30d 9fe92fb
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 09:04:15 2014 +0000

    Merge branch 'og-agg' of ssh://git.code.sf.net/p/netdisco/netdisco-ng into og-agg

commit 9fe92fb5e8
Merge: 6620a03 5557811
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 09:03:02 2014 +0000

    Merge branch 'og-agg' of ssh://olly_g@git.code.sf.net/p/netdisco/netdisco-ng into og-agg

commit 6620a03686
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 08:56:13 2014 +0000

    also store master neighbor port

commit 8bca30d085
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 00:41:46 2014 +0000

    release 2.021000_001

commit 5557811aeb
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Mon Jan 13 00:38:18 2014 +0000

    fix icon placement in editable device port cells

commit 25292e1ce8
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 22:20:08 2014 +0000

    fix name of class

commit 99ce56d794
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 22:13:53 2014 +0000

    remove brackets from lag name

commit 27aa80ed93
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 22:12:06 2014 +0000

    rename link agg legend

commit 84ed4c5008
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 22:11:15 2014 +0000

    move lag member icon into port icon column

commit 67c9c783ec
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 21:58:11 2014 +0000

    fix Cisco stack port ignore

commit 4531c61246
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 21:51:41 2014 +0000

    move nodes to lag master port

commit ffc6b9c315
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 20:45:58 2014 +0000

    use group icon for slave and master

commit 68fd345e37
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 20:34:01 2014 +0000

    indicate aggregate master

commit 79c69f5a0f
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 19:14:48 2014 +0000

    show aggreate parent in device ports

commit 3a4beed2f1
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 18:46:25 2014 +0000

    store aggregate port into db

commit fd7bb0cd62
Author: Oliver Gorwits <oliver@cpan.org>
Date:   Sun Jan 12 17:49:39 2014 +0000

    add device_port cols for aggregate links data
This commit is contained in:
Oliver Gorwits
2014-01-19 15:51:47 +00:00
parent 3fdf7802b6
commit 642546fd24
15 changed files with 199 additions and 69 deletions

View File

@@ -72,8 +72,6 @@ lib/App/Netdisco/DB/Result/Virtual/ActiveNodeWithAge.pm
lib/App/Netdisco/DB/Result/Virtual/ApRadioChannelPower.pm lib/App/Netdisco/DB/Result/Virtual/ApRadioChannelPower.pm
lib/App/Netdisco/DB/Result/Virtual/CidrIps.pm lib/App/Netdisco/DB/Result/Virtual/CidrIps.pm
lib/App/Netdisco/DB/Result/Virtual/DeviceLinks.pm lib/App/Netdisco/DB/Result/Virtual/DeviceLinks.pm
lib/App/Netdisco/DB/Result/Virtual/DevicePortVlanNative.pm
lib/App/Netdisco/DB/Result/Virtual/DevicePortVlanTagged.pm
lib/App/Netdisco/DB/Result/Virtual/DuplexMismatch.pm lib/App/Netdisco/DB/Result/Virtual/DuplexMismatch.pm
lib/App/Netdisco/DB/Result/Virtual/NodeWithAge.pm lib/App/Netdisco/DB/Result/Virtual/NodeWithAge.pm
lib/App/Netdisco/DB/Result/Virtual/PhonesDiscovered.pm lib/App/Netdisco/DB/Result/Virtual/PhonesDiscovered.pm
@@ -119,6 +117,9 @@ lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-28-29-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-29-30-PostgreSQL.sql lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-29-30-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-3-4-PostgreSQL.sql lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-3-4-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-30-31-PostgreSQL.sql lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-30-31-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-31-32-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-32-33-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-33-34-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-4-5-PostgreSQL.sql lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-4-5-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-5-6-PostgreSQL.sql lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-5-6-PostgreSQL.sql
lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-6-7-PostgreSQL.sql lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-6-7-PostgreSQL.sql

View File

@@ -71,4 +71,4 @@ resources:
homepage: http://netdisco.org/ homepage: http://netdisco.org/
license: http://opensource.org/licenses/bsd-license.php license: http://opensource.org/licenses/bsd-license.php
repository: git://git.code.sf.net/p/netdisco/netdisco-ng repository: git://git.code.sf.net/p/netdisco/netdisco-ng
version: 2.021000 version: 2.021000_004

View File

@@ -7,7 +7,7 @@ use 5.010_000;
use File::ShareDir 'dist_dir'; use File::ShareDir 'dist_dir';
use Path::Class; use Path::Class;
our $VERSION = '2.021000'; our $VERSION = '2.021000_004';
BEGIN { BEGIN {
if (not ($ENV{DANCER_APPDIR} || '') if (not ($ENV{DANCER_APPDIR} || '')

View File

@@ -206,6 +206,7 @@ sub store_interfaces {
my $i_stp_state = $snmp->i_stp_state; my $i_stp_state = $snmp->i_stp_state;
my $i_vlan = $snmp->i_vlan; my $i_vlan = $snmp->i_vlan;
my $i_lastchange = $snmp->i_lastchange; my $i_lastchange = $snmp->i_lastchange;
my $agg_ports = $snmp->agg_ports;
# clear the cached uptime and get a new one # clear the cached uptime and get a new one
my $dev_uptime = $snmp->load_uptime; my $dev_uptime = $snmp->load_uptime;
@@ -278,10 +279,22 @@ sub store_interfaces {
type => $i_type->{$entry}, type => $i_type->{$entry},
vlan => $i_vlan->{$entry}, vlan => $i_vlan->{$entry},
pvid => $i_vlan->{$entry}, pvid => $i_vlan->{$entry},
is_master => 'false',
slave_of => undef,
lastchange => $lc, lastchange => $lc,
}; };
} }
# must do this after building %interfaces so that we can set is_master
foreach my $sidx (keys %$agg_ports) {
my $slave = $interfaces->{$sidx} or next;
my $master = $interfaces->{ $agg_ports->{$sidx} } or next;
next unless exists $interfaces{$slave} and exists $interfaces{$master};
$interfaces{$slave}->{slave_of} = $master;
$interfaces{$master}->{is_master} = 'true';
}
schema('netdisco')->resultset('DevicePort')->txn_do_locked(sub { schema('netdisco')->resultset('DevicePort')->txn_do_locked(sub {
my $gone = $device->ports->delete({keep_nodes => 1}); my $gone = $device->ports->delete({keep_nodes => 1});
debug sprintf ' [%s] interfaces - removed %d interfaces', debug sprintf ' [%s] interfaces - removed %d interfaces',
@@ -695,18 +708,19 @@ sub store_neighbors {
# IP Phone and WAP detection type fixup # IP Phone and WAP detection type fixup
if (defined $remote_type) { if (defined $remote_type) {
my $phone_flag = grep {/phone/i} @$remote_cap; my $phone_flag = grep {/phone/i} @$remote_cap;
my $ap_flag = grep {/wlanAccessPoint/} @$remote_cap; my $ap_flag = grep {/wlanAccessPoint/} @$remote_cap;
if ($phone_flag or $remote_type =~ m/(mitel.5\d{3})/i) {
$remote_type = 'IP Phone: '. $remote_type if ($phone_flag or $remote_type =~ m/(mitel.5\d{3})/i) {
if $remote_type !~ /ip phone/i; $remote_type = 'IP Phone: '. $remote_type
} if $remote_type !~ /ip phone/i;
elsif ($ap_flag) { }
$remote_type = 'AP: '. $remote_type; elsif ($ap_flag) {
} $remote_type = 'AP: '. $remote_type;
else { }
$remote_type ||= ''; else {
} $remote_type ||= '';
}
} }
# hack for devices seeing multiple neighbors on the port # hack for devices seeing multiple neighbors on the port
@@ -719,7 +733,7 @@ sub store_neighbors {
foreach my $n (@$remote_ip) { foreach my $n (@$remote_ip) {
debug sprintf debug sprintf
' [%s] neigh - adding neighbor %s, type [%s], on %s to discovery queue', ' [%s] neigh - adding neighbor %s, type [%s], on %s to discovery queue',
$device->ip, $n, $remote_type, $port; $device->ip, $n, ($remote_type || ''), $port;
push @to_discover, [$n, $remote_type]; push @to_discover, [$n, $remote_type];
} }
} }
@@ -733,7 +747,7 @@ sub store_neighbors {
if (wantarray) { if (wantarray) {
debug sprintf debug sprintf
' [%s] neigh - adding neighbor %s, type [%s], on %s to discovery queue', ' [%s] neigh - adding neighbor %s, type [%s], on %s to discovery queue',
$device->ip, $remote_ip, $remote_type, $port; $device->ip, $remote_ip, ($remote_type || ''), $port;
push @to_discover, [$remote_ip, $remote_type]; push @to_discover, [$remote_ip, $remote_type];
} }
@@ -773,6 +787,26 @@ sub store_neighbors {
is_uplink => \"true", is_uplink => \"true",
manual_topo => \"false", manual_topo => \"false",
}); });
if (defined $portrow->slave_of and
my $master = schema('netdisco')->resultset('DevicePort')
->single({ip => $device->ip, port => $portrow->slave_of})) {
if (not ($portrow->is_master or defined $master->slave_of)) {
# TODO needs refactoring - this is quite expensive
my $peer = schema('netdisco')->resultset('DevicePort')->find({
ip => $portrow->neighbor->ip,
port => $portrow->remote_port,
}) if $portrow->neighbor;
$master->update({
remote_ip => ($peer ? $peer->ip : $remote_ip),
remote_port => ($peer ? $peer->slave_of : undef ),
is_uplink => \"true",
manual_topo => \"false",
});
}
}
} }
return @to_discover; return @to_discover;
@@ -860,7 +894,7 @@ sub discover_new_neighbors {
if (not is_discoverable($device, $remote_type)) { if (not is_discoverable($device, $remote_type)) {
debug sprintf debug sprintf
' queue - %s, type [%s] excluded by discover_* config', ' queue - %s, type [%s] excluded by discover_* config',
$ip, $remote_type; $ip, ($remote_type || '');
next; next;
} }

View File

@@ -57,8 +57,8 @@ sub do_macsuck {
my $ip = $device->ip; my $ip = $device->ip;
# would be possible just to use now() on updated records, but by using this # would be possible just to use now() on updated records, but by using this
# same value for them all, we _can_ if we want add a job at the end to # same value for them all, we can if we want add a job at the end to
# select and do something with the updated set (no reason to yet, though) # select and do something with the updated set (see set archive, below)
my $now = 'to_timestamp('. (join '.', gettimeofday) .')'; my $now = 'to_timestamp('. (join '.', gettimeofday) .')';
my $total_nodes = 0; my $total_nodes = 0;
@@ -98,8 +98,10 @@ sub do_macsuck {
debug sprintf ' [%s] macsuck - port %s vlan %s : %s nodes', debug sprintf ' [%s] macsuck - port %s vlan %s : %s nodes',
$ip, $port, $vlan, scalar keys %{ $fwtable->{$vlan}->{$port} }; $ip, $port, $vlan, scalar keys %{ $fwtable->{$vlan}->{$port} };
# make sure this port is UP in netdisco # make sure this port is UP in netdisco (unless it's a lag master,
$device_ports->{$port}->update({up_admin => 'up', up => 'up'}); # because we can still see nodes without a functioning aggregate)
$device_ports->{$port}->update({up_admin => 'up', up => 'up'})
if not $device_ports->{$port}->is_master;
foreach my $mac (keys %{ $fwtable->{$vlan}->{$port} }) { foreach my $mac (keys %{ $fwtable->{$vlan}->{$port} }) {
@@ -113,8 +115,18 @@ sub do_macsuck {
} }
} }
debug sprintf ' [%s] macsuck - %s forwarding table entries', debug sprintf ' [%s] macsuck - %s updated forwarding table entries',
$ip, $total_nodes; $ip, $total_nodes;
# a use for $now ... need to archive dissapeared nodes
my $archived = schema('netdisco')->resultset('Node')->search({
switch => $ip,
time_last => { '<' => \$now },
})->update({ active => \'false' });
debug sprintf ' [%s] macsuck - removed %s fwd table entries to archive',
$ip, $archived;
$device->update({last_macsuck => \$now}); $device->update({last_macsuck => \$now});
} }
@@ -324,14 +336,6 @@ sub _walk_fwtable {
next; next;
} }
# TODO: add proper port channel support!
if ($port =~ m/port.channel/i) {
debug sprintf
' [%s] macsuck %s - port %s is LAG member - skipping.',
$device->ip, $mac, $port;
next;
}
# this uses the cached $ports resultset to limit hits on the db # this uses the cached $ports resultset to limit hits on the db
my $device_port = $device_ports->{$port}; my $device_port = $device_ports->{$port};
@@ -389,8 +393,14 @@ sub _walk_fwtable {
next unless setting('macsuck_bleed'); next unless setting('macsuck_bleed');
} }
my $vlan = $fw_vlan->{$idx} || $comm_vlan || '0'; # possibly move node to lag master
if (defined $device_port->slave_of
and exists $device_ports->{$device_port->slave_of}) {
$port = $device_port->slave_of;
$device_ports->{$port}->update({is_uplink => \'true'});
}
my $vlan = $fw_vlan->{$idx} || $comm_vlan || '0';
++$cache->{$vlan}->{$port}->{$mac}; ++$cache->{$vlan}->{$port}->{$mac};
} }

View File

@@ -10,7 +10,7 @@ __PACKAGE__->load_namespaces(
default_resultset_class => 'ResultSet', default_resultset_class => 'ResultSet',
); );
our $VERSION = 33; # schema version used for upgrades, keep as integer our $VERSION = 34; # schema version used for upgrades, keep as integer
use Path::Class; use Path::Class;
use File::Basename; use File::Basename;

View File

@@ -53,6 +53,10 @@ __PACKAGE__->add_columns(
{ data_type => "text", is_nullable => 1 }, { data_type => "text", is_nullable => 1 },
"remote_id", "remote_id",
{ data_type => "text", is_nullable => 1 }, { data_type => "text", is_nullable => 1 },
"is_master",
{ data_type => "bool", is_nullable => 0, default_value => \"false" },
"slave_of",
{ data_type => "text", is_nullable => 1 },
"manual_topo", "manual_topo",
{ data_type => "bool", is_nullable => 0, default_value => \"false" }, { data_type => "bool", is_nullable => 0, default_value => \"false" },
"is_uplink", "is_uplink",
@@ -179,6 +183,22 @@ __PACKAGE__->might_have(
} }
); );
=head2 agg_master
Returns another row from the C<device_port> table if this port is slave
to another in a link aggregate.
=cut
__PACKAGE__->belongs_to(
agg_master => 'App::Netdisco::DB::Result::DevicePort', {
'foreign.ip' => 'self.ip',
'foreign.port' => 'self.slave_of',
}, {
join_type => 'LEFT',
}
);
=head2 neighbor_alias =head2 neighbor_alias
When a device port has an attached neighbor device, this relationship will When a device port has an attached neighbor device, this relationship will
@@ -231,7 +251,7 @@ __PACKAGE__->belongs_to( oui => 'App::Netdisco::DB::Result::Oui',
=head1 ADDITIONAL METHODS =head1 ADDITIONAL METHODS
=head2 =head2 neighbor
Returns the Device entry for the neighbour Device on the given port. Returns the Device entry for the neighbour Device on the given port.

View File

@@ -64,9 +64,9 @@ sub with_is_free {
->search({}, ->search({},
{ {
'+columns' => { is_free => '+columns' => { is_free =>
\["up != 'up' and " \["me.up != 'up' and "
."age(now(), to_timestamp(extract(epoch from device.last_discover) " ."age(now(), to_timestamp(extract(epoch from device.last_discover) "
."- (device.uptime - lastchange)/100)) " ."- (device.uptime - me.lastchange)/100)) "
."> ?::interval", ."> ?::interval",
[{} => $interval]] }, [{} => $interval]] },
join => 'device', join => 'device',
@@ -93,11 +93,11 @@ sub only_free_ports {
->search_rs($cond, $attrs) ->search_rs($cond, $attrs)
->search( ->search(
{ {
'up' => { '!=' => 'up' }, 'me.up' => { '!=' => 'up' },
},{ },{
where => where =>
\["age(now(), to_timestamp(extract(epoch from device.last_discover) " \["age(now(), to_timestamp(extract(epoch from device.last_discover) "
."- (device.uptime - lastchange)/100)) " ."- (device.uptime - me.lastchange)/100)) "
."> ?::interval", ."> ?::interval",
[{} => $interval]], [{} => $interval]],
join => 'device' }, join => 'device' },

View File

@@ -0,0 +1,7 @@
BEGIN;
ALTER TABLE device_port DROP COLUMN is_uplink_admin;
ALTER TABLE device_port ADD COLUMN "slave_of" text;
ALTER TABLE device_port ADD COLUMN "is_master" bool DEFAULT false NOT NULL;
COMMIT;

View File

@@ -63,7 +63,12 @@ get '/ajax/content/device/ports' => require_login sub {
if (($prefer eq 'port') or not $prefer and if (($prefer eq 'port') or not $prefer and
$set->search({'me.port' => $f})->count) { $set->search({'me.port' => $f})->count) {
$set = $set->search({'me.port' => $f}); $set = $set->search({
-or => [
'me.port' => $f,
'me.slave_of' => $f,
],
});
} }
else { else {
$set = $set->search({'me.name' => $f}); $set = $set->search({'me.name' => $f});
@@ -108,6 +113,13 @@ get '/ajax/content/device/ports' => require_login sub {
$set = $set->search({-or => \@combi}); $set = $set->search({-or => \@combi});
} }
# get aggregate master status
$set = $set->search({}, {
'join' => 'agg_master',
'+select' => [qw/agg_master.up_admin agg_master.up/],
'+as' => [qw/agg_master_up_admin agg_master_up/],
});
# make sure query asks for formatted timestamps when needed # make sure query asks for formatted timestamps when needed
$set = $set->with_times if param('c_lastchange'); $set = $set->with_times if param('c_lastchange');

View File

@@ -16,7 +16,7 @@ logger_format: '[%P] %L @%D> %m'
# WEB FRONTEND # WEB FRONTEND
# ------------ # ------------
domain_suffix: '' domain_suffix: ""
no_auth: false no_auth: false
suggest_guest: false suggest_guest: false
trust_remote_user: false trust_remote_user: false
@@ -24,9 +24,9 @@ trust_x_remote_user: false
#ldap: #ldap:
# servers: [] # servers: []
# user_string: 'MYDOMAIN\%USER%' # user_string: 'MYDOMAIN\%USER%'
# base: '' # base: ""
# proxy_user: '' # proxy_user: ""
# proxy_pass: '' # proxy_pass: ""
# opts: # opts:
# debug: 3 # debug: 3
# tls_opts: {} # tls_opts: {}
@@ -80,7 +80,7 @@ extra_web_plugins: []
community: ['public'] community: ['public']
community_rw: ['private'] community_rw: ['private']
snmp_auth: [] snmp_auth: []
get_community: '' get_community: ""
bulkwalk_off: false bulkwalk_off: false
bulkwalk_no: [] bulkwalk_no: []
bulkwalk_repeaters: 20 bulkwalk_repeaters: 20
@@ -117,7 +117,8 @@ ignore_interfaces:
- 'StackPort' - 'StackPort'
- 'Control Plane Interface' - 'Control Plane Interface'
- 'SPAN (S|R)P Interface' - 'SPAN (S|R)P Interface'
- 'StackSub' - 'StackSub-.*'
- 'StackPort\d+'
- 'netflow' - 'netflow'
- 'Vlan\d+-mpls layer' - 'Vlan\d+-mpls layer'
- 'BRI\S+-Bearer Channel' - 'BRI\S+-Bearer Channel'

View File

@@ -158,9 +158,14 @@ div.content > div.tab-content table.nd_floatinghead thead {
/* nudge cell content to the right when port_control controls are enabled */ /* nudge cell content to the right when port_control controls are enabled */
.nd_editable-cell > .nd_this-port-only { .nd_editable-cell > .nd_this-port-only {
margin-left: 18px; margin-left: 18px;
margin-right: 18px;
} }
.nd_editable-cell > .nd_port-only-first {
margin-left: 9px;
}
.nd_editable-cell > .nd_editable-cell-content { .nd_editable-cell > .nd_editable-cell-content {
margin-left: 18px; margin-right: 18px;
} }
.table .nd_nudge-for-icon { .table .nd_nudge-for-icon {
padding-left: 25px; padding-left: 25px;
@@ -177,6 +182,10 @@ div.content > div.tab-content table.nd_floatinghead thead {
text-align: center; text-align: center;
} }
td.nd_devport-icon i {
line-height: 18px;
}
/* undo nd_center-cell when in a modial dialog (which lives in table cell) */ /* undo nd_center-cell when in a modial dialog (which lives in table cell) */
.table .nd_center-cell .modal-body { .table .nd_center-cell .modal-body {
text-align: left; text-align: left;
@@ -261,7 +270,7 @@ td > form.nd_inline-form {
cursor: pointer; cursor: pointer;
color: black; color: black;
float: left; float: left;
display: none; visibility: hidden;
margin-top: 3px; margin-top: 3px;
} }
.nd_log-icon:hover, .nd_log-icon:focus { .nd_log-icon:hover, .nd_log-icon:focus {

View File

@@ -92,14 +92,16 @@ $(document).ready(function() {
// toggle visibility of port up/down and edit controls // toggle visibility of port up/down and edit controls
$('.tab-content').on('mouseenter', '.nd_editable-cell', function() { $('.tab-content').on('mouseenter', '.nd_editable-cell', function() {
$(this).children('.nd_hand-icon,.nd_log-icon').show(); $(this).children('.nd_hand-icon').show();
$(this).children('.nd_log-icon').css('visibility', 'visible');
if (! $(this).is(':focus')) { if (! $(this).is(':focus')) {
$(this).children('.nd_edit-icon').show(); // ports $(this).children('.nd_edit-icon').show(); // ports
$(this).siblings('td').find('.nd_device-details-edit').show(); // details $(this).siblings('td').find('.nd_device-details-edit').show(); // details
} }
}); });
$('.tab-content').on('mouseleave', '.nd_editable-cell', function() { $('.tab-content').on('mouseleave', '.nd_editable-cell', function() {
$(this).children('.nd_hand-icon,.nd_log-icon').hide(); $(this).children('.nd_hand-icon').hide();
$(this).children('.nd_log-icon').css('visibility', 'hidden');
if (! $(this).is(':focus')) { if (! $(this).is(':focus')) {
$(this).children('.nd_edit-icon').hide(); // ports $(this).children('.nd_edit-icon').hide(); // ports
$(this).siblings('td').find('.nd_device-details-edit').hide(); // details $(this).siblings('td').find('.nd_device-details-edit').hide(); // details

View File

@@ -17,7 +17,7 @@
</tbody> </tbody>
[% FOREACH row IN results %] [% FOREACH row IN results %]
<tr> <tr>
<td class="nd_center-cell"> <td class="nd_center-cell nd_devport-icon">
[% IF row.up_admin != 'up' %] [% IF row.up_admin != 'up' %]
<i class="icon-remove"></i> <i class="icon-remove"></i>
[% ELSIF row.stp == 'blocking' %] [% ELSIF row.stp == 'blocking' %]
@@ -29,6 +29,15 @@
[% ELSE %] [% ELSE %]
<i class="icon-angle-up text-success"></i> <i class="icon-angle-up text-success"></i>
[% END %] [% END %]
[% IF row.slave_of %]<br/>
[% IF row.get_column('agg_master_up_admin') != 'up' %]
<small><i class="icon-group muted"></i></small>
[% ELSIF row.get_column('agg_master_up') == 'up' %]
<small><i class="icon-group text-success"></i></small>
[% ELSE %]
<small><i class="icon-group text-error"></i></small>
[% END %]
[% END %]
</td> </td>
[% FOREACH config IN settings._extra_device_port_cols %] [% FOREACH config IN settings._extra_device_port_cols %]
@@ -66,10 +75,18 @@
[% ELSE %] [% ELSE %]
<td nowrap> <td nowrap>
[% END %] [% END %]
<a class="nd_linkcell nd_this-port-only" href="[% uri_for('/device', <a class="nd_this-port-only nd_port-only-first" href="[% uri_for('/device',
self_options) %]&q=[% params.q | uri %]&f=[% row.port | uri %]&prefer=port"> self_options) %]&q=[% params.q | uri %]&f=[% row.port | uri %]&prefer=port">
[% row.port | html_entity %] [% IF row.is_master %]
</a></td> <small><i class="icon-group muted"></i></small>&nbsp;
[% END %]
[% row.port | html_entity %]</a>
[% IF row.slave_of %]<br/>
<a class="nd_this-port-only" href="[% uri_for('/device',
self_options) %]&q=[% params.q | uri %]&f=[% row.slave_of | uri %]&prefer=port">
[% row.slave_of | html_entity %]</a>
[% END %]
</td>
[% END %] [% END %]
[% FOREACH config IN settings._extra_device_port_cols %] [% FOREACH config IN settings._extra_device_port_cols %]
@@ -216,27 +233,36 @@
<td> <td>
[% IF params.c_neighbors AND (row.remote_ip OR row.is_uplink) %] [% IF params.c_neighbors AND (row.remote_ip OR row.is_uplink) %]
[% IF row.neighbor %] [% IF row.neighbor %]
<i class="icon-link[% ' text-warning' IF row.manual_topo %]"></i> <i class="icon-link[% ' text-warning' IF row.manual_topo %]"></i>
<a href="[% uri_for('/device',
self_options) %]&q=[% row.neighbor.dns || row.neighbor.ip | uri %]&f=[% row.remote_port | uri %]">
[% row.neighbor.dns.remove(settings.domain_suffix) || row.neighbor.ip | html_entity %]
([% row.remote_port | html_entity %]
[% ' id: '_ row.remote_id IF row.remote_id %]
[% ' type: '_ row.remote_type IF row.remote_type %])</a>
[% ELSIF row.remote_ip AND row.remote_port %]
[% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %] [% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %]
<i class="icon-phone"></i>&nbsp; <i class="icon-phone"></i>&nbsp;
[% ELSIF row.remote_type AND row.remote_type.match('(cisco\s+AIR-[L|C]?AP|-K9W8-|^AP:\s)') %] [% ELSIF row.remote_type AND row.remote_type.match('(cisco\s+AIR-[L|C]?AP|-K9W8-|^AP:\s)') %]
<i class="icon-signal"></i>&nbsp; <i class="icon-signal"></i>&nbsp;
[% ELSE %]
<i class="icon-unlink text-error"></i>&nbsp;
[% END %] [% END %]
<a href="[% search_node %]&q=[% row.remote_ip | uri %]"> <a href="[% uri_for('/device',
[% row.remote_ip | html_entity %] (port: [% row.remote_port | html_entity %] self_options) %]&q=[% row.neighbor.dns || row.neighbor.ip | uri %]&f=[% row.remote_port | uri %]">
[% ' id: '_ row.remote_id IF row.remote_id %] [% row.neighbor.dns.remove(settings.domain_suffix) || row.neighbor.ip | html_entity %]
[% ' type: '_ row.remote_type IF row.remote_type %])</a> [% ' - ' IF row.remote_port %][% row.remote_port | html_entity %]</a><br/>
[% IF params.neigh_id and (row.remote_id or row.remote_type) %]
([% 'id: '_ row.remote_id IF row.remote_id %]
[% ' type: '_ row.remote_type IF row.remote_type %])<br/>
[% END %]
[% ELSIF row.remote_ip %]
<i class="icon-unlink text-error"></i>&nbsp;
[% IF row.remote_type AND row.remote_type.match('(?i)ip.phone') %]
<i class="icon-phone"></i>&nbsp;
[% ELSIF row.remote_type AND row.remote_type.match('(cisco\s+AIR-[L|C]?AP|-K9W8-|^AP:\s)') %]
<i class="icon-signal"></i>&nbsp;
[% END %]
<a href="[% search_node %]&q=[% row.remote_ip | uri %]">
[% row.remote_ip | html_entity %]
[% ' - ' IF row.remote_port %][% row.remote_port | html_entity %]</a><br/>
[% IF params.neigh_id and (row.remote_id or row.remote_type) %]
([% 'id: '_ row.remote_id IF row.remote_id %]
[% ' type: '_ row.remote_type IF row.remote_type %])<br/>
[% END %]
[% ELSE %] [% ELSE %]
<i class="icon-unlink text-error"></i>&nbsp; (possible uplink) <i class="icon-unlink text-error"></i>&nbsp; (possible uplink)
[% END %] [% END %]
[% END %] [% END %]
[% IF params.c_nodes %] [% IF params.c_nodes %]

View File

@@ -43,6 +43,7 @@
<li><i class="icon-li icon-phone"></i>&nbsp; IP Phone</li> <li><i class="icon-li icon-phone"></i>&nbsp; IP Phone</li>
<li><i class="icon-li icon-signal"></i>&nbsp; Wireless Client</li> <li><i class="icon-li icon-signal"></i>&nbsp; Wireless Client</li>
<li><i class="icon-li icon-book"></i>&nbsp; Archived Data</li> <li><i class="icon-li icon-book"></i>&nbsp; Archived Data</li>
<li><i class="icon-li icon-group"></i>&nbsp; Link Aggregate</li>
[% IF user_has_role('port_control') %] [% IF user_has_role('port_control') %]
<li><i class="icon-li icon-refresh icon-spin"></i>&nbsp; Click "Update View"</li> <li><i class="icon-li icon-refresh icon-spin"></i>&nbsp; Click "Update View"</li>
[% END %] [% END %]
@@ -104,6 +105,13 @@
</select> </select>
</div> </div>
</li> </li>
<li>
<label class="checkbox">
<input type="checkbox" id="neigh_id"
name="neigh_id"[% ' checked="checked"' IF params.neigh_id %] />
Connected Device ID
</label>
</li>
</ul> </ul>
</div> </div>
</div> </div>