# Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license # Copyright (C) 2003-2007, 2009-2011 Nominum, Inc. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose with or without fee is hereby granted, # provided that the above copyright notice and this permission notice # appear in all copies. # # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. import sys sys.path.insert(0, '../') # Force the local project to be *the* dns import unittest import dns.exception import dns.rdata import dns.rdataclass import dns.rdatatype import dns.rrset import dns.zone example_text = """$TTL 1h $ORIGIN 0.0.192.IN-ADDR.ARPA. $GENERATE 1-2 0 CNAME SERVER$.EXAMPLE. """ example_text1 = """$TTL 1h $ORIGIN 0.0.192.IN-ADDR.ARPA. $GENERATE 1-10 fooo$ CNAME $.0 """ example_text2 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 3-5 foo$ A 10.0.0.$ """ example_text3 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 4-8/2 foo$ A 10.0.0.$ """ example_text4 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 11-13 wp-db${-10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR. """ example_text5 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 11-13 wp-db${10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR. """ example_text6 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 11-13 wp-db${+10,2,d}.services.mozilla.com 0 CNAME SERVER.FOOBAR. """ example_text7 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 11-13 sync${-10}.db IN A 10.10.16.0 """ example_text8 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 11-12 wp-db${-10,2,d} IN A 10.10.16.0 """ example_text9 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 11-12 wp-db${-10,2,d} IN A 10.10.16.0 $GENERATE 11-13 sync${-10}.db IN A 10.10.16.0 """ example_text10 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 27-28 $.2 PTR zlb${-26}.oob """ example_text11 = """$TTL 1h @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 bar.foo 300 IN MX 0 blaz.foo ns1 3600 IN A 10.0.0.1 ns2 3600 IN A 10.0.0.2 $GENERATE 27-28 prefix-${0,3} A 10.0.0.$ """ last_ttl_input = """foo 300 mx 10 target. $GENERATE 1-10 foo$ CNAME $.0 @ 3600 IN SOA foo bar 1 2 3 4 5 @ 3600 IN NS ns1 @ 3600 IN NS ns2 """ def _rdata_sort(a): return (a[0], a[2].rdclass, a[2].to_text()) class GenerateTestCase(unittest.TestCase): def testFromText(self): # type: () -> None def bad(): # type: () -> None dns.zone.from_text(example_text, 'example.', relativize=True) self.assertRaises(dns.zone.NoSOA, bad) def testFromText1(self): # type: () -> None def bad(): # type: () -> None dns.zone.from_text(example_text1, 'example.', relativize=True) self.assertRaises(dns.zone.NoSOA, bad) def testIterateAllRdatas2(self): # type: () -> None z = dns.zone.from_text(example_text2, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('foo3', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.3')), (dns.name.from_text('foo4', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.4')), (dns.name.from_text('foo5', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.5'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testIterateAllRdatas3(self): # type: () -> None z = dns.zone.from_text(example_text3, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('foo4', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.4')), (dns.name.from_text('foo6', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.6')), (dns.name.from_text('foo8', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.8'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testGenerate1(self): # type: () -> None z = dns.zone.from_text(example_text4, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('wp-db01.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), (dns.name.from_text('wp-db02.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), (dns.name.from_text('wp-db03.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testGenerate2(self): # type: () -> None z = dns.zone.from_text(example_text5, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('wp-db21.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), (dns.name.from_text('wp-db22.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), (dns.name.from_text('wp-db23.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testGenerate3(self): # type: () -> None z = dns.zone.from_text(example_text6, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('wp-db21.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), (dns.name.from_text('wp-db22.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.')), (dns.name.from_text('wp-db23.services.mozilla.com', None), 0, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.CNAME, 'SERVER.FOOBAR.'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testGenerate4(self): # type: () -> None z = dns.zone.from_text(example_text7, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('sync1.db', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), (dns.name.from_text('sync2.db', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), (dns.name.from_text('sync3.db', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testGenerate6(self): # type: () -> None z = dns.zone.from_text(example_text9, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('wp-db01', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), (dns.name.from_text('wp-db02', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), (dns.name.from_text('sync1.db', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), (dns.name.from_text('sync2.db', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0')), (dns.name.from_text('sync3.db', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.10.16.0'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testGenerate7(self): # type: () -> None z = dns.zone.from_text(example_text10, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2')), (dns.name.from_text('27.2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR, 'zlb1.oob')), (dns.name.from_text('28.2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.PTR, 'zlb2.oob'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testGenerate8(self): # type: () -> None z = dns.zone.from_text(example_text11, 'example.', relativize=True) l = list(z.iterate_rdatas()) l.sort(key=_rdata_sort) exl = [(dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns1')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.NS, 'ns2')), (dns.name.from_text('@', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.SOA, 'foo bar 1 2 3 4 5')), (dns.name.from_text('bar.foo', None), 300, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.MX, '0 blaz.foo')), (dns.name.from_text('prefix-027', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.27')), (dns.name.from_text('prefix-028', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.28')), (dns.name.from_text('ns1', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.1')), (dns.name.from_text('ns2', None), 3600, dns.rdata.from_text(dns.rdataclass.IN, dns.rdatatype.A, '10.0.0.2'))] exl.sort(key=_rdata_sort) self.assertEqual(l, exl) def testNoOrigin(self): def bad(): dns.zone.from_text('$GENERATE 1-10 fooo$ CNAME $.0') self.assertRaises(dns.zone.UnknownOrigin, bad) def testBadRdata(self): def bad(): dns.zone.from_text('$GENERATE 1-10 fooo$ CNAME 10 $.0', 'example') self.assertRaises(dns.exception.SyntaxError, bad) def testUsesLastTTL(self): z = dns.zone.from_text(last_ttl_input, 'example') rrs = z.find_rrset('foo9', 'CNAME') self.assertEqual(rrs.ttl, 300) def testClassMismatch(self): def bad(): dns.zone.from_text('$GENERATE 1-10 fooo$ CH CNAME $.0', 'example') self.assertRaises(dns.exception.SyntaxError, bad) def testUnknownRdatatype(self): def bad(): dns.zone.from_text('$GENERATE 1-10 fooo$ BOGUSTYPE $.0', 'example') self.assertRaises(dns.exception.SyntaxError, bad) def testBadAndDangling(self): def bad1(): dns.zone.from_text('$GENERATE bogus fooo$ CNAME $.0', 'example.') self.assertRaises(dns.exception.SyntaxError, bad1) def bad2(): dns.zone.from_text('$GENERATE 1-10', 'example.') self.assertRaises(dns.exception.SyntaxError, bad2) def bad3(): dns.zone.from_text('$GENERATE 1-10 foo$', 'example.') self.assertRaises(dns.exception.SyntaxError, bad3) if __name__ == '__main__': unittest.main()