| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564 |
- <?php
- namespace MGModule\DNSManager2\mgLibs\custom\dns\submodules;
- use MGModule\DNSManager2\mgLibs\custom\dns;
- use MGModule\DNSManager2\mgLibs\custom\dns\exceptions\DNSSubmoduleException;
- use MGModule\DNSManager2\mgLibs\custom\dns\interfaces;
- use MGModule\DNSManager2\mgLibs\custom\dns\submodules\AWSRoute53 as AwsRouteHelpers;
- use MGModule\DNSManager2\mgLibs\custom\dns\submodules\AWSRoute53\AWSRoute53API;
- use MGModule\DNSManager2\mgLibs\custom\dns\submodules\AWSRoute53\AWSRoute53ResponseInterface;
- class AWSRoute53 extends dns\SubmoduleAbstract implements
- interfaces\SubmoduleRDNSInterface,
- interfaces\SubmoduleTTLInterface,
- interfaces\SubmoduleImportInterface,
- interfaces\SubmoduleRemoveDefaultRecords,
- interfaces\SubmoduleCustomParseEditZoneInput
- {
- public $configFields = [
- 'accessKeyId' => [
- 'friendlyName' => 'Access Key Id',
- 'validators' => [
- 'required' => 'required'
- ]
- ],
- 'secretAccessKey' => [
- 'friendlyName' => 'Secret Access Key',
- 'type' => 'password',
- 'validators' => [
- 'required' => 'required'
- ]
- ],
- 'region' => [
- 'friendlyName' => 'Region'
- ],
- 'delegation_set' => [
- 'friendlyName' => 'Delegation Set Id',
- 'validators' => [
- ]
- ],
- 'soa_edit' => [
- 'friendlyName' => 'Allow To Edit SOA Records',
- 'type' => 'yesno'
- ],
- 'delete_aws_ns' => [
- 'friendlyName' => 'Delete AWS NS Records After Zone Creation',
- 'type' => 'yesno'
- ],
- 'use_white_label_nameservers' => [
- 'friendlyName' => 'Using White Label Nameservers',
- 'type' => 'yesno',
- 'help' => 'Check this box if you are using White Label Nameservers'
- ],
- ];
- public $availableTypes = ['A', 'AAAA', 'ALIAS', 'CNAME', 'MX', 'NAPTR', 'NS', 'PTR', 'SOA', 'SPF', 'SRV', 'TXT'];
- /** @var AWSRoute53API */
- private $connection;
-
- public function testConnection()
- {
- if(!extension_loaded('SimpleXML'))
- {
- throw new DNSSubmoduleException('This server requires SimpleXML PHP extension', dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM);
- }
-
- $this->loadConnectionInstance();
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->testConnection();
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::CONNECTION_PROBLEM);
- }
-
- return true;
- }
- public function getNameServers( $index = false )
- {
- if($this->config['use_white_label_nameservers'] === 'on')
- {
- return (array)parent::getNameServers();
- }
- $this->loadConnectionInstance();
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->listZonesByName($this->domain);
- if( $zones->getResponseType() === 'error' )
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- $zone = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findZoneOnZoneList($zones->getParsedResponseBody(), $this->domain);
- if( !$zone )
- {
- throw new DNSSubmoduleException('Zone name is not valid!', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- $hostedZone = json_decode(json_encode($this->connection->getHostedZoneById($zone)->getParsedResponseBody()), true);
- return (array)$hostedZone['DelegationSet']['NameServers']['NameServer'];
- }
- public function getRecords($recordType = false)
- {
- $this->loadConnectionInstance();
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->listZonesByName($this->domain);
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $zone = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findZoneOnZoneList($zones->getParsedResponseBody(), $this->domain);
- if(!$zone)
- {
- throw new DNSSubmoduleException('Zone name is not valid!', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- /** @var AWSRoute53ResponseInterface $records */
- $records = $this->connection->listRecords($zone);
- if($records->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($records->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $availableTypes = $recordType ? [$recordType] : $this->availableTypes;
-
- return AwsRouteHelpers\AWSRoute53ResponseParseHelper::prepareRecordList($records->getParsedResponseBody(), $availableTypes, $this->config['soa_edit'] === 'on');
- }
-
- public function addRecord(dns\record\Record $record)
- {
- $this->loadConnectionInstance();
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->listZonesByName($this->domain);
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $zone = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findZoneOnZoneList($zones->getParsedResponseBody(), $this->domain);
- if(!$zone)
- {
- throw new DNSSubmoduleException('Zone name is not valid!', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- $aliasType = $this->gatAliasTypeIfRequired($record);
- if(!$aliasType)
- {
- $rSet = $this->matchSetForRecord($record);
- }
- if(isset($rSet) && $rSet)
- {
- AwsRouteHelpers\AWSRoute53ResponseParseHelper::mergeHostsRecordsForRdata($rSet, $record, $rSet->type);
- return $this->editRecord($rSet);
- }
- $record->name = $record->nameToAbsolute($this->domain);
- /** @var AWSRoute53ResponseInterface $aRecord */
- $aRecord = $this->connection->createRecord($zone, $record, $aliasType);
- if($aRecord->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($aRecord->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- return true;
- }
-
- public function editRecord(dns\record\Record $record)
- {
- $this->loadConnectionInstance();
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->listZonesByName($this->domain);
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $zone = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findZoneOnZoneList($zones->getParsedResponseBody(), $this->domain);
- if(!$zone)
- {
- throw new DNSSubmoduleException('Zone name is not valid!', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $aliasType = $this->gatAliasTypeIfRequired($record);
- /** @var AWSRoute53ResponseInterface $aRecord */
- $aRecord = $this->connection->updateRecord($zone, $record, $aliasType);
- if($aRecord->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($aRecord->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- return true;
- }
-
- public function deleteRecord(dns\record\Record $record)
- {
- $this->loadConnectionInstance();
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->listZonesByName($this->domain);
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $zone = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findZoneOnZoneList($zones->getParsedResponseBody(), $this->domain);
- if(!$zone)
- {
- throw new DNSSubmoduleException('Zone name is not valid!', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $aliasType = $this->gatAliasTypeIfRequired($record);
- if(!$aliasType)
- {
- $rSet = $this->matchSetForRecord($record);
- }
- if(isset($rSet) && $rSet)
- {
- return $this->editRecord($rSet);
- }
- /** @var AWSRoute53ResponseInterface $aRecord */
- $aRecord = $this->connection->deleteRecord($zone, $record, $aliasType);
- if($aRecord->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($aRecord->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- return true;
- }
-
- public function zoneExists()
- {
- $this->loadConnectionInstance();
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->listZonesByName($this->domain);
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $zone = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findZoneOnZoneList($zones->getParsedResponseBody(), $this->domain);
- return $zone ? true : false;
- }
-
- public function activateZone()
- {
- $this->loadConnectionInstance();
- $this->log('ACTIVATE ZONE');
- if($this->zoneExists())
- {
- throw new DNSSubmoduleException('Domain name already exists!', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- if(empty($this->domain))
- {
- throw new DNSSubmoduleException('Domain name is not valid!', dns\SubmoduleExceptionCodes::INVALID_PARAMETERS);
- }
- /** @var AWSRoute53ResponseInterface $zone */
- $zone = $this->connection->createZone($this->domain, $this->config['delegation_set']);
- if($zone->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zone->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- return true;
- }
-
- public function terminateZone()
- {
- $records = $this->getRecords();
- foreach($records as $record)
- {
- try
- {
- $this->deleteRecord($record);
- }
- catch(DNSSubmoduleException $exc)
- {
-
- }
- }
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->listZonesByName($this->domain);
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $zonesId = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findZoneOnZoneList($zones->getParsedResponseBody(), $this->domain);
- if($zonesId === false)
- {
- throw new DNSSubmoduleException('Zone name is not valid!', dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- /** @var AWSRoute53ResponseInterface $deleted */
- $deleted = $this->connection->deleteHostedZone($zonesId);
- if($deleted->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($deleted->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- return true;
- }
-
- public function getZones()
- {
- $this->loadConnectionInstance();
- $zones = $this->connection->listZones();
- /** @var AWSRoute53ResponseInterface $zones */
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- return AwsRouteHelpers\AWSRoute53ResponseParseHelper::zoneListXmlToArray($zones->getParsedResponseBody());
- }
-
- private function loadConnectionInstance()
- {
- if(!$this->connection)
- {
- $responseHandler = new AwsRouteHelpers\AWSRoute53Response();
- $requestHandler = new AwsRouteHelpers\AWSRoute53Request(
- $responseHandler,
- $this->config['accessKeyId'],
- $this->config['secretAccessKey'],
- $this->config['region']
- );
-
- $apiHandler = new AwsRouteHelpers\AWSRoute53API($requestHandler);
-
- $this->connection = $apiHandler;
- }
- }
-
- public function updateRDNS($ip, $ttl = false, $value = false)
- {
- $revDnsZoneName = dns\utils\ReverseDNSHelper::reverseZoneName($ip);
- $zoneId = $this->getRevDNSZoneID($revDnsZoneName);
-
- if(!$zoneId)
- {
- $zoneId = $this->createRevDnsZone($revDnsZoneName);
- }
-
- $revRecord = dns\utils\ReverseDNSHelper::createPTRRecord($ip, $ttl, $value);
- $revRecord->name .= '.'.$revDnsZoneName;
- /** @var AWSRoute53ResponseInterface $aRecord */
- $aRecord = $this->connection->updateRecord($zoneId, $revRecord);
- if($aRecord->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($aRecord->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- return true;
- }
- public function removeRDNS($ip)
- {
- $revDnsZoneName = dns\utils\ReverseDNSHelper::reverseZoneName($ip);
- $zoneId = $this->getRevDNSZoneID($revDnsZoneName);
- if(!$zoneId)
- {
- return true;
- }
- /** @var AWSRoute53ResponseInterface $records */
- $records = $this->connection->listRecords($zoneId);
- if($records->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($records->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- $recordPrev = dns\utils\ReverseDNSHelper::reverseRecordName($ip);
- $recordName = $recordPrev.'.'.$revDnsZoneName;
-
- $recordToRemove = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findPtrRecordByName($records->getParsedResponseBody(), $recordName);
- if(!$recordToRemove)
- {
- return true;
- }
- /** @var AWSRoute53ResponseInterface $aRecord */
- $aRecord = $this->connection->deleteRecord($zoneId, $recordToRemove);
- if($aRecord->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($aRecord->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- return true;
- }
- public function getRDNSRecord($ip)
- {
- $revDnsZoneName = dns\utils\ReverseDNSHelper::reverseZoneName($ip);
- $zoneId = $this->getRevDNSZoneID($revDnsZoneName);
-
- if(!$zoneId)
- {
- return [];
- }
- /** @var AWSRoute53ResponseInterface $records */
- $records = $this->connection->listRecords($zoneId);
- if($records->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($records->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- return AwsRouteHelpers\AWSRoute53ResponseParseHelper::prepareRecordList($records->getParsedResponseBody(), $this->availableTypes, $this->config['soa_edit'] === 'on');
- }
-
- private function getRevDNSZoneID($zoneName)
- {
- $this->loadConnectionInstance();
- /** @var AWSRoute53ResponseInterface $zones */
- $zones = $this->connection->listZonesByName($zoneName);
- if($zones->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zones->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
-
- $zone = AwsRouteHelpers\AWSRoute53ResponseParseHelper::findZoneOnZoneList($zones->getParsedResponseBody(), $zoneName);
-
- return $zone ? : false;
- }
-
- private function createRevDnsZone($revDnsZoneName)
- {
- /** @var AWSRoute53ResponseInterface $zone */
- $zone = $this->connection->createZone($revDnsZoneName);
- if($zone->getResponseType() === 'error')
- {
- throw new DNSSubmoduleException($zone->getResponseMessage(), dns\SubmoduleExceptionCodes::COMMAND_ERROR);
- }
- return AwsRouteHelpers\AWSRoute53ResponseParseHelper::getZoneIdFromCreateConfirmation($zone->getParsedResponseBody());
- }
-
- private function gatAliasTypeIfRequired($record)
- {
- if($record->type !== 'ALIAS')
- {
- return false;
- }
-
- $dNamePos = stripos($record->name, trim($this->domain, '.'));
- if(!$dNamePos && $dNamePos !== 0)
- {
- $record->name .= '.'.$this->domain;
- }
-
- $deafultType = 'A';
-
- $recordsList = $this->getRecords();
- foreach($recordsList as $rec)
- {
- $trimedName = trim($rec->name, '.');
- if(($rec->name === $record->rdata->target || $trimedName === $record->rdata->target ) && $rec->type === 'AAAA')
- {
- return 'AAAA';
- }
- }
-
- return $deafultType;
- }
-
- public function convertInputFormData(&$input)
- {
- AwsRouteHelpers\AWSRoute53ResponseParseHelper::convertInputFormData($input);
- }
- /**
- * @param dns\record\Record $record
- * @return bool|dns\record\Record
- * @throws DNSSubmoduleException
- */
- public function matchSetForRecord( dns\record\Record $record)
- {
- $cRecord = clone $record;
- $allowedTypes = ['MX', 'A', 'AAAA', 'NS'];
- if(!in_array($cRecord->type, $allowedTypes, true) )
- {
- return false;
- }
-
- $basicRdata = $cRecord->rdata->toString();
- $cRecord->createRDATAObject($cRecord->type);
- $cRecord->rdata = null;
- $recordList = $this->getRecords();
- foreach($recordList as $rec)
- {
- if($cRecord->type === $rec->type && trim($cRecord->name, '.') === trim($rec->name, '.'))
- {
- if($rec->rdata->toString() === $basicRdata)
- {
- continue;
- }
-
- AwsRouteHelpers\AWSRoute53ResponseParseHelper::mergeHostsRecordsForRdata($cRecord, $rec, $cRecord->type);
- }
- }
- return $cRecord->rdata !== null ? $cRecord : false;
- }
-
- public function removeDefaultServerRecords($defaultModuleRecords)
- {
- if($this->config['delete_aws_ns'] !== 'on')
- {
- return false;
- }
- $cRecords = $this->getRecords();
- foreach($cRecords as $cRecord)
- {
- if($cRecord->type !== 'NS')
- {
- continue;
- }
-
- $found = false;
- foreach($defaultModuleRecords as $dRecord)
- {
- if($this->areRecordsEqual($cRecord, $dRecord))
- {
- $found = true;
- break;
- }
- }
-
- if($found === false)
- {
- $this->deleteRecord($cRecord);
- }
- }
- return true;
- }
-
- private function areRecordsEqual( dns\record\Record $rec1, dns\record\Record $rec2)
- {
- $recAname = rtrim($rec1->name,'.');
- $recBname = rtrim($rec2->name,'.');
- return $recAname === $recBname &&
- $rec1->type === $rec2->type &&
- $rec1->ttl === $rec2->ttl &&
- $rec1->rdata->toString() === $rec2->rdata->toString();
- }
- }
|