PowerDNS

alessandro123

Verified User
Joined
Sep 11, 2008
Messages
46
I'm developing a dns_write_post.sh script that will populate some external PowerDNS servers.
With that, should be possibile to manage dns from external servers with ease.

I think that should be usefull.
I'll post here after done.
 
Hi alessandro123,

I was about to start on the same thing.
If you want maybe I can help you out.

I will be waiting for your input. No need to invent the wheel 2 times.
 
My script is almost done.
The only "bad" thing is that is written in PHP.
Actually I'm unable to fetch environmental variables passed by directadmin.
I've done some testing with static variables and seems to work nicely.

More over, actually I delete the whole domain from pdns database and i'll reinsert brand new from scratch when dns_write_post.sh is called.

May be a better way should be to write only differences and update serial.
 
No problem if it's writtin in php.
I was planning to do it that way as well because I'm better in programming in php.

Deleting then inserting new from scratch isn't an option for me. Because of master slave configuration of the primary master pdns server. But when you're done if you would provide some code. I will ajust the code: Retrieve the current serial and when inserting, update that with one, and of course I would share my updates with you.

I was also thinking about creating an OOP php class for powerdns. (but that's a little off topic and not really related to directadmin)

I already wrote down how I would program the script. (It's easier for me to write it down in human language and then convert to script).

I was also thinking about just updating the changes. But it would be faster to retrieve the serial, update with one, remove all records from database and reinserting into database with new serial.
 
Last edited:
Actually I'm unable to fetch environmental variables passed by directadmin.
I've done some testing with static variables and seems to work nicely.

I just did a quick check,
And using the environmental variables passed by directadmin,
wasn't a problem at all on my end.

How did you try to catch them?
 
I'm trying to catch env variables with two script like this:

Code:
$ cat prova_import_dns.sh 
#!/bin/sh
A='www=1.2.3.4&ftp=1.2.3.4&localhost=127.0.0.1&mail=1.2.3.4'
AAAA=
AAAA_TIME=14400
A_TIME=14400
CNAME=
CNAME_TIME=14400
DOMAIN=domain.com
MX=mail=10
MX_TIME=14400
NS='ns1.domain.com.=domain.com.&ns2.domain.com.=domain.com.'
NS_TIME=14400
PTR=
PTR_TIME=14400
SRV=
SRV_TIME=14400
TXT='domain.com.="v=spf1 a mx ip4:1.2.3.4 ~all"'
TXT_TIME=14400

./importa_dns.php




$ cat importa_dns.php
#!/usr/bin/php
<?
print_r($_ENV);
?>

but $_ENV doesn't containes the directadmin values.

I even tryied with "export" or "set" with no luck.
 
It works for me with export before every variable declaration/definition, which is exactly what that script needs.
Unless you have a PHP wrapper that cleans out all environment variables, it should work for you too.
Code:
$ head -n2 prova_import_dns.sh
#!/bin/sh
export A='www=1.2.3.4&ftp=1.2.3.4&localhost=127.0.0.1&mail=1.2.3.4'
$ ./importa_import_dns.sh |grep '\[A\]'
    [A] => www=1.2.3.4&ftp=1.2.3.4&localhost=127.0.0.1&mail=1.2.3.4
 
Martino I've read on your CV that your primary language is Italian...
I'm Italian, and I speak much better Italian then English :D
 
I know you are (the name of your scripts don't leave any doubt about it :D), but since this is an english-based forum I think it would be rude to discuss your problem in italian.

Let's return in topic: make sure your /usr/bin/php isn't a shell script that automatically wipes out any environment variable that isn't mandatory for PHP to run correctly. It happens.
Otherwise, just use arguments and $argv instead of environment variables and $_ENV; see http://php.net/manual/en/features.commandline.php
 
This is a very ugly pdns import code.
Need to be executed by "dns_write_pre.sh".

Table domains must contain a valid domain record that
can be created with domain_create_post.sh.

With domain_destroy_post.sh is possibile to remove the
whole record and domain for the destroyed domain.

Code is not tested, I haven't a text box to try.

Code:
#!/usr/bin/php
<?
/*************************************
 * DirectAdmin to Power DNS Importer *
 *-----------------------------------*
 * (c) 2009 by GUEST s.r.l. - Italy  *
 * License: GPL                      *
 * Feel free to customize on your    *
 * needs as long this copyright      *
 * remains intact                    *
 *************************************/

// MySQL Host
define("MYSQL_HOST","");

// MySQL Username
define("MYSQL_USERNAME","");

// MySQL Password
define("MYSQL_PASSWORD","");

// MySQL Database
define("MYSQL_DATABASE","");

// Default TTL
define("DEFAULT_TTL", 14400);


function run_query($sql)
{
	$conn 		= mysql_connect( MYSQL_HOST, MYSQL_USERNAME, MYSQL_PASSWORD ) or die ("Can't connect to MySQL server: ".mysql_error());
	$select_db 	= mysql_select_db(MYSQL_DATABASE, $conn) or die ("Can't connect to MySQL database: ".mysql_error());
	$result 	= mysql_query($sql) or die ("Error in SQL query: ".mysql_error()."\n".$sql);
	return $result;
}

function get_domain_id($DOMAIN) {
	// Check if domain is already present (id > 0)
	$sql 	= " SELECT id FROM domains WHERE name = '".$DOMAIN."' LIMIT 1 ";
	$result = run_query($sql);

	if ( mysql_num_rows($result) == 1 ) {
		// domain exists.
		$id	= mysql_result($result,0,'id');
	}

	if ( ! $id > 0 ) {
		// domain id not present, an error occured in fetch or insert
		die("Domain not found.");
	}

	return $id;
}

function insert_record ($TYPE, $RECORD, $RECORD_TIME, $DOMAIN, $DOMAIN_ID) {
	if ( trim($RECORD) == "" ) {
		// invalid record or domain.
		return false;
	}

	$arr_record 	= explode("&",$RECORD);

	// Record's TTL doesn't exist. I'll set the default.
	if ( ! $RECORD_TIME > 0 ) {
		$RECORD_TIME = DEFAULT_TTL;
	}

	// Delete old records
	$sql = "DELETE FROM records WHERE domain_id = '".$DOMAIN_ID."' AND type = '".$TYPE."'";
	run_query($sql);

	foreach ( $arr_record as $record_singolo ) {
		$arr_chiave_valore 	= explode("=",$record_singolo,2);
		$left 			= $arr_chiave_valore[0];
		$content		= $arr_chiave_valore[1];		

		// Last char is a ".", skip concatenating second level domain.
		if ( substr($left,-1,1) == "." ) {
			// I'll remove latest dot from domain's leftpart
			$name = substr($left,0,strlen($left)-1);
		} else {
			// Recompose the whole domain.
			$name = $left.".".$DOMAIN;
		}

		switch ( $TYPE ) {
			case "MX":
				// Insert MX records
		                $sql = "INSERT INTO records SET domain_id = '".$DOMAIN_ID."', name = '".$DOMAIN."', type = '".$TYPE."', content = '".$name."', ttl = '".$RECORD_TIME."', prio = '".$content."', change_date = '".time()."'";
				run_query($sql);
				break;
			case "NS":
				// Insert NS records
				$sql = "INSERT INTO records SET domain_id = '".$DOMAIN_ID."', name = '".$DOMAIN."', type = '".$TYPE."', content = '".$name."', ttl = '".$RECORD_TIME."', prio = NULL, change_date = '".time()."'";
				run_query($sql);
				break;
			default:
				// Insert standard records (A, AAAA, TXT, ...)
			        $sql = "INSERT INTO records SET domain_id = '".$DOMAIN_ID."', name = '".$name."', type = '".$TYPE."', content = '".$content."', ttl = '".$RECORD_TIME."', prio = NULL, change_date = '".time()."'";
				run_query($sql);
				break;
		}
	}
}


if ( trim($_ENV['DOMAIN']) != "" ) {
	// domain ID
	$domain_id = get_domain_id($_ENV['DOMAIN']);
} else {
	die("Invalid domain specified.");
}

// Record type to be parsed with the same function
$record=array('A','AAAA','CNAME','MX', "NS", "TXT", "PTR");

foreach ( $record as $type ) {
	// Insert record.
	insert_record($type, $_ENV[$type], $_ENV[$type."_TIME"], $_ENV['DOMAIN'], $domain_id);
}

?>
 
Hi,

I silently started to work on my own version.
I wanted to make use of a pdns class so I could reuse the script.

(I'm planning on creating my own pdns administrator, the current ones are hard to work with when you got 2000+ domains to manage)

Also why do you use? "dns_write_pre.sh"
I was working on the "dns_write_post.sh"

I don't think it will really matter in this case, But still.
 
This code should be added in "domain_destroy_post.sh"

Code:
domain_id=$(/usr/bin/mysql -umy_username -pmy_password -h my_db_server my_db_name -NB -e " SELECT id FROM domains WHERE name = '$domain' LIMIT 1;")
/usr/bin/mysql -umy_username -pmy_password -h my_db_server my_db_name -e "DELETE FROM domains WHERE name = '$domain' LIMIT 1;"
/usr/bin/mysql -umy_username -pmy_password -h my_db_server my_db_name -e "DELETE FROM records WHERE domain_id = '$domain_id' LIMIT 1;"


Code to add in domain_create_post.sh
Code:
/usr/bin/mysql -umy_username -pmy_password -h my_db_server my_db_name -e "INSERT INTO domains SET name = '$domain', type = 'NATIVE';"
 
Are there any way to simulate a dns_write_post.sh execution for the exesting domains?
We have to migrate more or less 150 domains to pdns and we would like to skip bind's zone file parsing.
Is possibile to execute dns_write_post.sh as it was ran for the first time?

Our script can handle environment variables from dns_write_post and is no able to parse the raw bind zone file.

thank you.
 
Back
Top