Saturday 9 August 2008

Plesk Interface in PHP



Our initial Design of FreeNameServers.co.uk used PLESK as a back-end DNS provider, we moved away from this model for licensing issues, however, the PHP interface was already developed, so this is included below for anyone who is looking to automate their plesk DNS system.

<?php

define("HOST", "localhost");
define("PORT", 8443);
define("PATH", "enterprise/control/agent.php");
define("LOGIN", "admin");
define("PASSWD", "xxxxxxx");
define("PROTO_VER", "1.3.1.0");


$proto = PROTO_VER;
$action=$_GET['action'];
$domain=$_GET['domain'];
$host=$_GET['host'];
$type=$_GET['type'];
$value=$_GET['value'];
$opt=$_GET['opt'];
$domain_id=NULL;
$record_id=NULL;

//retrieve the domain id
if ( $action != 'adddomain' && $action !='listdomains' ) {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<domain>
<get>
<filter/>
<dataset>
<gen_info/>
</dataset>
</get>
</domain>
</packet>
EOF;

sendCommand(get_domid);
}

switch ( $action ) {

case 'listdomains':
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<domain>
<get>
<filter/>
<dataset>
<gen_info/>
</dataset>
</get>
</domain>
</packet>
EOF;
sendCommand(print_response);
break;

case 'adddomain':
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<domain>
<add>
<gen_setup>
<name>$domain</name>
<client_id>1</client_id>
<ip_address>62.233.105.208</ip_address>
</gen_setup>
</add>
</domain>
</packet>
EOF;

sendCommand(print_response);
break;

case 'removedomain':
if ( $domain_id ) {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<domain>
<del>
<filter>
<id>$domain_id</id>
</filter>
</del>
</domain>
</packet>
EOF;
sendCommand(print_response);
} else {
echo "Error: domain $domain not found in the database<br>";
}
break;

case 'listrecords':
if ( $domain_id) {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<dns>
<get_rec>
<filter>
<domain_id>$domain_id</domain_id>
</filter>
</get_rec>
</dns>
</packet>
EOF;
} else {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<dns>
<get_rec>
</get_rec>
</dns>
</packet>
EOF;
}
sendCommand(print_response);
break;

case 'addrecord':
switch ( $type ) {
case 'A':
case 'CNAME':
case 'TXT':
case 'NS':
case 'MX':
if ( $opt) {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<dns>
<add_rec>
<domain_id>$domain_id</domain_id>
<type>$type</type>
<host>$host</host>
<value>$value</value>
<value>$value</value>
<opt>$opt</opt>
</add_rec>
</dns>
</packet>
EOF;
} else {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<dns>
<add_rec>
<domain_id>$domain_id</domain_id>
<type>$type</type>
<host>$host</host>
<value>$value</value>
</add_rec>
</dns>
</packet>
EOF;
}
sendCommand(print_response);
break;
default:
echo "Error: unknown record type $type<br>";
break;
}
break;

case 'removerecord':
//retrieve the record id
if ( $domain_id) {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<dns>
<get_rec>
<filter>
<domain_id>$domain_id</domain_id>
</filter>
</get_rec>
</dns>
</packet>
EOF;
} else {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<dns>
<get_rec>
</get_rec>
</dns>
</packet>
EOF;
}
sendCommand(get_recid);

//remove the record
if ( $record_id ) {
$data =<<<EOF
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<packet version="$proto">
<dns>
<del_rec>
<filter>
<id>$record_id</id>
</filter>
</del_rec>
</dns>
</packet>
EOF;
sendCommand(print_response);
} else {
echo "Error: the specified record not found in the database<br>";
}
break;

default:
echo "Error: unknown action $action<br>";
break;
}

//handles the response. This default handler simply prints the response.
function print_response($ch, $data)
{
echo $data;
return strlen($data);
}

//handles the response. This handler extracts the domain id that corresponds $domain
function get_domid($ch, $data)
{
global $domain;
global $domain_id;
$xml = new SimpleXMLElement($data);
foreach ($xml->xpath('/packet/domain/get/result') as $result) {
if ( $result->data->gen_info->name == "$domain" ) { $domain_id = $result->id; }
}
return strlen($data);
}

//handles the response. This handler extracts the record id that corresponds search conditions
function get_recid($ch, $data)
{
global $host;
global $type;
global $value;
global $opt;
global $record_id;
$xml = new SimpleXMLElement($data);
foreach ($xml->xpath('/packet/dns/get_rec/result') as $result) {
if ( $result->data->host != "$host" ) { continue; }
if ( $result->data->type != "$type" ) { continue; }
if ( $result->data->value != "$value" ) { continue; }
if ( $opt ) { if ( $result->data->opt != "$opt" ) { continue; } }
$record_id = $result->id;
}
return strlen($data);
}

//sends the request to plesk and call the response handler
function sendCommand($handler)
{
$url = "https://" . HOST . ":" . PORT . "/" . PATH;
$headers = array(
"HTTP_AUTH_LOGIN: " . LOGIN,
"HTTP_AUTH_PASSWD: " . PASSWD,
"HTTP_PRETTY_PRINT: TRUE",
"Content-Type: text/xml",
);

// Initalize the curl engine
$ch = curl_init();

// Set the curl options
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
// this line makes it work under https
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, &$headers);

// Set the URL to be processed
curl_setopt($ch, CURLOPT_URL, $url);

// Set the callback functions
curl_setopt($ch, CURLOPT_WRITEFUNCTION, $handler);

// Set the data to be send
global $data;
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

// Debug, however...
curl_setopt($ch, CURLOPT_VERBOSE, 1);

$result = curl_exec($ch);

if ($result == CURL_OK) {
#print_r(curl_getinfo($ch));
} else {
echo "\n\n-------------------------\n" .
"cURL error number:" .
curl_errno($ch);
echo "\n\ncURL error:" . curl_error($ch);
}

curl_close($ch);

return;
}
?>

No comments: