summaryrefslogtreecommitdiffstats
path: root/third_party/dnspython/examples
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2014-11-07 20:09:10 +0000
committerJeremy Allison <jra@samba.org>2014-11-12 22:40:53 +0100
commitfb39c6fb5edf70097ee31e1b8638838dfc081892 (patch)
tree670982bbd040b87c7acb3d91c0da1a05bfe65994 /third_party/dnspython/examples
parent776424e99113a3ffc6679c583093e2892304a7fd (diff)
downloadsamba-fb39c6fb5edf70097ee31e1b8638838dfc081892.tar.gz
samba-fb39c6fb5edf70097ee31e1b8638838dfc081892.tar.xz
samba-fb39c6fb5edf70097ee31e1b8638838dfc081892.zip
Move dnspython to third_party.
Signed-off-by: Jelmer Vernooij <jelmer@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> Autobuild-User(master): Jeremy Allison <jra@samba.org> Autobuild-Date(master): Wed Nov 12 22:40:53 CET 2014 on sn-devel-104
Diffstat (limited to 'third_party/dnspython/examples')
-rwxr-xr-xthird_party/dnspython/examples/ddns.py51
-rwxr-xr-xthird_party/dnspython/examples/e164.py6
-rwxr-xr-xthird_party/dnspython/examples/mx.py7
-rwxr-xr-xthird_party/dnspython/examples/name.py13
-rwxr-xr-xthird_party/dnspython/examples/reverse.py40
-rwxr-xr-xthird_party/dnspython/examples/reverse_name.py6
-rwxr-xr-xthird_party/dnspython/examples/xfr.py14
-rwxr-xr-xthird_party/dnspython/examples/zonediff.py270
8 files changed, 407 insertions, 0 deletions
diff --git a/third_party/dnspython/examples/ddns.py b/third_party/dnspython/examples/ddns.py
new file mode 100755
index 0000000000..84814b73cf
--- /dev/null
+++ b/third_party/dnspython/examples/ddns.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+#
+# Use a TSIG-signed DDNS update to update our hostname-to-address
+# mapping.
+#
+# usage: ddns.py <ip-address>
+#
+# On linux systems, you can automatically update your DNS any time an
+# interface comes up by adding an ifup-local script that invokes this
+# python code.
+#
+# E.g. on my systems I have this
+#
+# #!/bin/sh
+#
+# DEVICE=$1
+#
+# if [ "X${DEVICE}" == "Xeth0" ]; then
+# IPADDR=`LANG= LC_ALL= ifconfig ${DEVICE} | grep 'inet addr' |
+# awk -F: '{ print $2 } ' | awk '{ print $1 }'`
+# /usr/local/sbin/ddns.py $IPADDR
+# fi
+#
+# in /etc/ifup-local.
+#
+
+import sys
+
+import dns.update
+import dns.query
+import dns.tsigkeyring
+
+#
+# Replace the keyname and secret with appropriate values for your
+# configuration.
+#
+keyring = dns.tsigkeyring.from_text({
+ 'keyname.' : 'NjHwPsMKjdN++dOfE5iAiQ=='
+ })
+
+#
+# Replace "example." with your domain, and "host" with your hostname.
+#
+update = dns.update.Update('example.', keyring=keyring)
+update.replace('host', 300, 'A', sys.argv[1])
+
+#
+# Replace "10.0.0.1" with the IP address of your master server.
+#
+response = dns.query.tcp(update, '10.0.0.1', timeout=10)
diff --git a/third_party/dnspython/examples/e164.py b/third_party/dnspython/examples/e164.py
new file mode 100755
index 0000000000..ad40ccf84b
--- /dev/null
+++ b/third_party/dnspython/examples/e164.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+
+import dns.e164
+n = dns.e164.from_e164("+1 555 1212")
+print n
+print dns.e164.to_e164(n)
diff --git a/third_party/dnspython/examples/mx.py b/third_party/dnspython/examples/mx.py
new file mode 100755
index 0000000000..3036e70ddf
--- /dev/null
+++ b/third_party/dnspython/examples/mx.py
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+
+import dns.resolver
+
+answers = dns.resolver.query('nominum.com', 'MX')
+for rdata in answers:
+ print 'Host', rdata.exchange, 'has preference', rdata.preference
diff --git a/third_party/dnspython/examples/name.py b/third_party/dnspython/examples/name.py
new file mode 100755
index 0000000000..b099c49d16
--- /dev/null
+++ b/third_party/dnspython/examples/name.py
@@ -0,0 +1,13 @@
+#!/usr/bin/env python
+
+import dns.name
+
+n = dns.name.from_text('www.dnspython.org')
+o = dns.name.from_text('dnspython.org')
+print n.is_subdomain(o) # True
+print n.is_superdomain(o) # False
+print n > o # True
+rel = n.relativize(o) # rel is the relative name www
+n2 = rel + o
+print n2 == n # True
+print n.labels # ['www', 'dnspython', 'org', '']
diff --git a/third_party/dnspython/examples/reverse.py b/third_party/dnspython/examples/reverse.py
new file mode 100755
index 0000000000..8657baed44
--- /dev/null
+++ b/third_party/dnspython/examples/reverse.py
@@ -0,0 +1,40 @@
+#!/usr/bin/env python
+
+# Usage: reverse.py <zone_filename>...
+#
+# This demo script will load in all of the zones specified by the
+# filenames on the command line, find all the A RRs in them, and
+# construct a reverse mapping table that maps each IP address used to
+# the list of names mapping to that address. The table is then sorted
+# nicely and printed.
+#
+# Note! The zone name is taken from the basename of the filename, so
+# you must use filenames like "/wherever/you/like/dnspython.org" and
+# not something like "/wherever/you/like/foo.db" (unless you're
+# working with the ".db" GTLD, of course :)).
+#
+# If this weren't a demo script, there'd be a way of specifying the
+# origin for each zone instead of constructing it from the filename.
+
+import dns.zone
+import dns.ipv4
+import os.path
+import sys
+
+reverse_map = {}
+
+for filename in sys.argv[1:]:
+ zone = dns.zone.from_file(filename, os.path.basename(filename),
+ relativize=False)
+ for (name, ttl, rdata) in zone.iterate_rdatas('A'):
+ try:
+ reverse_map[rdata.address].append(name.to_text())
+ except KeyError:
+ reverse_map[rdata.address] = [name.to_text()]
+
+keys = reverse_map.keys()
+keys.sort(lambda a1, a2: cmp(dns.ipv4.inet_aton(a1), dns.ipv4.inet_aton(a2)))
+for k in keys:
+ v = reverse_map[k]
+ v.sort()
+ print k, v
diff --git a/third_party/dnspython/examples/reverse_name.py b/third_party/dnspython/examples/reverse_name.py
new file mode 100755
index 0000000000..351896b015
--- /dev/null
+++ b/third_party/dnspython/examples/reverse_name.py
@@ -0,0 +1,6 @@
+#!/usr/bin/env python
+
+import dns.reversename
+n = dns.reversename.from_address("127.0.0.1")
+print n
+print dns.reversename.to_address(n)
diff --git a/third_party/dnspython/examples/xfr.py b/third_party/dnspython/examples/xfr.py
new file mode 100755
index 0000000000..e67ab18927
--- /dev/null
+++ b/third_party/dnspython/examples/xfr.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+import dns.query
+import dns.resolver
+import dns.zone
+
+soa_answer = dns.resolver.query('dnspython.org', 'SOA')
+master_answer = dns.resolver.query(soa_answer[0].mname, 'A')
+
+z = dns.zone.from_xfr(dns.query.xfr(master_answer[0].address, 'dnspython.org'))
+names = z.nodes.keys()
+names.sort()
+for n in names:
+ print z[n].to_text(n)
diff --git a/third_party/dnspython/examples/zonediff.py b/third_party/dnspython/examples/zonediff.py
new file mode 100755
index 0000000000..ad81fb1d2d
--- /dev/null
+++ b/third_party/dnspython/examples/zonediff.py
@@ -0,0 +1,270 @@
+#!/usr/bin/env python
+#
+# Small library and commandline tool to do logical diffs of zonefiles
+# ./zonediff -h gives you help output
+#
+# Requires dnspython to do all the heavy lifting
+#
+# (c)2009 Dennis Kaarsemaker <dennis@kaarsemaker.net>
+#
+# 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 THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR 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.
+"""See diff_zones.__doc__ for more information"""
+
+__all__ = ['diff_zones', 'format_changes_plain', 'format_changes_html']
+
+try:
+ import dns.zone
+except ImportError:
+ import sys
+ sys.stderr.write("Please install dnspython")
+ sys.exit(1)
+
+def diff_zones(zone1, zone2, ignore_ttl=False, ignore_soa=False):
+ """diff_zones(zone1, zone2, ignore_ttl=False, ignore_soa=False) -> changes
+ Compares two dns.zone.Zone objects and returns a list of all changes
+ in the format (name, oldnode, newnode).
+
+ If ignore_ttl is true, a node will not be added to this list if the
+ only change is its TTL.
+
+ If ignore_soa is true, a node will not be added to this list if the
+ only changes is a change in a SOA Rdata set.
+
+ The returned nodes do include all Rdata sets, including unchanged ones.
+ """
+
+ changes = []
+ for name in zone1:
+ name = str(name)
+ n1 = zone1.get_node(name)
+ n2 = zone2.get_node(name)
+ if not n2:
+ changes.append((str(name), n1, n2))
+ elif _nodes_differ(n1, n2, ignore_ttl, ignore_soa):
+ changes.append((str(name), n1, n2))
+
+ for name in zone2:
+ n1 = zone1.get_node(name)
+ if not n1:
+ n2 = zone2.get_node(name)
+ changes.append((str(name), n1, n2))
+ return changes
+
+def _nodes_differ(n1, n2, ignore_ttl, ignore_soa):
+ if ignore_soa or not ignore_ttl:
+ # Compare datasets directly
+ for r in n1.rdatasets:
+ if ignore_soa and r.rdtype == dns.rdatatype.SOA:
+ continue
+ if r not in n2.rdatasets:
+ return True
+ if not ignore_ttl:
+ return r.ttl != n2.find_rdataset(r.rdclass, r.rdtype).ttl
+
+ for r in n2.rdatasets:
+ if ignore_soa and r.rdtype == dns.rdatatype.SOA:
+ continue
+ if r not in n1.rdatasets:
+ return True
+ else:
+ return n1 != n2
+
+def format_changes_plain(oldf, newf, changes, ignore_ttl=False):
+ """format_changes(oldfile, newfile, changes, ignore_ttl=False) -> str
+ Given 2 filenames and a list of changes from diff_zones, produce diff-like
+ output. If ignore_ttl is True, TTL-only changes are not displayed"""
+
+ ret = "--- %s\n+++ %s\n" % (oldf, newf)
+ for name, old, new in changes:
+ ret += "@ %s\n" % name
+ if not old:
+ for r in new.rdatasets:
+ ret += "+ %s\n" % str(r).replace('\n','\n+ ')
+ elif not new:
+ for r in old.rdatasets:
+ ret += "- %s\n" % str(r).replace('\n','\n+ ')
+ else:
+ for r in old.rdatasets:
+ if r not in new.rdatasets or (r.ttl != new.find_rdataset(r.rdclass, r.rdtype).ttl and not ignore_ttl):
+ ret += "- %s\n" % str(r).replace('\n','\n+ ')
+ for r in new.rdatasets:
+ if r not in old.rdatasets or (r.ttl != old.find_rdataset(r.rdclass, r.rdtype).ttl and not ignore_ttl):
+ ret += "+ %s\n" % str(r).replace('\n','\n+ ')
+ return ret
+
+def format_changes_html(oldf, newf, changes, ignore_ttl=False):
+ """format_changes(oldfile, newfile, changes, ignore_ttl=False) -> str
+ Given 2 filenames and a list of changes from diff_zones, produce nice html
+ output. If ignore_ttl is True, TTL-only changes are not displayed"""
+
+ ret = '''<table class="zonediff">
+ <thead>
+ <tr>
+ <th>&nbsp;</th>
+ <th class="old">%s</th>
+ <th class="new">%s</th>
+ </tr>
+ </thead>
+ <tbody>\n''' % (oldf, newf)
+
+ for name, old, new in changes:
+ ret += ' <tr class="rdata">\n <td class="rdname">%s</td>\n' % name
+ if not old:
+ for r in new.rdatasets:
+ ret += ' <td class="old">&nbsp;</td>\n <td class="new">%s</td>\n' % str(r).replace('\n','<br />')
+ elif not new:
+ for r in old.rdatasets:
+ ret += ' <td class="old">%s</td>\n <td class="new">&nbsp;</td>\n' % str(r).replace('\n','<br />')
+ else:
+ ret += ' <td class="old">'
+ for r in old.rdatasets:
+ if r not in new.rdatasets or (r.ttl != new.find_rdataset(r.rdclass, r.rdtype).ttl and not ignore_ttl):
+ ret += str(r).replace('\n','<br />')
+ ret += '</td>\n'
+ ret += ' <td class="new">'
+ for r in new.rdatasets:
+ if r not in old.rdatasets or (r.ttl != old.find_rdataset(r.rdclass, r.rdtype).ttl and not ignore_ttl):
+ ret += str(r).replace('\n','<br />')
+ ret += '</td>\n'
+ ret += ' </tr>\n'
+ return ret + ' </tbody>\n</table>'
+
+# Make this module usable as a script too.
+if __name__ == '__main__':
+ import optparse
+ import subprocess
+ import sys
+ import traceback
+
+ usage = """%prog zonefile1 zonefile2 - Show differences between zones in a diff-like format
+%prog [--git|--bzr|--rcs] zonefile rev1 [rev2] - Show differences between two revisions of a zonefile
+
+The differences shown will be logical differences, not textual differences.
+"""
+ p = optparse.OptionParser(usage=usage)
+ p.add_option('-s', '--ignore-soa', action="store_true", default=False, dest="ignore_soa",
+ help="Ignore SOA-only changes to records")
+ p.add_option('-t', '--ignore-ttl', action="store_true", default=False, dest="ignore_ttl",
+ help="Ignore TTL-only changes to Rdata")
+ p.add_option('-T', '--traceback', action="store_true", default=False, dest="tracebacks",
+ help="Show python tracebacks when errors occur")
+ p.add_option('-H', '--html', action="store_true", default=False, dest="html",
+ help="Print HTML output")
+ p.add_option('-g', '--git', action="store_true", default=False, dest="use_git",
+ help="Use git revisions instead of real files")
+ p.add_option('-b', '--bzr', action="store_true", default=False, dest="use_bzr",
+ help="Use bzr revisions instead of real files")
+ p.add_option('-r', '--rcs', action="store_true", default=False, dest="use_rcs",
+ help="Use rcs revisions instead of real files")
+ opts, args = p.parse_args()
+ opts.use_vc = opts.use_git or opts.use_bzr or opts.use_rcs
+
+ def _open(what, err):
+ if isinstance(what, basestring):
+ # Open as normal file
+ try:
+ return open(what, 'rb')
+ except:
+ sys.stderr.write(err + "\n")
+ if opts.tracebacks:
+ traceback.print_exc()
+ else:
+ # Must be a list, open subprocess
+ try:
+ proc = subprocess.Popen(what, stdout=subprocess.PIPE)
+ proc.wait()
+ if proc.returncode == 0:
+ return proc.stdout
+ sys.stderr.write(err + "\n")
+ except:
+ sys.stderr.write(err + "\n")
+ if opts.tracebacks:
+ traceback.print_exc()
+
+ if not opts.use_vc and len(args) != 2:
+ p.print_help()
+ sys.exit(64)
+ if opts.use_vc and len(args) not in (2,3):
+ p.print_help()
+ sys.exit(64)
+
+ # Open file desriptors
+ if not opts.use_vc:
+ oldn, newn = args
+ else:
+ if len(args) == 3:
+ filename, oldr, newr = args
+ oldn = "%s:%s" % (oldr, filename)
+ newn = "%s:%s" % (newr, filename)
+ else:
+ filename, oldr = args
+ newr = None
+ oldn = "%s:%s" % (oldr, filename)
+ newn = filename
+
+
+ old, new = None, None
+ oldz, newz = None, None
+ if opts.use_bzr:
+ old = _open(["bzr", "cat", "-r" + oldr, filename],
+ "Unable to retrieve revision %s of %s" % (oldr, filename))
+ if newr != None:
+ new = _open(["bzr", "cat", "-r" + newr, filename],
+ "Unable to retrieve revision %s of %s" % (newr, filename))
+ elif opts.use_git:
+ old = _open(["git", "show", oldn],
+ "Unable to retrieve revision %s of %s" % (oldr, filename))
+ if newr != None:
+ new = _open(["git", "show", newn],
+ "Unable to retrieve revision %s of %s" % (newr, filename))
+ elif opts.use_rcs:
+ old = _open(["co", "-q", "-p", "-r" + oldr, filename],
+ "Unable to retrieve revision %s of %s" % (oldr, filename))
+ if newr != None:
+ new = _open(["co", "-q", "-p", "-r" + newr, filename],
+ "Unable to retrieve revision %s of %s" % (newr, filename))
+ if not opts.use_vc:
+ old = _open(oldn, "Unable to open %s" % oldn)
+ if not opts.use_vc or newr == None:
+ new = _open(newn, "Unable to open %s" % newn)
+
+ if not old or not new:
+ sys.exit(65)
+
+ # Parse the zones
+ try:
+ oldz = dns.zone.from_file(old, origin = '.', check_origin=False)
+ except dns.exception.DNSException:
+ sys.stderr.write("Incorrect zonefile: %s\n", old)
+ if opts.tracebacks:
+ traceback.print_exc()
+ try:
+ newz = dns.zone.from_file(new, origin = '.', check_origin=False)
+ except dns.exception.DNSException:
+ sys.stderr.write("Incorrect zonefile: %s\n" % new)
+ if opts.tracebacks:
+ traceback.print_exc()
+ if not oldz or not newz:
+ sys.exit(65)
+
+ changes = diff_zones(oldz, newz, opts.ignore_ttl, opts.ignore_soa)
+ changes.sort()
+
+ if not changes:
+ sys.exit(0)
+ if opts.html:
+ print format_changes_html(oldn, newn, changes, opts.ignore_ttl)
+ else:
+ print format_changes_plain(oldn, newn, changes, opts.ignore_ttl)
+ sys.exit(1)