* initial v0 creator * working json api for generic reports * add require login * move report swagger into plugin, and set new default layout of noop * require proper role and also use new util func * start to tidy authn * some work on cleaning up web authn * clean up the authN checks * fix bug * fix the auth for api * fixes to json handling * set swagger sort order * enable most reports for api endpoints * fix doc * add paramters to reports * add missed report * allow api_parameters in reports config * reorganise api * add vlan search * add port search * make sure to enable layout processing * add device search * add v1 to api paths * add Node Search * support api_responses * add device object search; fix spurious ports field in device result class * handle some plugins just returning undef if search fails * errors from api seamlessley * fix error in date range default * more sensible default for prefix * change order of endpoints in swagger-ui * all db row classes can now TO_JSON * add device_port api endpoint * add device ports endpoint * do not expand docs * add swagger ui json tree formatter * add all relations from Device table * add port relations * add nodes retrieve on device or vlan * rename to GetAPIKey * update config for previous commit
95 lines
3.1 KiB
Perl
95 lines
3.1 KiB
Perl
package App::Netdisco::Web::GenericReport;
|
|
|
|
use Dancer ':syntax';
|
|
use Dancer::Plugin::Ajax;
|
|
use Dancer::Plugin::DBIC;
|
|
use Dancer::Plugin::Auth::Extensible;
|
|
|
|
use App::Netdisco::Web::Plugin;
|
|
use Path::Class 'file';
|
|
use Storable 'dclone';
|
|
use Safe;
|
|
|
|
our ($config, @data);
|
|
|
|
foreach my $report (@{setting('reports')}) {
|
|
my $r = $report->{tag};
|
|
|
|
register_report({
|
|
tag => $r,
|
|
label => $report->{label},
|
|
category => ($report->{category} || 'My Reports'),
|
|
($report->{hidden} ? (hidden => true) : ()),
|
|
provides_csv => true,
|
|
api_endpoint => true,
|
|
bind_params => $report->{bind_params},
|
|
api_parameters => $report->{api_parameters},
|
|
});
|
|
|
|
get "/ajax/content/report/$r" => require_login sub {
|
|
# 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 $schema = ($report->{database} || 'netdisco');
|
|
my $rs = schema($schema)->resultset('Virtual::GenericReport')->result_source;
|
|
(my $query = $report->{query}) =~ s/;$//;
|
|
|
|
# unpick the rather hairy config of 'columns' to get field,
|
|
# displayname, and "_"-prefixed options
|
|
my %column_config = ();
|
|
my @column_order = ();
|
|
foreach my $col (@{ $report->{columns} }) {
|
|
foreach my $k (keys %$col) {
|
|
if ($k !~ m/^_/) {
|
|
push @column_order, $k;
|
|
$column_config{$k} = dclone($col || {});
|
|
$column_config{$k}->{displayname} = delete $column_config{$k}->{$k};
|
|
}
|
|
}
|
|
}
|
|
|
|
$rs->view_definition($query);
|
|
$rs->remove_columns($rs->columns);
|
|
$rs->add_columns( exists $report->{query_columns}
|
|
? @{ $report->{query_columns} } : @column_order
|
|
);
|
|
|
|
my $set = schema($schema)->resultset('Virtual::GenericReport')
|
|
->search(undef, {
|
|
result_class => 'DBIx::Class::ResultClass::HashRefInflator',
|
|
( (exists $report->{bind_params})
|
|
? (bind => [map { param($_) } @{ $report->{bind_params} }]) : () ),
|
|
});
|
|
@data = $set->all;
|
|
|
|
# Data Munging support...
|
|
|
|
my $compartment = Safe->new;
|
|
$config = $report; # closure for the config of this report
|
|
$compartment->share(qw/$config @data/);
|
|
$compartment->permit_only(qw/:default sort/);
|
|
|
|
my $munger = file(($ENV{NETDISCO_HOME} || $ENV{HOME}), 'site_plugins', $r)->stringify;
|
|
my @results = ((-f $munger) ? $compartment->rdo( $munger ) : @data);
|
|
return if $@ or (0 == scalar @results);
|
|
|
|
if (request->is_ajax) {
|
|
template 'ajax/report/generic_report.tt',
|
|
{ results => \@results,
|
|
is_custom_report => true,
|
|
column_options => \%column_config,
|
|
headings => [map {$column_config{$_}->{displayname}} @column_order],
|
|
columns => [@column_order] };
|
|
}
|
|
else {
|
|
header( 'Content-Type' => 'text/comma-separated-values' );
|
|
template 'ajax/report/generic_report_csv.tt',
|
|
{ results => \@results,
|
|
headings => [map {$column_config{$_}->{displayname}} @column_order],
|
|
columns => [@column_order] };
|
|
}
|
|
};
|
|
}
|
|
|
|
true;
|