From 9f9aba68a2b86a897c39e96a0809b8e76f6dd8ee Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Wed, 6 May 2015 23:37:55 +0100 Subject: [PATCH] Support for connecting to external databases for custom Reports/Plugins --- Netdisco/Changes | 4 +++ Netdisco/MANIFEST | 2 ++ Netdisco/lib/App/Netdisco/Configuration.pm | 7 +++++ Netdisco/lib/App/Netdisco/GenericDB.pm | 10 +++++++ .../GenericDB/Result/Virtual/GenericReport.pm | 13 ++++++++++ .../lib/App/Netdisco/Manual/Configuration.pod | 21 +++++++++++++++ .../App/Netdisco/Manual/WritingPlugins.pod | 26 +++++++++++++++++++ .../lib/App/Netdisco/Web/GenericReport.pm | 6 +++-- Netdisco/share/config.yml | 1 + 9 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 Netdisco/lib/App/Netdisco/GenericDB.pm create mode 100644 Netdisco/lib/App/Netdisco/GenericDB/Result/Virtual/GenericReport.pm diff --git a/Netdisco/Changes b/Netdisco/Changes index a952169f..0c99e9ca 100644 --- a/Netdisco/Changes +++ b/Netdisco/Changes @@ -1,5 +1,9 @@ 2.032004 - + [NEW FEATURES] + + * Support for connecting to external databases for custom Reports/Plugins + [ENHANCEMENTS] * Allow "hidden" option to reports config diff --git a/Netdisco/MANIFEST b/Netdisco/MANIFEST index a4d8cf8b..aed92de5 100644 --- a/Netdisco/MANIFEST +++ b/Netdisco/MANIFEST @@ -143,6 +143,8 @@ lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-7-8-PostgreSQL.sql lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-8-9-PostgreSQL.sql lib/App/Netdisco/DB/schema_versions/App-Netdisco-DB-9-10-PostgreSQL.sql lib/App/Netdisco/Environment.pm +lib/App/Netdisco/GenericDB.pm +lib/App/Netdisco/GenericDB/Result/Virtual/GenericReport.pm lib/App/Netdisco/JobQueue.pm lib/App/Netdisco/JobQueue/PostgreSQL.pm lib/App/Netdisco/Manual/BSDInstall.pod diff --git a/Netdisco/lib/App/Netdisco/Configuration.pm b/Netdisco/lib/App/Netdisco/Configuration.pm index 4da11670..1a8f7739 100644 --- a/Netdisco/lib/App/Netdisco/Configuration.pm +++ b/Netdisco/lib/App/Netdisco/Configuration.pm @@ -33,6 +33,13 @@ if (ref {} eq ref setting('database')) { schema_class => 'App::Netdisco::DB', }; + foreach my $c (@{setting('external_databases')}) { + my $schema = delete $c->{tag} or next; + next if $schema eq 'netdisco'; + setting('plugins')->{DBIC}->{$schema} = $c; + setting('plugins')->{DBIC}->{$schema}->{schema_class} + ||= 'App::Netdisco::GenericDB'; + } } # defaults for workers diff --git a/Netdisco/lib/App/Netdisco/GenericDB.pm b/Netdisco/lib/App/Netdisco/GenericDB.pm new file mode 100644 index 00000000..f1040f98 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/GenericDB.pm @@ -0,0 +1,10 @@ +use utf8; +package App::Netdisco::GenericDB; + +use strict; +use warnings; + +use base 'DBIx::Class::Schema'; +__PACKAGE__->load_namespaces(); + +1; diff --git a/Netdisco/lib/App/Netdisco/GenericDB/Result/Virtual/GenericReport.pm b/Netdisco/lib/App/Netdisco/GenericDB/Result/Virtual/GenericReport.pm new file mode 100644 index 00000000..8a0b3846 --- /dev/null +++ b/Netdisco/lib/App/Netdisco/GenericDB/Result/Virtual/GenericReport.pm @@ -0,0 +1,13 @@ +package App::Netdisco::GenericDB::Result::Virtual::GenericReport; + +use strict; +use warnings; + +use base 'DBIx::Class::Core'; + +__PACKAGE__->table_class('DBIx::Class::ResultSource::View'); +__PACKAGE__->table("generic_report"); +__PACKAGE__->result_source_instance->is_virtual(1); +__PACKAGE__->result_source_instance->view_definition(q{}); + +1; diff --git a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod index b1662012..7fa0e337 100644 --- a/Netdisco/lib/App/Netdisco/Manual/Configuration.pod +++ b/Netdisco/lib/App/Netdisco/Manual/Configuration.pod @@ -80,6 +80,27 @@ Additional library paths for the application (both web frontend and backend poller daemons). You can also use a colon-separated list in the "C" environment variable. +=head3 C + +Value: List of Database Configuration Hashes. Default: None. + +The Plugins and User Reports features of Netdisco can gather data from +external databases. You need to install the Perl database driver for the +target database platform, and configure this setting appropriately. For +example: + + external_databases: + - tag: externaldb + dsn: 'dbi:Pg:dbname=myexternaldb;host=192.0.2.1' + user: oliver + password: letmein + options: + pg_enable_utf8: true + +Note that C is I and maps to the C key if you use the +Generic Reports feature (see "L", below), or becomes the Dancer +database schema name if you program the Plugin directly. + =head2 Web Frontend =head3 C diff --git a/Netdisco/lib/App/Netdisco/Manual/WritingPlugins.pod b/Netdisco/lib/App/Netdisco/Manual/WritingPlugins.pod index 40ba2c68..bde07ada 100644 --- a/Netdisco/lib/App/Netdisco/Manual/WritingPlugins.pod +++ b/Netdisco/lib/App/Netdisco/Manual/WritingPlugins.pod @@ -330,6 +330,32 @@ C: Take care over the subtle differences in syntax, especially the placement of the fat comma ("C<< => >>"). +=head1 Database Connections + +The Netdisco database is available via the C schema key, as below. +You can also use the C configuration item to set up +connections to other databases. + + # possibly install another database driver + ~netdisco/bin/localenv cpanm --notest DBD::mysql + + # deployment.yml + external_databases: + - tag: externaldb + dsn: 'dbi:mysql:dbname=myexternaldb;host=192.0.2.1' + user: oliver + password: letmein + + # plugin code + use Dancer::Plugin::DBIC; + + schema('netdisco')->resultset('Devices')->search({vendor => 'cisco'}); + schema('externaldb')->resultset('MyTable')->search({field => 'foobar'}); + +You'll need to install a L Schema and also set C to +its name within the C setting, for the second example +above. + =head1 Templates All of Netdisco's web page templates are stashed away in its distribution, diff --git a/Netdisco/lib/App/Netdisco/Web/GenericReport.pm b/Netdisco/lib/App/Netdisco/Web/GenericReport.pm index a6c3e959..84a2cda8 100644 --- a/Netdisco/lib/App/Netdisco/Web/GenericReport.pm +++ b/Netdisco/lib/App/Netdisco/Web/GenericReport.pm @@ -26,7 +26,9 @@ foreach my $report (@{setting('reports')}) { # TODO: this should be done by creating a new Virtual Result class on # the fly (package...) and then calling DBIC register_class on it. - my $rs = schema('netdisco')->resultset('Virtual::GenericReport')->result_source; + my $schema = ($report->{database} || 'netdisco'); + my $rs = schema($schema)->resultset('Virtual::GenericReport')->result_source; + $rs->view_definition($report->{query}); $rs->remove_columns($rs->columns); $rs->add_columns( exists $report->{query_columns} @@ -34,7 +36,7 @@ foreach my $report (@{setting('reports')}) { : (map {keys %{$_}} @{$report->{columns}}) ); - my $set = schema('netdisco')->resultset('Virtual::GenericReport') + my $set = schema($schema)->resultset('Virtual::GenericReport') ->search(undef, { result_class => 'DBIx::Class::ResultClass::HashRefInflator', ( (exists $report->{bind_params}) diff --git a/Netdisco/share/config.yml b/Netdisco/share/config.yml index 0b093cad..31f03f5c 100644 --- a/Netdisco/share/config.yml +++ b/Netdisco/share/config.yml @@ -12,6 +12,7 @@ log: 'warning' logger_format: '[%P] %U %L %m' include_paths: [] +external_databases: [] # ------------ # WEB FRONTEND