API implementation (#712)
* 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
This commit is contained in:
@@ -7,19 +7,55 @@ use Dancer::Plugin::DBIC;
|
||||
use Dancer::Plugin::Auth::Extensible;
|
||||
use Dancer::Plugin::Swagger;
|
||||
|
||||
use Dancer::Error;
|
||||
use Dancer::Continuation::Route::ErrorSent;
|
||||
|
||||
use URI ();
|
||||
use Socket6 (); # to ensure dependency is met
|
||||
use HTML::Entities (); # to ensure dependency is met
|
||||
use URI::QueryParam (); # part of URI, to add helper methods
|
||||
use Path::Class 'dir';
|
||||
use Module::Load ();
|
||||
use App::Netdisco::Util::Web 'interval_to_daterange';
|
||||
use App::Netdisco::Util::Web qw/
|
||||
interval_to_daterange
|
||||
request_is_api
|
||||
request_is_api_report
|
||||
request_is_api_search
|
||||
/;
|
||||
|
||||
BEGIN {
|
||||
# https://github.com/PerlDancer/Dancer/issues/967
|
||||
no warnings 'redefine';
|
||||
*Dancer::_redirect = sub {
|
||||
my ($destination, $status) = @_;
|
||||
my $response = Dancer::SharedData->response;
|
||||
$response->status($status || 302);
|
||||
$response->headers('Location' => $destination);
|
||||
};
|
||||
# neater than using Dancer::Plugin::Res to handle JSON differently
|
||||
*Dancer::send_error = sub {
|
||||
my ($body, $status) = @_;
|
||||
if (request_is_api) {
|
||||
status $status || 400;
|
||||
$body = '' unless defined $body;
|
||||
Dancer::Continuation::Route::ErrorSent->new(
|
||||
return_value => to_json { error => $body, return_url => param('return_url') }
|
||||
)->throw;
|
||||
}
|
||||
Dancer::Continuation::Route::ErrorSent->new(
|
||||
return_value => Dancer::Error->new(
|
||||
message => $body,
|
||||
code => $status || 500)->render()
|
||||
)->throw;
|
||||
};
|
||||
}
|
||||
|
||||
use App::Netdisco::Web::AuthN;
|
||||
use App::Netdisco::Web::Static;
|
||||
use App::Netdisco::Web::Search;
|
||||
use App::Netdisco::Web::Device;
|
||||
use App::Netdisco::Web::Report;
|
||||
use App::Netdisco::Web::API::Objects;
|
||||
use App::Netdisco::Web::AdminTask;
|
||||
use App::Netdisco::Web::TypeAhead;
|
||||
use App::Netdisco::Web::PortControl;
|
||||
@@ -82,13 +118,14 @@ $swagger->{schemes} = ['http','https'];
|
||||
$swagger->{consumes} = 'application/json';
|
||||
$swagger->{produces} = 'application/json';
|
||||
$swagger->{tags} = [
|
||||
{name => 'Global'},
|
||||
{name => 'Devices',
|
||||
description => 'Operations relating to Devices (switches, routers, etc)'},
|
||||
{name => 'Nodes',
|
||||
description => 'Operations relating to Nodes (end-stations such as printers)'},
|
||||
{name => 'NodeIPs',
|
||||
description => 'Operations relating to MAC-IP mappings (IPv4 ARP and IPv6 Neighbors)'},
|
||||
{name => 'General',
|
||||
description => 'Log in and Log out'},
|
||||
{name => 'Search',
|
||||
description => 'Search Operations'},
|
||||
{name => 'Objects',
|
||||
description => 'Retrieve Device, Port, and associated Node Data'},
|
||||
{name => 'Reports',
|
||||
description => 'Canned and Custom Reports'},
|
||||
];
|
||||
$swagger->{securityDefinitions} = {
|
||||
APIKeyHeader =>
|
||||
@@ -229,6 +266,15 @@ hook 'after_template_render' => sub {
|
||||
# debug $template_engine->{config}->{AUTO_FILTER};
|
||||
};
|
||||
|
||||
# support for report api which is basic table result in json
|
||||
hook before_layout_render => sub {
|
||||
my ($tokens, $html_ref) = @_;
|
||||
return unless request_is_api_report or request_is_api_search;
|
||||
|
||||
${ $html_ref } =
|
||||
$tokens->{results} ? (to_json $tokens->{results}) : {};
|
||||
};
|
||||
|
||||
# workaround for Swagger plugin weird response body
|
||||
hook 'after' => sub {
|
||||
my $r = shift; # a Dancer::Response
|
||||
@@ -237,6 +283,13 @@ hook 'after' => sub {
|
||||
$r->content( to_json( $r->content ) );
|
||||
header('Content-Type' => 'application/json');
|
||||
}
|
||||
|
||||
# instead of setting serialiser
|
||||
# and also to handle some plugins just returning undef if search fails
|
||||
if (request_is_api) {
|
||||
header('Content-Type' => 'application/json');
|
||||
$r->content( $r->content || '[]' );
|
||||
}
|
||||
};
|
||||
|
||||
# remove empty lines from CSV response
|
||||
@@ -262,15 +315,4 @@ any qr{.*} => sub {
|
||||
template 'index';
|
||||
};
|
||||
|
||||
{
|
||||
# https://github.com/PerlDancer/Dancer/issues/967
|
||||
no warnings 'redefine';
|
||||
*Dancer::_redirect = sub {
|
||||
my ($destination, $status) = @_;
|
||||
my $response = Dancer::SharedData->response;
|
||||
$response->status($status || 302);
|
||||
$response->headers('Location' => $destination);
|
||||
};
|
||||
}
|
||||
|
||||
true;
|
||||
|
||||
Reference in New Issue
Block a user