array ( 'friendlyName' => 'Username', 'validators' => array( 'required' => 'required', ) ), 'password' =>array ( 'friendlyName' => 'User Password', 'type'=> 'password', ), 'resellerAccount' =>array ( 'friendlyName' => 'Reseller Account', 'type'=> 'yesno', ), 'apiURL' =>array ( 'friendlyName' => 'API URL', ), 'default_ip' =>array ( 'friendlyName' => 'Default IP', 'validators' => array( 'required' => 'required', 'pattern' => Patterns::IP4_OR_IP6, ) ), 'debug' =>array ( 'friendlyName' => 'Debugging', 'type'=> 'yesno', ), ); public $availableTypes = array('A', 'AAAA', 'CAA', 'CNAME', 'MX', 'NS', 'SOA', 'SPF', 'SRV', 'TXT'); public function testConnection() { $this->executeCommand('searchZoneDnsRequest', array('limit' => 1)); return true; } public function getRecords($recordType = false) { $result = $this->executeCommand('retrieveZoneDnsRequest', array( 'name' => $this->domain, 'withRecords' => 1, )); foreach($result->value['records'] as $r) { /* Adding dot for proper domain parsing */ $r['name'] = $r['name'].'.'; if(in_array((string)$r['type'], $recordType!==false ? array(strtoupper($recordType)) : $this->getAvailableRecordTypes())) { $recordAdapter = '\MGModule\DNSManager2\mgLibs\custom\dns\submodules\OpenProvider\Adapters\\'.$r['type'].'Adapter'; if (class_exists($recordAdapter)) { $return[] = $recordAdapter::toDnsManagerRecord($r); } else { $return[] = dns\record\Record::tryToCreateFromArray((array)$r); } } } foreach($return as $key => $record){ $record->line = sha1(json_encode($record)); } return $return; } public function addRecord(dns\record\Record $record) { $recordsData = $this->unsetDefaultRecords($this->getRecords()); $adapterClassName = '\MGModule\DNSManager2\mgLibs\custom\dns\submodules\OpenProvider\Adapters\\'.$record->type.'Adapter'; if (class_exists($adapterClassName)) { /** @var dns\record\Record $record */ $record = new $adapterClassName($record); } $recordsData[] = $record; $recordsToQuery = $this->groupRecords($recordsData); $domain = explode(".", $this->domain, 2); $this->executeCommand('modifyZoneDnsRequest', array('domain' => array( 'name' => $domain[0], 'extension' => $domain[1]), 'records' => $recordsToQuery, ) ); } public function editRecord(dns\record\Record $record) { $recordsData = $this->unsetDefaultRecords($this->getRecords()); if (empty($recordsData)) return false; $adapterClassName = '\MGModule\DNSManager2\mgLibs\custom\dns\submodules\OpenProvider\Adapters\\'.$record->type.'Adapter'; if (class_exists($adapterClassName)) { /** @var dns\record\Record $record */ $record = new $adapterClassName($record); } foreach ($recordsData as $key => $recordData) { if ($recordData->line == $record->line) { $recordsData[$key] = $record; } } $recordsToQuery = $this->groupRecords($recordsData); $domain = explode(".", $this->domain, 2); $this->executeCommand('modifyZoneDnsRequest', array('domain' => array( 'name' => $domain[0], 'extension' => $domain[1]), 'records' => $recordsToQuery, ) ); } public function deleteRecord(dns\record\Record $record) { $recordsData = $this->unsetDefaultRecords($this->getRecords()); if (empty($recordsData)) return false; foreach ($recordsData as $key => $recordData) { if ($recordData->line == $record->line) { unset($recordsData[$key]); } } $recordsToQuery = $this->groupRecords($recordsData); if(empty($recordsToQuery)) { return $this->reCreateZone(); } $domain = explode(".", $this->domain, 2); $this->executeCommand('modifyZoneDnsRequest', array('domain' => array( 'name' => $domain[0], 'extension' => $domain[1]), 'records' => $recordsToQuery, ) ); } public function zoneExists() { $result = $this->executeCommand('searchZoneDnsRequest', array('namePattern' => '%'.$this->domain.'%')); if($result->value['total'] > 0) return true; else return false; } public function activateZone() { $domain = explode(".", $this->domain, 2); $this->executeCommand('createZoneDnsRequest', array('domain' => array( 'name' => $domain[0], 'extension' => $domain[1], ), 'type' => 'master', ) ); } public function terminateZone() { $domain = explode(".", $this->domain, 2); $this->executeCommand('deleteZoneDnsRequest', array('domain' => array( 'name' => $domain[0], 'extension' => $domain[1], )) ); } public function getZones() { $out = []; $result = $this->executeCommand('searchZoneDnsRequest', ['namePattern' => '%']); foreach( $result->getValue()['results'] as $zone ) { $out[$zone['name']] = ''; } return $out; } private function groupRecords(array $recordsData) { $recordsToQuery = array(); foreach($recordsData as $rdata) { /* Trimming last added dot for proper API usage */ $rdata->name = rtrim($rdata->name, '.'); /* For Root Records for proper API usage */ if($rdata->name == $this->domain) { $rdata->name = ''; } if($rdata->type == 'CAA') { $rdata->rdata->target = $this->addQuotes($rdata->rdata->target); } $rdataStringProperties = $this->parseOPDataToPrevious($rdata->rdata); $prio = null; if(isset($rdata->rdata->priority)) { array_push($recordsToQuery, array('type' => $rdata->type, 'name' => str_replace('.'.$this->domain, '', $rdata->name), 'value' => $rdataStringProperties, 'ttl' => intval($rdata->ttl), 'prio' => intval($rdata->rdata->priority))); } elseif(isset($rdata->rdata->preference)) { array_push($recordsToQuery, array('type' => $rdata->type, 'name' => str_replace('.'.$this->domain, '', $rdata->name), 'value' => $rdataStringProperties, 'ttl' => intval($rdata->ttl), 'prio' => intval($rdata->rdata->preference))); } else { array_push($recordsToQuery, array('type' => $rdata->type, 'name' => str_replace('.'.$this->domain, '', $rdata->name), 'value' => $rdataStringProperties, 'ttl' => intval($rdata->ttl))); } } return $recordsToQuery; } private function parseOPDataToPrevious( $opData) { $rdataStringProperties = ''; foreach($opData as $key => $rdata) { if(!in_array($key, ['preference', 'priority'])) { $rdataStringProperties .= $rdata . ' '; } } $rdataStringProperties = rtrim($rdataStringProperties); return $rdataStringProperties; } private function reCreateZone() { $this->terminateZone(); $this->activateZone(); } private function executeCommand( $command, array $args){ $api = new OPApi ($this->config['apiURL']); $request = new OPRequest(); $request->setCommand($command) ->setAuth(array('username' => $this->config['username'], 'password' => $this->config['password'])) ->setArgs($args); if ($this->config['debug'] == 'on') { $result = $api->setDebug(1)->process($request); if ($result->getFaultCode() != 0) throw new exceptions\DNSSubmoduleException($result->getFaultString()); return $result; } else { $result = $api->process($request); if ($result->getFaultCode() != 0) throw new exceptions\DNSSubmoduleException($result->getFaultString()); return $result; } } private function addQuotes( $recordTarget) { return '"'.$recordTarget.'"'; } /** * Unsetting default records - they are unmodifiable * @param array $records * @return array */ private function unsetDefaultRecords(array $records) { $recordsCollection = collect($records); /* Getting default SOA Record array key */ $soaRecord = $recordsCollection ->where('type', 'SOA') ->where('name', $this->domain.'.') ->where('rdata.rname', 'dns.openprovider.eu'); if(count($soaRecord) < 0) { throw new exceptions\DNSSubmoduleException('Default SOA Record Error'); } $soaRecordKey[] = $soaRecord->keys()->first(); /* Getting default NS Records array keys */ $nsRecords = $recordsCollection ->where('type', 'NS') ->where('name', $this->domain.'.') ->whereIn('rdata.nsdname', ['ns1.openprovider.nl', 'ns2.openprovider.be', 'ns3.openprovider.eu']); if(count($nsRecords) < 0) { throw new exceptions\DNSSubmoduleException('Default NS Records Error'); } $nsRecordsKeys = $nsRecords->keys()->toArray(); $defaultRecordsKeys = array_merge_recursive($soaRecordKey, $nsRecordsKeys); foreach($defaultRecordsKeys as $key) { unset($records[$key]); } return $records; } }