Commit a1d319bd authored by anarcat's avatar anarcat Committed by anarcat

change the data structure storage to be more logical and efficient

a complete zonefile can now be described like this:

$zonefile = array('www' => array('a' => array('1.2.3.3', '1.2.3.4')),
                  '@' => array('SOA' => array('hostmaster' => 'localhost', 'email' => 'admin.localhost', 'serial' => '2010082301', 'refresh' => 21600 3600 604800 86400 )'),
                              'A' => array('1.2.3.3'),
                              'MX' => array('mail.localhost'),
                              'NS' => array('localhost', 'ns2.localhost'),
                              )
                 );

i had to change the provision storage class to merge with existing
records in some cases for that to work.
parent 60f596e2
...@@ -24,10 +24,28 @@ Bugs: ...@@ -24,10 +24,28 @@ Bugs:
1. since the rewrite of the parser, some fields in the SOA are 1. since the rewrite of the parser, some fields in the SOA are
missing (retry, refresh, etc) because we lack the context from the missing (retry, refresh, etc) because we lack the context from the
server (switching to create_config() shoudl fix that) server (switching to create_config() shoudl fix that)
2. there's a duplicate serial in PHP storage (patched?)
3. the internal data structure is confusing and not efficient. here's
a proposed change:
$zonefile = array('www' => array('a' => array('1.2.3.3', '1.2.3.4')),
'@' => array('SOA' => array('hostmaster' => 'localhost', 'email' => 'admin.localhost', 'serial' => '2010082301', 'refresh' => 21600 3600 604800 86400 )'),
'A' => array('1.2.3.3'),
'MX' => array('mail.localhost'),
'NS' => array('localhost', 'ns2.localhost'),
)
);
(patched, needs testing and verification)
4. removing the last record in a zonefile doesn't remove the zone
5. removing records doesn't work either
6. we increment the serial in two places, it seems
Caveats: Caveats:
1. only targeting bind right now 1. there's duplicate storage altogether: we could parse zonefiles and
use that as storage, not PHP files, but that would make switching
engines more difficult and would require writing parsers for all
engines.
Todo: Todo:
......
...@@ -4,29 +4,39 @@ ...@@ -4,29 +4,39 @@
$TTL <?php print $server->dns_ttl; ?> $TTL <?php print $server->dns_ttl; ?>
<?php <?php
print("@ IN SOA $server->remote_host $dns_email print("@ IN SOA $server->remote_host $dns_email (
$serial ; serial " . $records['@']['SOA']['serial'] . " ; serial
$server->dns_refresh; refresh $server->dns_refresh; refresh
$server->dns_retry ; retry $server->dns_retry ; retry
$server->dns_expire ; expire $server->dns_expire ; expire
$server->dns_negativettl ; minimum $server->dns_negativettl ; minimum
)\n"); )\n");
?>
print "@\tIN\tNS\t" . $server->remote_host . " ; primary DNS\n";
IN NS <?php print $server->remote_host ?>. ; primary DNS foreach ($server->dns_slaves as $slave) {
IN NS ns2.example.com. ; secondary DNS print "@\tIN\tNS\t$slave ; slave DNS\n";
IN MX 10 <?php print $server->remote_host ?>. ; external mail provider }
; non server domain hosts
<?php
foreach ($records['A'] as $ip) { foreach ($records['@'] as $type => $destinations) {
print " IN A {$ip}\n"; if ($type != 'SOA' && $type != 'NS') {
foreach ($destinations as $destination) {
print "@\tIN\t$type\t$destination\n";
}
}
} }
foreach ($records as $name => $record) {
if ($name != '@') {
foreach ($record as $type => $destinations) {
foreach ($destinations as $destination) {
print "$name\tIN\t$type\t$destination\n";
}
}
}
}
foreach ($hosts as $host => $info) { foreach ($hosts as $host => $info) {
foreach ($info['A'] as $ip) { foreach ($info['A'] as $ip) {
print "{$info['sub']} IN A {$ip}\n"; print "{$info['sub']} IN A {$ip}\n";
} }
} }
?>
...@@ -95,13 +95,9 @@ class provisionConfig_dns_zone extends provisionConfig_dns { ...@@ -95,13 +95,9 @@ class provisionConfig_dns_zone extends provisionConfig_dns {
$this->data['dns_email'] = str_replace('@', '.', $this->data['server']->admin_email); $this->data['dns_email'] = str_replace('@', '.', $this->data['server']->admin_email);
// increment the serial. // increment the serial.
$this->store->records['serial'] = $this->data['serial'] = provisionService_dns::increment_serial($records['serial']); $this->store->records['@']['SOA']['serial'] = $records['serial'] = provisionService_dns::increment_serial($records['@']['SOA']['serial']);
foreach ($records as $key => $record) { $this->data['records'] = $records;
if (preg_match('/^host:/', $key)) {
$this->data['hosts'][$record['host']] = $record;
}
}
} }
function write() { function write() {
......
...@@ -14,6 +14,7 @@ include_once(dirname(__FILE__) . '/../provision.service.inc'); ...@@ -14,6 +14,7 @@ include_once(dirname(__FILE__) . '/../provision.service.inc');
/** /**
* Implementation of hok_drush_command(). * Implementation of hok_drush_command().
*/
function dns_drush_command() { function dns_drush_command() {
$items['provision-zone'] = array( $items['provision-zone'] = array(
'arguments' => array('operation' => dt('The operation to perform on a zone (verify, delete, rr-add, rr-delete)')), 'arguments' => array('operation' => dt('The operation to perform on a zone (verify, delete, rr-add, rr-delete)')),
...@@ -39,18 +40,14 @@ function drush_dns_provision_zone($action, $zone, $name = null, $type = null, $d ...@@ -39,18 +40,14 @@ function drush_dns_provision_zone($action, $zone, $name = null, $type = null, $d
$status = d()->service('dns')->delete_zone($zone); $status = d()->service('dns')->delete_zone($zone);
break; break;
case 'rr-add': case 'rr-add':
d()->service('dns')->config('zone', $zone)->record_set("host:$host", array( $record = d()->service('dns')->config('zone', $zone)->record_get($name);
'sub' => $sub, $record[$type] = array_merge($record[$type], array($destination));
'A' => $ips, d()->service('dns')->config('zone', $zone)->record_set($name, $record)->write();
'host' => $host,
));
$status = d()->service('dns')->add_record($zone, $name, $type, $destination);
break; break;
case 'rr-modify': case 'rr-modify':
$status = d()->service('dns')->modify_record($zone, $name, $type, $destination); d()->service('dns')->config('zone', $zone)->record_set($name, array($type => array($destination)))->write();
break; break;
case 'rr-delete': case 'rr-delete':
$status = d()->service('dns')->delete_record($zone, $name, $type, $destination);
break; break;
} }
$status = $status && d()->service('dns')->commit($zone); $status = $status && d()->service('dns')->commit($zone);
...@@ -58,8 +55,6 @@ function drush_dns_provision_zone($action, $zone, $name = null, $type = null, $d ...@@ -58,8 +55,6 @@ function drush_dns_provision_zone($action, $zone, $name = null, $type = null, $d
return $status; return $status;
} }
*/
function dns_provision_services() { function dns_provision_services() {
return array('dns' => NULL); return array('dns' => NULL);
} }
...@@ -236,8 +231,7 @@ class provisionService_dns extends provisionService { ...@@ -236,8 +231,7 @@ class provisionService_dns extends provisionService {
$this->config('server')->record_set($zone, $zone)->write(); $this->config('server')->record_set($zone, $zone)->write();
$soa['serial'] = $this->increment_serial($soa['serial']); $this->config('zone', $zone)->record_set('serial', $this->increment_serial())->write();
$this->config('zone', $zone)->record_set('soa', $soa)->write();
} }
/** /**
...@@ -278,19 +272,17 @@ class provisionService_dns extends provisionService { ...@@ -278,19 +272,17 @@ class provisionService_dns extends provisionService {
$ips = array('127.0.0.1'); $ips = array('127.0.0.1');
} }
if (is_array($ips)) { // XXX: kill me?
if ($sub) { if (!is_array($ips)) {
$this->config('zone', $zone)->record_set("host:$host", array( $ips = array($ips); // backward compatibility?
'sub' => $sub, }
'A' => $ips,
'host' => $host, if (empty($sub)) {
)); $sub = '@';
}
else {
$this->config('zone', $zone)->record_set("A", $ips);
}
} }
drush_log("zone: $zone, sub: $sub");
$this->config('zone', $zone)->record_set($sub, array('A' => $ips));
$this->create_zone($zone); $this->create_zone($zone);
$this->create_config('host'); $this->create_config('host');
} }
...@@ -320,9 +312,11 @@ class provisionService_dns extends provisionService { ...@@ -320,9 +312,11 @@ class provisionService_dns extends provisionService {
// remove the records from the zone store // remove the records from the zone store
$this->config('zone', $zone)-> $this->config('zone', $zone)->
record_del("host:$host"); record_set($host, array('A' => null));
$this->create_zone($zone); // XXX: need to guess the number of records left now and remove only if
// there are no more records
//$this->delete_zone($zone);
$this->delete_config('host'); $this->delete_config('host');
} }
......
...@@ -131,7 +131,17 @@ class provisionService extends provisionChainedState { ...@@ -131,7 +131,17 @@ class provisionService extends provisionChainedState {
$this->_config->store->records = array_merge($this->_config->store->records, $arg1); $this->_config->store->records = array_merge($this->_config->store->records, $arg1);
} }
elseif (!is_numeric($arg1)) { elseif (!is_numeric($arg1)) {
$this->_config->store->records[$arg1] = $arg2; if (is_array($arg2)) {
if (!is_array($this->_config->store->loaded_records[$arg1])) {
$this->_config->store->loaded_records[$arg1] = array();
}
if (!is_array($this->_config->store->records[$arg1])) {
$this->_config->store->records[$arg1] = array();
}
$this->_config->store->records[$arg1] = array_merge($this->_config->store->loaded_records[$arg1], $this->_config->store->records[$arg1], $arg2);
} else {
$this->_config->store->records[$arg1] = $arg2;
}
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment