Hi, Every now and then I tend to maintain domains that end up to be clones of other domeins. The company has registered company.com, and wants the same DNS records for company.net or maybe even brandx.com.
So I thought up a solution for this, implemented in the postgreSQL backend: I replaced the table records with a view. This solution has the following features: - domain.org can be a clone of domain.com - domain.org can have extra records that do not exist in domain.com (hoeever: at this moment not the opposite) at the moment it is not yet possible to 'override' a record in domain.org. To avoid confusion, I used copcepts SOURCE and COPY, to avoid names like MASTER and SLAVE. -- NOTE: this is a PROOF OF CONCEPT. Not thoroughly tested. Not suitable for production yet. The main difference is the table virtdomains, that links a set of records to multiple DNS zones. This is the SQL I used. create table supermasters ( ip VARCHAR(25) NOT NULL, nameserver VARCHAR(255) NOT NULL, account VARCHAR(40) DEFAULT NULL ); GRANT SELECT ON supermasters TO pdns; GRANT ALL ON domains_org TO pdns; GRANT ALL ON domains_org_id_seq TO pdns; GRANT ALL ON records_org TO pdns; GRANT ALL ON records_org_id_seq TO pdns; create table domains ( id SERIAL PRIMARY KEY, name VARCHAR(255) NOT NULL, master VARCHAR(128) DEFAULT NULL, last_check INT DEFAULT NULL, type VARCHAR(6) NOT NULL, notified_serial INT DEFAULT NULL, account VARCHAR(40) DEFAULT NULL ); CREATE UNIQUE INDEX name_index ON domains(name); create type virttype as enum ('SOURCE', 'COPY', 'EXTENSION'); -- this is an extra table that links DNS records to multiple zones. -- SOURCE identifies a 'normal' zone. -- COPY identifes that a zone is a copy of another (SOURCE) zone -- EXTENSION makes it possible to add records to a copy zone that do not exist in the SOURCE create table virtdomains ( id SERIAL PRIMARY KEY, domain_id INT DEFAULT NULL, recordtype virttype default 'SOURCE', copydomain_id INT DEFAULT NULL, CONSTRAINT domain_exists FOREIGN KEY(domain_id) REFERENCES domains(id) ON DELETE CASCADE ); -- todo: constraint to check that copydomain is not null -- when recordtype = 'COPY' -- todo: constraint to check that extension points to the same domain of -- an existing copy zone CREATE UNIQUE INDEX virt_domain_id ON virtdomains (domain_id, recordtype); CREATE TABLE realrecords ( id SERIAL PRIMARY KEY, virtdomain_id INT DEFAULT NULL, name VARCHAR(255) DEFAULT NULL, type VARCHAR(6) DEFAULT NULL, content VARCHAR(255) DEFAULT NULL, ttl INT DEFAULT NULL, prio INT DEFAULT NULL, change_date INT DEFAULT NULL, CONSTRAINT virtdomain_exists FOREIGN KEY(virtdomain_id) REFERENCES virtdomains(id) ON DELETE CASCADE ); CREATE INDEX rec_name_index ON realrecords(name); CREATE INDEX nametype_index ON realrecords(name,type); CREATE INDEX domain_id ON realrecords(virtdomain_id); create view records as select d.id * 100000 + r.id as id, v.domain_id as domain_id, trim (leading '.' from r.name || '.' || d.name) as name, r.type as type, r.content as content, r.ttl as ttl, r.prio as prio, r.change_date as change_date from realrecords r, virtdomains v, domains d where d.id = v.domain_id and ( (v.recordtype in ('SOURCE', 'EXTENSION') and r.virtdomain_id = v.id ) OR (v.recordtype = 'COPY' and r.virtdomain_id = v.copydomain_id )); -- todo: fix view to make sure a record in the extension zone has -- precedence over SOURCE records -- todo: create a rule so it is possible to do inserts in records table -- insert some testdata: -- we have 3 domains: insert into domains (name, type) values ('company.com', ''); insert into domains (name, type) values ('company.net', ''); insert into domains (name, type) values ('company.org', ''); -- company.com has copyzones company.net and company.org insert into virtdomains (domain_id, recordtype) select id, 'SOURCE' from domains where name = 'company.com'; insert into virtdomains (domain_id, recordtype, copydomain_id) select d1.id, 'COPY', d2.id from domains d1, domains d2 where d1.name = 'company.net' and d2.name = 'company.com'; insert into virtdomains (domain_id, recordtype, copydomain_id) select d1.id, 'COPY', d2.id from domains d1, domains d2 where d1.name = 'company.org' and d2.name = 'company.com'; -- make a virtual zone that extends the COPY zone company.org to hold extra records only for company.org insert into virtdomains (domain_id, recordtype) select d1.id, 'EXTENSION' from domains d1 where d1.name = 'company.org'; -- insert some DNS records for all zones: insert into realrecords (virtdomain_id, name, type, content) select v.id, '', 'SOA', 'ns1.company.com hostmaster.company.com 2010030301' from virtdomains v, domains d where d.name = 'company.com' and d.id = v.domain_id; insert into realrecords (virtdomain_id, name, type, content) select v.id, 'www', 'A', '192.168.1.1' from virtdomains v, domains d where d.name = 'company.com' and d.id = v.domain_id; insert into realrecords (virtdomain_id, name, type, content) select v.id, 'ftp', 'A', '192.168.1.2' from virtdomains v, domains d where d.name = 'company.com' and d.id = v.domain_id; -- insert a record that only exists in the zone company.org insert into realrecords (virtdomain_id, name, type, content) select v.id, 'orgonly', 'A', '192.168.1.3' from virtdomains v, domains d where d.name = 'company.org' and d.id = v.domain_id and v.recordtype = 'EXTENSION'; -- SQL check: # select * from domains; id | name | master | last_check | type | notified_serial | account ----+-------------+--------+------------+------+-----------------+--------- 1 | company.com | | | | | 2 | company.net | | | | | 3 | company.org | | | | | (3 rows) ^^ 3 domains (as expected) # select id, domain_id, name, type, content from records ; id | domain_id | name | type | content --------+-----------+---------------------+------+--------------------------------------------------- 100001 | 1 | company.com | SOA | ns1.company.com hostmaster.company.com 2010030301 100002 | 1 | www.company.com | A | 192.168.1.1 100003 | 1 | ftp.company.com | A | 192.168.1.2 200001 | 2 | company.net | SOA | ns1.company.com hostmaster.company.com 2010030301 200002 | 2 | www.company.net | A | 192.168.1.1 200003 | 2 | ftp.company.net | A | 192.168.1.2 300001 | 3 | company.org | SOA | ns1.company.com hostmaster.company.com 2010030301 300002 | 3 | www.company.org | A | 192.168.1.1 300003 | 3 | ftp.company.org | A | 192.168.1.2 300004 | 3 | orgonly.company.org | A | 192.168.1.3 (10 rows) ^^^ 3 records for each domain, and 1 extra that only exists in de company.org zone (note that the ID is made unique here by adding the record id to 100,000 times the domain_id. Some tools might rely on the fact that id is unique) # select id, virtdomain_id, name, type, content from realrecords; id | virtdomain_id | name | type | content ----+---------------+---------+------+--------------------------------------------------- 1 | 1 | | SOA | ns1.company.com hostmaster.company.com 2010030301 2 | 1 | www | A | 192.168.1.1 3 | 1 | ftp | A | 192.168.1.2 4 | 4 | orgonly | A | 192.168.1.3 (4 rows) ^^^ only 4 real records. -- __________________________________________________ "Nothing is as subjective as reality" Reinoud van Leeuwen reinou...@n.leeuwen.net http://reinoud.van.leeuwen.net kvk 27320762 __________________________________________________ _______________________________________________ Pdns-users mailing list Pdns-users@mailman.powerdns.com http://mailman.powerdns.com/mailman/listinfo/pdns-users