#!/usr/bin/perl use strict; use warnings; use English; use Getopt::Long; use Pod::Usage; use NGCP::API::Client; use Readonly; Readonly my @required => qw(op); my $opts = { verbose => 0, }; # XXX: Remove after mr10.5. sub old_option { my ($name, $value) = @_; my $newname = $name =~ tr/_/-/r; $opts->{$name} = $value; warn "$0: option --$name is deprecated; use --$newname instead\n"; } sub parse_option { my ($name, $value) = @_; $name =~ tr/-/_/; $opts->{$name} = $value; } GetOptions($opts, 'help|h' => sub { usage() }, 'op=s', 'login=s', 'password=s', 'email=s', 'reseller_id=i' => \&old_option, 'reseller-id=i' => \&parse_option, 'is_system=i' => \&old_option, 'is-system=i' => \&parse_option, 'is_master=i' => \&old_option, 'is-master=i' => \&parse_option, 'is_superuser=i' => \&old_option, 'is-superuser=i' => \&parse_option, 'is_ccare=i' => \&old_option, 'is-ccare=i' => \&parse_option, 'read_only=i' => \&old_option, 'read-only=i' => \&parse_option, 'show_paswords=i' => \&old_option, 'show-paswords=i' => \&parse_option, 'call_data=i' => \&old_option, 'call-data=i' => \&parse_option, 'billing_data=i' => \&old_option, 'billing-data=i' => \&parse_option, 'lawful_intercept=i' => \&old_option, 'lawful-intercept=i' => \&parse_option, 'verbose', ) or usage(); sub check_params { my @missing; my @invalid; foreach my $param (@required) { push @missing, $param unless grep { defined $opts->{$_} } split /\|/, $param; } if ($opts->{op} and $opts->{op} !~ /^(list|add|update|delete)$/) { push @invalid, "'op' must be one of list|add|update|delete"; } if ($opts->{op} and $opts->{op} =~ /^(add|update|delete)$/) { unless ($opts->{login}) { push @missing, "'login' must provided"; } } die "Missing parameters: ".join(' ',@missing),"\n" if @missing; die "Invalid parameters: ".join(' ',@invalid),"\n" if @invalid; return; } sub usage { pod2usage( -exitval => 0, -verbose => 99, -sections => 'SYNOPSIS|REQUIRED ARGUMENTS|OPTIONS', ); return; } sub main { usage() unless $opts->{op}; check_params(); my $client = NGCP::API::Client->new(verbose => $opts->{verbose}); my $op = $opts->{op}; my $id; my $login = $opts->{login} // ''; my $res; my $login_query = $login ? "?login=$login" : ""; $res = $client->request('GET', '/api/admins/' .$login_query); unless ($res->is_success) { die "Error while retrieving admins data\n"; } if ($op eq 'update' or $op eq 'delete') { my $id_ref = $res->as_hash->{_embedded}{'ngcp:admins'}; unless ($id_ref) { die "Login '$login' does not exist\n"; } $id = $id_ref->[0]{id}; } if ($op eq 'list') { print $res->decoded_content,"\n"; return !$res->is_success; } elsif ($op eq 'add') { my %data = map { (defined $opts->{$_} ? ($_ => $opts->{$_}) : ()) } qw(login password email reseller_id is_system is_master is_ccare read_only show_passwords call_data billing_data lawful_intercept); $res = $client->request('POST', '/api/admins/', \%data); } elsif ($op eq 'update' ) { my @data = map { (defined $opts->{$_} ? ({op => 'replace', path => "/$_", "value", $opts->{$_} }) : ()) } qw(login password email reseller_id is_system is_master is_ccare read_only show_passwords call_data billing_data lawful_intercept); $res = $client->request('PATCH', '/api/admins/'.$id, \@data); } elsif ($op eq 'delete' ) { $res = $client->request('DELETE', '/api/admins/'.$id); } print $res->result . "\n"; return !$res->is_success; } exit main(); __END__ =head1 NAME ngcp-api-admins - manage NGCP API admin users =head1 SYNOPSIS B<ngcp-api-admins> [I<options>...] I<required-arguments>... =head1 DESCRIPTION B<This program> list/add/update/delete NGCP API administrators =head1 REQUIRED ARGUMENTS =over 8 =item B<--op> Operation: "list", "add", "update", "delete" =back =head1 OPTIONS =over 8 =item B<--login> B<login> Administrator login name =item B<--password> I<password> Password field =item B<--email> I<email> Email field =item B<--reseller-id> I<id> Reseller id the administartor belongs to (used in "add" and "update"). =item B<--is-system> I<0|1> A flag that defines wether the user is the system root and can manage everything. *Only administrators with this flag are able to manage "lawful intercept" administrators. =item B<--is-superuser> I<0|1> A flag that defines wether the administrator can manage all resellers on the platform. =item B<--is-master> I<0|1> A flag that defines wether the administrator can manage other administrators within the same reseller. =item B<--is-ccare> I<0|1> A flag that defines wether the administrator is limited only to manage Customers and Subscribers. (coped with <is_superuser> defines wether the scope is limited to only Reseller the administrator belongs to or across all Resellers) =item B<--read-only> I<0|1> Engages "Read Only" functionality for the administrator. =item B<--show-passwords> I<0|1> Show clear text passwords to the administrator. =item B<--call-data> I<0|1> The administrator is able to access call traces ("voisniff" must be also enabled). =item B<--billing-data> I<0|1> Enables the administrator to apply "Balance top up" and "Vouchers". =item B<--verbose> I<0|1> Show additional debug information. Default false. =item B<--help> Print a brief help message. =back =head1 EXIT STATUS =over =item B<0> Command completed successfully. =item B<1> Command failed with errors. =back =head1 SEE ALSO NGCP::API::Client =head1 BUGS AND LIMITATIONS Please report problems you notice to the Sipwise Development Team <support@sipwise.com>. =head1 AUTHOR Sipwise Development Test <support@sipwise.com> =head1 LICENSE Copyright (C) 2020 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 program. If not, see <http://www.gnu.org/licenses/>. =cut