Add worker to collect various PortAccessEntity (NAC) attributes (PR #937, partially implements #887)
* Add macsuck worker to collect various PortAccessEntity (NAC) attributes * Incorporate PAE feedback on #937 * missing Result/Device.pm column added * pae_is... columns instead of pae_capabilities * moved most code to Util/PortAccessEntity.pm so the update can be done in discover and macsuck * Refactor PAE attributes during discover as separate Plugin * PortAccessEntity: don't use device->dns in log string * Fix "Experimental keys on scalar is now forbidden" test failure * Revamp pae_control and add missing attribute - device.pae_control (text) is now device.pae_is_enabled (bool) - also store pae_authconfig_port_control (port mode auto/force(un)Auth) * Fix "Experimental keys on scalar is now forbidden" test failure - ... again because of botched merge - at least perlgolfed away a set of curly braces * Update PortAccessEntity.pm * Incorporate @ollyg PR feedback Co-authored-by: Christian Ramseyer <ramseyer@netnea.com>
This commit is contained in:
@@ -83,6 +83,8 @@ __PACKAGE__->add_columns(
|
|||||||
{ data_type => "timestamp", is_nullable => 1 },
|
{ data_type => "timestamp", is_nullable => 1 },
|
||||||
"is_pseudo",
|
"is_pseudo",
|
||||||
{ data_type => "boolean", is_nullable => 0, default_value => \"false" },
|
{ data_type => "boolean", is_nullable => 0, default_value => \"false" },
|
||||||
|
"pae_is_enabled",
|
||||||
|
{ data_type => "boolean", is_nullable => 1 },
|
||||||
);
|
);
|
||||||
__PACKAGE__->set_primary_key("ip");
|
__PACKAGE__->set_primary_key("ip");
|
||||||
|
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ __PACKAGE__->add_columns(
|
|||||||
{ data_type => "text", is_nullable => 1 },
|
{ data_type => "text", is_nullable => 1 },
|
||||||
"remote_os_ver",
|
"remote_os_ver",
|
||||||
{ data_type => "text", is_nullable => 1 },
|
{ data_type => "text", is_nullable => 1 },
|
||||||
"remote_serial",
|
"remote_serial",
|
||||||
{ data_type => "text", is_nullable => 1 },
|
{ data_type => "text", is_nullable => 1 },
|
||||||
"remote_dns",
|
"remote_dns",
|
||||||
{ data_type => "text", is_nullable => 1 },
|
{ data_type => "text", is_nullable => 1 },
|
||||||
@@ -35,6 +35,23 @@ __PACKAGE__->add_columns(
|
|||||||
{ data_type => "boolean", default_value => \"false", is_nullable => 1 },
|
{ data_type => "boolean", default_value => \"false", is_nullable => 1 },
|
||||||
"ifindex",
|
"ifindex",
|
||||||
{ data_type => "bigint", is_nullable => 1 },
|
{ data_type => "bigint", is_nullable => 1 },
|
||||||
|
"pae_authconfig_state",
|
||||||
|
{ data_type => "text", is_nullable => 1 },
|
||||||
|
"pae_authconfig_port_control",
|
||||||
|
{ data_type => "text", is_nullable => 1 },
|
||||||
|
"pae_authconfig_port_status",
|
||||||
|
{ data_type => "text", is_nullable => 1 },
|
||||||
|
"pae_authsess_user",
|
||||||
|
{ data_type => "text", is_nullable => 1 },
|
||||||
|
"pae_authsess_mab",
|
||||||
|
{ data_type => "text", is_nullable => 1 },
|
||||||
|
"pae_last_eapol_frame_source",
|
||||||
|
{ data_type => "text", is_nullable => 1 },
|
||||||
|
"pae_is_authenticator",
|
||||||
|
{ data_type => "boolean", default_value => \"false", is_nullable => 1 },
|
||||||
|
"pae_is_supplicant",
|
||||||
|
{ data_type => "boolean", default_value => \"false", is_nullable => 1 },
|
||||||
|
|
||||||
);
|
);
|
||||||
__PACKAGE__->set_primary_key("port", "ip");
|
__PACKAGE__->set_primary_key("port", "ip");
|
||||||
|
|
||||||
|
|||||||
85
lib/App/Netdisco/Util/PortAccessEntity.pm
Normal file
85
lib/App/Netdisco/Util/PortAccessEntity.pm
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
package App::Netdisco::Util::PortAccessEntity;
|
||||||
|
|
||||||
|
use Dancer qw/:syntax/;
|
||||||
|
use Dancer::Plugin::DBIC 'schema';
|
||||||
|
use aliased 'App::Netdisco::Worker::Status';
|
||||||
|
|
||||||
|
|
||||||
|
use base 'Exporter';
|
||||||
|
our @EXPORT = ();
|
||||||
|
our @EXPORT_OK = qw/update_pae_attributes/;
|
||||||
|
our %EXPORT_TAGS = (all => \@EXPORT_OK);
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
App::Netdisco::Util::PortAccessEntity
|
||||||
|
|
||||||
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
|
Helper subroutines to update PAE details in device_port_properties
|
||||||
|
These are updated both during discover and macsuck.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
sub update_pae_attributes {
|
||||||
|
my ($device) = @_;
|
||||||
|
no warnings "uninitialized";
|
||||||
|
|
||||||
|
my $snmp = App::Netdisco::Transport::SNMP->reader_for($device)
|
||||||
|
or return Status->defer("pae failed: could not SNMP connect to $device");
|
||||||
|
debug sprintf ' [%s] pae - updating PortAccessEntity details', $device->ip;
|
||||||
|
|
||||||
|
# device property
|
||||||
|
my $pae_control = $snmp->pae_control();
|
||||||
|
|
||||||
|
if ($pae_control and $pae_control eq 'enabled') {
|
||||||
|
debug sprintf ' [%s] pae - PortAccessEntity device-wide support: %s', $device->ip, $pae_control;
|
||||||
|
schema('netdisco')->resultset('Device')->search({ 'me.ip' => $device->ip})
|
||||||
|
->update({ pae_is_enabled => 't' });
|
||||||
|
} else {
|
||||||
|
debug sprintf ' [%s] pae - no PortAccessEntity support, leaving worker', $device->ip;
|
||||||
|
schema('netdisco')->resultset('Device')->search({ 'me.ip' => $device->ip})
|
||||||
|
->update({ pae_is_enabled => 'f' });
|
||||||
|
return Status->info("Skipped pae for $device");
|
||||||
|
}
|
||||||
|
|
||||||
|
# individual port properties
|
||||||
|
my $interfaces = $snmp->interfaces;
|
||||||
|
my $pae_authconfig_state = $snmp->pae_authconfig_state();
|
||||||
|
my $pae_authconfig_port_control = $snmp->dot1xAuthAuthControlledPortControl();
|
||||||
|
my $pae_authconfig_port_status = $snmp->pae_authconfig_port_status();
|
||||||
|
my $pae_authsess_user = $snmp->pae_authsess_user();
|
||||||
|
my $pae_authsess_mab = $snmp->pae_authsess_mab();
|
||||||
|
my $pae_capabilities = $snmp->pae_i_capabilities();
|
||||||
|
my $pae_last_eapol_frame_source = $snmp->pae_i_last_eapol_frame_source();
|
||||||
|
|
||||||
|
foreach my $ind (sort keys %$interfaces){
|
||||||
|
debug sprintf ' [%s] pae - attributes found for ifindex %s: %s %s %s %s %s %s %s',
|
||||||
|
$device->ip, $ind,
|
||||||
|
$pae_authconfig_state->{$ind} || 'no pae_authconfig_state',
|
||||||
|
$pae_authconfig_port_control->{$ind},
|
||||||
|
$pae_authconfig_port_status->{$ind},
|
||||||
|
$pae_authsess_user->{$ind},
|
||||||
|
$pae_authsess_mab->{$ind},
|
||||||
|
$pae_capabilities->{$ind},
|
||||||
|
$pae_last_eapol_frame_source->{$ind};
|
||||||
|
|
||||||
|
schema('netdisco')->resultset('DevicePortProperties')
|
||||||
|
->search({ 'me.ip' => $device->ip, 'me.port' => $interfaces->{$ind} })
|
||||||
|
->update({
|
||||||
|
pae_authconfig_state => $pae_authconfig_state->{$ind} ,
|
||||||
|
pae_authconfig_port_control => $pae_authconfig_port_control->{$ind} ,
|
||||||
|
pae_authconfig_port_status => $pae_authconfig_port_status->{$ind} ,
|
||||||
|
pae_authsess_user => $pae_authsess_user->{$ind} ,
|
||||||
|
pae_authsess_mab => $pae_authsess_mab->{$ind} ,
|
||||||
|
pae_is_authenticator => $pae_capabilities->{$ind} =~ m/dot1xPaePortAuthCapable/ ? "t" : "f",
|
||||||
|
pae_is_supplicant => $pae_capabilities->{$ind} =~ m/dot1xPaePortSuppCapable/ ? "t" : "f",
|
||||||
|
pae_last_eapol_frame_source => $pae_last_eapol_frame_source->{$ind} ,
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status->info("Completed pae for $device");
|
||||||
|
}
|
||||||
|
|
||||||
|
1;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package App::Netdisco::Worker::Plugin::Discover::PortProperties::PortAccessEntity;
|
||||||
|
|
||||||
|
use Dancer ':syntax';
|
||||||
|
use App::Netdisco::Worker::Plugin;
|
||||||
|
use aliased 'App::Netdisco::Worker::Status';
|
||||||
|
use Dancer::Plugin::DBIC 'schema';
|
||||||
|
use App::Netdisco::Util::Worker;
|
||||||
|
use App::Netdisco::Util::PortAccessEntity qw/update_pae_attributes/;
|
||||||
|
|
||||||
|
register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
||||||
|
|
||||||
|
my ($job, $workerconf) = @_;
|
||||||
|
my $device = $job->device;
|
||||||
|
return update_pae_attributes($device)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
true;
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package App::Netdisco::Worker::Plugin::Macsuck::Nodes::PortAccessEntity;
|
||||||
|
|
||||||
|
use Dancer ':syntax';
|
||||||
|
use App::Netdisco::Worker::Plugin;
|
||||||
|
use aliased 'App::Netdisco::Worker::Status';
|
||||||
|
use Dancer::Plugin::DBIC 'schema';
|
||||||
|
use App::Netdisco::Util::Worker;
|
||||||
|
use App::Netdisco::Util::PortAccessEntity qw/update_pae_attributes/;
|
||||||
|
|
||||||
|
register_worker({ phase => 'main', driver => 'snmp' }, sub {
|
||||||
|
|
||||||
|
my ($job, $workerconf) = @_;
|
||||||
|
my $device = $job->device;
|
||||||
|
return update_pae_attributes($device)
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
true;
|
||||||
@@ -443,6 +443,7 @@ worker_plugins:
|
|||||||
- 'Discover::Neighbors::Routed'
|
- 'Discover::Neighbors::Routed'
|
||||||
- 'Discover::PortPower'
|
- 'Discover::PortPower'
|
||||||
- 'Discover::PortProperties'
|
- 'Discover::PortProperties'
|
||||||
|
- 'Discover::PortProperties::PortAccessEntity'
|
||||||
- 'Discover::Properties'
|
- 'Discover::Properties'
|
||||||
- 'Discover::VLANs'
|
- 'Discover::VLANs'
|
||||||
- 'Discover::Wireless'
|
- 'Discover::Wireless'
|
||||||
@@ -462,6 +463,7 @@ worker_plugins:
|
|||||||
- 'Macsuck::Hooks'
|
- 'Macsuck::Hooks'
|
||||||
- 'Macsuck::Nodes'
|
- 'Macsuck::Nodes'
|
||||||
- 'Macsuck::WirelessNodes'
|
- 'Macsuck::WirelessNodes'
|
||||||
|
- 'Macsuck::Nodes::PortAccessEntity'
|
||||||
- 'Macwalk'
|
- 'Macwalk'
|
||||||
- 'MakeRancidConf'
|
- 'MakeRancidConf'
|
||||||
- 'Nbtstat'
|
- 'Nbtstat'
|
||||||
|
|||||||
14
share/schema_versions/App-Netdisco-DB-75-76-PostgreSQL.sql
Normal file
14
share/schema_versions/App-Netdisco-DB-75-76-PostgreSQL.sql
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
BEGIN;
|
||||||
|
|
||||||
|
ALTER TABLE device ADD COLUMN "pae_is_enabled" boolean;
|
||||||
|
|
||||||
|
ALTER TABLE device_port_properties ADD COLUMN "pae_authconfig_state" text;
|
||||||
|
ALTER TABLE device_port_properties ADD COLUMN "pae_authconfig_port_control" text;
|
||||||
|
ALTER TABLE device_port_properties ADD COLUMN "pae_authconfig_port_status" text;
|
||||||
|
ALTER TABLE device_port_properties ADD COLUMN "pae_authsess_user" text;
|
||||||
|
ALTER TABLE device_port_properties ADD COLUMN "pae_authsess_mab" text;
|
||||||
|
ALTER TABLE device_port_properties ADD COLUMN "pae_last_eapol_frame_source" text;
|
||||||
|
ALTER TABLE device_port_properties ADD COLUMN "pae_is_authenticator" boolean;
|
||||||
|
ALTER TABLE device_port_properties ADD COLUMN "pae_is_supplicant" boolean;
|
||||||
|
|
||||||
|
COMMIT;
|
||||||
Reference in New Issue
Block a user