You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcp-panel/tools_bin/ngcp-api-generate-doc

406 lines
11 KiB

#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Long;
use Pod::Usage qw(pod2usage);
use Config::General qw();
use File::Slurp qw();
use XML::Simple qw();
use NGCP::Schema::Config qw();
use NGCP::Schema qw();
use NGCP::Panel::Controller::API::Root qw();
my @panel_configs = qw(
/etc/ngcp-panel/ngcp_panel.conf
/etc/ngcp_panel.conf
/ngcp_panel.conf
);
my @provisioning_configs = qw(
/etc/ngcp-panel/provisioning.conf
);
my %db = (
host => undef,
port => 3306,
user => 'root',
password => undef,
);
my $help;
my $log_level;
my $doc_file;
my $doc_format = 'json';
GetOptions(
( map { ('db-' . $_ . ':s') => \$db{$_}; } keys %db ),
"format:s" => \$doc_format,
"file:s" => \$doc_file,
'log-level:s' => \$log_level,
"help|?" => \$help,
) or pod2usage(2);
pod2usage(1) if $help;
my %mock_objs = ();
my $c = _create_c();
my $controller = NGCP::Panel::Controller::API::Root->new;
$controller->GET($c);
_write_file($c->response->body);
exit(0);
sub _write_file {
my ($str) = @_;
if (defined $doc_file) {
open(my $fh, '>', $doc_file) or die('cannot open file ' . $doc_file . ': ' . $!);
binmode($fh);
print $fh $str;
close $fh;
} else {
print $str;
}
}
sub _create_c {
{
print "loading panel components ...\n";
my $module = 'NGCP::Panel';
my $file = $module;
$file =~ s[::][/]g;
$file .= '.pm';
require $file;
$module->import;
}
my $config = _get_panel_config();
{
no strict "refs"; ## no critic (ProhibitNoStrict)
*{'NGCP::Schema::set_transaction_isolation'} = sub {
my ($self,$level) = @_;
return $self->storage->dbh_do(
sub {
my ($storage, $dbh, @args) = @_;
$dbh->do("SET TRANSACTION ISOLATION LEVEL " . $args[0]);
},
$level,
);
};
*{'NGCP::Schema::set_wait_timeout'} = sub {
my ($self,$timeout) = @_;
return $self->storage->dbh_do(
sub {
my ($storage, $dbh, @args) = @_;
$dbh->do("SET SESSION wait_timeout = " . $args[0]);
},
$timeout,
);
};
}
my $db = _get_schema();
my $req = sub {
my $self = shift;
return _create_mock('_request',
_param => {
($doc_format eq 'swagger-yml' ? ('swagger' => 'yml') : ()),
($doc_format eq 'swagger-json' ? ('swagger' => 'json') : ()),
#'oldapidoc' => 1,
},
_header => {
($doc_format eq 'json' ? ('Accept' => 'application/json') : ())
},
param => sub {
my $self = shift;
my $key = shift;
return $self->{param}->{$key} if $key;
return $self->{param};
},
path => sub {
my $self = shift;
return 'api/';
},
params => sub {
my $self = shift;
return $self->{param};
},
query_params => sub {
my $self = shift;
return $self->{param};
},
header => sub {
my $self = shift;
my $key = shift;
return $self->{header}->{$key} if $key;
return $self->{header};
},
);
};
my $res = sub {
my $self = shift;
return _create_mock('_response',
_body => undef,
_code => undef,
_header => {
},
body => sub {
my $self = shift;
if (scalar @_) {
$self->{body} = shift;
}
return $self->{body};
},
code => sub {
my $self = shift;
if (scalar @_) {
$self->{code} = shift;
}
return $self->{code};
},
headers => sub {
my $self = shift;
my $key = shift;
return $self->{header}->{$key} if $key;
return $self->{header};
},
);
};
$c = _create_mock('c',
_stash => {
},
stash => sub {
my $self = shift;
my $key = shift;
return $self->{stash}->{$key} if $key;
return $self->{stash};
},
_model => {
DB => $db,
},
model => sub {
my $self = shift;
my $key = shift;
return $self->{model}->{$key} if $key;
return $self->{model};
},
log => sub {
my $self = shift;
return _create_mock('log',
debug => sub {
my $self = shift;
my $str = shift;
my @params = @_;
print $str . "\n" if ($log_level and grep { $_ eq lc($log_level); } qw(debug));
},
info => sub {
my $self = shift;
my $str = shift;
my @params = @_;
print $str . "\n" if ($log_level and grep { $_ eq lc($log_level); } qw(info debug));
},
warn => sub {
my $self = shift;
my $str = shift;
my @params = @_;
print $str . "\n" if ($log_level and grep { $_ eq lc($log_level); } qw(warn info debug));
},
error => sub {
my $self = shift;
my $str = shift;
my @params = @_;
print $str . "\n" if ($log_level and grep { $_ eq lc($log_level); } qw(error warn info debug));
},
);
},
config => sub {
my $self = shift;
return $config;
},
user => sub {
my $self = shift;
return _create_mock('user',
roles => sub {
my $self = shift;
return 'admin';
},
read_only => sub {
my $self = shift;
return 0;
},
is_system => sub {
my $self = shift;
return 0;
},
is_superuser => sub {
my $self = shift;
return 1;
},
);
},
loc => sub {
my $self = shift;
my $str = shift;
my @params = @_;
for (my $i = 1; $i <= scalar @params; $i++) {
my $subst = quotemeta("[_$i]");
my $repl = $params[$i - 1];
$str =~ s/$subst/$repl/g;
}
return $str;
},
detach => sub {
my $self = shift;
my $sub = shift;
my ($package, $filename, $line) = caller;
return $package->$sub($self);
},
view => sub {
return 'NGCP::Panel'->view('View::TT');
},
request => $req,
req => $req,
response => $res,
res => $res,
);
}
sub _create_mock {
my $class = shift;
return $mock_objs{$class} if exists $mock_objs{$class};
my %members = @_;
my $obj = bless({},$class);
foreach my $member (keys %members) {
if ('CODE' eq ref $members{$member}) {
no strict "refs"; ## no critic (ProhibitNoStrict)
*{$class.'::'.$member} = $members{$member};
} else {
$obj->{substr($member,1)} = $members{$member};
}
}
$mock_objs{$class} = $obj;
return $obj;
}
sub _get_schema {
my $schema;
if ($db{host}) {
$schema = NGCP::Schema->connect({
dsn => "DBI:mysql:database=provisioning;host=$db{host};port=$db{port}",
user => $db{user},
( exists $db{password} ? (password => $db{password}) : ()),
mysql_enable_utf8 => "1",
on_connect_do => "SET NAMES utf8mb4",
quote_char => "`",
});
$schema->set_wait_timeout(3600);
return $schema;
} else {
foreach my $provisioning_config (@provisioning_configs) {
if (-f $provisioning_config) {
my $conf = XML::Simple->new->XMLin($provisioning_config, ForceArray => 1);
if ($conf && $conf->{ngcp_connect_info}) {
my $connectors;
if (exists $conf->{ngcp_connect_info}->[0]->{connectors}) {
$connectors = $conf->{ngcp_connect_info}->[0]->{connectors};
} else {
$connectors = $conf->{ngcp_connect_info};
}
$connectors //= [];
$schema = NGCP::Schema->connect($connectors->[0]);
$schema->set_wait_timeout(3600);
return $schema;
}
}
}
die("no provisioning.conf found\n") unless $schema;
}
}
sub _get_panel_config {
my $config;
foreach my $panel_config (@panel_configs) {
if( -f $panel_config ){
my $catalyst_config = Config::General->new($panel_config);
my %config = $catalyst_config->getall();
$config = \%config;
last;
}
}
die("no ngcp_panel.conf found\n") unless $config;
return $config;
}
__END__
=head1 NAME
ngcp-api-generate-doc - generate apidoc output
=head1 SYNOPSIS
E<9>B<ngcp-api-generate-doc> [I<options>]
=head1 DESCRIPTION
This program allows to generate the NGCP Rest-API documentation offline (without running nginx).
=head1 OPTIONS
=over 4
=item B<--help>
Print a brief help message and exits.
=item B<--format=>I<format>
Specify the apidoc format (json/swagger-json/swagger-yml).
=item B<--file=>I<filename>
Specify a file to write the apidoc output to.
=item B<--log-level>
Verbosity of printed messages while processing (debug, info, warn, error).
=back
=head1 AUTHOR
Sipwise Development Team C<< <support@sipwise.com> >>
=head1 LICENSE
This software is Copyright © 2020 by Sipwise GmbH, Austria.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this package. If not, see <https://www.gnu.org/licenses/>.
=cut