modules/geobackend/Makefile modules/opendbxbackend/Makefile \
modules/pipebackend/Makefile modules/oraclebackend/Makefile \
modules/xdbbackend/Makefile modules/godbcbackend/Makefile \
-modules/mongodbbackend/Makefile \
modules/gpgsqlbackend/Makefile modules/ldapbackend/Makefile \
modules/gsqlite3backend/Makefile \
modules/goraclebackend/Makefile modules/mydnsbackend/Makefile \
SUBDIRS=@moduledirs@
-DIST_SUBDIRS=db2backend geobackend gmysqlbackend godbcbackend goraclebackend gpgsqlbackend gsqlite3backend ldapbackend luabackend mongodbbackend mydnsbackend opendbxbackend oraclebackend pipebackend xdbbackend tinydnsbackend remotebackend
+DIST_SUBDIRS=db2backend geobackend gmysqlbackend godbcbackend goraclebackend gpgsqlbackend gsqlite3backend ldapbackend luabackend mydnsbackend opendbxbackend oraclebackend pipebackend xdbbackend tinydnsbackend remotebackend
+++ /dev/null
-AM_CPPFLAGS=@THREADFLAGS@ $(BOOST_CPPFLAGS)
-EXTRA_DIST=OBJECTFILES OBJECTLIBS
-
-INCLUDES=-I/opt/mongo/include/mongo/
-
-lib_LTLIBRARIES = libmongodbbackend.la
-
-libmongodbbackend_la_SOURCES=mongodbbackend.cc mongodbbackend.hh minimal.cc slave.cc master.cc reload.cc private.cc dnssec.cc supermaster.cc crc32.cc
-libmongodbbackend_la_LDFLAGS=-module -avoid-version -L/opt/mongo/lib64 $(BOOST_THREAD_LDFLAGS) $(BOOST_FILESYSTEM_LDFLAGS) $(BOOST_SYSTEM_LDFLAGS) -lmongoclient $(BOOST_THREAD_LIBS) $(BOOST_FILESYSTEM_LIBS) $(BOOST_SYSTEM_LIBS)
-
+++ /dev/null
-mongodbbackend.o minimal.o slave.o master.o reload.o private.o dnssec.o supermaster.o crc32.o
\ No newline at end of file
+++ /dev/null
--L/opt/mongo/lib64/ -lmongoclient -lboost_thread -lboost_filesystem -lboost_system
+++ /dev/null
-====================================================
-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
-
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include <boost/crc.hpp>
-
-#include "mongodbbackend.hh"
-
-int MONGODBBackend::generateCRC32(const string& data) {
- boost::crc_32_type crc32;
- crc32.process_bytes(data.data(), data.length());
- return crc32.checksum();
-}
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-
-#include "mongodbbackend.hh"
-
-#include "pdns/logger.hh"
-#include "pdns/arguments.hh"
-
-/*
- virtual bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth)
- virtual bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth)
- virtual bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after)
-
- virtual bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys)
- virtual bool removeDomainKey(const string& name, unsigned int id)
- virtual int addDomainKey(const string& name, const KeyData& key)
- virtual bool activateDomainKey(const string& name, unsigned int id)
- virtual bool deactivateDomainKey(const string& name, unsigned int id)
-
- virtual bool getTSIGKey(const string& name, string* algorithm, string* content) { return false; }
-
- virtual bool setDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta)
- virtual bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta)
- virtual void alsoNotifies(const string &domain, set<string> *ips)
-
-*/
-
-bool MONGODBBackend::updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth) {
-
- if(!dnssec)
- return false;
-
- string ins=toLower(labelReverse(makeRelative(qname, zonename)));
- return this->updateDNSSECOrderAndAuthAbsolute(domain_id, qname, ins, auth);
-}
-
-bool MONGODBBackend::updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth) {
- if(!dnssec)
- return false;
-
- mongo::Query mongo_q = QUERY( "name" << qname << "domain_id" << domain_id );
- bson::bo update = BSON( "$set" << BSON("ordername" << ordername << "auth" << auth) );
-
- if(logging) {
- L<<Logger::Info << backend_name << "(updateDNSSECOrderAndAuthAbsolute) Query: '"<< mongo_q.toString() << "'" << endl;
- if(logging_content)
- L<<Logger::Info << backend_name << "(updateDNSSECOrderAndAuthAbsolute) Update: '"<< update.toString() << "'" << endl;
- }
-
- if(logging_cerr) {
- cerr << backend_name << "(updateDNSSECOrderAndAuthAbsolute) Query: '"<< mongo_q.toString() << "'" << endl;
- if(logging_content)
- cerr << backend_name << "(updateDNSSECOrderAndAuthAbsolute) Update: '"<< update.toString() << "'" << endl;
- }
-
- m_db.update(collection_records, mongo_q , update);
-
- return true;
-}
-
-bool MONGODBBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after) {
- if(logging)
- L<<Logger::Info << backend_name << "(getBeforeAndAfterNamesAbsolute) BEGIN domain_id: '" << id << "' qname: '" << qname << "'" << endl;
-
- unhashed.clear();
- before.clear();
- after.clear();
-
- string lqname = toLower(qname);
-
- mongo::Query mongo_q = QUERY( "domain_id" << id << "auth" << true << "ordername" << BSON("$gt" << lqname ) );
-
- auto_ptr<mongo::DBClientCursor> mongo_c;
-
- bool afterafter = false;
- bson::bo fields = BSON("ordername" << 1);
-
-retryAfter:
- if(logging)
- L<<Logger::Info << backend_name << "(getBeforeAndAfterNamesAbsolute) Query after: '"<< mongo_q.toString() << "'" << endl;
-
- mongo_q.hint(BSON("domain_id" << 1 << "auth" << 1 << "ordername" << 1));
- mongo::BSONObj mongo_r = m_db.findOne(collection_records, mongo_q, &fields );
-
- if (mongo_r.isEmpty() && !afterafter) {
- mongo_q = QUERY( "domain_id" << id << "auth" << true << "ordername" << BSON("$gt" << "")) ;
- afterafter = true;
- goto retryAfter;
- }
-
- after = mongo_r.getStringField("ordername");
-
- if(logging_content)
- L<<Logger::Info << backend_name << "(getBeforeAndAfterNamesAbsolute) after record '" << mongo_r.toString() << "'" << endl;
-
- bool beforebefore = false;
-
- fields = BSON("name" << 1 << "ordername" << 1);
-
-retryBefore:
- mongo_q = QUERY( "domain_id" << id << "auth" << true << "ordername" << BSON("$lte" << lqname)) ;
-
- if(logging)
- L<<Logger::Info << backend_name << "(getBeforeAndAfterNamesAbsolute) Query before: '"<< mongo_q.toString() << "'" << endl;
-
- mongo_q.hint(BSON("domain_id" << 1 << "auth" << 1 << "ordername" << -1));
-
- mongo_c = m_db.query(collection_records, mongo_q, 0, 0, &fields);
-
- if (!mongo_c->more() && !beforebefore) {
- lqname = "{";
- beforebefore = true;
- goto retryBefore;
- }
-
- if (mongo_c->more()) {
- mongo_r = mongo_c->next();
-
- if(logging_content)
- L<<Logger::Info << backend_name << "(getBeforeAndAfterNamesAbsolute) before next record 1 '" << mongo_r.toString() << "'" << endl;
-
- if (mongo_c->more())
- mongo_r = mongo_c->next();
-
- if(logging_content)
- L<<Logger::Info << backend_name << "(getBeforeAndAfterNamesAbsolute) before next record 2 '" << mongo_r.toString() << "'" << endl;
-
- before = mongo_r.getStringField("ordername");
- unhashed = mongo_r.getStringField("name");
-
- if(logging)
- L<<Logger::Info << backend_name << "(getBeforeAndAfterNamesAbsolute) END unhashed: '" << unhashed << "' before: '" << before << "' after: '" << after << "' " << endl;
-
- return true;
-
- } else {
- L<<Logger::Error << backend_name << "(getBeforeAndAfterNamesAbsolute) Did not get any result for the 'before' query: '"<< mongo_q.toString() << "'" << endl;
- return false;
- }
-}
-
-
-int MONGODBBackend::addDomainKey(const string& name, const KeyData& key) {
-// there is no logging function in pdnssec when running this routine?
-
- if (!dnssec)
- return false;
-
- DomainInfo di;
-
- if (!getDomainInfo(name, di, NULL))
- return -1;
-
- //we are using this to generate an unique id since
- //mongodb does not have an autoinc type with global locking.
-
- unsigned int id = generateCRC32(name + key.content);
-
- bson::bo update1 = BSON( "name" << name << "domain_id" << di.id );
- bson::bo update2 = BSON( "$push" << BSON("content" << BSON("id" << id << "flags" << key.flags << "active" << key.active << "data" << key.content) ) );
-
- if(logging_cerr) {
- cerr << backend_name << "(addDomainKey) Query: '"<< update1.toString() << "'" << endl;
- if(logging_content)
- cerr << backend_name << "(addDomainKey) Update: '"<< update2.toString() << "'" << endl;
- }
-
- mongo::BSONObj mongo_r = m_db.findOne(collection_cryptokeys, update1 );
- if (mongo_r.isEmpty())
- m_db.insert(collection_cryptokeys, update1);
-
- string m_error = m_db.getLastError();
-
- if(logging_cerr && !m_error.empty())
- cerr << backend_name << "(addDomainKey) getLastError1: "<< m_error << endl;
-
- m_db.update(collection_cryptokeys, update1 , update2);
-
- m_error = m_db.getLastError();
-
- if(logging_cerr && !m_error.empty())
- cerr << backend_name << "(addDomainKey) getLastError2: "<< m_error << endl;
-
- return 1; //or id ??
-}
-
-bool MONGODBBackend::getTSIGKey(const string& name, string* algorithm, string* content) {
- if (!dnssec)
- return false;
-
- mongo::Query mongo_q = QUERY( "name" << name << "content.algorithm" << *algorithm);
-
- if(logging)
- L<<Logger::Info << backend_name << "(getTSIGKey) Query: '"<< mongo_q.toString() << "'" << endl;
-
- mongo::BSONObj mongo_r = m_db.findOne(collection_tsigkeys, mongo_q );
-
- if (mongo_r.isEmpty())
- return false;
-
- if (!mongo_r.hasElement("content.$.secret")) {
- L<<Logger::Error << backend_name << "(getTSIGKey) The record '" << mongo_r.toString() << "' is missing the data for the query: '"<< mongo_q.toString() << "'" << endl;
- return false;
- }
-
- *content = mongo_r.getStringField("content.$.secret");
-
- return !content->empty();
-}
-
-bool MONGODBBackend::changeDomainKey(const string& name, unsigned int &id, bool toowhat ) {
- if (!dnssec)
- return false;
-
- mongo::Query mongo_q = QUERY( "name" << name << "content.id" << id);
- bson::bo update = BSON( "$set" << BSON("content.$.active" << toowhat) );
-
- string f_name = toowhat ? "(activateDomainKey)" : "(deactivateDomainKey)";
-
- if(logging) {
- L<<Logger::Info << backend_name << f_name << " Query: '"<< mongo_q.toString() << "'" << endl;
- if(logging_content)
- L<<Logger::Info << backend_name << f_name << " Update: '"<< update.toString() << "'" << endl;
- }
-
- if(logging_cerr) {
- cerr << backend_name << f_name << " Query: '"<< mongo_q.toString() << "'" << endl;
- if(logging_content)
- cerr << backend_name << f_name << " Update: '"<< update.toString() << "'" << endl;
- }
-
- m_db.update(collection_cryptokeys, mongo_q , update, false);
-
- return true; //?? how do we know that ??
-}
-
-bool MONGODBBackend::activateDomainKey(const string& name, unsigned int id) {
-
- return changeDomainKey(name, id, true);
-
-}
-
-bool MONGODBBackend::deactivateDomainKey(const string& name, unsigned int id) {
-
- return changeDomainKey(name, id, false);
-
-}
-
-bool MONGODBBackend::removeDomainKey(const string& name, unsigned int id) {
- if (!dnssec)
- return false;
-
- mongo::Query mongo_q = QUERY( "name" << name << "content.id" << id);
- bson::bo update = BSON("$pop" << BSON("content" << "$") );
-
- if(logging) {
- L<<Logger::Info << backend_name << "(removeDomainKey)" << " Query: '"<< mongo_q.toString() << "'" << endl;
- if(logging_content)
- L<<Logger::Info << backend_name << "(removeDomainKey)" << " Update: '"<< update.toString() << "'" << endl;
- }
-
- if(logging_cerr) {
- cerr << backend_name << "(removeDomainKey)" << " Query: '"<< mongo_q.toString() << "'" << endl;
- if(logging_content)
- cerr << backend_name << "(removeDomainKey)" << " Update: '"<< update.toString() << "'" << endl;
- }
-
- m_db.update(collection_cryptokeys, mongo_q, update );
-
- string m_error = m_db.getLastError();
-
- if(logging_cerr && !m_error.empty())
- cerr << backend_name << "(removeDomainKey) getLastError: "<< m_error << endl;
-
- return true; //?? how do we know that ??
-}
-
-bool MONGODBBackend::getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys) {
- //what is kind used for?
-
- if (!dnssec)
- return false;
-
- mongo::Query mongo_q = QUERY( "name" << name);
-
- if(logging)
- L<<Logger::Info << backend_name << "(getDomainKeys)" << " Query: '"<< mongo_q.toString() << "'" << endl;
-
- mongo::BSONObj mongo_r = m_db.findOne(collection_cryptokeys, mongo_q );
-
- if (mongo_r.isEmpty())
- return false;
-
- int c = 0;
-
- if(mongo_r.hasElement("content")) {
- for( bson::bo::iterator i(mongo_r.getObjectField("content")); i.more(); ) {
- bson::bo o1, o2;
- o1 = i.next().wrap();
- o2 = o1.firstElement().embeddedObject();
-
- if(o2.hasElement("id") && o2.hasElement("flags") && o2.hasElement("active") && o2.hasElement("data")) {
- c++;
- KeyData kd;
-
- kd.id = o2.getIntField("id");
- kd.flags = o2.getIntField("flags");
- kd.active = o2.getBoolField("active");
- kd.content = o2.getStringField("data");
-
- keys.push_back(kd);
-
- } else {
- L<<Logger::Error << backend_name << "(getDomainKeys) The contents '" << o2.toString() << "' is missing the id/flags/active/data field for the record '" << mongo_r.toString() << "'" << endl;
- c--;
- }
- }
- } else {
- L<<Logger::Error << backend_name << "(getDomainKeys) The record '" << mongo_r.toString() << "' is missing the content for the query: '"<< mongo_q.toString() << "'" << endl;
- }
-
- return c > 0;
-}
-
-bool MONGODBBackend::setDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta) {
- if (!dnssec)
- return false;
-
- mongo::Query mongo_q1 = QUERY( "name" << name << "content.kind" << kind);
-
- if(logging)
- L<<Logger::Info << backend_name << "(setDomainMetadata) Query: '"<< mongo_q1.toString() << "'" << endl;
-
- bson::bo mongo_q2 = BSON( "name" << name);
-
- mongo::BSONObj mongo_r = m_db.findOne(collection_domainmetadata, mongo_q2 );
- if (mongo_r.isEmpty())
- m_db.insert(collection_domainmetadata, mongo_q2 );
-
-
- bson::bo update1 = BSON("$pop" << BSON("content" << "$") );
- m_db.update(collection_domainmetadata, mongo_q1, update1 );
-
- string m_error = m_db.getLastError();
-
- if(logging_cerr && !m_error.empty())
- cerr << backend_name << "(setDomainMetadata) getLastError1: "<< m_error << endl;
-
- if (meta.empty()) {
- return true; //?
- }
-
- std::vector<std::string>::iterator i;
-
- mongo::BSONArrayBuilder contents;
-
- for(i = meta.begin(); i<meta.end(); i++ ) {
- contents.append(*i);
- }
-
- bson::bo update2 = BSON( "$push" << BSON("content" << BSON("kind" << kind << "data" << contents.arr() ) ) );
-
- if(logging_content)
- L<<Logger::Info << backend_name << "(setDomainMetadata) Update: '"<< update2.toString() << "'" << endl;
-
- m_db.update(collection_domainmetadata, mongo_q1 , update2, true);
-
- m_error = m_db.getLastError();
-
- if(logging_cerr && !m_error.empty())
- cerr << backend_name << "(setDomainMetadata) getLastError2: "<< m_error << endl;
-
- return true;
-}
-
-bool MONGODBBackend::getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta, set<string> *ips) {
- if (!dnssec)
- return false;
-
- mongo::Query mongo_q = QUERY( "name" << name << "content.kind" << kind);
-
- if(logging)
- L<<Logger::Info << backend_name << "(getDomainMetadata) Query: '"<< mongo_q.toString() << "'" << endl;
-
- mongo::BSONObj mongo_r = m_db.findOne(collection_domainmetadata, mongo_q );
-
- if (mongo_r.isEmpty())
- return false;
-
- if (!mongo_r.hasElement("content.$.data")) {
- L<<Logger::Error << backend_name << "(getDomainMetadata) The record '" << mongo_r.toString() << "' is missing the data for the query: '"<< mongo_q.toString() << "'" << endl;
- return false;
- }
-
- int c = 0;
-
- if (ips == NULL)
- for( bson::bo::iterator i(mongo_r.getObjectField("content.$.data")); i.more(); ) {
- bson::bo o;
- bson::be e;
- o = i.next().wrap();
- e = o.firstElement();
- meta.push_back(e.valuestr());
- c++;
- }
- else
- for( bson::bo::iterator i(mongo_r.getObjectField("content.$.data")); i.more(); ) {
- bson::bo o;
- bson::be e;
- o = i.next().wrap();
- e = o.firstElement();
- ips->insert(e.valuestr());
- c++;
- }
-
- return c > 0;
-}
-
-void MONGODBBackend::alsoNotifies(const string &domain, set<string> *ips) {
- if (!dnssec)
- return;
-
- string kind = "ALSO-NOTIFY";
- std::vector<std::string> meta;
-
- getDomainMetadata(domain, kind, meta , ips);
-}
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-
-#include "mongodbbackend.hh"
-
-#include "pdns/logger.hh"
-#include "pdns/arguments.hh"
-
-/*
- virtual void getUpdatedMasters(vector<DomainInfo>* domains);
- virtual void setNotifed(int id, u_int32_t serial);
-*/
-
-void MONGODBBackend::getUpdatedMasters(vector<DomainInfo>* domains) {
- //please see the function getTheFreshOnes in private.cc
-
- string type = "MASTER";
- string f_name = "(getUpdatedMasters)";
-
- getTheFreshOnes(domains, &type, &f_name);
-}
-
-void MONGODBBackend::setNotifed(int id, u_int32_t serial) {
- mongo::Query mongo_q = QUERY( "domain_id" << id );
- bson::bo update = BSON( "$set" << BSON("notified_serial" << serial ));
-
- if(logging) {
- L<<Logger::Info << backend_name << "(setNotifed)" << " Query: "<< mongo_q.toString() << endl;
- if(logging_content)
- L<<Logger::Info << backend_name << "(setNotifed)" << " Update: "<< update.toString() << endl;
- }
-
- m_db.update(collection_domains, mongo_q , update, false );
-}
-
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "mongodbbackend.hh"
-
-#include "pdns/logger.hh"
-#include "pdns/arguments.hh"
-
-/* FIRST PART */
-
-MONGODBBackend::MONGODBBackend(const string &suffix) {
- setArgPrefix("mongodb"+suffix);
- string host;
- try {
-
- if (pthread_equal(backend_pid, pthread_self())) {
- backend_count++;
- } else {
- backend_count = 1;
- backend_pid = pthread_self();
- }
-
- reload();
-
- host = getArg("host");
- mongo::HostAndPort hap = mongo::HostAndPort(host);
- string errmsg;
-
- if (! m_db.connect(hap, errmsg) ) {
- throw MONGODBException ("Can't connect to '" + host + "' (" + errmsg + ")");
- }
-
- mongo_db = getArg("database");
- collection_domains = mongo_db + "." + getArg("collection-domains");
- collection_records = mongo_db + "." + getArg("collection-records");
-
- collection_domainmetadata = mongo_db + "." + getArg("collection-domainmetadata");
- collection_cryptokeys = mongo_db + "." + getArg("collection-cryptokeys");
- collection_tsigkeys = mongo_db + "." + getArg("collection-tsigkeys");
-
- string mongo_user = getArg("user");
-
- if (! mongo_user.empty()) {
- string mongo_password = getArg("password");
-
- if (! m_db.auth(mongo_db, mongo_user, mongo_password, errmsg)) {
- throw MONGODBException ("Can't be authorized to database '" +mongo_db + "' with username '" + mongo_user +"' password 'not shown' (" + errmsg + ")");
- }
- }
-
- if (checkindex) {
- L<<Logger::Error << backend_name << "(Re)creating index... " << endl;
-
-
- m_db.ensureIndex(collection_domains , BSON( "domain_id" << 1), true, "domain_id", true); //, true);
- L<<Logger::Error << backend_name << "Index: domains: 'domain_id' done." << endl;
-
- m_db.ensureIndex(collection_domains , BSON( "name" << 1), true, "name", true); //, true);
- L<<Logger::Error << backend_name << "Index: domains: 'name' done." << endl;
-
- m_db.ensureIndex(collection_domains , BSON( "type" << 1), false, "type", true); //, true);
- L<<Logger::Error << backend_name << "Index: domains: 'type' done." << endl;
-
- m_db.ensureIndex(collection_domains , BSON( "account" << 1), false, "account", true); //, true);
- L<<Logger::Error << backend_name << "Index: domains: 'account' done." << endl;
-
-
- m_db.ensureIndex(collection_records, BSON( "domain_id" << 1), false, "domain_id", true); //, true);
- L<<Logger::Error << backend_name << "Index: records: 'domain_id' done." << endl;
-
- m_db.ensureIndex(collection_records, BSON( "name" << 1), false, "name", true); //, true);
- L<<Logger::Error << backend_name << "Index: records: 'name' done." << endl;
-
- m_db.ensureIndex(collection_records, BSON( "name" << 1 << "type" << 1), true, "name_type", true); //, true);
- L<<Logger::Error << backend_name << "Index: records: 'name_type' done." << endl;
-
- m_db.ensureIndex(collection_records, BSON( "domain_id" << 1 << "auth" << 1 << "ordername" << -1), false, "domainid_auth_ordername_desc", true); //, true);
- L<<Logger::Error << backend_name << "Index: records: 'domainid_auth_ordername_desc' done." << endl;
-
- m_db.ensureIndex(collection_records, BSON( "domain_id" << 1 << "auth" << 1 << "ordername" << 1), false, "domainid_auth_ordername_asc", true); //, true);
- L<<Logger::Error << backend_name << "Index: records: 'domainid_auth_ordername_asc' done." << endl;
-
- m_db.ensureIndex(collection_records, BSON( "domain_id" << 1 << "name" << 1 ), false, "domainid_name", true); //, true);
- L<<Logger::Error << backend_name << "Index: records: 'domainid_name' done." << endl;
-
-
- m_db.ensureIndex(collection_domainmetadata, BSON( "name" << 1 ), true, "name", true); //, true);
- L<<Logger::Error << backend_name << "Index: domainmetadata: 'name' done." << endl;
-
- m_db.ensureIndex(collection_domainmetadata, BSON( "name" << 1 << "content.kind" << 1), true, "name_kind", true); //, true);
- L<<Logger::Error << backend_name << "Index: domainmetadata: 'name_kind' done." << endl;
-
-
- m_db.ensureIndex(collection_cryptokeys, BSON( "domain_id" << 1 ), true, "domain_id", true); //, true);
- L<<Logger::Error << backend_name << "Index: cryptokeys: 'domain_id' done." << endl;
-
- m_db.ensureIndex(collection_cryptokeys, BSON( "name" << 1 ), true, "name", true); //, true);
- L<<Logger::Error << backend_name << "Index: cryptokeys: 'name' done." << endl;
-
- m_db.ensureIndex(collection_cryptokeys, BSON( "name" << 1 << "domain_id" << 1), true, "name_domainid", true); //, true);
- L<<Logger::Error << backend_name << "Index: cryptokeys: 'name_domainid' done." << endl;
-
- m_db.ensureIndex(collection_cryptokeys, BSON( "domain_id" << 1 << "content.id" << 1), true, "domainid_id", true); //, true);
- L<<Logger::Error << backend_name << "Index: cryptokeys: 'domainid_id' done." << endl;
-
- m_db.ensureIndex(collection_cryptokeys, BSON( "name" << 1 << "content.id" << 1), true, "name_id", true); //, true);
- L<<Logger::Error << backend_name << "Index: cryptokeys: 'name_id' done." << endl;
-
-
- m_db.ensureIndex(collection_tsigkeys, BSON( "name" << 1 << "content.algorithm" << 1), true, "name_algo", true); //, true);
- L<<Logger::Error << backend_name << "Index: tsigkeys: 'name_algo' done." << endl;
-
-
- L<<Logger::Error << backend_name << "(Re)creating index... DONE!" << endl;
-
- }
- }
-
- catch(MONGODBException &e) {
- L<<Logger::Error<<backend_name<<"Error: "<<e.what<<endl;
- throw AhuException(e.what);
- }
-
- L<<Logger::Info << backend_name << "Connected to host: " << host << " with database: " << mongo_db << endl;
-
-}
-
-MONGODBBackend::~MONGODBBackend() {
-// delete m_db;
- L<<Logger::Info<<backend_name<<"Disconnected!" << endl;
-}
-
-bool MONGODBBackend::list(const string &target, int domain_id) {
-
- mongo_query = QUERY( "domain_id" << domain_id );
-
- elements = false;
- default_ttl = 0;
-
- if(logging)
- L<<Logger::Info<< backend_name << "(list) Query: "<< mongo_query.toString() << endl;
-
- cursor = m_db.query(collection_records, mongo_query );
-
- return cursor->more();
-}
-
-void MONGODBBackend::lookup(const QType &qtype, const string &qname, DNSPacket *p, int domain_id) {
- string q_type;
-
- q_type = qtype.getName();
- q_name = qname;
-
- mongo_query = q_type == "ANY" ? QUERY( "name" << toLower(qname) ) : QUERY( "name" << toLower(qname) << "type" << q_type);
- mongo_query.hint(q_type == "ANY" ? BSON("name" << 1) : BSON("name" << 1 << "type" << 1));
-
- elements = false;
- default_ttl = 0;
-
- if(logging)
- L<<Logger::Info<< backend_name <<"(lookup) Query: "<< mongo_query.toString() << endl;
-
- cursor = m_db.query(collection_records, mongo_query);
-
-}
-
-bool MONGODBBackend::content(DNSResourceRecord* rr) {
-
-again:
- if (!contents->more())
- return false;
-
- bson::bo o1, o2;
-
- o1 = contents->next().wrap();
-
- if(logging_content)
- L<<Logger::Info<< backend_name <<"(content) Contents: " << o1.toString() << endl;
-
- rr->qname.clear();
- rr->qtype = 255;
- rr->ttl = 0;
- rr->domain_id = 0;
- rr->last_modified = 0;
- rr->priority = 0;
- rr->content.clear();
- rr->auth = false;
-
- o2 = o1.firstElement().embeddedObject();
-
- if (!o2.hasElement("data")) {
- L<<Logger::Error<< backend_name << "(content) Error: The record '" << o2.toString() << "' is missing 'data' for the query '"<< mongo_query.toString() << "'" << endl;
- goto again;
- }
-
- if ((type == "MX" || type == "SRV") && !o2.hasElement("prio")) {
- L<<Logger::Error<< backend_name << "(content) Error: The record '" << o2.toString() << "' is missing 'prio' for the query '"<< mongo_query.toString() << "'" << endl;
- goto again;
- }
-
- rr->qtype = rr_record.qtype;
- rr->qname = rr_record.qname;
- rr->domain_id = rr_record.domain_id;
- rr->last_modified = rr_record.last_modified;
- rr->auth = rr_record.auth;
-
- rr->priority = o2.getIntField("prio");
-
- if (o2.hasElement("ttl"))
- rr->ttl = o2.getIntField("ttl");
- else
- rr->ttl = rr_record.ttl;
-
- rr->content = o2.getStringField("data");
- if (rr->content.empty()) {
- L<<Logger::Error<< backend_name << "(content) Error: The record '" << o2.toString() << "' has no content for the query '"<< mongo_query.toString() << "'" << endl;
- goto again;
- }
-
- return contents->more();
-}
-
-bool MONGODBBackend::get(DNSResourceRecord &rr) {
-
- rr.content.clear();
-
- if (elements) {
- elements = content(&rr);
- if (!rr.content.empty() )
- return true;
- }
-
-again:
- if (cursor->more()) {
-
- mongo_record = cursor->next();
-
- if(logging_content)
- L<<Logger::Info<< backend_name << "(get) mongo_record " << mongo_record.toString() << endl;
-
- if (mongo_record.hasElement("type") && mongo_record.hasElement("domain_id") && mongo_record.hasElement("name") && mongo_record.hasElement("content")) {
- type = mongo_record.getStringField("type");
-
- rr_record.qtype = type;
- rr_record.qname = mongo_record.getStringField("name");
- rr_record.domain_id = mongo_record.getIntField("domain_id");
- rr_record.auth = mongo_record.getIntField("auth");
- rr_record.last_modified = 0;
- rr_record.priority = 0;
- rr_record.content.clear();
-
- rr_record.ttl = mongo_record.getIntField("ttl");
- if (rr_record.ttl == 0) {
- rr_record.ttl = ::arg().asNum( "default-ttl" );
- if (rr_record.ttl == 0 && default_ttl == 0) {
- SOAData soadata;
- DomainInfo DI;
-
- if (getDomainInfo("", DI, &soadata, rr_record.domain_id)) {
- if (!use_default_ttl && (soadata.ttl < soadata.default_ttl))
- default_ttl = soadata.ttl;
- else
- default_ttl = soadata.default_ttl;
-
- rr_record.ttl = default_ttl;
-
- if(logging)
- L<<Logger::Info<< backend_name << "(get) Got default_ttl: '" << default_ttl << "' from SOA for recordname '" << rr_record.qname << "'" << endl;
- } else {
- L<<Logger::Error << backend_name << "(get) Could not get SOA for default_ttl for recordname '" << rr_record.qname << "'!" << endl;
- goto again;
- }
- } else if (rr_record.ttl == 0 && default_ttl > 0) {
- rr_record.ttl = default_ttl;
- } else {
- L<<Logger::Error << backend_name << "(get) Could not get default_ttl for recordname '" << rr_record.qname << "'!" << endl;
- goto again;
- }
- }
-
-// if (contents)
-// delete []contents;
-
- contents = new mongo::BSONObjIterator(mongo_record.getObjectField("content"));
-
- elements = content(&rr);
-
- } else {
- L<<Logger::Error<< backend_name << "(get) Error: The record '" << mongo_record.toString() << "' is missing required element(s) for the query '"<< mongo_query.toString() << "'" << endl;
- goto again;
- }
- }
-
- return !rr.content.empty() ;
-}
-
-bool MONGODBBackend::getSOA(const string &name, SOAData &soadata, DNSPacket *p) {
- //please see getDomainInfo in slave.cc for this function.
-
- DomainInfo DI;
-
- return getDomainInfo(name, DI, &soadata);
-}
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "mongodbbackend.hh"
-#include "pdns/logger.hh"
-
-/* SECOND PART */
-
-class MONGODBFactory : public BackendFactory
-{
-public:
- MONGODBFactory() : BackendFactory("mongodb") {}
-
- void declareArguments(const string &suffix="")
- {
- declare(suffix,"host","which mongodb server to connect to","localhost:27017");
- declare(suffix,"database","which database to use","dns");
- declare(suffix,"user","which user to authenticate with","");
- declare(suffix,"password","which password to use with authentication","");
-
- declare(suffix,"collection-domains","name of the collections for domains","domains");
- declare(suffix,"collection-records","name of the collections for records","records");
- declare(suffix,"collection-domainmetadata","name of the collections for domainmetadata","domainmetadata");
- declare(suffix,"collection-cryptokeys","name of the collections for cryptokeys","cryptokeys");
- declare(suffix,"collection-tsigkeys","name of the collections for cryptokeys","tsigkeys");
-
- declare(suffix, "dnssec", "Using DNSSEC","yes");
- declare(suffix, "checkindex", "Creating the index if needed","no");
- declare(suffix, "logging-query", "Logging query(s)","no");
- declare(suffix, "logging-cerr", "Logging message(s) to cerr","no");
- declare(suffix, "logging-content", "Logging the content ","no");
- declare(suffix, "use-default-ttl", "If we should use soa.ttl if soa.ttl is less than soa.default_ttl ","no");
-
- }
-
- DNSBackend *make(const string &suffix="")
- {
- return new MONGODBBackend(suffix);
- }
-
-};
-
-/* THIRD PART */
-
-class MONGODBLoader
-{
-public:
- MONGODBLoader()
- {
- BackendMakers().report(new MONGODBFactory);
-
- L<<Logger::Notice<<"[MONGODBBackend] This is the mongodbbackend ("__DATE__", "__TIME__") reporting"<<endl;
- }
-};
-
-static MONGODBLoader mongodbLoader;
+++ /dev/null
-#ifndef MONGODB_HH
-#define MONGODB_HH
-
-#include "pdns/dnsbackend.hh"
-
-#undef VERSION
-#include <string>
-using std::string;
-
-#include "client/dbclient.h"
-
-class MONGODBException {
-public:
- MONGODBException(const string &ex) : what(ex){}
- string what;
-};
-
-class MONGODBBackend : public DNSBackend {
-
-public:
-
-
-// MINIMAL BACKEND
-
- MONGODBBackend(const string &suffix="");
- ~MONGODBBackend();
- bool list(const string &target, int domain_id);
- void lookup(const QType &qtype, const string &qname, DNSPacket *p, int domain_id);
- bool get(DNSResourceRecord &rr);
- //! fills the soadata struct with the SOA details. Returns false if there is no SOA.
- bool getSOA(const string &name, SOAData &soadata, DNSPacket *p=0);
-
-
-// SLAVE BACKEND
-
- bool getDomainInfo(const string &domain, DomainInfo &di, SOAData *soadata = NULL, unsigned int domain_id = 0);
- bool isMaster(const string &name, const string &ip);
- void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
- void setFresh(int id);
-/*
- bool startTransaction(const string &qname, int id);
- bool commitTransaction();
- bool abortTransaction();
- bool feedRecord(const DNSResourceRecord &rr);
-*/
-
-
-// SUPERMASTER BACKEND
-/*
- bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
- bool createSlaveDomain(const string &ip, const string &domain, const string &account)
-*/
-
-
-// MASTER BACKEND
-
- void getUpdatedMasters(vector<DomainInfo>* domains);
- void setNotifed(int id, u_int32_t serial);
-
-
-// DNSSEC BACKEND
- //! get a list of IP addresses that should also be notified for a domain
- void alsoNotifies(const string &domain, set<string> *ips);
- bool getDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta, set<string> *ips = NULL);
- bool setDomainMetadata(const string& name, const std::string& kind, std::vector<std::string>& meta);
-
- bool getDomainKeys(const string& name, unsigned int kind, std::vector<KeyData>& keys);
- bool removeDomainKey(const string& name, unsigned int id);
- bool activateDomainKey(const string& name, unsigned int id);
- bool deactivateDomainKey(const string& name, unsigned int id);
- bool getTSIGKey(const string& name, string* algorithm, string* content);
- int addDomainKey(const string& name, const KeyData& key);
-
- bool getBeforeAndAfterNamesAbsolute(uint32_t id, const std::string& qname, std::string& unhashed, std::string& before, std::string& after);
- bool updateDNSSECOrderAndAuthAbsolute(uint32_t domain_id, const std::string& qname, const std::string& ordername, bool auth);
- bool updateDNSSECOrderAndAuth(uint32_t domain_id, const std::string& zonename, const std::string& qname, bool auth);
-
-
-// OTHER
- void reload();
-
-
-private:
-// FUNCTIONS TO THIS BACKEND
-
- //minimal.cc
- bool content(DNSResourceRecord* rr);
-
- //private.cc
- void getTheFreshOnes(vector<DomainInfo>* domains, string *type, string *f_name);
- bool checkDomainInfo(const string *domain, mongo::BSONObj *mongo_r, string *f_name, string *mongo_q, DomainInfo *di, SOAData *soadata = NULL);
-
- //dnssec.cc
- bool changeDomainKey(const string& name, unsigned int &id, bool toowhat);
-
- //crc32.cc
- int generateCRC32(const string& my_string);
-
- string mongo_db;
- string collection_domains;
- string collection_records;
-
- string collection_domainmetadata;
- string collection_cryptokeys;
- string collection_tsigkeys;
-
- mongo::DBClientConnection m_db;
-
- auto_ptr<mongo::DBClientCursor> cursor;
-
- string q_name;
-
-// long long unsigned int count;
- mongo::Query mongo_query;
- mongo::BSONObj mongo_record;
- bool elements;
- DNSResourceRecord rr_record;
- string type;
- mongo::BSONObjIterator* contents;
-
-
- string backend_name;
- pthread_t backend_pid;
- unsigned int backend_count;
-
- unsigned int default_ttl;
-
- bool logging;
- bool logging_cerr;
- bool logging_content;
-
- bool dnssec;
- bool checkindex;
-
- bool use_default_ttl;
-
-};
-#endif
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "mongodbbackend.hh"
-
-#include "pdns/logger.hh"
-#include "pdns/arguments.hh"
-
-bool MONGODBBackend::checkDomainInfo(const string *domain, mongo::BSONObj *mongo_r, string *f_name, string *mongo_q, DomainInfo *di, SOAData *soadata) {
- if (mongo_r->hasElement("type") && mongo_r->hasElement("domain_id") && mongo_r->hasElement("SOA")) {
- di->backend = this;
- di->serial = 0;
- di->zone = *domain;
-
- di->id = mongo_r->getIntField("domain_id");
- di->last_check = mongo_r->getIntField("last_check");
- di->notified_serial = mongo_r->getIntField("notified_serial");
-
- if (soadata == NULL)
- for( bson::bo::iterator i(mongo_r->getObjectField("masters")); i.more(); ) {
- bson::bo o;
- bson::be e;
- o = i.next().wrap();
- e = o.firstElement();
- di->masters.push_back(e.valuestr());
- }
-
- string type = toUpper(mongo_r->getStringField("type"));
-
- if (soadata != NULL || type == "SLAVE") {
- //filling out soadata.
- mongo::BSONObj soa = mongo_r->getObjectField("SOA");
- if (soa.hasElement("serial") && soa.hasElement("refresh") && soa.hasElement("retry") && soa.hasElement("expire") && soa.hasElement("default_ttl") && mongo_r->hasElement("ttl")) {
- if (soadata != NULL) {
- soadata->db = this;
- soadata->serial = soa.getIntField("serial");
- di->serial = soadata->serial;
-
- soadata->refresh = soa.getIntField("refresh");
- soadata->retry = soa.getIntField("retry");
- soadata->expire = soa.getIntField("expire");
- soadata->default_ttl = soa.getIntField("default_ttl");
- soadata->domain_id = di->id;
-
- soadata->ttl = mongo_r->getIntField("ttl");
-
- soadata->nameserver = soa.getStringField("nameserver");
- if (soadata->nameserver.empty()) {
- soadata->nameserver = arg()["default-soa-name"];
- if (soadata->nameserver.empty()) {
- L<<Logger::Error << backend_name << *f_name << " Error: SOA Record '" << soa.toString() << "' is missing nameserver for the query '" << *mongo_q << "'" << endl;
- return false;
- }
- }
- soadata->hostmaster = soa.getStringField("hostmaster");
- if (soadata->hostmaster.empty())
- soadata->hostmaster = "hostmaster." + *domain;
-
- } else {
- //hopefully called as getDomainInfo with no soadata!
- di->serial = soa.getIntField("serial");
- }
-
- } else {
- L<<Logger::Error << backend_name << *f_name << " Error: SOA Record '" << soa.toString() << "' is missing required element(s) for the query '" << *mongo_q << "'" << endl;
- return false;
- }
- }
-
- if (type == "SLAVE") {
- di->kind = DomainInfo::Slave;
-
- } else if (type == "MASTER") {
- di->kind = DomainInfo::Master;
-
- } else {
- di->kind = DomainInfo::Native;
- }
-
- return true;
-
- } else {
- L<<Logger::Error << backend_name << *f_name << " Error: The record '" << mongo_r->toString() << "' is missing required element(s) for the query '" << *mongo_q << "'" << endl;
- }
-
- return false;
-}
-
-void MONGODBBackend::getTheFreshOnes(vector<DomainInfo>* domains, string *type, string *f_name) {
- mongo::Query mongo_q = QUERY( "type" << *type );
-
- auto_ptr<mongo::DBClientCursor> mongo_c;
- mongo_c = m_db.query(collection_domains, mongo_q);
-
- string m_q = mongo_q.toString();
-
- if(logging)
- L<<Logger::Info << backend_name << *f_name << " Query: "<< m_q << endl;
-
- if (!mongo_c->more())
- return;
-
- while(mongo_c->more()) {
- DomainInfo di;
- SOAData sd;
-
- mongo::BSONObj mongo_r = mongo_c->next();
-
- string domain = mongo_r.getStringField("domain");
-
- if (checkDomainInfo(&domain, &mongo_r, f_name, &m_q, &di, &sd)) {
- if ( (*type == "SLAVE" && ((time_t)(di.last_check + sd.refresh) < time(0)) ) || (*type == "MASTER" && (di.notified_serial != sd.serial) ) ) {
- di.serial = sd.serial;
- domains->push_back(di);
- }
- }
- }
-}
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-#include "mongodbbackend.hh"
-
-#include "pdns/logger.hh"
-#include "pdns/arguments.hh"
-
-/*
- virtual void reload();
-*/
-
-void MONGODBBackend::reload() {
- logging = ::arg().mustDo("query-logging") || mustDo("logging-query");
-
- logging_cerr = mustDo("logging-cerr");
- logging_content = mustDo("logging-content");
-
- dnssec = mustDo("dnssec");
- checkindex = mustDo("checkindex");
-
- use_default_ttl = mustDo("use-default-ttl");
-
- backend_name.clear();
-
-// backend_name = "[MONGODBBackend: " + uitoa(backend_pid) + " (" + uitoa(backend_count) +")] ";
- backend_name = "[MONGODBBackend: (" + uitoa(backend_count) +")] ";
-}
+++ /dev/null
-/* the name ends with .sql because of (some) nice colours in mcedit ;-) */
-
-
-mongo table domains
- { "domain_id" : int,
- "name" : string,
- "last_check" : int,
- "notified_serial" : int,
- "type" : string,
- "ttl" : int,
- "account" : string,
- "SOA" : {
- "serial" : int,
- "refresh" : int,
- "retry" : int,
- "expire" : int,
- "default_ttl" : int,
- "hostmaster" : string
- },
- "masters" : [ string, ... ],
- }
-
-mongo table record
- { "domain_id" : int ,
- "name" : string,
- "type" : string,
- "ttl" : int,
- "ordername" : string,
- "auth" : bool,
- "content" : [
- { "prio" : int,
- "ttl" : int,
- "data" : string
- }
- , ...
- ]
-
-mongo table domainmetadata
- { "name" : string ,
- "content" : [
- { "kind" : string,
- "data" : [ string, ...]
- }
- , ...
- ]
- }
-
-mongo table cryptokeys
- { "domain_id" : int,
- "name" : string ,
- "content" : [
- { "id" : int,
- "flags" : int,
- "active" : bool,
- "data" : string
- }
- , ...
- ]
- }
-
-mongo table tsigkeys
- { "name" : string,
- "content" : [
- { "algorithm" : string,
- "secret" : string
- }
- , ...
- ]
- }
-
-
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-
-#include "mongodbbackend.hh"
-
-#include "pdns/logger.hh"
-#include "pdns/arguments.hh"
-
-/*
- //transaction is not yet implemented in this backend
-
- virtual bool startTransaction(const string &qname, int id);
- virtual bool commitTransaction();
- virtual bool abortTransaction();
- virtual bool feedRecord(const DNSResourceRecord &rr);
-
- virtual bool getDomainInfo(const string &domain, DomainInfo &di);
- virtual bool isMaster(const string &name, const string &ip);
- virtual void getUnfreshSlaveInfos(vector<DomainInfo>* domains);
- virtual void setFresh(int id);
-*/
-
-void MONGODBBackend::setFresh(int id) {
- mongo::Query mongo_q = QUERY( "domain_id" << id );
- bson::bo update = BSON( "$set" << BSON("last_check" << (unsigned int) time(0) ) );
-
- if(logging) {
- L<<Logger::Info << backend_name << "(setFresh)" << " Query: "<< mongo_q.toString() << endl;
- if(logging_content)
- L<<Logger::Info << backend_name << "(setFresh)" << " Update: "<< update.toString() << endl;
- }
-
- m_db.update(collection_domains, mongo_q , update, false );
-}
-
-void MONGODBBackend::getUnfreshSlaveInfos(vector<DomainInfo>* domains) {
- //please see the function getTheFreshOnes in private.cc
-
- string type = "SLAVE";
- string f_name = "(getUnfreshSlaveInfos)";
-
- getTheFreshOnes(domains, &type, &f_name);
-}
-
-bool MONGODBBackend::isMaster(const string &domain, const string &ip) {
-
- mongo::Query mongo_q = QUERY( "name" << toLower(domain) );
-
- mongo::BSONObj mongo_r = m_db.findOne(collection_domains, mongo_q );
-
- string f_name = "(isMaster)";
-
- string m_q = mongo_q.toString();
-
- if(logging)
- L<<Logger::Info << backend_name << f_name << " Query: "<< m_q << endl;
-
- if (mongo_r.isEmpty())
- return false;
-
- DomainInfo di;
-
- if(!checkDomainInfo(&domain, &mongo_r, &f_name, &m_q, &di))
- return false;
-
- for(vector<string>::const_iterator iter=di.masters.begin(); iter != di.masters.end(); ++iter) {
- // we can also have masters with a port specified (which we ignore here)
- ServiceTuple st;
- parseService(*iter, st);
- if (!strcmp(ip.c_str(), st.host.c_str())) {
- return true;
- }
- }
-
- return false;
-}
-
-bool MONGODBBackend::getDomainInfo(const string &domain, DomainInfo &di, SOAData *soadata, unsigned int domain_id) {
-
- mongo::Query mongo_q;
-
- if (domain_id > 0)
- mongo_q = QUERY( "domain_id" << domain_id );
- else
- mongo_q = QUERY( "name" << toLower(domain) );
-
- mongo::BSONObj mongo_r = m_db.findOne(collection_domains, mongo_q );
-
- string f_name = soadata == NULL ? "(getDomainInfo)" : "(getSOA)";
-
- string m_q = mongo_q.toString();
-
- if(logging)
- L<<Logger::Info << backend_name << f_name << " Query: "<< m_q << endl;
-
- if (mongo_r.isEmpty())
- return false;
-
- return checkDomainInfo(&domain, &mongo_r, &f_name, &m_q, &di, soadata);
-}
+++ /dev/null
-/*
- Copyright (C) 2011 Fredrik Danerklint
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License version 2 as published
- by the Free Software Foundation
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
-
-
-#include "mongodbbackend.hh"
-
-#include "pdns/logger.hh"
-#include "pdns/arguments.hh"
-
-/*
- //! determine if ip is a supermaster or a domain
- virtual bool superMasterBackend(const string &ip, const string &domain, const vector<DNSResourceRecord>&nsset, string *account, DNSBackend **db)
-
- //! called by PowerDNS to create a slave record for a superMaster
- virtual bool createSlaveDomain(const string &ip, const string &domain, const string &account)
-
-*/
-
-//void MONGODBBackend::
+++ /dev/null
-time mongoexport -d dns -c records >json.exported.records
-time mongoexport -d dns -c domains >json.exported.domains
-
-time mongoexport -d dns -c cryptokeys >json.exported.cryptokeys
-time mongoexport -d dns -c domainmetadata >json.exported.domainmetadata
-time mongoexport -d dns -c tsigkeys >json.exported.tsigkeys
+++ /dev/null
-time mongoexport -d dns -c records -f "name,ordername" -q "{"domain_id" : 10, "auth" : true }" | awk '{ print $11,$14 }' | sort >json.exported.records.sorted
+++ /dev/null
-head -n1 mongodb.example.com >json.imported.domains
-head -n1 mongodb.test.com >>json.imported.domains
-head -n1 mongodb.wtest.com >>json.imported.domains
-
-tail -n+2 mongodb.example.com >json.imported.records
-tail -n+2 mongodb.test.com >>json.imported.records
-tail -n+2 mongodb.wtest.com >>json.imported.records
-
-mongoimport -d dns -c records --drop <json.imported.records
-
-./mongodb.example.com.generate-hosts | mongoimport -d dns -c records
-
-mongoimport -d dns -c domains --drop <json.imported.domains
-
-mongoimport -d dns -c cryptokeys --drop <json.imported.empty
-mongoimport -d dns -c domainmetadata --drop <json.imported.empty
-mongoimport -d dns -c tsigkeys --drop <json.imported.empty
+++ /dev/null
-{"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 } }
-{"domain_id" : 11, "name" : "test.com", "type" : "NATIVE", "ttl" : 3600, "SOA" : {"hostmaster" : "ahu.example.com", "nameserver" : "ns1.test.com", "serial" : 2005092501, "refresh" : 28800, "retry" : 7200, "expire" : 604800, "default_ttl" : 86400 } }
-{"domain_id" : 12, "name" : "wtest.com", "type" : "NATIVE", "ttl" : 3600, "SOA" : {"hostmaster" : "ahu.example.com", "nameserver" : "ns1.wtest.com", "serial" : 2005092501, "refresh" : 28800, "retry" : 7200, "expire" : 604800, "default_ttl" : 86400 } }
+++ /dev/null
-{"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 } }
-{"domain_id" : 10, "name" : "example.com", "type" : "NS", "ttl" : 120, "content" : [ {"data" : "ns1.example.com"}, {"data" : "ns2.example.com"} ] }
-{"domain_id" : 10, "name" : "example.com", "type" : "MX", "ttl" : 120, "content" : [ {"prio" : 10, "data" : "smtp-servers.example.com"}, {"prio" : 15, "data" : "smtp-servers.test.com"} ] }
-{"domain_id" : 10, "name" : "example.com", "type" : "DNSKEY", "ttl" : 120, "content" : [ {"data" : "256 3 5 AwEAAarTiHhPgvD28WCN8UBXcEcf8f+OF+d/bEoN6zTuHl/oVra5/qfonhYK/RjI74RzHc2wli9TpXOWycQV3YSfpFZ9z+GB/bbsvBon1XMyNf5KXuOwRdHZXIZh1cku3AcIyNroD26MPkbFLHY0+xRI+7u7OsQ6nYcPBpqDiJnB2BMh"} ] }
-{"domain_id" : 10, "name" : "ns1.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.1.1"} ] }
-{"domain_id" : 10, "name" : "ns2.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.1.2"} ] }
-{"domain_id" : 10, "name" : "localhost.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "127.0.0.1"} ] }
-{"domain_id" : 10, "name" : "www.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "outpost.example.com"} ] }
-{"domain_id" : 10, "name" : "location.example.com", "type" : "LOC", "ttl" : 120, "content" : [ {"data" : "51 56 0.123 N 5 54 0.000 E 4.00m 1.00m 10000.00m 10.00m"}, {"data" : "51 56 1.456 S 5 54 0.000 E 4.00m 2.00m 10000.00m 10.00m"}, {"data" : "51 56 2.789 N 5 54 0.000 W 4.00m 3.00m 10000.00m 10.00m"}, {"data" : "51 56 3.012 S 5 54 0.000 W 4.00m 4.00m 10000.00m 10.00m" } ] }
-{"domain_id" : 10, "name" : "hwinfo.example.com", "type" : "HINFO", "ttl" : 120, "content" : [ {"data" : "\"abc\" \"def\""} ] }
-{"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"} ] }
-{"domain_id" : 10, "name" : "outpost.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.2.1"} ] }
-{"domain_id" : 10, "name" : "start1.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "start2.example.com"} ] }
-{"domain_id" : 10, "name" : "start2.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "start3.example.com"} ] }
-{"domain_id" : 10, "name" : "start3.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "start4.example.com"} ] }
-{"domain_id" : 10, "name" : "start4.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.2.2"} ] }
-{"domain_id" : 10, "name" : "loop1.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "loop2.example.com"} ] }
-{"domain_id" : 10, "name" : "loop2.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "loop3.example.com"} ] }
-{"domain_id" : 10, "name" : "loop3.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "loop1.example.com"} ] }
-{"domain_id" : 10, "name" : "external.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "somewhere.else.net"} ] }
-{"domain_id" : 10, "name" : "server1.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "server1.france.example.com"} ] }
-{"domain_id" : 10, "name" : "france.example.com", "type" : "NS", "ttl" : 120, "content" : [ {"data" : "ns1.otherprovider.net"}, {"data" : "ns2.otherprovider.net"} ] }
-{"domain_id" : 10, "name" : "usa.example.com", "type" : "NS", "ttl" : 120, "content" : [ {"data" : "usa-ns1.usa.example.com"}, {"data" : "usa-ns2.usa.example.com"} ] }
-{"domain_id" : 10, "name" : "usa-ns1.usa.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.4.1"} ] }
-{"domain_id" : 10, "name" : "usa-ns2.usa.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.4.2"} ] }
-{"domain_id" : 10, "name" : "italy.example.com", "type" : "NS", "ttl" : 120, "content" : [ {"data" : "italy-ns1.example.com"}, {"data" : "italy-ns2.example.com"} ] }
-{"domain_id" : 10, "name" : "italy-ns1.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.5.1"} ] }
-{"domain_id" : 10, "name" : "italy-ns2.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.5.2"} ] }
-{"domain_id" : 10, "name" : "mail.example.com", "type" : "MX", "ttl" : 120, "content" : [ {"prio" : 25, "data" : "smtp1.example.com"} ] }
-{"domain_id" : 10, "name" : "smtp1.example.com", "type" : "CNAME", "ttl" : 120, "content" : [ {"data" : "outpost.example.com"} ] }
-{"domain_id" : 10, "name" : "external-mail.example.com", "type" : "MX", "ttl" : 120, "content" : [ {"prio" : 25, "data" : "server1.test.com"} ] }
-{"domain_id" : 10, "name" : "text.example.com", "type" : "TXT", "ttl" : 120, "content" : [ {"data" : "Hi, this is some text"} ] }
-{"domain_id" : 10, "name" : "multitext.example.com", "type" : "TXT", "ttl" : 120, "content" : [ {"data" : "\"text part one\" \"text part two\" \"text part three\""} ] }
-#{"domain_id" : 10, "name" : "escapedtext.example.com", "type" : "TXT", "ttl" : 120, "content" : [ {"data" : "\"begin\" \"the \\\"middle\\\" p\\\\art\" \"the end\""} ] }
-{"domain_id" : 10, "name" : "ipv6.example.com", "type" : "AAAA", "ttl" : 120, "content" : [ {"data" : "2001:6A8:0:1:210:4BFF:FE4B:4C61"} ] }
-{"domain_id" : 10, "name" : "together-too-much.example.com", "type" : "MX", "ttl" : 120, "content" : [ {"prio" : 25, "data" : "toomuchinfo-a.example.com"}, {"prio" : 25, "data" : "toomuchinfo-b.example.com"} ] }
-{"domain_id" : 10, "name" : "toomuchinfo-a.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.99.1"}, {"data" : "192.168.99.2"},{"data" : "192.168.99.3"},{"data" : "192.168.99.4"},{"data" : "192.168.99.5"},{"data" : "192.168.99.6"},{"data" : "192.168.99.7"},{"data" : "192.168.99.8"},{"data" : "192.168.99.9"},{"data" : "192.168.99.10"},{"data" : "192.168.99.11"},{"data" : "192.168.99.12"},{"data" : "192.168.99.13"},{"data" : "192.168.99.14"},{"data" : "192.168.99.15"},{"data" : "192.168.99.16"},{"data" : "192.168.99.17"},{"data" : "192.168.99.18"},{"data" : "192.168.99.19"},{"data" : "192.168.99.20"},{"data" : "192.168.99.21"},{"data" : "192.168.99.22"},{"data" : "192.168.99.23"},{"data" : "192.168.99.24"},{"data" : "192.168.99.25"} ] }
-{"domain_id" : 10, "name" : "toomuchinfo-b.example.com", "type" : "A", "ttl" : 120, "content" : [ {"data" : "192.168.99.26"}, {"data" : "192.168.99.27"},{"data" : "192.168.99.28"},{"data" : "192.168.99.29"},{"data" : "192.168.99.30"},{"data" : "192.168.99.31"},{"data" : "192.168.99.32"},{"data" : "192.168.99.33"},{"data" : "192.168.99.34"},{"data" : "192.168.99.35"},{"data" : "192.168.99.36"},{"data" : "192.168.99.37"},{"data" : "192.168.99.38"},{"data" : "192.168.99.39"},{"data" : "192.168.99.40"},{"data" : "192.168.99.41"},{"data" : "192.168.99.42"},{"data" : "192.168.99.43"},{"data" : "192.168.99.44"},{"data" : "192.168.99.45"},{"data" : "192.168.99.46"},{"data" : "192.168.99.47"},{"data" : "192.168.99.48"},{"data" : "192.168.99.49"},{"data" : "192.168.99.50"},{"data" : "192.168.99.66"},{"data" : "192.168.99.67"},{"data" : "192.168.99.68"},{"data" : "192.168.99.69"},{"data" : "192.168.99.70"},{"data" : "192.168.99.71"},{"data" : "192.168.99.72"},{"data" : "192.168.99.73"},{"data" : "192.168.99.74"},{"data" : "192.168.99.75"},{"data" : "192.168.99.76"},{"data" : "192.168.99.77"},{"data" : "192.168.99.78"},{"data" : "192.168.99.79"},{"data" : "192.168.99.80"},{"data" : "192.168.99.81"},{"data" : "192.168.99.82"},{"data" : "192.168.99.83"},{"data" : "192.168.99.84"},{"data" : "192.168.99.85"},{"data" : "192.168.99.86"},{"data" : "192.168.99.87"},{"data" : "192.168.99.88"},{"data" : "192.168.99.89"},{"data" : "192.168.99.90"} ] }
+++ /dev/null
-#!/usr/local/bin/bash
-
-h=0
-i=0
-
-for h in {0..19999}; do
- if [ "${i}" -eq 256 ]; then
- i=0
- fi
-
- echo "{\"domain_id\" : 10, \"name\" : \"host-${h}.example.com\", \"type\" : \"A\", \"ttl\" : 120, \"content\" : [ {\"data\" : \"192.168.1.${i}\" } ] } "
-
- ((i += 1))
-
-done
-
+++ /dev/null
-{"domain_id" : 11, "name" : "test.com", "type" : "NATIVE", "ttl" : 3600, "SOA" : {"hostmaster" : "ahu.example.com", "nameserver" : "ns1.test.com", "serial" : 2005092501, "refresh" : 28800, "retry" : 7200, "expire" : 604800, "default_ttl" : 86400 } }
-{"domain_id" : 11, "name" : "test.com", "type" : "NS", "ttl" : 3600, "content" : [ {"data" : "ns1.test.com"}, {"data" : "ns2.test.com"} ] }
-{"domain_id" : 11, "name" : "test.com", "type" : "MX", "ttl" : 3600, "content" : [ {"prio" : 10, "data" : "smtp-servers.example.com"}, {"prio" : 15, "data" : "smtp-servers.test.com"} ] }
-{"domain_id" : 11, "name" : "www.test.com", "type" : "CNAME", "ttl" : 3600, "content" : [ {"data" : "server1.test.com"} ] }
-{"domain_id" : 11, "name" : "server1.test.com", "type" : "A", "ttl" : 3600, "content" : [ {"data" : "1.2.3.4"} ] }
-{"domain_id" : 11, "name" : "server1.test.com", "type" : "RP", "ttl" : 3600, "content" : [ {"data" : "ahu.ds9a.nl. counter.test.com."} ] }
-{"domain_id" : 11, "name" : "*.test.com", "type" : "CNAME", "ttl" : 3600, "content" : [ {"data" : "server1.test.com"} ] }
-{"domain_id" : 11, "name" : "www.test.test.com", "type" : "A", "ttl" : 3600, "content" : [ {"data" : "4.3.2.1"} ] }
-{"domain_id" : 11, "name" : "enum.test.com", "type" : "NAPTR", "ttl" : 3600, "content" : [ {"data" : "100 50 \"u\" \"e2u+sip\" \"\" testuser@domain.com."} ] }
-{"domain_id" : 11, "name" : "counter.test.com", "type" : "A", "ttl" : 3600, "content" : [ {"data" : "1.1.1.5"} ] }
-{"domain_id" : 11, "name" : "_ldap._tcp.dc.test.com", "type" : "SRV", "ttl" : 3600, "content" : [ {"prio" : 0, "data" : "100 389 server1.test.com"} ] }
-{"domain_id" : 11, "name" : "_double._tcp.dc.test.com", "type" : "SRV", "ttl" : 3600, "content" : [ {"prio" : 0, "data" : "100 389 server1.test.com"}, {"prio" : 1, "data" : "100 389 server1.test.com"} ] }
-{"domain_id" : 11, "name" : "blah.test.com", "type" : "NS", "ttl" : 3600, "content" : [ {"data" : "blah.test.com"} ] }
-{"domain_id" : 11, "name" : "blah.test.com", "type" : "A", "ttl" : 3600, "content" : [ {"data" : "9.9.9.9"} ] }
-{"domain_id" : 11, "name" : "images.test.com", "type" : "URL", "ttl" : 3600, "content" : [ {"data" : "http://www.ds9a.nl"} ] }
-{"domain_id" : 11, "name" : "bert@auto.test.com", "type" : "MBOXFW", "ttl" : 3600, "content" : [ {"data" : "bert@ds9a.nl"} ] }
-{"domain_id" : 11, "name" : "very-long-txt.test.com", "type" : "TXT", "ttl" : 3600, "content" : [ {"data" : "A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long. A very long TXT record! boy you won't believe how long!" } ] }
+++ /dev/null
-{"domain_id" : 12, "name" : "wtest.com", "type" : "NATIVE", "ttl" : 3600, "SOA" : {"hostmaster" : "ahu.example.com", "nameserver" : "ns1.wtest.com", "serial" : 2005092501, "refresh" : 28800, "retry" : 7200, "expire" : 604800, "default_ttl" : 86400 } }
-{"domain_id" : 12, "name" : "wtest.com", "type" : "NS", "ttl" : 3600, "content" : [ {"data" : "ns1.wtest.com"}, {"data" : "ns2.wtest.com"} ] }
-{"domain_id" : 12, "name" : "wtest.com", "type" : "A", "ttl" : 3600, "content" : [ {"data" : "9.9.9.9"} ] }
-{"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"} ] }
-{"domain_id" : 12, "name" : "*.wtest.com", "type" : "CNAME", "ttl" : 3600, "content" : [ {"data" : "server1.wtest.com"} ] }
-{"domain_id" : 12, "name" : "secure.wtest.com", "type" : "MX", "ttl" : 3600, "content" : [ {"prio" : 10, "data" : "server1.wtest.com"} ] }
-{"domain_id" : 12, "name" : "server1.wtest.com", "type" : "A", "ttl" : 3600, "content" : [ {"data" : "1.2.3.4"} ] }
-{"domain_id" : 12, "name" : "*.something.wtest.com", "type" : "A", "ttl" : 3600, "content" : [ {"data" : "4.3.2.1"} ] }
+++ /dev/null
-../../../pdns/pdns_server --daemon=no --local-port=5300 --socket-dir=./ \
---no-shuffle --launch=mongodb \
---fancy-records --query-logging --send-root-referral --loglevel=9 \
---cache-ttl=0 --config-dir=./
+++ /dev/null
-# Autogenerated configuration file template
-#################################
-# allow-axfr-ips Allow zonetransfers only to these subnets
-#
-# allow-axfr-ips=0.0.0.0/0
-
-#################################
-# allow-recursion List of subnets that are allowed to recurse
-#
-# allow-recursion=0.0.0.0/0
-
-#################################
-# allow-recursion-override Set this so that local data fully overrides the recursor
-#
-# allow-recursion-override=no
-
-#################################
-# cache-ttl Seconds to store packets in the PacketCache
-#
-# cache-ttl=20
-
-#################################
-# chroot If set, chroot to this directory for more security
-#
-# chroot=
-
-#################################
-# config-dir Location of configuration directory (pdns.conf)
-#
-# config-dir=/usr/local/etc
-
-#################################
-# config-name Name of this virtual configuration - will rename the binary image
-#
-# config-name=
-
-#################################
-# control-console Debugging switch - don't use
-#
-# control-console=no
-
-#################################
-# daemon Operate as a daemon
-#
-# daemon=no
-
-#################################
-# default-soa-name name to insert in the SOA record if none set in the backend
-#
-# default-soa-name=a.misconfigured.powerdns.server
-
-#################################
-# default-ttl Seconds a result is valid if not set otherwise
-#
-# default-ttl=3600
-
-#################################
-# disable-axfr Disable zonetransfers but do allow TCP queries
-#
-# disable-axfr=no
-
-#################################
-# disable-tcp Do not listen to TCP queries
-#
-# disable-tcp=no
-
-#################################
-# distributor-threads Default number of Distributor (backend) threads to start
-#
-# distributor-threads=3
-
-#################################
-# do-ipv6-additional-processing Do AAAA additional processing
-#
-# do-ipv6-additional-processing=no
-
-#################################
-# fancy-records Process URL and MBOXFW records
-#
-# fancy-records=no
-
-#################################
-# guardian Run within a guardian process
-#
-# guardian=no
-
-#################################
-# launch Which backends to launch and order to query them in
-#
-# launch=
-
-#################################
-# lazy-recursion Only recurse if question cannot be answered locally
-#
-# lazy-recursion=yes
-
-#################################
-# load-modules Load this module - supply absolute or relative path
-#
-# load-modules=
-
-#################################
-# local-address Local IP addresses to which we bind
-#
-# local-address=0.0.0.0
-
-#################################
-# local-ipv6 Local IP address to which we bind
-#
-# local-ipv6=
-
-#################################
-# local-port The port on which we listen
-#
-# local-port=53
-
-#################################
-# log-dns-details If PDNS should log DNS non-erroneous details
-#
-# log-dns-details=
-
-#################################
-# log-failed-updates If PDNS should log failed update requests
-#
-# log-failed-updates=
-
-#################################
-# logfile Logfile to use (Windows only)
-#
-# logfile=pdns.log
-
-#################################
-# logging-facility Log under a specific facility
-#
-# logging-facility=
-
-#################################
-# loglevel Amount of logging. Higher is more. Do not set below 3
-#
-# loglevel=4
-
-#################################
-# master Act as a master
-#
-# master=no
-
-#################################
-# max-queue-length Maximum queuelength before considering situation lost
-#
-# max-queue-length=5000
-
-#################################
-# max-tcp-connections Maximum number of TCP connections
-#
-# max-tcp-connections=10
-
-#################################
-# module-dir Default directory for modules
-#
-# module-dir=/usr/local/lib
-
-#################################
-# negquery-cache-ttl Seconds to store packets in the PacketCache
-#
-# negquery-cache-ttl=60
-
-#################################
-# no-shuffle Set this to prevent random shuffling of answers - for regression testing
-#
-# no-shuffle=off
-
-#################################
-# out-of-zone-additional-processing Do out of zone additional processing
-#
-# out-of-zone-additional-processing=yes
-
-#################################
-# pipebackend-abi-version Version of the pipe backend ABI
-#
-# pipebackend-abi-version=1
-
-#################################
-# query-cache-ttl Seconds to store packets in the PacketCache
-#
-# query-cache-ttl=20
-
-#################################
-# query-local-address Source IP address for sending queries
-#
-# query-local-address=
-
-#################################
-# query-logging Hint backends that queries should be logged
-#
-# query-logging=no
-
-#################################
-# queue-limit Maximum number of milliseconds to queue a query
-#
-# queue-limit=1500
-
-#################################
-# recursive-cache-ttl Seconds to store packets in the PacketCache
-#
-# recursive-cache-ttl=10
-
-#################################
-# recursor If recursion is desired, IP address of a recursing nameserver
-#
-# recursor=no
-
-#################################
-# send-root-referral Send out old-fashioned root-referral instead of ServFail in case of no authority
-#
-# send-root-referral=no
-
-#################################
-# setgid If set, change group id to this gid for more security
-#
-# setgid=
-
-#################################
-# setuid If set, change user id to this uid for more security
-#
-# setuid=
-
-#################################
-# skip-cname Do not perform CNAME indirection for each query
-#
-# skip-cname=no
-
-#################################
-# slave Act as a slave
-#
-# slave=no
-
-#################################
-# slave-cycle-interval Reschedule failed SOA serial checks once every .. seconds
-#
-# slave-cycle-interval=60
-
-#################################
-# smtpredirector Our smtpredir MX host
-#
-# smtpredirector=a.misconfigured.powerdns.smtp.server
-
-#################################
-# soa-expire-default Default SOA expire
-#
-# soa-expire-default=604800
-
-#################################
-# soa-minimum-ttl Default SOA minimum ttl
-#
-# soa-minimum-ttl=3600
-
-#################################
-# soa-refresh-default Default SOA refresh
-#
-# soa-refresh-default=10800
-
-#################################
-# soa-retry-default Default SOA retry
-#
-# soa-retry-default=3600
-
-#################################
-# soa-serial-offset Make sure that no SOA serial is less than this number
-#
-# soa-serial-offset=0
-
-#################################
-# socket-dir Where the controlsocket will live
-#
-# socket-dir=/var/run
-
-#################################
-# strict-rfc-axfrs Perform strictly rfc compliant axfrs (very slow)
-#
-# strict-rfc-axfrs=no
-
-#################################
-# trusted-notification-proxy IP address of incoming notification proxy
-#
-# trusted-notification-proxy=
-
-#################################
-# urlredirector Where we send hosts to that need to be url redirected
-#
-# urlredirector=127.0.0.1
-
-#################################
-# use-logfile Use a log file (Windows only)
-#
-# use-logfile=no
-
-#################################
-# version-string PowerDNS version in packets - full, anonymous, powerdns or custom
-#
-# version-string=full
-
-#################################
-# webserver Start a webserver for monitoring
-#
-# webserver=no
-
-#################################
-# webserver-address IP Address of webserver to listen on
-#
-# webserver-address=127.0.0.1
-
-#################################
-# webserver-password Password required for accessing the webserver
-#
-# webserver-password=
-
-#################################
-# webserver-port Port of webserver to listen on
-#
-# webserver-port=8081
-
-#################################
-# webserver-print-arguments If the webserver should print arguments
-#
-# webserver-print-arguments=no
-
-#################################
-# wildcard-url Process URL and MBOXFW records
-#
-# wildcard-url=no
-
-#################################
-# wildcards Honor wildcards in the database
-#
-# wildcards=
-
-
-query-logging=yes
-launch=mongodb
-mongodb-checkindex=yes
-mongodb-logging-cerr=yes
-
+++ /dev/null
-../../../pdns/pdnssec --config-dir=./ $@
<filename>modules/geobackend/README</filename>, part of the PowerDNS Authoritative Server distribution.
</para>
</sect1>
- <sect1 id="mongo"><title>MongoDB Backend</title>
- <para>
- <warning>
- <para>
- This section is a subset of the full documentation which can be found in <filename>modules/mongodbbackend/README</filename> of
- the PowerDNS distribution.
- </para>
- </warning>
- </para>
- <para>
- The main author for this module is Fredrik Danerklint.
- </para>
- <para>
- <table>
- <title>MongoDB backend capabilities</title>
- <tgroup cols="2">
- <tbody>
- <row><entry>Native</entry><entry>Yes</entry></row>
- <row><entry>Master</entry><entry>Yes</entry></row>
- <row><entry>Slave</entry><entry>No</entry></row>
- <row><entry>Superslave</entry><entry>No</entry></row>
- <row><entry>Autoserial</entry><entry>No</entry></row>
- <row><entry>DNSSEC</entry><entry>Yes</entry></row>
- </tbody>
- </tgroup>
- </table>
- </para>
- <para>
- <warning><para>The MongoDB Backend is available since PowerDNS Authoritative Server 3.0. In 3.0 and 3.1, this backend is marked as
- Experimental!</para></warning>
- </para>
- <para>
- The MongoDB backend is a full service backend that stores data in a MongoDB instance.
- </para>
- <para>
- More details can be found <ulink url="http://wiki.powerdns.com/cgi-bin/trac.fcgi/browser/trunk/pdns/modules/mongodbbackend/README">here</ulink>, or in
- <filename>modules/mongodbbackend/README</filename>, part of the PowerDNS Authoritative Server distribution.
- </para>
- </sect1>
<sect1 id="luabackend"><title>Lua Backend</title>
<para>
<warning>