/usr/share/pyshared/twill/extensions/dns_check.py is in python-twill 0.9-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | """
Extension functions to help query/assert name service information.
Functions:
* dns_resolves -- assert that a host resolves to a specific IP address.
* dns_a -- assert that a host directly resolves to a specific IP address
* dns_cname -- assert that a host is an alias for another hostname.
* dnx_mx -- assert that a given host is a mail exchanger for the given name.
* dns_ns -- assert that a given hostname is a name server for the given name.
"""
import socket
from twill.errors import TwillAssertionError
try:
import dns.resolver
except ImportError:
raise Exception("ERROR: must have dnspython installed to use the DNS extension module")
def dns_a(host, ipaddress, server=None):
"""
>> dns_a <name> <ipaddress> [<name server>]
Assert that <name> resolves to <ipaddress> (and is an A record).
Optionally use the given name server.
"""
if not is_ip_addr(ipaddress):
raise Exception("<ipaddress> parameter must be an IP address, not a hostname")
for answer in _query(host, 'A', server):
if ipaddress == answer.address:
return True
raise TwillAssertionError
def dns_cname(host, cname, server=None):
"""
>> dns_cname <name> <alias_for> [<name server>]
Assert that <name> is a CNAME alias for <alias_for> Optionally use
<name server>.
"""
if is_ip_addr(cname):
raise Exception("<alias_for> parameter must be a hostname, not an IP address")
cname = dns.name.from_text(cname)
for answer in _query(host, 'CNAME', server):
if cname == answer.target:
return True
raise TwillAssertionError
def dns_resolves(host, ipaddress, server=None):
"""
>> dns_resolves <name> <name2/ipaddress> [<name server>]
Assert that <name> ultimately resolves to the given IP address (or
the same IP address that 'name2' resolves to). Optionally use the
given name server.
"""
if not is_ip_addr(ipaddress):
ipaddress = _resolve_name(ipaddress, server)
for answer in _query(host, 1, server):
if ipaddress == answer.address:
return True
raise TwillAssertionError
def dns_mx(host, mailserver, server=None):
"""
>> dns_mx <name> <mailserver> [<name server>]
Assert that <mailserver> is a mailserver for <name>.
"""
mailserver = dns.name.from_text(mailserver)
for rdata in _query(host, 'MX', server):
if mailserver == rdata.exchange:
return True
raise TwillAssertionError
def dns_ns(host, query_ns, server=None):
"""
>> dns_ns <domain> <nameserver> [<name server to use>]
Assert that <nameserver> is a mailserver for <domain>.
"""
query_ns = dns.name.from_text(query_ns)
for answer in _query(host, 'NS', server):
if query_ns == answer.target:
return True
raise TwillAssertionError
###
def is_ip_addr(text):
"""
Check the 'name' to see if it's just an IP address.
"""
try:
v = dns.ipv4.inet_aton(text)
return True
except socket.error:
return False
def _resolve_name(name, server):
"""
Resolve the given name to an IP address.
"""
if is_ip_addr(name):
return name
r = dns.resolver.Resolver()
if server:
r.nameservers = [_resolve_name(server, None)]
answers = r.query(name)
answer = None
for answer in answers: # @CTB !?
break
assert answer
return str(answer)
def _query(query, query_type, server):
"""
Query, perhaps via the given name server. (server=None to use default).
"""
r = dns.resolver.Resolver()
if server:
r.nameservers = [_resolve_name(server, None)]
return r.query(query, query_type)
|