array(
'friendlyName' => 'Host',
'validators' => array(
'required' => 'required',
)
),
'username' => array(
'friendlyName' => 'Username',
'validators' => array(
'required' => 'required',
)
),
'password' => array(
'friendlyName' => 'Password',
'type'=> 'password',
'validators' => array(
'required' => 'required',
)
),
'substriction_domain' => array(
'friendlyName' => 'Subscription Domain',
'validators' => array(
'required' => 'required',
)
),
'default_ip' => array(
'friendlyName' => 'Default IP',
'validators' => array(
'pattern' => Patterns::IP4_OR_IP6,
)
),
);
public $availableTypes = array('A', 'AAAA', 'NS', 'MX', 'CNAME', 'TXT', 'SRV', 'PTR');
private $webspace_id = null;
private function get($packet) {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, "https://{$this->config['host']}:8443/enterprise/control/agent.php");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $packet);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"HTTP_AUTH_LOGIN: {$this->config['username']}",
"HTTP_AUTH_PASSWD: {$this->config['password']}",
"HTTP_PRETTY_PRINT: TRUE",
"Content-Type: text/xml")
);
$retval = curl_exec($curl);
if (curl_errno($curl)) {
throw new exceptions\DNSSubmoduleException("cURL Error: " . curl_errno($curl) . " - " . curl_error($curl), dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM);
}
curl_close($curl);
@$result = simplexml_load_string($retval);
if($result===FALSE) {
throw new exceptions\DNSSubmoduleException('Unable to parse response', dns\SubmoduleExceptionCodes::INVALID_RESPONSE);
}
if($result->system->status == 'error') {
throw new exceptions\DNSSubmoduleException((string)$result->system->errtext, dns\SubmoduleExceptionCodes::COMMAND_ERROR);
}
return $result;
}
public function testConnection(){
$this->webspace_id= $this->getWebspaceID();
$ok = $this->webspace_id !== false && $this->webspace_id > 0;
return true;
}
private function getWebspaceID(){
if(empty($this->config['substriction_domain'])){
throw new exceptions\DNSSubmoduleException('Invalid substriction domain in configuration', dns\SubmoduleExceptionCodes::INVALID_PARAMETERS);
}
$packet = '
'.$this->config['substriction_domain'].'
';
$return = $this->get($packet);
if(isset($return->webspace->get->result->id)){
return (string)$return->webspace->get->result->id;
}else{
if($return->webspace->get->result->errcode == 1013){
throw new exceptions\DNSSubmoduleException('Substriction domain does not exist', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
}
$this->throwError($return->webspace->get->result);
}
}
private function throwError($result) {
if($result->status == 'error') {
throw new exceptions\DNSSubmoduleException((string)$result->errtext, dns\SubmoduleExceptionCodes::COMMAND_ERROR);
} else if (strpos($result, 'Please') !== false) {
throw new exceptions\DNSSubmoduleException($result, dns\SubmoduleExceptionCodes::COMMAND_ERROR);
} else {
throw new exceptions\DNSSubmoduleException('Unexpected error', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
}
}
private function getDomainInfo(){
$packet = '
'.$this->domain.'
';
$return = $this->get($packet);
if(isset($return->site->get->result->result->id)){
return (int)$return->site->get->result->result->id;
}elseif($return->site->get->result->status == 'ok'){
return (int)$return->site->get->result->id;
}else{
$this->throwError($return->site->get->result);
}
}
public function getRecords($recordType = false) {
$domain_id = $this->getDomainInfo();
if($domain_id === false || $domain_id <= 0)
return false;
$packet = '
'.$domain_id.'
';
$return = $this->get($packet);
$out = array();
if((string)$return->dns->get_rec->result->status == 'ok'){
foreach($return->dns->get_rec->result as $record_data){
$type = strtoupper((string)$record_data->data->type);
if(in_array($type, $recordType!==false ? array(strtoupper($recordType)) : $this->getAvailableRecordTypes())) {
$record = new dns\record\Record();
$record->line = (string)$record_data->id;
$record->name = (string)$record_data->data->host;
$record->type = $type;
$record->createRDATAObject($type);
switch($type) {
case 'MX':
$record->rdata->preference = (string)$record_data->data->opt;
$record->rdata->exchange = (string)$record_data->data->value;
break;
case 'SRV':
$record->rdata->fromString((string)$record_data->data->opt . ' ' . (string)$record_data->data->value);
break;
case 'PTR':
if($record_data->data->opt)
$record->name .= "/" . $record_data->data->opt;
$record->rdata->setFirstProperty((string)$record_data->data->value);
break;
default:
$record->rdata->setFirstProperty((string)$record_data->data->value);
break;
}
$out[] = $record;
}
}
} else {
$this->throwError($return->dns->get_rec->result);
}
return $out;
}
public function addRecord(dns\record\Record $record) {
$domain_id = $this->getDomainInfo();
if($domain_id === false || $domain_id <= 0)
return false;
switch($record->type) {
case 'MX':
$value = $record->rdata->exchange;
$opt = $record->rdata->preference;
break;
case 'SRV':
$value = $record->rdata->target;
$opt = str_replace("\t", ' ', $record->rdata->toString(['priority','weight','port']));
break;
case 'TXT':
$value = trim($record->rdata->toString(), '"');
$opt = '';
break;
default:
$value = $record->rdata->toString();
$opt = '';
break;
}
if($record->type === 'PTR') {
$host = str_replace('@', '', $record->nameToRelative($this->domain));
$opt = explode('/',$host)[1];
if(!($opt == '8' || $opt =='16' || $opt =='24'))
$this->throwError('Please specify the subnet mask for the IP. Right now Plesk supports only the 8, 16 and 24 masks.');
$host = explode('/',$host)[0];
$packet = '
' . $domain_id . '
' . $record->type . '
' . $host . '
' . $value . '
' . (!empty($opt) ? "$opt" : '') . '
';
}
else
{
$packet = '
' . $domain_id . '
' . $record->type . '
' . str_replace('@', '', $record->nameToRelative($this->domain)) . '
' . $value . '
' . (!empty($opt) ? "$opt" : '') . '
';
}
$return = $this->get($packet);
if((string)$return->dns->add_rec->result->status === 'ok'){
return true;
}
$this->throwError($return->dns->add_rec->result);
}
public function editRecord(dns\record\Record $record) {
$this->deleteRecord($record);
$record->nameToAbsolute($this->domain);
$this->addRecord($record);
}
public function deleteRecord(dns\record\Record $record) {
$packet = '
'.$record->line.'
';
$return = $this->get($packet);
if((string)$return->dns->del_rec->result->status == 'ok'){
return true;
}
$this->throwError($return->dns->del_rec->result);
}
public function zoneExists() {
try {
$domain_id = $this->getDomainInfo();
} catch (exceptions\DNSSubmoduleException $e) {
if($e->getCode() == dns\SubmoduleExceptionCodes::COMMAND_ERROR) {
return false;
}
throw $e;
}
return $domain_id !== false && $domain_id > 0;
}
public function activateZone() {
if(empty($this->webspace_id)){
$this->webspace_id = $this->getWebspaceID();
}
if(empty($this->webspace_id)){
return false; //TODO: error?
}
$packet = '
'.$this->domain.'
'.$this->webspace_id.'
';
$return = $this->get($packet);
if((string)$return->site->add->result->status == 'ok'){
return true;
}
$this->throwError($return->site->add->result);
}
public function terminateZone() {
if($this->domain == $this->config['substriction_domain']){
throw new exceptions\DNSSubmoduleException('You cannot delete subscription domain', dns\SubmoduleExceptionCodes::INVALID_PARAMETERS);
}
if(empty($this->webspace_id)){
$this->webspace_id = $this->getWebspaceID();
}
if(empty($this->webspace_id)){
return false;
}
$packet = '
'.$this->domain.'
';
$return = $this->get($packet);
if((string)$return->site->del->result->status == 'ok'){
return true;
}
$this->throwError($return->site->del->result);
}
public function getZones() {
$packet = '
';
$return = $this->get($packet);
$out = array();
if((string)$return->webspace->get->result->status == 'ok'){
foreach($return->webspace->get->result as $info) {
$out[(string)$info->data->gen_info->name] = (string)$info->data->gen_info->dns_ip_address;
}
}
return $out;
}
}