====================================================
README FILE FOR MONGODBBACKEND FOR USE WITH POWERDNS
====================================================

You do understand the concept of Mongo DB? 
If not please go to www.mongodb.org first!


Supported functions for this backend is for the moment:

    o) NATIVE
    o) MASTER
    o) DNSSEC

============================
WHY NO SLAVE SUPPORT FOR NOW
============================

The first reason that slave isn't suported at this time is that there is no
transaction support in Mongo DB per se. 
I do know that "db.eval" will lock the database and this is probably the
route to take to implement the slave functionallity with Mongo DB.

The second reason is that is very difficult to generate an unique id within
a database cluster when some database server could be disconnected from eachother
and at the same time everybody wants an unique id.

My proposal to this problem is to use uuid (universally unique identifier) and take
that string and calculate an crc32 of that for the use of unique id and yes, also
check that the crc32 doesn't exists before it's use!

In a shell you can use something like this to generate the crc32 of an uuid:

--------------------------------------------
#!/bin/sh

u=`uuidgen -r`

c=`echo "${u}" | cksum | awk '{print $1}'`

echo "uuid: ${u}"
echo "crc32: ${c}"
---------------------------------------------


===========================================
WHAT YOU WILL FIND UNDER THE TEST DIRECTORY
===========================================

I have converted all the domains (example.com, test.com, wtest.com) that does 
exists under the pdns/regression-tests into json format for this backend. 

To import this you first need to change the path to the "mongoimport" program 
in the file "json.import". When you run this program, remember that

IT WILL DELETE YOUR FULL DATABASE WITH ALL INFORMATION IN IT!

so don't run/use it on a production server, okay?

There is one line within the file "mongodb.example.com" that does not import 
correctly at this time and the reason for that is that I haven't figured out 
to escape the string for it to import.

When you have run "json.import" you have an clean database with no dnssec 
information in it. To get that run the "./pdnssec secure-zone <domain>" from the 
test directory and you should be ready to test it!


=============================
OPTIONS IN THE CONFIGURE FILE
=============================

The default values is:

mongodb-host = localhost:27017
mongodb-database = dns

Tables in Mongo DB is called collection:

collection-domains = domains
collection-records = records
collection-domainmetadata = domainmetadata
collection-cryptokeys = cryptokeys
collection-tsigkeys = tsigkeys

DNSSEC is set to yes as default since you don't have to convert anything to get 
this functionallity. Only if don't want dnssec you should set "mongodb-dnssec" 
to "no".

For the first time you connect to an empty or populated database, you should run 
PowerDNS with the option "mongodb-checkindex" set to "yes". This will create all 
the index that the backend use and then some more. In your log you will see this 
a couple of times:

"Apr 05 19:40:29 [MONGODBBackend: 2466240256 (1)] (Re)creating index... "

Now you can stop PowerDNS and set this option to no. You don't need it anymore 
since it is created. A tip is to check with Mongo DB that this as been done for 
example via the web interface which normaly is at 
http://localhost:28017/


If you have the global option "query-logging" set to yes, you will get something 
like this in your log:

".....(getSOA) Query: { name: "example.com" }"

If you also have the "mongodb-logging-content" set to "yes" you will also 
get the result from that question. This can be very much of information but 
also very helpfull if something is wrong with the answer.

If you are running the pdnssec utility it can be a little difficult to get
log information so there also exists an option to log to stderr with the 
"mongodb-logging-cerr" set to "yes".


=========================================================================
OBS! OBS! THE RECORD OF "SOA" IS MOVED FROM RECORDS TO DOMAINS! OBS! OBS!
=========================================================================

I did this for the benefit of losing at least one database query every time 
you allready have got the information for the domain you are looking for in 
the collection "domains".

It has only came back and bite me (and you) in the back once. In the 
regression-tests there is the 'any-query' test that fails. It does this
because it does not get the SOA record in a question of 'any example.com' since 
that record does not exists in the collection "records" anymore. 

The funny part of this is that PowerDNS allready has got the SOA record to know
if we have the domain we are asking for. Because of that I don't know if this 
really should be fixed in the backend or in the logic of PowerDNS.


===========================
THE FAILED REGRESSION-TESTS
===========================

If you have imported the test domains with the help of the "json.import" you can
run the test with the following command:

src_svn/pdns/regression-tests$ nameserver=127.0.0.1 port=5300 ./runtests

The failed test are:

    o) url-record
    o) mboxfw-record
    o) any-query
    o) external-cname-pointer
    o) multi-txt-escape-resolution


============================
THE JSON FORMAT OF THE DATA
===========================

The structure of the data is that there should only be one record and not as in the sql variants
of PowerDNS multiply of the same record. To duplicate some data that is unqiue in json format we 
use arrays. 

For all of the collections in this backend the field 'content' does hold the data for that record.
The 'content' can be an array of either strings or an array of records (documents in Mongo DB language).

For example, take this record:

{	"domain_id" : 10, "name" : "smtp-servers.example.com", "type" : "A", "ttl" : 120, 
	"content" : [ {"data" : "192.168.0.2"}, {"data" : "192.168.0.3"}, {"data" : "192.168.0.4"} ] 
}

As you can see this is an dns type 'A' record for the name 'smtp-servers.example.com' 
with a ttl of '120' seconds with three ip addresses of that server with the numbers: 
192.168.0.2, 192.168.0.3, 192.168.0.4.

Now let's say that we need to change the ttl field for the ip address 192.168.0.3. 
What needed to be changed is the document (record) that holds data for the ip address 
'192.168.0.3' and not the other ones.

{	"domain_id" : 10, "name" : "smtp-servers.example.com", "type" : "A", "ttl" : 120, 
	"content" : [ {"data" : "192.168.0.2"}, {"data" : "192.168.0.3", "ttl" : 60}, {"data" : "192.168.0.4"} ] 
}

See?!? It's that easy to change the ttl for the ip address 192.168.0.3 to '60' 
seconds and the others will still have the '120' seconds ttl and we don't have 
duplicate the same data anymore.

For the dns type 'MX' and 'SRV' there must also be an field with name "prio" (for the priority).

{	"domain_id" : 12, "name" : "wtest.com", "type" : "MX", "ttl" : 3600, 
	"content" : [ 	{"prio" : 10, "data" : "smtp-servers.example.com"}, 
			{"prio" : 15, "data" : "smtp-servers.wtest.com"} 
		    ] 
}


Let's also take a look at the SOA record since that now are in the collection of 'domains':

{"domain_id" : 10, "name" : "example.com", "type" : "NATIVE", "ttl" : 120, 
    "SOA" : {	"hostmaster" : "ahu.example.com", 
		"nameserver" : "ns1.example.com", 
		"serial" : 2000081501, 
		"refresh" : 28800, 
		"retry" : 7200, 
		"expire" : 604800, 
		"default_ttl" : 86400 
	} 
}

The field "SOA" in 'domains' holds a document of the values required for this dns type.


You can send question about this backend to >dev/null first and if you don't get any 
answer from that you can try to send them to me at fredan-pdns@fredan.org

