diff --git a/lib/App/Netdisco/DB.pm b/lib/App/Netdisco/DB.pm index 74074f95..e0461961 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 = 56; # schema version used for upgrades, keep as integer + $VERSION = 57; # schema version used for upgrades, keep as integer use Path::Class; use File::ShareDir 'dist_dir'; diff --git a/lib/App/Netdisco/DB/Result/DevicePortVlan.pm b/lib/App/Netdisco/DB/Result/DevicePortVlan.pm index fca103d2..acf58954 100644 --- a/lib/App/Netdisco/DB/Result/DevicePortVlan.pm +++ b/lib/App/Netdisco/DB/Result/DevicePortVlan.pm @@ -18,6 +18,8 @@ __PACKAGE__->add_columns( { data_type => "integer", is_nullable => 0 }, "native", { data_type => "boolean", default_value => \"false", is_nullable => 0 }, + "egress_tag", + { data_type => "boolean", default_value => \"true", is_nullable => 0 }, "creation", { data_type => "timestamp", diff --git a/lib/App/Netdisco/Worker/Plugin/Discover/VLANs.pm b/lib/App/Netdisco/Worker/Plugin/Discover/VLANs.pm index 70bf26d2..0ac7034e 100644 --- a/lib/App/Netdisco/Worker/Plugin/Discover/VLANs.pm +++ b/lib/App/Netdisco/Worker/Plugin/Discover/VLANs.pm @@ -18,35 +18,24 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub { my $v_name = $snmp->v_name; my $v_index = $snmp->v_index; - # build device vlans suitable for DBIC - my %v_seen = (); - my @devicevlans; - foreach my $entry (keys %$v_name) { - my $vlan = $v_index->{$entry}; - next unless defined $vlan and $vlan; - ++$v_seen{$vlan}; - - push @devicevlans, { - vlan => $vlan, - description => $v_name->{$entry}, - last_discover => \'now()', - }; - } - # cache the device ports to save hitting the database for many single rows my $device_ports = vars->{'device_ports'} || { map {($_->port => $_)} $device->ports->all }; my $i_vlan = $snmp->i_vlan; - my $i_vlan_membership = $snmp->i_vlan_membership; my $i_vlan_type = $snmp->i_vlan_type; my $interfaces = $snmp->interfaces; + my $i_vlan_membership = $snmp->i_vlan_membership; + my $i_vlan_membership_untagged = $snmp->i_vlan_membership_untagged; - # build device port vlans suitable for DBIC + my %p_seen = (); my @portvlans = (); - foreach my $entry (keys %$i_vlan_membership) { + + # build port vlans suitable for DBIC + foreach my $entry (keys %$i_vlan_membership_untagged, keys %$i_vlan_membership) { my %port_vseen = (); my $port = $interfaces->{$entry} or next; + my $type = $i_vlan_type->{$entry}; if (!defined $device_ports->{$port}) { debug sprintf ' [%s] vlans - local port %s already skipped, ignoring', @@ -54,8 +43,6 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub { next; } - my $type = $i_vlan_type->{$entry}; - foreach my $vlan (@{ $i_vlan_membership->{$entry} }) { next unless defined $vlan and $vlan; next if ++$port_vseen{$vlan} > 1; @@ -65,31 +52,30 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub { port => $port, vlan => $vlan, native => $native, + egress_tag => 't', vlantype => $type, last_discover => \'now()', }; + ++$p_seen{$vlan}; + } - next if $v_seen{$vlan}; + foreach my $vlan (@{ $i_vlan_membership_untagged->{$entry} }) { + next unless defined $vlan and $vlan; + next if ++$port_vseen{$vlan} > 1; - # also add an unnamed vlan to the device - push @devicevlans, { + my $native = ((defined $i_vlan->{$entry}) and ($vlan eq $i_vlan->{$entry})) ? "t" : "f"; + push @portvlans, { + port => $port, vlan => $vlan, - description => (sprintf "VLAN %d", $vlan), + native => $native, + egress_tag => 'f', + vlantype => $type, last_discover => \'now()', }; - ++$v_seen{$vlan}; + ++$p_seen{$vlan}; } } - schema('netdisco')->txn_do(sub { - my $gone = $device->vlans->delete; - debug sprintf ' [%s] vlans - removed %d device VLANs', - $device->ip, $gone; - $device->vlans->populate(\@devicevlans); - debug sprintf ' [%s] vlans - added %d new device VLANs', - $device->ip, scalar @devicevlans; - }); - schema('netdisco')->txn_do(sub { my $gone = $device->port_vlans->delete; debug sprintf ' [%s] vlans - removed %d port VLANs', @@ -99,6 +85,41 @@ register_worker({ phase => 'main', driver => 'snmp' }, sub { return Status->info(sprintf ' [%s] vlans - added %d new port VLANs', $device->ip, scalar @portvlans); }); + + my %d_seen = (); + my @devicevlans = (); + + # add unnamed vlans to the device + foreach my $entry (keys %$v_name) { + my $vlan = $v_index->{$entry}; + next unless defined $vlan and $vlan; + ++$d_seen{$vlan}; + + push @devicevlans, { + vlan => $vlan, + description => $v_name->{$entry}, + last_discover => \'now()', + }; + } + + # also add unnamed vlans to the device + foreach my $vlan (keys %p_seen) { + next if $d_seen{$vlan}; + push @devicevlans, { + vlan => $vlan, + description => (sprintf "VLAN %d", $vlan), + last_discover => \'now()', + }; + } + + schema('netdisco')->txn_do(sub { + my $gone = $device->vlans->delete; + debug sprintf ' [%s] vlans - removed %d device VLANs', + $device->ip, $gone; + $device->vlans->populate(\@devicevlans); + debug sprintf ' [%s] vlans - added %d new device VLANs', + $device->ip, scalar @devicevlans; + }); }); true; diff --git a/share/schema_versions/App-Netdisco-DB-56-57-PostgreSQL.sql b/share/schema_versions/App-Netdisco-DB-56-57-PostgreSQL.sql new file mode 100644 index 00000000..480c4ba2 --- /dev/null +++ b/share/schema_versions/App-Netdisco-DB-56-57-PostgreSQL.sql @@ -0,0 +1,5 @@ +BEGIN; + +ALTER TABLE device_port_vlan ADD COLUMN "egress_tag" boolean not null default false; + +COMMIT;