OpenProvider.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. <?php
  2. namespace MGModule\DNSManager2\mgLibs\custom\dns\submodules;
  3. use \MGModule\DNSManager2\mgLibs\custom\dns;
  4. use \MGModule\DNSManager2\mgLibs\custom\dns\exceptions;
  5. use \MGModule\DNSManager2\mgLibs\custom\dns\submodules\OpenProvider\OPRequest;
  6. use \MGModule\DNSManager2\mgLibs\custom\dns\submodules\OpenProvider\OPApi;
  7. use \MGModule\DNSManager2\mgLibs\custom\dns\interfaces;
  8. use MGModule\DNSManager2\mgLibs\custom\dns\utils\Patterns;
  9. class OpenProvider extends dns\SubmoduleAbstract implements
  10. interfaces\SubmoduleTTLInterface,
  11. interfaces\SubmoduleImportInterface
  12. {
  13. public $configFields = array(
  14. 'username' =>array (
  15. 'friendlyName' => 'Username',
  16. 'validators' => array(
  17. 'required' => 'required',
  18. )
  19. ),
  20. 'password' =>array (
  21. 'friendlyName' => 'User Password',
  22. 'type'=> 'password',
  23. ),
  24. 'resellerAccount' =>array (
  25. 'friendlyName' => 'Reseller Account',
  26. 'type'=> 'yesno',
  27. ),
  28. 'apiURL' =>array (
  29. 'friendlyName' => 'API URL',
  30. ),
  31. 'default_ip' =>array (
  32. 'friendlyName' => 'Default IP',
  33. 'validators' => array(
  34. 'required' => 'required',
  35. 'pattern' => Patterns::IP4_OR_IP6,
  36. )
  37. ),
  38. 'debug' =>array (
  39. 'friendlyName' => 'Debugging',
  40. 'type'=> 'yesno',
  41. ),
  42. );
  43. public $availableTypes = array('A', 'AAAA', 'CAA', 'CNAME', 'MX', 'NS', 'SOA', 'SPF', 'SRV', 'TXT');
  44. public function testConnection()
  45. {
  46. $this->executeCommand('searchZoneDnsRequest', array('limit' => 1));
  47. return true;
  48. }
  49. public function getRecords($recordType = false)
  50. {
  51. $result = $this->executeCommand('retrieveZoneDnsRequest',
  52. array(
  53. 'name' => $this->domain,
  54. 'withRecords' => 1,
  55. ));
  56. foreach($result->value['records'] as $r) {
  57. /* Adding dot for proper domain parsing */
  58. $r['name'] = $r['name'].'.';
  59. if(in_array((string)$r['type'], $recordType!==false ? array(strtoupper($recordType)) : $this->getAvailableRecordTypes())) {
  60. $recordAdapter = '\MGModule\DNSManager2\mgLibs\custom\dns\submodules\OpenProvider\Adapters\\'.$r['type'].'Adapter';
  61. if (class_exists($recordAdapter))
  62. {
  63. $return[] = $recordAdapter::toDnsManagerRecord($r);
  64. } else {
  65. $return[] = dns\record\Record::tryToCreateFromArray((array)$r);
  66. }
  67. }
  68. }
  69. foreach($return as $key => $record){
  70. $record->line = sha1(json_encode($record));
  71. }
  72. return $return;
  73. }
  74. public function addRecord(dns\record\Record $record)
  75. {
  76. $recordsData = $this->unsetDefaultRecords($this->getRecords());
  77. $adapterClassName = '\MGModule\DNSManager2\mgLibs\custom\dns\submodules\OpenProvider\Adapters\\'.$record->type.'Adapter';
  78. if (class_exists($adapterClassName))
  79. {
  80. /** @var dns\record\Record $record */
  81. $record = new $adapterClassName($record);
  82. }
  83. $recordsData[] = $record;
  84. $recordsToQuery = $this->groupRecords($recordsData);
  85. $domain = explode(".", $this->domain, 2);
  86. $this->executeCommand('modifyZoneDnsRequest',
  87. array('domain' => array(
  88. 'name' => $domain[0],
  89. 'extension' => $domain[1]),
  90. 'records' => $recordsToQuery,
  91. )
  92. );
  93. }
  94. public function editRecord(dns\record\Record $record)
  95. {
  96. $recordsData = $this->unsetDefaultRecords($this->getRecords());
  97. if (empty($recordsData))
  98. return false;
  99. $adapterClassName = '\MGModule\DNSManager2\mgLibs\custom\dns\submodules\OpenProvider\Adapters\\'.$record->type.'Adapter';
  100. if (class_exists($adapterClassName))
  101. {
  102. /** @var dns\record\Record $record */
  103. $record = new $adapterClassName($record);
  104. }
  105. foreach ($recordsData as $key => $recordData) {
  106. if ($recordData->line == $record->line) {
  107. $recordsData[$key] = $record;
  108. }
  109. }
  110. $recordsToQuery = $this->groupRecords($recordsData);
  111. $domain = explode(".", $this->domain, 2);
  112. $this->executeCommand('modifyZoneDnsRequest',
  113. array('domain' => array(
  114. 'name' => $domain[0],
  115. 'extension' => $domain[1]),
  116. 'records' => $recordsToQuery,
  117. )
  118. );
  119. }
  120. public function deleteRecord(dns\record\Record $record)
  121. {
  122. $recordsData = $this->unsetDefaultRecords($this->getRecords());
  123. if (empty($recordsData))
  124. return false;
  125. foreach ($recordsData as $key => $recordData) {
  126. if ($recordData->line == $record->line) {
  127. unset($recordsData[$key]);
  128. }
  129. }
  130. $recordsToQuery = $this->groupRecords($recordsData);
  131. if(empty($recordsToQuery))
  132. {
  133. return $this->reCreateZone();
  134. }
  135. $domain = explode(".", $this->domain, 2);
  136. $this->executeCommand('modifyZoneDnsRequest',
  137. array('domain' => array(
  138. 'name' => $domain[0],
  139. 'extension' => $domain[1]),
  140. 'records' => $recordsToQuery,
  141. )
  142. );
  143. }
  144. public function zoneExists()
  145. {
  146. $result = $this->executeCommand('searchZoneDnsRequest', array('namePattern' => '%'.$this->domain.'%'));
  147. if($result->value['total'] > 0)
  148. return true;
  149. else
  150. return false;
  151. }
  152. public function activateZone()
  153. {
  154. $domain = explode(".", $this->domain, 2);
  155. $this->executeCommand('createZoneDnsRequest',
  156. array('domain' => array(
  157. 'name' => $domain[0],
  158. 'extension' => $domain[1],
  159. ),
  160. 'type' => 'master',
  161. )
  162. );
  163. }
  164. public function terminateZone()
  165. {
  166. $domain = explode(".", $this->domain, 2);
  167. $this->executeCommand('deleteZoneDnsRequest',
  168. array('domain' => array(
  169. 'name' => $domain[0],
  170. 'extension' => $domain[1],
  171. ))
  172. );
  173. }
  174. public function getZones()
  175. {
  176. $out = [];
  177. $result = $this->executeCommand('searchZoneDnsRequest', ['namePattern' => '%']);
  178. foreach( $result->getValue()['results'] as $zone )
  179. {
  180. $out[$zone['name']] = '';
  181. }
  182. return $out;
  183. }
  184. private function groupRecords(array $recordsData)
  185. {
  186. $recordsToQuery = array();
  187. foreach($recordsData as $rdata) {
  188. /* Trimming last added dot for proper API usage */
  189. $rdata->name = rtrim($rdata->name, '.');
  190. /* For Root Records for proper API usage */
  191. if($rdata->name == $this->domain)
  192. {
  193. $rdata->name = '';
  194. }
  195. if($rdata->type == 'CAA')
  196. {
  197. $rdata->rdata->target = $this->addQuotes($rdata->rdata->target);
  198. }
  199. $rdataStringProperties = $this->parseOPDataToPrevious($rdata->rdata);
  200. $prio = null;
  201. if(isset($rdata->rdata->priority))
  202. {
  203. 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)));
  204. } elseif(isset($rdata->rdata->preference))
  205. {
  206. 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)));
  207. } else
  208. {
  209. array_push($recordsToQuery, array('type' => $rdata->type, 'name' => str_replace('.'.$this->domain, '', $rdata->name), 'value' => $rdataStringProperties, 'ttl' => intval($rdata->ttl)));
  210. }
  211. }
  212. return $recordsToQuery;
  213. }
  214. private function parseOPDataToPrevious( $opData)
  215. {
  216. $rdataStringProperties = '';
  217. foreach($opData as $key => $rdata)
  218. {
  219. if(!in_array($key, ['preference', 'priority']))
  220. {
  221. $rdataStringProperties .= $rdata . ' ';
  222. }
  223. }
  224. $rdataStringProperties = rtrim($rdataStringProperties);
  225. return $rdataStringProperties;
  226. }
  227. private function reCreateZone()
  228. {
  229. $this->terminateZone();
  230. $this->activateZone();
  231. }
  232. private function executeCommand( $command, array $args){
  233. $api = new OPApi ($this->config['apiURL']);
  234. $request = new OPRequest();
  235. $request->setCommand($command)
  236. ->setAuth(array('username' => $this->config['username'], 'password' => $this->config['password']))
  237. ->setArgs($args);
  238. if ($this->config['debug'] == 'on') {
  239. $result = $api->setDebug(1)->process($request);
  240. if ($result->getFaultCode() != 0)
  241. throw new exceptions\DNSSubmoduleException($result->getFaultString());
  242. return $result;
  243. } else {
  244. $result = $api->process($request);
  245. if ($result->getFaultCode() != 0)
  246. throw new exceptions\DNSSubmoduleException($result->getFaultString());
  247. return $result;
  248. }
  249. }
  250. private function addQuotes( $recordTarget)
  251. {
  252. return '"'.$recordTarget.'"';
  253. }
  254. /**
  255. * Unsetting default records - they are unmodifiable
  256. * @param array $records
  257. * @return array
  258. */
  259. private function unsetDefaultRecords(array $records)
  260. {
  261. $recordsCollection = collect($records);
  262. /* Getting default SOA Record array key */
  263. $soaRecord = $recordsCollection
  264. ->where('type', 'SOA')
  265. ->where('name', $this->domain.'.')
  266. ->where('rdata.rname', 'dns.openprovider.eu');
  267. if(count($soaRecord) < 0)
  268. {
  269. throw new exceptions\DNSSubmoduleException('Default SOA Record Error');
  270. }
  271. $soaRecordKey[] = $soaRecord->keys()->first();
  272. /* Getting default NS Records array keys */
  273. $nsRecords = $recordsCollection
  274. ->where('type', 'NS')
  275. ->where('name', $this->domain.'.')
  276. ->whereIn('rdata.nsdname', ['ns1.openprovider.nl', 'ns2.openprovider.be', 'ns3.openprovider.eu']);
  277. if(count($nsRecords) < 0)
  278. {
  279. throw new exceptions\DNSSubmoduleException('Default NS Records Error');
  280. }
  281. $nsRecordsKeys = $nsRecords->keys()->toArray();
  282. $defaultRecordsKeys = array_merge_recursive($soaRecordKey, $nsRecordsKeys);
  283. foreach($defaultRecordsKeys as $key)
  284. {
  285. unset($records[$key]);
  286. }
  287. return $records;
  288. }
  289. }