API-PleskExpand

 view release on metacpan or  search on metacpan

Build.PL  view on Meta::CPAN


use strict;
use warnings;

use Module::Build;

my $build = Module::Build->new(
    module_name => 'API::PleskExpand',
    license     => 'perl',
    dist_author => 'NRG <pavel.odintsov@googlemail.com>',
    requires    => {
        'API::Plesk'      => '1.06',
        'Data::Dumper'    => 0,
        'LWP::UserAgent'  => 0,
        'Getopt::Long'    => 0,
        'HTTP::Request'   => 0,
        'Carp'            => 0,
        'URI'             => 0,
    },
    build_requires => {
        'Test::More'       => 0,
        'Test::LongString' => 0,
        'URI'              => 0,
    },
    create_makefile_pl => 'traditional',
);

$build->create_build_script;

META.yml  view on Meta::CPAN

--- #YAML:1.0
name:               API-PleskExpand
version:            1.07
abstract:           API::PleskExpand - OOP interface to the Plesk Expand XML API
author:
    - NRG <pavel.odintsov@googlemail.com>
license:            perl
distribution_type:  module
configure_requires:
    ExtUtils::MakeMaker:  0
requires:
    API::Plesk:        1.06
    Carp:              0
    Data::Dumper:      0
    Getopt::Long:      0
    HTTP::Request:     0
    LWP::UserAgent:    0
    Test::LongString:  0
    Test::More:        0
    URI:               0
no_index:

README  view on Meta::CPAN

API-PleskExpand version 1.00
=======================

The given module is intended for interaction with the XML API of the Plesk Expand centralized hosting panel. API is realized not completely, but there is a full support of operations with Account and Domains. 

API::PleskExpand module gives the convenient interface for addition of new functions. Extensions represent modules in a folder Expand with definitions of demanded functions. Each demanded operation is described by two functions: op and op_response_pa...

INSTALLATION

To install this module type the following:

    perl Makefile.PL
    make
    make test
    make install

TESTS
	
    make test

DEPENDENCIES

This module requires these other modules and libraries:

    API::Plesk 1.04,
    Carp (standard),
    Data::Dumper,
    Getopt::Long,
    HTTP::Request,
    LWP::UserAgent,
    Test::More.

AUTHOR

lib/API/PleskExpand.pm  view on Meta::CPAN

=head1 NAME

API::PleskExpand - OOP interface to the Plesk Expand XML API (http://www.parallels.com/en/products/plesk/expand/).

=head1 SYNOPSIS

    use API::PleskExpand;
    use API::Plesk::Response;

    my $expand_client = API::PleskExpand->new(%params);
    my $res = $expand_client->Func_Module->operation_type(%params);

    if ($res->is_success) {
        $res->get_data; # return arr ref of answer blocks
    }

=head1 DESCRIPTION

At present the module provides interaction with Plesk Expand 2.2.4 (API 2.2.4.1). Complete support of operations with Accounts, partial support of work with domains. Support of addition of domains to user Accounts.

API::PleskExpand module gives the convenient interface for addition of new functions. Extensions represent modules in a folder Plesk with definitions of demanded functions. Each demanded operation is described by two functions: op and op_response_par...

For example, here the set of subs in the Accounts module is those.

  create  / create_response_parse
  modify  / modify_response_parse
  delete  / delete_response_parse
  get     / get_response_parse

=head1 EXPORT

Nothing.

=head1 METHODS

=over 3

=item new(%params)

lib/API/PleskExpand.pm  view on Meta::CPAN

    unless ($self->{api_version}) {
        $self->{api_version} = '2.2.4.1';
    }

    return $self;
}


=item AUTOLOADed methods

All other methods are loaded by Autoload from corresponding modules. 
Execute some operations (see API::PleskExpand::* modules documentation).

Example:

  my $res = $expand_client->Func_Module->operation_type(%params); 
  # Func_Module -- module in API/PleskExpand folder
  # operation_type -- sub which defined in Func_Module.
  # params hash used as @_ for operation_type sub.

=back

=cut



lib/API/PleskExpand/Accounts.pm  view on Meta::CPAN

  'attach_to_template' => 1, # attach account to a certain template
  'general_info'  => {
    login   => 'plesk_login',
    pname   => 'perldonal name',
    passwd  => 'userpasswd',
    status  => 0,                   # active
    cname   => '',                  # company name
    phone   => '',
    fax     => '',
    email   => '',
    address => '',
    city    => '',
    state   => '',                  # state, for USA only
    pcode   => '',
    country => 'RU',
  }

You can let Plesk Expand automatically select a Plesk server based on certain filtering parameters (params for 'select' field):

    'optimal' -- Least Integral Estimate (% used) selects the least loaded server (integrally estimated).
    'min_domains' -- Least Domains (% used) registers a client on the server with the minimum number of domains.

lib/API/PleskExpand/Accounts.pm  view on Meta::CPAN

        
        return create_node( 'add_use_template',
            generate_info_block('gen_info', %{ $params{'general_info'} } ) . '<!-- create_client -->' . $template . $select);

    } else {
        return '';  # not enought data
    }
}


# Parse XML response
# STATIC
sub create_response_parse {
    return abstract_parser('add_use_template', +shift, [ ]);
}


=item modify(%params)

Changes the account params.

Params:
  general_info -- hashref`s with new user details

lib/API/PleskExpand/Accounts.pm  view on Meta::CPAN

            <gen_info>
                <status>0</status>
            </gen_info>
        </values>
    </set>
</packet>
DOC
}


# SET response handler
# STATIC
sub modify_response_parse {
    return abstract_parser('set', +shift, []);
}


=item delete(%params)

Delete accounts.

Params:
  id -- client id in Plesk

lib/API/PleskExpand/Accounts.pm  view on Meta::CPAN

        $filter = create_filter( id => $params{'id'});
    } else {
        return '';  # id required!
    }
    

    return create_node('del', '<!-- del_client -->' . $filter);
}


# DEL response handler
# STATIC
sub delete_response_parse {
    return abstract_parser('del', +shift, [ ]);
}


# Get all element data
# STATIC
sub get {
    my %params = @_;

    unless ($params{all}) {
        return '';
    }

    return create_node( 'get',
        create_node('filter', '') . create_node( 'dataset', create_node('gen_info') )
    ) . '<!-- get_client -->';
}


# GET response handler
# STATIC
sub get_response_parse {
    my $answer = abstract_parser('get', +shift, [ ], 'system_error' );

    if (ref $answer eq 'ARRAY') {
        for my $domain (@$answer) {
            $domain->{data} = xml_extract_values($domain->{data} =~ m#<gen_info>(.*?)</gen_info>#);
        }
    } elsif ($answer) {
        $answer->{data} = xml_extract_values($answer->{data} =~ m#<gen_info>(.*?)</gen_info>#);
    }

lib/API/PleskExpand/Domains.pm  view on Meta::CPAN

        create_node( 
            'gen_setup',
            create_node( 'name', $params{dname} ) .
            create_node( 'client_id', $params{client_id} ) .
            create_node( 'status', 0)
        ) . $hosting_block . '<!-- create_domain -->' . $template_block        
    );
}


# Parse XML response
# STATIC
sub create_response_parse {
    return abstract_parser('add_use_template', +shift, [ ], 'system_error' );
}


# Modify element
# STATIC
sub modify {
    # stub
}


# SET response handler
# STATIC
sub modify_response_parse {
    # stub
}


# Delete element
# STATIC( %args )
sub delete {
    # stub
}


# DEL response handler
# STATIC
sub delete_response_parse {
    # stub
}


# Get all element data
# STATIC
sub get {
    my %params = @_;

    unless ($params{all}) {

lib/API/PleskExpand/Domains.pm  view on Meta::CPAN

    }

    #return '<get><filter></filter><dataset><gen_info/></dataset></get><!-- create_domain -->';

    return create_node( 'get',
        create_node('filter', '') . create_node( 'dataset', create_node('gen_info') )
    ) . '<!-- create_domain -->';
}


# GET response handler 
# STATIC
sub get_response_parse {
    my $answer = abstract_parser('get', +shift, [ ], 'system_error' );

    if (ref $answer eq 'ARRAY') {
        for my $domain (@$answer) {
            $domain->{data} = xml_extract_values($domain->{data} =~ m#<gen_info>(.*?)</gen_info>#);
        }
    } elsif ($answer) {
        $answer->{data} = xml_extract_values($answer->{data} =~ m#<gen_info>(.*?)</gen_info>#);
    }

t/expand.t  view on Meta::CPAN

use Carp;
use Test::More;
use Test::LongString;
use Data::Dumper;

use lib 't';
use TestData;


BEGIN {
    plan tests => $ENV{online_stress_tests} ? 34 : 28;
    use_ok( 'API::PleskExpand' );
    use_ok( 'API::PleskExpand::Accounts' );
    use_ok( 'API::PleskExpand::Domains' );
    use_ok( 'API::Plesk::Response');
}


my $expand_client = API::PleskExpand->new( %TestData::online_expand_valid_params);
isa_ok( $expand_client, 'API::PleskExpand', 'STATIC call new' );

t/expand.t  view on Meta::CPAN

    'template-id'   =>  1,
    'general_info'  => {
        login   => 'suxdffffxx',
        pname   => 'stdsdffafff',
        passwd  => '1234d5678',
        status  => 0,
        cname   => '',
        phone   => '',
        fax     => '',
        email   => '',
        address => '',
        city    => '',
        state   => '',
        pcode   => '',
        country => 'RU',
    }
);


my $create_request = API::PleskExpand::Accounts::create( %create_account_data );

is_string($create_request, $_, 'create account test') for
'<add_use_template><gen_info><address></address><city></city><cname></cname>'          .
'<country>RU</country><email></email><fax></fax><login>suxdffffxx</login>'             .
'<passwd>1234d5678</passwd><pcode></pcode><phone></phone><pname>stdsdffafff</pname>'   .
'<state></state><status>0</status></gen_info><!-- create_client -->'                   .
'<tmpl_id>1</tmpl_id><server_auto><optimal></optimal></server_auto></add_use_template>';

$create_request = API::PleskExpand::Accounts::create(
    %create_account_data,
    'attach_to_template' => 1 
);

is_string($create_request, $_, 'create account test') for 
'<add_use_template><gen_info><address></address><city></city><cname></cname>'        .
'<country>RU</country><email></email><fax></fax><login>suxdffffxx</login>'           .
'<passwd>1234d5678</passwd><pcode></pcode><phone></phone><pname>stdsdffafff</pname>' .
'<state></state><status>0</status></gen_info><!-- create_client -->'                 .
'<tmpl_id>1</tmpl_id><attach_to_template></attach_to_template><server_auto>'         .
'<optimal></optimal></server_auto></add_use_template>';


is_deeply(
    API::PleskExpand::Accounts::create( %create_account_data, select => ''),  
    '',

t/expand.t  view on Meta::CPAN

my $req_answer1 = {
    errtext     => "[Operator] Client already exists. Plesk client 'hello_medved' is exist.",
    server_id   => 1,
    status      => 'error',
    tmpl_id     => 1,
    expiration  => -1,
    errcode     => 4203,
};

is_deeply(
    API::PleskExpand::Accounts::create_response_parse( $_ ),
    $req_answer1,
    'create with error parser'
) for
'<?xml version="1.0" encoding="UTF-8" standalone="no" ?>'           .
'<packet version="2.2.4.1"><add_use_template><result>'              .
'<status>error</status><errcode>4203</errcode><errtext>'            .
"[Operator] Client already exists. Plesk client 'hello_medved' "    .
'is exist.</errtext><server_id>1</server_id><tmpl_id>1</tmpl_id>'   .
'<expiration>-1</expiration></result></add_use_template></packet>';


is_deeply(
    API::PleskExpand::Accounts::create_response_parse( $_ ), 
    {
        'server_id'  => '1',
        'status'     => 'ok',
        'expiration' => '-1',
        'tmpl_id'    => '1',
        'id'         => '29'
    },
    'parse success create xml response '
) for '<?xml version="1.0" encoding="UTF-8" standalone="no" ?>'    .
'<packet version="2.2.4.1"><add_use_template><result><status>ok'   .
'</status><id>29</id><server_id>1</server_id><tmpl_id>1</tmpl_id>' .
'<expiration>-1</expiration></result></add_use_template></packet>' ;


is_deeply(
    API::PleskExpand::Accounts::modify_response_parse( $_ ), 
    {
        'server_id' => '1',
        'status' => 'ok',
        'tmpl_id' => '1',
        'id' => '32',
        'plesk_client_id' => '395',
        'login' => 'aseaasdsassrews'
    },
    'parse success modify xml response'
) for '<?xml version="1.0" encoding="UTF-8" standalone="no" ?><packet version="2.2.4.1">' .
      '<set><result><status>ok</status><id>32</id><server_id>1</server_id><tmpl_id>1</tmpl_id>' .
      '<plesk_client_id>395</plesk_client_id><login>aseaasdsassrews</login></result></set></packet>';


is_deeply(
    API::PleskExpand::Accounts::delete_response_parse( $_ ), 
    {
        'server_id' => '1',
        'status' => 'ok',
        'id' => '33',
    },
    'parse success delete xml response'
) for '<?xml version="1.0" encoding="UTF-8" standalone="no" ?><packet version="2.2.4.1">' . 
      '<del><result><status>ok</status><id>33</id><server_id>1</server_id></result></del></packet>';



is_deeply(
    API::PleskExpand::Domains::create_response_parse( $_ ), 
    {
        'server_id'     => '1',
        'status'        => 'ok',
        'expiration'    => '-1',
        'tmpl_id'       => '1',
        'client_id'     => '38',
        'id'            => '16'

    },
    'parse success add domain xml response')
for '<?xml version="1.0" encoding="UTF-8" standalone="no" ?><packet version="2.2.4.1">' .
    '<add_use_template><result><status>ok</status><id>16</id><client_id>38</client_id>' .
    '<server_id>1</server_id><tmpl_id>1</tmpl_id><expiration>-1</expiration></result></add_use_template></packet>';



is_deeply(
    API::PleskExpand::Domains::create_response_parse( $_ ), 
    {
        errtext     => "[Operator] Domain already exists. Plesk domain 'yandex.ru' is exist.",
        errcode     => '4304',
        status      => 'error',
        tmpl_id     => 1,
        expiration  => -1,
        client_id   => 40,
        server_id   => 1,
    },
    'parse fail add domain xml response')
for '<?xml version="1.0" encoding="UTF-8" standalone="no" ?><packet version="2.2.4.1"><add_use_template>' .
    '<result><status>error</status><errcode>4304</errcode><errtext>[Operator] Domain already exists.'     .
    " Plesk domain 'yandex.ru' is exist.</errtext><client_id>40</client_id><server_id>1</server_id>"      .
    '<tmpl_id>1</tmpl_id><expiration>-1</expiration></result></add_use_template></packet>';

is_string(
    API::PleskExpand::Domains::get(all => 1),
    '<get><filter></filter><dataset><gen_info/></dataset></get><!-- create_domain -->',
    'Domains get'
);



exit unless $ENV{'online_stress_tests'};

my ($domain_template_id, $client_template_id);
$domain_template_id = $client_template_id = $ENV{template_id} || 1;

diag "Online tests start!";
# 5 tests -- full set !!!
my $login = $ENV{'online_stress_tests_login'} || 'expandtestaccount';
my $create_account_result = $expand_client->Accounts->create(
    'select'             => 'optimal',
    'template-id'        =>  $client_template_id,
    'attach_to_template' => 1,
    'general_info'  => {
        login   => $login,
        pname   => $login,
        passwd  => 'asdasdasd',
        status  => 0,
        cname   => '',
        phone   => '',
        fax     => '',
        email   => '',
        address => '',
        city    => '',
        state   => '',
        pcode   => '',
        country => 'RU',
    }
);

if ($create_account_result->is_success) {
    #warn Dumper $create_account_result;

    my $client_id =  $create_account_result->{answer_data}->[0]->{id};
    my $server_id =  $create_account_result->{answer_data}->[0]->{server_id};

    pass "Account succcessful created!";

    my $deactivate_result = $expand_client->Accounts->modify(
        general_info => { status => 16 }, # deactivate! 
        id           => $client_id,
    );

    if ($deactivate_result->is_success) {
        pass "Deactivation success!";

        my $activate_result = $expand_client->Accounts->modify(
            general_info => { status => 0 }, # activate! 
            id           => $client_id,
        );

        my $plesk_id = $activate_result->get_data->[0]->{plesk_client_id};

        if ($activate_result->is_success) {
            pass "Activation success!";

            
            my $create_domain = $expand_client->Domains->create(
                dname                => $login . '.ru',
                client_id            => $client_id,
                'template-id'        => $domain_template_id,
                'attach_to_template' => 1,
                ftp_login            => $login,
                ftp_password         => 'afsfsaf',
            );

        
            if ($create_domain->is_success) {
   
                pass "Create domain successful";

                my $nop_result = $expand_client->Accounts->modify(
                    general_info => { },         # blank operation
                    id           => $client_id,
                );

                if ($nop_result->is_success && $nop_result->get_data->[0]->{plesk_client_id} eq $plesk_id) {
                    pass "Get plesk_id $plesk_id success";
                        
                    my $delete_result = $expand_client->Accounts->delete(
                        id => $client_id,
                    );
        
                    if ( $delete_result->is_success ) {
                        pass "Delete account success";
                    } else {
                        fail "Remove account failed";   
                        exit;
                    }

                } else {
                    fail "Get plesk_id failed";
                    exit;
                }      

t/expand.t  view on Meta::CPAN

        } else {
            fail "Activation failed!";
            exit;
        }

    } else {
        fail "Deactivation failed!";
        exit;
    }
} else {
    fail $create_account_result->get_error_string;
    exit;
}



( run in 0.739 second using v1.01-cache-2.11-cpan-49f99fa48dc )