Parallels Plesk Panel 11 RPC API - reading DNS records
Tuesday, July 9. 2013
Getting Parallels Plesk Panel to do something without admin's interaction is not tricky. My favorite method of remote-controlling Plesk is via its RPC API. I am a co-author of Perl-implementation API::Plesk, which is available in CPAN.
All XML RPC -requests should be directed towards your Plesk-server at URL
https://-your-plesk-box-here-:8443/enterprise/control/agent.php
Raw XML
First we'll need to get the internal site ID of a domain. A request to get all the subscriptions looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<packet version="1.6.3.5">
<webspace>
<get>
<filter/>
<dataset>
<gen_info/>
</dataset>
</get>
</webspace>
</packet>
Note: It would have been possible to filter a specific subscription by domain name, but in this case we just wanted a list of all.
A response to it will contain domain names and their Ids:
<?xml version="1.0" encoding="UTF-8"?>
<packet version="1.6.3.5">
<webspace>
<get>
<result>
<status>ok</status>
<filter-id>1</filter-id>
<id>1</id>
<data>
<gen_info>
<name>www.testdomain.org</name>
</gen_info>
</data>
</result>
</get>
</webspace>
</packet>
The response packet contains internal ID and name. We'll be using the internal ID of 1 to get all the DNS-records of the zone:
<?xml version="1.0" encoding="UTF-8"?>
<packet version="1.6.3.5">
<dns>
<get_rec>
<filter>
<site-id>1</site-id>
</filter>
</get_rec>
</dns>
</packet>
A response packet will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<packet version="1.6.3.5">
<dns>
<get_rec>
<result>
<status>ok</status>
<id>111</id>
<data>
<site-id>1</site-id>
<type>CNAME</type>
<host>www.testdomain.org.</host>
<value>testdomain.org.</value>
<opt/>
</data>
</result>
</get_rec>
</dns>
</packet>
There seems not to be any other way of picking a specific record. A filter with type/name would be welcome. Any further operations would be done with the domain record's ID. In this case it is 111.
Perl-code
With a software library, the access is much easier. The same requests would be something like this in Perl:
my $plesk_client = API::Plesk->new('api_version' => '1.6.3.5',
'secret_key' => $plesk_api_key,
'url'=>'https://-your-plesk-box-here-:8443/enterprise/control/agent.php',
'debug' => 0);
$res = $plesk_client->webspace->get();
die "Subscriptions->get() failed!\n" . $res->error . "\n" if (!$res->is_success);
my @domains = @{$res->results()};
my $cnt = $#domains + 1;
for (my $idx = 0; $idx < $cnt; ++$idx) {
my $domainId = $domains[$idx]{"id"};
$domainId += 0; # toInt
my $res = $plesk_client->dns->get('site-id' => $domainId);
die "DNS->get() failed!\n" . $res->error . "\n" if (!$res->is_success);
my %dns = %{@{$res->results()}[0]};
print Dump::Dumper(%dns);
}
That is pretty much it.
Update (2nd Nov 2013)
To get all of the domains will require a two-step process (order does not matter): 1) get all the subscriptions (kind of main domains) and 2) get the other domains under subscriptions.
In my Perl-code I do it like this:
# NOTE: This is from the above code
# 1st round:
# Get all the subscriptions.
# There we have the "main" domains
$res = $plesk_client->webspace->get();
die "Subscriptions->get() failed!\n" . $res->error . "\n" if (!$res->is_success);
# NOTE: New one:
# 2nd round:
# Get all the sites.
# There we have the "non-main" domains
$res = $plesk_client->site->get();
die "Sites->get() failed!\n" . $res->error . "\n" if (!$res->is_success);
@domains = @{$res->results()};
In my case, the $res-hash is fed into a ExtractDomains()-function to get the details I need from them. If only the name is required, then no further processing is necessary.
Getting Parallels Plesk Panel to do something without admin's interaction is not tricky. My favorite method of remote-controlling Plesk is via its RPC API. I am a co-author of Perl-implementation API::Plesk, which is available in CPAN.
All XML RPC -requests should be directed towards your Plesk-server at URL
https://-your-plesk-box-here-:8443/enterprise/control/agent.php
Raw XML
First we'll need to get the internal site ID of a domain. A request to get all the subscriptions looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<packet version="1.6.3.5">
<webspace>
<get>
<filter/>
<dataset>
<gen_info/>
</dataset>
</get>
</webspace>
</packet>
Note: It would have been possible to filter a specific subscription by domain name, but in this case we just wanted a list of all.
A response to it will contain domain names and their Ids:
<?xml version="1.0" encoding="UTF-8"?>
<packet version="1.6.3.5">
<webspace>
<get>
<result>
<status>ok</status>
<filter-id>1</filter-id>
<id>1</id>
<data>
<gen_info>
<name>www.testdomain.org</name>
</gen_info>
</data>
</result>
</get>
</webspace>
</packet>
The response packet contains internal ID and name. We'll be using the internal ID of 1 to get all the DNS-records of the zone:
<?xml version="1.0" encoding="UTF-8"?>
<packet version="1.6.3.5">
<dns>
<get_rec>
<filter>
<site-id>1</site-id>
</filter>
</get_rec>
</dns>
</packet>
A response packet will look like this:
<?xml version="1.0" encoding="UTF-8"?>
<packet version="1.6.3.5">
<dns>
<get_rec>
<result>
<status>ok</status>
<id>111</id>
<data>
<site-id>1</site-id>
<type>CNAME</type>
<host>www.testdomain.org.</host>
<value>testdomain.org.</value>
<opt/>
</data>
</result>
</get_rec>
</dns>
</packet>
There seems not to be any other way of picking a specific record. A filter with type/name would be welcome. Any further operations would be done with the domain record's ID. In this case it is 111.
Perl-code
With a software library, the access is much easier. The same requests would be something like this in Perl:
my $plesk_client = API::Plesk->new('api_version' => '1.6.3.5',
'secret_key' => $plesk_api_key,
'url'=>'https://-your-plesk-box-here-:8443/enterprise/control/agent.php',
'debug' => 0);
$res = $plesk_client->webspace->get();
die "Subscriptions->get() failed!\n" . $res->error . "\n" if (!$res->is_success);
my @domains = @{$res->results()};
my $cnt = $#domains + 1;
for (my $idx = 0; $idx < $cnt; ++$idx) {
my $domainId = $domains[$idx]{"id"};
$domainId += 0; # toInt
my $res = $plesk_client->dns->get('site-id' => $domainId);
die "DNS->get() failed!\n" . $res->error . "\n" if (!$res->is_success);
my %dns = %{@{$res->results()}[0]};
print Dump::Dumper(%dns);
}
That is pretty much it.
Update (2nd Nov 2013)
To get all of the domains will require a two-step process (order does not matter): 1) get all the subscriptions (kind of main domains) and 2) get the other domains under subscriptions.
In my Perl-code I do it like this:
# NOTE: This is from the above code
# 1st round:
# Get all the subscriptions.
# There we have the "main" domains
$res = $plesk_client->webspace->get();
die "Subscriptions->get() failed!\n" . $res->error . "\n" if (!$res->is_success);
# NOTE: New one:
# 2nd round:
# Get all the sites.
# There we have the "non-main" domains
$res = $plesk_client->site->get();
die "Sites->get() failed!\n" . $res->error . "\n" if (!$res->is_success);
@domains = @{$res->results()};
In my case, the $res-hash is fed into a ExtractDomains()-function to get the details I need from them. If only the name is required, then no further processing is necessary.
http://download1.parallels.com/Plesk/PP11/11.0/Doc/en-US/online/plesk-api-rpc/index.htm?fileName=66544.htm
However, this does not get customers domains, why?