[#66] Fix display of vlan membership
This commit is contained in:
@@ -80,16 +80,29 @@ Returns the Device table entry to which the given Port is related.
|
|||||||
|
|
||||||
__PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device', 'ip' );
|
__PACKAGE__->belongs_to( device => 'App::Netdisco::DB::Result::Device', 'ip' );
|
||||||
|
|
||||||
=head2 vlans
|
=head2 port_vlans
|
||||||
|
|
||||||
Returns the set of C<device_port_vlan> entries associated with this Port.
|
Returns the set of C<device_port_vlan> entries associated with this Port.
|
||||||
|
These will be both tagged and untagged. Use this relation in search conditions.
|
||||||
|
|
||||||
These will be both tagged and untagged. See also C<port_vlans_tagged> and
|
See also C<all_port_vlans>.
|
||||||
C<tagged_vlans>.
|
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->has_many( vlans => 'App::Netdisco::DB::Result::DevicePortVlan',
|
__PACKAGE__->has_many( port_vlans => 'App::Netdisco::DB::Result::DevicePortVlan',
|
||||||
|
{ 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port' } );
|
||||||
|
|
||||||
|
=head2 all_port_vlans
|
||||||
|
|
||||||
|
Returns the set of C<device_port_vlan> entries associated with this Port.
|
||||||
|
These will be both tagged and untagged. Use this relation when prefetching related
|
||||||
|
C<device_port_vlan> rows.
|
||||||
|
|
||||||
|
See also C<port_vlans>.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
__PACKAGE__->has_many( all_port_vlans => 'App::Netdisco::DB::Result::DevicePortVlan',
|
||||||
{ 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port' } );
|
{ 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port' } );
|
||||||
|
|
||||||
=head2 nodes / active_nodes / nodes_with_age / active_nodes_with_age
|
=head2 nodes / active_nodes / nodes_with_age / active_nodes_with_age
|
||||||
@@ -183,39 +196,17 @@ __PACKAGE__->has_many( neighbor_alias => 'App::Netdisco::DB::Result::DeviceIp',
|
|||||||
{ join_type => 'LEFT' },
|
{ join_type => 'LEFT' },
|
||||||
);
|
);
|
||||||
|
|
||||||
=head2 port_vlans_tagged
|
=head2 vlans
|
||||||
|
|
||||||
Returns a set of rows from the C<device_port_vlan> table relating to this
|
As compared to C<port_vlans>, this relationship returns a set of VLAN
|
||||||
port, where the VLANs are all tagged.
|
|
||||||
|
|
||||||
=cut
|
|
||||||
|
|
||||||
__PACKAGE__->has_many( port_vlans_tagged => 'App::Netdisco::DB::Result::DevicePortVlan',
|
|
||||||
sub {
|
|
||||||
my $args = shift;
|
|
||||||
return {
|
|
||||||
"$args->{foreign_alias}.ip" => { -ident => "$args->{self_alias}.ip" },
|
|
||||||
"$args->{foreign_alias}.port" => { -ident => "$args->{self_alias}.port" },
|
|
||||||
-not_bool => "$args->{foreign_alias}.native",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
{
|
|
||||||
join_type => 'LEFT',
|
|
||||||
cascade_copy => 0, cascade_update => 0, cascade_delete => 0,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
=head2 tagged_vlans
|
|
||||||
|
|
||||||
As compared to C<port_vlans_tagged>, this relationship returns a set of VLAN
|
|
||||||
row objects for the VLANs on the given port, which might be more useful if you
|
row objects for the VLANs on the given port, which might be more useful if you
|
||||||
want to find out details such as the VLAN name.
|
want to find out details such as the VLAN name.
|
||||||
|
|
||||||
See also C<tagged_vlans_count>.
|
See also C<vlan_count>.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
__PACKAGE__->many_to_many( tagged_vlans => 'port_vlans_tagged', 'vlan' );
|
__PACKAGE__->many_to_many( vlans => 'all_port_vlans', 'vlan' );
|
||||||
|
|
||||||
|
|
||||||
=head2 oui
|
=head2 oui
|
||||||
@@ -259,26 +250,26 @@ sub neighbor {
|
|||||||
|
|
||||||
=head2 native
|
=head2 native
|
||||||
|
|
||||||
An alias for the C<pvid> column, which stores the PVID (that is, the VLAN
|
An alias for the C<vlan> column, which stores the PVID (that is, the VLAN
|
||||||
ID assigned to untagged frames received on the port).
|
ID assigned to untagged frames received on the port).
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
sub native { return (shift)->pvid }
|
sub native { return (shift)->vlan }
|
||||||
|
|
||||||
=head2 tagged_vlans_count
|
=head2 vlan_count
|
||||||
|
|
||||||
Returns the number of tagged VLANs active on this device port. Enable this
|
Returns the number of VLANs active on this device port. Enable this column by
|
||||||
column by applying the C<with_vlan_count()> modifier to C<search()>.
|
applying the C<with_vlan_count()> modifier to C<search()>.
|
||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
sub tagged_vlans_count { return (shift)->get_column('tagged_vlans_count') }
|
sub vlan_count { return (shift)->get_column('vlan_count') }
|
||||||
|
|
||||||
=head2 lastchange_stamp
|
=head2 lastchange_stamp
|
||||||
|
|
||||||
Formatted version of the C<lastchange> field, accurate to the minute. Enable
|
Formatted version of the C<lastchange> field, accurate to the minute. Enable
|
||||||
this column by applying the C<with_vlan_count()> modifier to C<search()>.
|
this column by applying the C<with_times()> modifier to C<search()>.
|
||||||
|
|
||||||
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
The format is somewhat like ISO 8601 or RFC3339 but without the middle C<T>
|
||||||
between the date stamp and time stamp. That is:
|
between the date stamp and time stamp. That is:
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ will add the following additional synthesized columns to the result set:
|
|||||||
|
|
||||||
=over 4
|
=over 4
|
||||||
|
|
||||||
=item tagged_vlans_count
|
=item vlan_count
|
||||||
|
|
||||||
=back
|
=back
|
||||||
|
|
||||||
@@ -124,15 +124,14 @@ sub with_vlan_count {
|
|||||||
->search_rs($cond, $attrs)
|
->search_rs($cond, $attrs)
|
||||||
->search({},
|
->search({},
|
||||||
{
|
{
|
||||||
'+columns' => { tagged_vlans_count =>
|
'+columns' => { vlan_count =>
|
||||||
$rs->result_source->schema->resultset('DevicePortVlan')
|
$rs->result_source->schema->resultset('DevicePortVlan')
|
||||||
->search(
|
->search(
|
||||||
{
|
{
|
||||||
'dpvt.ip' => { -ident => 'me.ip' },
|
'dpv.ip' => { -ident => 'me.ip' },
|
||||||
'dpvt.port' => { -ident => 'me.port' },
|
'dpv.port' => { -ident => 'me.port' },
|
||||||
-not_bool => { -ident => 'dpvt.native' },
|
|
||||||
},
|
},
|
||||||
{ alias => 'dpvt' }
|
{ alias => 'dpv' }
|
||||||
)->count_rs->as_query
|
)->count_rs->as_query
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ hook 'before' => sub {
|
|||||||
{ name => 'c_speed', label => 'Speed', default => '' },
|
{ name => 'c_speed', label => 'Speed', default => '' },
|
||||||
{ name => 'c_mac', label => 'Port MAC', default => '' },
|
{ name => 'c_mac', label => 'Port MAC', default => '' },
|
||||||
{ name => 'c_mtu', label => 'MTU', default => '' },
|
{ name => 'c_mtu', label => 'MTU', default => '' },
|
||||||
{ name => 'c_vlan', label => 'Native VLAN', default => 'on' },
|
{ name => 'c_pvid', label => 'Native VLAN', default => 'on' },
|
||||||
{ name => 'c_vmember', label => 'Tagged VLANs', default => 'on' },
|
{ name => 'c_vmember', label => 'VLAN Membership', default => 'on' },
|
||||||
{ name => 'c_power', label => 'PoE', default => '' },
|
{ name => 'c_power', label => 'PoE', default => '' },
|
||||||
{ name => 'c_nodes', label => 'Connected Nodes', default => '' },
|
{ name => 'c_nodes', label => 'Connected Nodes', default => '' },
|
||||||
{ name => 'c_neighbors', label => 'Connected Devices', default => 'on' },
|
{ name => 'c_neighbors', label => 'Connected Devices', default => 'on' },
|
||||||
|
|||||||
@@ -27,18 +27,18 @@ get '/ajax/content/device/ports' => require_login sub {
|
|||||||
if (param('invert')) {
|
if (param('invert')) {
|
||||||
$set = $set->search({
|
$set = $set->search({
|
||||||
'me.vlan' => { '!=' => $f },
|
'me.vlan' => { '!=' => $f },
|
||||||
'port_vlans_tagged.vlan' => [
|
'port_vlans.vlan' => [
|
||||||
'-or' => { '!=' => $f }, { '=' => undef }
|
'-or' => { '!=' => $f }, { '=' => undef }
|
||||||
],
|
],
|
||||||
}, { join => 'port_vlans_tagged' });
|
}, { join => 'port_vlans' });
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
$set = $set->search({
|
$set = $set->search({
|
||||||
-or => {
|
-or => {
|
||||||
'me.vlan' => $f,
|
'me.vlan' => $f,
|
||||||
'port_vlans_tagged.vlan' => $f,
|
'port_vlans.vlan' => $f,
|
||||||
},
|
},
|
||||||
}, { join => 'port_vlans_tagged' });
|
}, { join => 'port_vlans' });
|
||||||
}
|
}
|
||||||
|
|
||||||
return unless $set->count;
|
return unless $set->count;
|
||||||
@@ -116,7 +116,7 @@ get '/ajax/content/device/ports' => require_login sub {
|
|||||||
|
|
||||||
# run single collapsed query for all relations, but only if we're not
|
# run single collapsed query for all relations, but only if we're not
|
||||||
# also fetching archived data (tests show it's better this way)
|
# also fetching archived data (tests show it's better this way)
|
||||||
$set = $set->search_rs({}, { prefetch => [{ port_vlans_tagged => 'vlan'}] })
|
$set = $set->search_rs({}, { prefetch => 'all_port_vlans' })
|
||||||
if param('c_vmember') and not (param('c_nodes') and param('n_archived'));
|
if param('c_vmember') and not (param('c_nodes') and param('n_archived'));
|
||||||
|
|
||||||
# what kind of nodes are we interested in?
|
# what kind of nodes are we interested in?
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ ajax '/ajax/portcontrol' => require_role port_control => sub {
|
|||||||
'contact' => 'contact',
|
'contact' => 'contact',
|
||||||
'c_port' => 'portcontrol',
|
'c_port' => 'portcontrol',
|
||||||
'c_name' => 'portname',
|
'c_name' => 'portname',
|
||||||
'c_vlan' => 'vlan',
|
'c_pvid' => 'vlan',
|
||||||
'c_power' => 'power',
|
'c_power' => 'power',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -146,7 +146,7 @@ $(document).ready(function() {
|
|||||||
else if (nl) {
|
else if (nl) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
if (td.data('field') == 'c_vlan') {
|
if (td.data('field') == 'c_pvid') {
|
||||||
$('#nd_portlog').one('hidden', function() {
|
$('#nd_portlog').one('hidden', function() {
|
||||||
port_control(cell); // save
|
port_control(cell); // save
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -129,10 +129,10 @@
|
|||||||
<td>[% row.mtu | html_entity %]</td>
|
<td>[% row.mtu | html_entity %]</td>
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[% IF params.c_vlan %]
|
[% IF params.c_pvid %]
|
||||||
[% IF user_can_port_control AND params.c_admin %]
|
[% IF user_can_port_control AND params.c_admin %]
|
||||||
<td class="nd_editable-cell" contenteditable="true" data-default="[% row.vlan | html_entity %]"
|
<td class="nd_editable-cell" contenteditable="true" data-default="[% row.vlan | html_entity %]"
|
||||||
data-field="c_vlan" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
|
data-field="c_pvid" data-for-device="[% device.ip | html_entity %]" data-for-port="[% row.port | html_entity %]">
|
||||||
<i class="icon-edit nd_edit-icon"></i>
|
<i class="icon-edit nd_edit-icon"></i>
|
||||||
<div class="nd_editable-cell-content">
|
<div class="nd_editable-cell-content">
|
||||||
[% IF row.vlan %][% row.vlan | html_entity %][% END %]
|
[% IF row.vlan %][% row.vlan | html_entity %][% END %]
|
||||||
@@ -149,17 +149,17 @@
|
|||||||
|
|
||||||
[% IF params.c_vmember %]
|
[% IF params.c_vmember %]
|
||||||
<td>
|
<td>
|
||||||
[% IF row.tagged_vlans_count %]
|
[% IF row.vlan_count %]
|
||||||
[% SET output = '' %]
|
[% SET output = '' %]
|
||||||
[% SET vlanlist = [] %]
|
[% SET vlanlist = [] %]
|
||||||
[% FOREACH vlan IN row.tagged_vlans %][% vlanlist.push(vlan.vlan) %][% END %]
|
[% FOREACH vlan IN row.all_port_vlans %][% vlanlist.push(vlan.get_column('vlan')) %][% END %]
|
||||||
[% FOREACH vlan IN vlanlist.nsort %]
|
[% FOREACH vlan IN vlanlist.nsort %]
|
||||||
[% SET output = output _
|
[% SET output = output _
|
||||||
'<a href="' _ uri_for('/search') _ '?tab=vlan&q=' _ vlan _ '">' _ vlan _ '</a>' %]
|
'<a href="' _ uri_for('/search') _ '?tab=vlan&q=' _ vlan _ '">' _ vlan _ '</a>' %]
|
||||||
[% SET output = output _ ', ' IF NOT loop.last %]
|
[% SET output = output _ ', ' IF NOT loop.last %]
|
||||||
[% END %]
|
[% END %]
|
||||||
[% IF row.tagged_vlans_count > 10 %] [%# TODO make this a settable variable %]
|
[% IF row.vlan_count > 10 %] [%# TODO make this a settable variable %]
|
||||||
[% SET output = '<div class="nd_vlan-total">(' _ row.tagged_vlans_count
|
[% SET output = '<div class="nd_vlan-total">(' _ row.vlan_count
|
||||||
_ ')</div><span class="nd_linkcell nd_collapse-vlans">
|
_ ')</div><span class="nd_linkcell nd_collapse-vlans">
|
||||||
<div class="nd_arrow-up-down-left icon-chevron-up icon-large"></div>Show VLANs</span>
|
<div class="nd_arrow-up-down-left icon-chevron-up icon-large"></div>Show VLANs</span>
|
||||||
<div class="nd_collapsing nd_collapse-pre-hidden">' _ output %]
|
<div class="nd_collapsing nd_collapse-pre-hidden">' _ output %]
|
||||||
|
|||||||
@@ -95,15 +95,15 @@
|
|||||||
[% myport.push(row.mtu) %]
|
[% myport.push(row.mtu) %]
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[% IF params.c_vlan %]
|
[% IF params.c_pvid %]
|
||||||
[% myport.push(row.vlan) %]
|
[% myport.push(row.vlan) %]
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|
||||||
[% IF params.c_vmember %]
|
[% IF params.c_vmember %]
|
||||||
[% IF row.tagged_vlans_count %]
|
[% IF row.vlan_count %]
|
||||||
[% SET output = '' %]
|
[% SET output = '' %]
|
||||||
[% SET vlanlist = [] %]
|
[% SET vlanlist = [] %]
|
||||||
[% FOREACH vlan IN row.tagged_vlans %][% vlanlist.push(vlan.vlan) %][% END %]
|
[% FOREACH vlan IN row.all_port_vlans %][% vlanlist.push(vlan.get_column('vlan')) %][% END %]
|
||||||
[% FOREACH vlan IN vlanlist.nsort %]
|
[% FOREACH vlan IN vlanlist.nsort %]
|
||||||
[% SET output = output _ ',' IF NOT loop.first %]
|
[% SET output = output _ ',' IF NOT loop.first %]
|
||||||
[% SET output = output _ vlan %]
|
[% SET output = output _ vlan %]
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
[% ' (' _ row.device.dns _ ')' IF row.device.dns %]
|
[% ' (' _ row.device.dns _ ')' IF row.device.dns %]
|
||||||
</td>
|
</td>
|
||||||
<td>[% row.descr | html_entity %]</td>
|
<td>[% row.descr | html_entity %]</td>
|
||||||
<td>[% row.vlan | html_entity %]</td>
|
<td>[% row.vlan | html_entity %]</td>
|
||||||
</tr>
|
</tr>
|
||||||
[% END %]
|
[% END %]
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -9,4 +9,4 @@
|
|||||||
[% END %]
|
[% END %]
|
||||||
[% CSV.dump(mylist) %]
|
[% CSV.dump(mylist) %]
|
||||||
|
|
||||||
[% END %]
|
[% END %]
|
||||||
|
|||||||
Reference in New Issue
Block a user