From 7191a1cd00b471116c3c179a2cf64f23ede8d27a Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Tue, 20 Feb 2018 22:45:53 +0000 Subject: [PATCH] implement port properties table and error disable gathering to it --- lib/App/Netdisco/DB.pm | 2 +- lib/App/Netdisco/DB/Result/Device.pm | 11 +++++ lib/App/Netdisco/DB/Result/DevicePort.pm | 11 +++++ .../DB/Result/DevicePortProperties.pm | 32 +++++++++++++ .../Worker/Plugin/Discover/PortProperties.pm | 48 +++++++++++++++++++ share/config.yml | 1 + .../App-Netdisco-DB-46-47-PostgreSQL.sql | 10 ++++ 7 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 lib/App/Netdisco/DB/Result/DevicePortProperties.pm create mode 100644 lib/App/Netdisco/Worker/Plugin/Discover/PortProperties.pm create mode 100644 share/schema_versions/App-Netdisco-DB-46-47-PostgreSQL.sql diff --git a/lib/App/Netdisco/DB.pm b/lib/App/Netdisco/DB.pm index abb2af1a..4a7b959d 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 = 46; # schema version used for upgrades, keep as integer + $VERSION = 47; # schema version used for upgrades, keep as integer use Path::Class; use File::ShareDir 'dist_dir'; diff --git a/lib/App/Netdisco/DB/Result/Device.pm b/lib/App/Netdisco/DB/Result/Device.pm index 7a6e37e0..4545817e 100644 --- a/lib/App/Netdisco/DB/Result/Device.pm +++ b/lib/App/Netdisco/DB/Result/Device.pm @@ -171,6 +171,17 @@ __PACKAGE__->has_many( 'ip', { join_type => 'RIGHT' } ); +=head2 properties_ports + +Returns the set of ports known to have recorded properties + +=cut + +__PACKAGE__->has_many( + properties_ports => 'App::Netdisco::DB::Result::DevicePortProperties', + 'ip', { join_type => 'RIGHT' } +); + =head2 powered_ports Returns the set of ports known to have PoE capability diff --git a/lib/App/Netdisco/DB/Result/DevicePort.pm b/lib/App/Netdisco/DB/Result/DevicePort.pm index 398ebe08..034754fa 100644 --- a/lib/App/Netdisco/DB/Result/DevicePort.pm +++ b/lib/App/Netdisco/DB/Result/DevicePort.pm @@ -166,6 +166,17 @@ __PACKAGE__->might_have( power => 'App::Netdisco::DB::Result::DevicePortPower', 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port', }); +=head2 properties + +Returns a row from the C table if one refers to this +device port. + +=cut + +__PACKAGE__->might_have( properties => 'App::Netdisco::DB::Result::DevicePortProperties', { + 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port', +}); + =head2 ssid Returns a row from the C table if one refers to this diff --git a/lib/App/Netdisco/DB/Result/DevicePortProperties.pm b/lib/App/Netdisco/DB/Result/DevicePortProperties.pm new file mode 100644 index 00000000..7ebb64c5 --- /dev/null +++ b/lib/App/Netdisco/DB/Result/DevicePortProperties.pm @@ -0,0 +1,32 @@ +use utf8; +package App::Netdisco::DB::Result::DevicePortProperties; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; +__PACKAGE__->table("device_port_properties"); +__PACKAGE__->add_columns( + "ip", + { data_type => "inet", is_nullable => 0 }, + "port", + { data_type => "text", is_nullable => 0 }, + "error_disable_cause", + { data_type => "text", is_nullable => 1 }, +); +__PACKAGE__->set_primary_key("port", "ip"); + + +=head1 RELATIONSHIPS + +=head2 port + +Returns the entry from the C table for which this Power entry applies. + +=cut + +__PACKAGE__->belongs_to( port => 'App::Netdisco::DB::Result::DevicePort', { + 'foreign.ip' => 'self.ip', 'foreign.port' => 'self.port', +}); + +1; diff --git a/lib/App/Netdisco/Worker/Plugin/Discover/PortProperties.pm b/lib/App/Netdisco/Worker/Plugin/Discover/PortProperties.pm new file mode 100644 index 00000000..e837b452 --- /dev/null +++ b/lib/App/Netdisco/Worker/Plugin/Discover/PortProperties.pm @@ -0,0 +1,48 @@ +package App::Netdisco::Worker::Plugin::Discover::PortProperties; + +use Dancer ':syntax'; +use App::Netdisco::Worker::Plugin; +use aliased 'App::Netdisco::Worker::Status'; + +use App::Netdisco::Transport::SNMP (); +use Dancer::Plugin::DBIC 'schema'; + +register_worker({ phase => 'main', driver => 'snmp' }, sub { + my ($job, $workerconf) = @_; + + my $device = $job->device; + return unless $device->in_storage; + my $snmp = App::Netdisco::Transport::SNMP->reader_for($device) + or return Status->defer("discover failed: could not SNMP connect to $device"); + + my $interfaces = $snmp->interfaces; + my $err_cause = $snmp->i_err_disable_cause; + + if (!defined $err_cause or !defined $interfaces) { + return Status->info(sprintf ' [%s] props - 0 errored ports', $device->ip); + } + + # build device port properties info suitable for DBIC + my @portproperties; + foreach my $entry (keys %$err_cause) { + my $port = $interfaces->{$entry}; + next unless $port; + + push @portproperties, { + port => $port, + error_disable_cause => $err_cause->{$entry}, + }; + } + + schema('netdisco')->txn_do(sub { + my $gone = $device->properties_ports->delete; + debug sprintf ' [%s] props - removed %d ports with properties', + $device->ip, $gone; + $device->properties_ports->populate(\@portproperties); + + return Status->info(sprintf ' [%s] props - added %d new port properties', + $device->ip, scalar @portproperties); + }); +}); + +true; diff --git a/share/config.yml b/share/config.yml index 8d6c2123..aaf6b982 100644 --- a/share/config.yml +++ b/share/config.yml @@ -341,6 +341,7 @@ worker_plugins: - 'Discover::Neighbors' - 'Discover::Neighbors::Routed' - 'Discover::PortPower' + - 'Discover::PortProperties' - 'Discover::Properties' - 'Discover::VLANs' - 'Discover::Wireless' diff --git a/share/schema_versions/App-Netdisco-DB-46-47-PostgreSQL.sql b/share/schema_versions/App-Netdisco-DB-46-47-PostgreSQL.sql new file mode 100644 index 00000000..04830128 --- /dev/null +++ b/share/schema_versions/App-Netdisco-DB-46-47-PostgreSQL.sql @@ -0,0 +1,10 @@ +BEGIN; + +CREATE TABLE device_port_properties ( + "ip" "inet", + "port" "text", + "error_disable_cause" "text", + PRIMARY KEY ("port", "ip") +); + +COMMIT;