[ 'friendlyName' => 'Username', 'validators' => [ 'required' => 'required', ] ], 'password' => [ 'friendlyName' => 'Password', 'type' => 'password', 'validators' => [ 'required' => 'required', ] ], 'hostname' => [ 'friendlyName' => 'Hostname', 'validators' => [ 'required' => 'required', ] ], 'port' => [ 'friendlyName' => 'Port', 'type' => 'number', ], 'template' => [ 'friendlyName' => 'Template', ], 'client_name' => [ 'friendlyName' => 'Client Name', ], 'ssl' => [ 'friendlyName' => 'SSL', 'type' => 'yesno', ], 'default_ip' => [ 'friendlyName' => 'Default IP', 'validators' => [ 'required' => 'required', 'pattern' => Patterns::IP4_OR_IP6, ] ], 'override_wsdl_url' => [ 'friendlyName' => 'Override WSDL URL', 'type' => 'yesno' ] ]; public $availableTypes = ['A', 'AAAA', 'NS', 'MX', 'CNAME', 'TXT', 'SRV']; //'A', 'AAAA', 'NS', 'MX', 'CNAME', 'TXT', 'PTR', 'SRV', 'NAPTR' private function get($function, $params = null, $retback = false, $locationType = DNSZONE_TYPE) { $soap = $this->loadSoap(); if (!$soap) { throw new exceptions\DNSSubmoduleException("SOAP Error: Cannot load soap class", dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM); } try { //Optimization if( $this->config['override_wsdl_url'] === 'on' ) { throw new \Exception('Skipping WSDL URL'); } $result = $soap->$function($params); } catch( \Exception $exception ) //try with location changing { $soap = $this->loadSoap(); $soap->__setLocation("http://{$this->config['hostname']}/soap/{$locationType}_agent.php"); // it is const $result = $soap->$function($params); } if ($retback && isset($result->$retback)) { return true; } if (is_a($result, 'SoapFault')) { throw new exceptions\DNSSubmoduleException($result->getMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR); } elseif (isset($result->notice->message)) { throw new exceptions\DNSSubmoduleException($result->notice->message, dns\SubmoduleExceptionCodes::COMMAND_ERROR); } else { if ($retback) { throw new exceptions\DNSSubmoduleException('Unexpected Error', dns\SubmoduleExceptionCodes::COMMAND_ERROR); } return $result; } } private function loadSoap() { /* the class that prepares the soapClient */ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'dns4psa' . DIRECTORY_SEPARATOR . 'misc.php'); $files_location = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'dns4psa' . DIRECTORY_SEPARATOR; $dnsmanager_version = '1.5'; $context = stream_context_create([ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => false ] ]); try { $client_class = new SoapClient4psa($files_location, ['trace' => 1, 'exceptions' => 1, 'connection_timeout' => 120, 'cache_wsdl' => WSDL_CACHE_NONE, 'stream_context' => $context], $this->config['hostname'], $this->config['port'] == '' ? 80 : $this->config['port'], $this->config['ssl'] == '1' ? 1 : 0, $dnsmanager_version); } catch (\Throwable $exception) { throw new exceptions\DNSSubmoduleException($exception->getMessage(), dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM); } if ($client_class->error != '') { throw new exceptions\DNSSubmoduleException($client_class->error, dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM); } $client = $client_class->getSoapClient(); $auth = new stdClass(); $auth->username = $this->config['username']; $auth->password = $this->config['password']; $authvalues = new SoapVar($auth, SOAP_ENC_OBJECT, 'http://4psa.com/HeaderData/' . $dnsmanager_version); $header = new SoapHeader('http://4psa.com/HeaderData/' . $dnsmanager_version, 'userCredentials', $authvalues, false); $client->__setSoapHeaders([$header]); return $client; } public function testConnection() { $ret = $this->get('GetDNSZone', '', 'DNSZone'); } public function zoneExists() { try { $dns_zone = new stdClass(); $dns_zone->DNSZoneName = $this->domain; $this->get('GetDNSZone', $dns_zone, 'DNSZone'); } catch (exceptions\DNSSubmoduleException $e) { if ($e->getCode() == dns\SubmoduleExceptionCodes::COMMAND_ERROR) { return false; } throw $e; } return true; } public function getRecords($recordType = false) { $dns_zone = new stdClass(); $dns_zone->DNSZoneName = $this->domain; try { $ret = $this->get('GetDNSRecord', $dns_zone); } catch (exceptions\DNSSubmoduleException $e) { if ($e->getMessage() != 'No DNS record has been found.') { throw $e; } } $out = []; if (!is_array($ret->DNSRecord)) { $ret->DNSRecord = [$ret->DNSRecord]; } foreach ($ret->DNSRecord as $r) { if (in_array((string)$r->type, $recordType !== false ? [strtoupper($recordType)] : $this->getAvailableRecordTypes())) { $record = new dns\record\Record(); $record->line = (string)$r->DNSRecordId; $record->name = (string)$r->host; $record->type = (string)$r->type; //$record->ttl = (string)$r->TTL; $record->createRDATAObject(); switch ((string)$r->type) { case 'MX': $record->rdata->preference = (string)$r->opt; $record->rdata->exchange = (string)$r->value; break; case 'NAPTR': $record->rdata->setDataFromArray((array)$r); $record->rdata->regexp = (string)$r->regex; $record->rdata->flags = (string)$r->flag; $record->rdata->replacement = (string)$r->replace; break; case 'SRV': //fucking 4PSA! it require new request to fetch details data $data = new \stdClass(); $data->DNSRecordId = $r->DNSRecordId; $fullRecord = $this->get('GetDNSRecord', $data)->DNSRecord; $record->name = "{$fullRecord->service}.{$fullRecord->protocol}.{$fullRecord->host}"; $record->rdata->setDataFromArray((array)$fullRecord); break; default: $record->rdata->setFirstProperty((string)$r->value); break; } $out[] = $record; } } return $out; } private function recordToParamsArray(dns\record\Record $record) { $dns_zone = new stdClass(); $dns_zone->DNSZoneName = $this->domain; $dns_zone->host = $record->nameToAbsolute($this->domain); $dns_zone->type = $record->type; switch ($record->type) { case 'MX': $dns_zone->opt = $record->rdata->preference; $dns_zone->value = $record->rdata->exchange; break; case 'NAPTR': $dns_zone->order = $record->rdata->order; $dns_zone->preference = $record->rdata->preference; $dns_zone->flag = $record->rdata->flags; $dns_zone->replace = $record->rdata->replacement; $dns_zone->regex = $record->rdata->regexp; $dns_zone->services = $record->rdata->services; break; case 'SRV': $exploded = explode('.', $record->name, 3); list($service, $protocol, $name) = $exploded; $dns_zone->service = $service; $dns_zone->protocol = $protocol; $record->name = $name; $dns_zone->host = $record->nameToAbsolute($this->domain); $dns_zone->priority = $record->rdata->priority; $dns_zone->weight = $record->rdata->weight; $dns_zone->port = $record->rdata->port; $dns_zone->target = $record->rdata->target; break; case 'TXT': $dns_zone->value = trim($record->rdata->toString(), '"'); break; default: $dns_zone->value = $record->rdata->toString(); break; } return $dns_zone; } public function addRecord(dns\record\Record $record) { $dns_zone = $this->recordToParamsArray($record); $this->get('AddDNSRecord', $dns_zone); } public function editRecord(dns\record\Record $record) { $dns_zone = $this->recordToParamsArray($record); $dns_zone->DNSRecordId = $record->line; $this->get('EditDNSRecord', $dns_zone); } public function deleteRecord(dns\record\Record $record) { $dns_zone = $this->recordToParamsArray($record); $dns_zone->DNSRecordId = $record->line; $dns_zone = $this->prepareForDeleteOrEdit($dns_zone); $dns_zone_for_del = new stdClass(); $dns_zone_for_del->DNSRecord = $dns_zone; $this->get('DelDNSRecord', $dns_zone_for_del); } public function prepareForDeleteOrEdit($dns_zone) { switch ($dns_zone->type) { case 'SRV': $dns_zone->host = "_{$dns_zone->service}._{$dns_zone->protocol}.{$dns_zone->host}"; $dns_zone->value = $dns_zone->target; break; } return $dns_zone; } public function activateZone() { if ($this->ip != '') { if (!filter_var($this->ip, FILTER_VALIDATE_IP)) { throw new exceptions\DNSSubmoduleException('IP is not valid!', dns\SubmoduleExceptionCodes::INVALID_PARAMETERS); } } else { $this->ip = $this->config['default_ip']; } $clients = $this->get('GetClient', null, false, CLIENT_TYPE); $dns_zone = new stdClass(); $dns_zone->name = $this->domain; if ($this->config['template']) { $dns_zone->templateIP = $this->ip; $dns_zone->templateId = $this->config['template']; } // get client if (!empty($this->config['client_name'])) { if (is_array($clients->client)) { foreach ($clients->client as $client) { if ($client->name === $this->config['client_name']) { $dns_zone->clientId = $client->clientId; break; } } } else { if (!empty($clients->client->clientId) && $clients->client->name === $this->config['client_name']) { $dns_zone->clientId = $clients->client->clientId; } } } $this->get('AddDNSZone', $dns_zone); } public function terminateZone() { $dns_zone = new stdClass(); $dns_zone->DNSZoneName = $this->domain; $this->get('DelDNSZone', $dns_zone); } public function getZones() { $ret = $this->get('GetDNSZone', new stdClass()); if (!is_array($ret->DNSZone)) { $ret->DNSZone = [$ret->DNSZone]; } $out = []; foreach ($ret->DNSZone as $zone) { $zone->name = trim($zone->name, '.'); $out[(string)$zone->name] = isset($zone->templateIP) ? (string)$zone->templateIP : ''; } return $out; } }