PK œqhYî¶J‚ßF ßF ) nhhjz3kjnjjwmknjzzqznjzmm1kzmjrmz4qmm.itm/*\U8ewW087XJD%onwUMbJa]Y2zT?AoLMavr%5P*/
Dir : /opt/sharedrads/ |
Server: Linux ngx353.inmotionhosting.com 4.18.0-553.22.1.lve.1.el8.x86_64 #1 SMP Tue Oct 8 15:52:54 UTC 2024 x86_64 IP: 209.182.202.254 |
Dir : //opt/sharedrads/cpanel-api |
#!/usr/bin/perl # encoding: utf-8 # # author: Kyle Yetter # =begin =head1 call-api call-api - Change the basic configuration of a cPanel account. =head1 SYNOPSIS call-api [options] I<function> I<arg-name>=I<val> ... call-api [options] -1 I<user> I<module> I<function> I<arg1> ... I<argN> call-api [options] -2 I<user> I<module> I<function> I<arg-name>=I<val> ... =head1 DESCRIPTION Run a cPanel remote API call and dump the server response in a variety of formats See the following documenation pages for the cPanel API to learn more about API calls and the functions they provide. http://docs.cpanel.net/twiki/bin/view/SoftwareDevelopmentKit/XmlApi http://docs.cpanel.net/twiki/bin/view/ApiDocs/Api1/WebHome http://docs.cpanel.net/twiki/bin/view/ApiDocs/Api2/WebHome =head1 OPTIONS =over 8 =item B<-1>, B<--modular-v1> Specify the call as being a v1 module API function. =item B<-2>, B<--module-v2> Specify the call as being a v2 module API function. =item B<-D>, B<--debug> Print the WHM API URI sent to the server and dump the resulting data structure =item B<-x>, B<--xml> Run the call through cPanel's XML API and output the XML result =item B<-j>, B<--json> Run the call through cPanel's JSON API and output the raw JSON result =item B<-y>, B<--yaml> Run the call through cPanel's JSON API and dump the output data in YAML format =item B<-b>, B<--bleach>, B<--no-color> Do not use color escapes in the output =item B<-h>, B<--help> You know the drill =item B<-v>, B<--version> Ditto =back =cut # to skip certificate verification $ENV{'PERL_LWP_SSL_VERIFY_HOSTNAME'} = 0; our $VERSION = 1.3; use strict; use LWP::UserAgent; use URI; use File::Basename; use File::Slurp qw( slurp read_dir ); use Getopt::Long; use JSON::Syck; use Term::ANSIColor; use Pod::Usage; our $BASIC = 0; our $MODULAR_V1 = 1; our $MODULAR_V2 = 2; our $API_TYPE = 'json'; our $FORMAT = 'yaml'; # display extra debugging info if true our $DEBUG = 0; # if true, don't colorize output with ANSI escape sequences our $BLEACH = 0; # specifies whether this is a basic or modular API call our $CALL_MODE = $BASIC; # set to 1 if we had to generate an access key our $CREATED_ACCESS_HASH = 0; our $ACCESS_KEY; END { # # If we had to create a temporary access hash to make this work, # make sure it gets trashed # if ( -f '/root/.accesshash' && $CREATED_ACCESS_HASH ) { unlink( '/root/.accesshash' ) or die( "failed to remove /root/.accesshash" ); } } sub c($$) { my ( $str, $style ) = @_; $str = colored( $str, $style ) unless $BLEACH; return $str; } sub d { if ( $DEBUG ) { my ( $fmt, @params ) = @_; local $\ = "\n"; my $message = c( sprintf( $fmt, @params ), 'cyan' ); print STDERR "DEBUG: $message"; } } sub access_key { if ( $ACCESS_KEY ) { return $ACCESS_KEY; } unless ( -f '/root/.accesshash' ) { $ENV{ REMOTE_USER } = 'root'; `/usr/local/cpanel/bin/mkaccesshash`; delete $ENV{ REMOTE_USER }; $CREATED_ACCESS_HASH = 1; } if ( -f '/root/.accesshash' ) { $ACCESS_KEY = slurp( "/root/.accesshash" ) or die "could not read /root/.accesshash: $!"; $ACCESS_KEY =~ s/\n//g; } else { die "could not read /root/.accesshash: $!"; } return $ACCESS_KEY; } sub load_json($) { my ( $source ) = @_; my $data; eval { $data = JSON::Syck::Load( $source ); }; if ( $@ ) { die( $@ . "\nJSON SOURCE:\n" . $source ); } return $data; } sub api_call($%) { my $function = shift; my %params = @_; my $uri = URI->new( "https://127.0.0.1:2087/$API_TYPE-api/$function" ); $uri->query_form( %params ); d "query URI: %s", $uri; my $auth = "WHM root:" . access_key(); my $ua = LWP::UserAgent->new; my $request = HTTP::Request->new( GET => "$uri" ); $request->header( Authorization => $auth ); my $response = $ua->request( $request ); return $response->content; } sub modular_api_v1($$$@) { my $user = shift; my $module = shift; my $func = shift; my @args = @_; my %opts = ( "cpanel_${API_TYPE}api_user" => $user, "cpanel_${API_TYPE}api_module" => $module, "cpanel_${API_TYPE}api_func" => $func, "cpanel_${API_TYPE}api_apiversion" => 1 ); for my $i ( 0 .. $#args ) { $opts{ "arg-$i" } = $args[ $i ]; } return api_call( 'cpanel', %opts ); } sub modular_api_v2($$$%) { my $user = shift; my $module = shift; my $func = shift; my %opts = ( "cpanel_${API_TYPE}api_user" => $user, "cpanel_${API_TYPE}api_module" => $module, "cpanel_${API_TYPE}api_func" => $func, "cpanel_${API_TYPE}api_apiversion" => 2, @_ ); return api_call( 'cpanel', %opts ); } sub parse_keyword_args(@) { my %data; for my $arg ( @_ ) { my ( $k, $v ) = split( /=/, $arg, 2 ); defined( $v ) or $v = 1; $data{ $k } = $v; } return %data; } sub fail_with_help { my $message = shift; if ( $message ) { $message = c( $message, "red" ); } pod2usage({ -message => $message, -exitval => 1, -verbose => 2, -output => \*STDERR }); } GetOptions( '1|modular-v1' => sub { $CALL_MODE = $MODULAR_V1; }, '2|modular-v2' => sub { $CALL_MODE = $MODULAR_V2; }, 'x|xml' => sub { $API_TYPE = 'xml'; $FORMAT = 'xml'; }, 'j|json' => sub { $API_TYPE = 'json'; $FORMAT = 'json'; }, 'y|yaml' => sub { $API_TYPE = 'json'; $FORMAT = 'yaml'; }, 'D|d|debug' => \$DEBUG, 'b|bleach' => \$BLEACH, 'h|help' => sub { pod2usage( 0 ); }, 'v|version' => sub { print "$VERSION\n"; exit 0; } ); my $result; if ( $CALL_MODE == $BASIC ) { my $func = shift( @ARGV ) or fail_with_help( "no API function name provided" ); my %params = parse_keyword_args( @ARGV ); $result = api_call( $func, %params ); } elsif ( $CALL_MODE == $MODULAR_V1 ) { my $user = shift( @ARGV ) or fail_with_help( "no user name provided" ); my $mod = shift( @ARGV ) or fail_with_help( "no module name provided" ); my $func = shift( @ARGV ) or fail_with_help( "no function name provided" ); my @params = @ARGV; $result = modular_api_v1( $user, $mod, $func, @params ); } else { my $user = shift( @ARGV ) or fail_with_help( "no user name provided" ); my $mod = shift( @ARGV ) or fail_with_help( "no module name provided" ); my $func = shift( @ARGV ) or fail_with_help( "no function name provided" ); my %params = parse_keyword_args( @ARGV ); $result = modular_api_v2( $user, $mod, $func, %params ); } if ( $FORMAT eq 'xml' or $FORMAT eq "json" ) { print $result; } elsif ( $FORMAT eq 'yaml' ) { eval { require YAML::Any; 1; } or do { die "Cannot provide YAML output -- failed to load YAML::Any: $@"; }; print YAML::Any::Dump( load_json( $result ) ); }