mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-07-15 01:32:57 -07:00
Update dnspython-2.2.0
This commit is contained in:
parent
4b28040d59
commit
4d62245cf5
111 changed files with 9077 additions and 5877 deletions
|
@ -1,3 +1,5 @@
|
|||
# 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
|
||||
|
@ -23,62 +25,99 @@ import dns.rdata
|
|||
import dns.rdataclass
|
||||
import dns.rdataset
|
||||
import dns.tsig
|
||||
from ._compat import string_types
|
||||
|
||||
|
||||
class Update(dns.message.Message):
|
||||
class UpdateSection(dns.enum.IntEnum):
|
||||
"""Update sections"""
|
||||
ZONE = 0
|
||||
PREREQ = 1
|
||||
UPDATE = 2
|
||||
ADDITIONAL = 3
|
||||
|
||||
def __init__(self, zone, rdclass=dns.rdataclass.IN, keyring=None,
|
||||
keyname=None, keyalgorithm=dns.tsig.default_algorithm):
|
||||
@classmethod
|
||||
def _maximum(cls):
|
||||
return 3
|
||||
|
||||
globals().update(UpdateSection.__members__)
|
||||
|
||||
|
||||
class UpdateMessage(dns.message.Message):
|
||||
|
||||
_section_enum = UpdateSection
|
||||
|
||||
def __init__(self, zone=None, rdclass=dns.rdataclass.IN, keyring=None,
|
||||
keyname=None, keyalgorithm=dns.tsig.default_algorithm,
|
||||
id=None):
|
||||
"""Initialize a new DNS Update object.
|
||||
|
||||
@param zone: The zone which is being updated.
|
||||
@type zone: A dns.name.Name or string
|
||||
@param rdclass: The class of the zone; defaults to dns.rdataclass.IN.
|
||||
@type rdclass: An int designating the class, or a string whose value
|
||||
is the name of a class.
|
||||
@param keyring: The TSIG keyring to use; defaults to None.
|
||||
@type keyring: dict
|
||||
@param keyname: The name of the TSIG key to use; defaults to None.
|
||||
The key must be defined in the keyring. If a keyring is specified
|
||||
but a keyname is not, then the key used will be the first key in the
|
||||
keyring. Note that the order of keys in a dictionary is not defined,
|
||||
so applications should supply a keyname when a keyring is used, unless
|
||||
they know the keyring contains only one key.
|
||||
@type keyname: dns.name.Name or string
|
||||
@param keyalgorithm: The TSIG algorithm to use; defaults to
|
||||
dns.tsig.default_algorithm. Constants for TSIG algorithms are defined
|
||||
in dns.tsig, and the currently implemented algorithms are
|
||||
HMAC_MD5, HMAC_SHA1, HMAC_SHA224, HMAC_SHA256, HMAC_SHA384, and
|
||||
HMAC_SHA512.
|
||||
@type keyalgorithm: string
|
||||
See the documentation of the Message class for a complete
|
||||
description of the keyring dictionary.
|
||||
|
||||
*zone*, a ``dns.name.Name``, ``str``, or ``None``, the zone
|
||||
which is being updated. ``None`` should only be used by dnspython's
|
||||
message constructors, as a zone is required for the convenience
|
||||
methods like ``add()``, ``replace()``, etc.
|
||||
|
||||
*rdclass*, an ``int`` or ``str``, the class of the zone.
|
||||
|
||||
The *keyring*, *keyname*, and *keyalgorithm* parameters are passed to
|
||||
``use_tsig()``; see its documentation for details.
|
||||
"""
|
||||
super(Update, self).__init__()
|
||||
super().__init__(id=id)
|
||||
self.flags |= dns.opcode.to_flags(dns.opcode.UPDATE)
|
||||
if isinstance(zone, string_types):
|
||||
if isinstance(zone, str):
|
||||
zone = dns.name.from_text(zone)
|
||||
self.origin = zone
|
||||
if isinstance(rdclass, string_types):
|
||||
rdclass = dns.rdataclass.from_text(rdclass)
|
||||
rdclass = dns.rdataclass.RdataClass.make(rdclass)
|
||||
self.zone_rdclass = rdclass
|
||||
self.find_rrset(self.question, self.origin, rdclass, dns.rdatatype.SOA,
|
||||
create=True, force_unique=True)
|
||||
if self.origin:
|
||||
self.find_rrset(self.zone, self.origin, rdclass, dns.rdatatype.SOA,
|
||||
create=True, force_unique=True)
|
||||
if keyring is not None:
|
||||
self.use_tsig(keyring, keyname, algorithm=keyalgorithm)
|
||||
|
||||
@property
|
||||
def zone(self):
|
||||
"""The zone section."""
|
||||
return self.sections[0]
|
||||
|
||||
@zone.setter
|
||||
def zone(self, v):
|
||||
self.sections[0] = v
|
||||
|
||||
@property
|
||||
def prerequisite(self):
|
||||
"""The prerequisite section."""
|
||||
return self.sections[1]
|
||||
|
||||
@prerequisite.setter
|
||||
def prerequisite(self, v):
|
||||
self.sections[1] = v
|
||||
|
||||
@property
|
||||
def update(self):
|
||||
"""The update section."""
|
||||
return self.sections[2]
|
||||
|
||||
@update.setter
|
||||
def update(self, v):
|
||||
self.sections[2] = v
|
||||
|
||||
def _add_rr(self, name, ttl, rd, deleting=None, section=None):
|
||||
"""Add a single RR to the update section."""
|
||||
|
||||
if section is None:
|
||||
section = self.authority
|
||||
section = self.update
|
||||
covers = rd.covers()
|
||||
rrset = self.find_rrset(section, name, self.zone_rdclass, rd.rdtype,
|
||||
covers, deleting, True, True)
|
||||
rrset.add(rd, ttl)
|
||||
|
||||
def _add(self, replace, section, name, *args):
|
||||
"""Add records. The first argument is the replace mode. If
|
||||
false, RRs are added to an existing RRset; if true, the RRset
|
||||
"""Add records.
|
||||
|
||||
*replace* is the replacement mode. If ``False``,
|
||||
RRs are added to an existing RRset; if ``True``, the RRset
|
||||
is replaced with the specified contents. The second
|
||||
argument is the section to add to. The third argument
|
||||
is always a name. The other arguments can be:
|
||||
|
@ -87,9 +126,10 @@ class Update(dns.message.Message):
|
|||
|
||||
- ttl, rdata...
|
||||
|
||||
- ttl, rdtype, string..."""
|
||||
- ttl, rdtype, string...
|
||||
"""
|
||||
|
||||
if isinstance(name, string_types):
|
||||
if isinstance(name, str):
|
||||
name = dns.name.from_text(name, None)
|
||||
if isinstance(args[0], dns.rdataset.Rdataset):
|
||||
for rds in args:
|
||||
|
@ -106,9 +146,7 @@ class Update(dns.message.Message):
|
|||
for rd in args:
|
||||
self._add_rr(name, ttl, rd, section=section)
|
||||
else:
|
||||
rdtype = args.pop(0)
|
||||
if isinstance(rdtype, string_types):
|
||||
rdtype = dns.rdatatype.from_text(rdtype)
|
||||
rdtype = dns.rdatatype.RdataType.make(args.pop(0))
|
||||
if replace:
|
||||
self.delete(name, rdtype)
|
||||
for s in args:
|
||||
|
@ -117,32 +155,39 @@ class Update(dns.message.Message):
|
|||
self._add_rr(name, ttl, rd, section=section)
|
||||
|
||||
def add(self, name, *args):
|
||||
"""Add records. The first argument is always a name. The other
|
||||
"""Add records.
|
||||
|
||||
The first argument is always a name. The other
|
||||
arguments can be:
|
||||
|
||||
- rdataset...
|
||||
|
||||
- ttl, rdata...
|
||||
|
||||
- ttl, rdtype, string..."""
|
||||
self._add(False, self.authority, name, *args)
|
||||
- ttl, rdtype, string...
|
||||
"""
|
||||
|
||||
self._add(False, self.update, name, *args)
|
||||
|
||||
def delete(self, name, *args):
|
||||
"""Delete records. The first argument is always a name. The other
|
||||
"""Delete records.
|
||||
|
||||
The first argument is always a name. The other
|
||||
arguments can be:
|
||||
|
||||
- I{nothing}
|
||||
- *empty*
|
||||
|
||||
- rdataset...
|
||||
|
||||
- rdata...
|
||||
|
||||
- rdtype, [string...]"""
|
||||
- rdtype, [string...]
|
||||
"""
|
||||
|
||||
if isinstance(name, string_types):
|
||||
if isinstance(name, str):
|
||||
name = dns.name.from_text(name, None)
|
||||
if len(args) == 0:
|
||||
self.find_rrset(self.authority, name, dns.rdataclass.ANY,
|
||||
self.find_rrset(self.update, name, dns.rdataclass.ANY,
|
||||
dns.rdatatype.ANY, dns.rdatatype.NONE,
|
||||
dns.rdatatype.ANY, True, True)
|
||||
elif isinstance(args[0], dns.rdataset.Rdataset):
|
||||
|
@ -155,11 +200,9 @@ class Update(dns.message.Message):
|
|||
for rd in args:
|
||||
self._add_rr(name, 0, rd, dns.rdataclass.NONE)
|
||||
else:
|
||||
rdtype = args.pop(0)
|
||||
if isinstance(rdtype, string_types):
|
||||
rdtype = dns.rdatatype.from_text(rdtype)
|
||||
rdtype = dns.rdatatype.RdataType.make(args.pop(0))
|
||||
if len(args) == 0:
|
||||
self.find_rrset(self.authority, name,
|
||||
self.find_rrset(self.update, name,
|
||||
self.zone_rdclass, rdtype,
|
||||
dns.rdatatype.NONE,
|
||||
dns.rdataclass.ANY,
|
||||
|
@ -171,7 +214,9 @@ class Update(dns.message.Message):
|
|||
self._add_rr(name, 0, rd, dns.rdataclass.NONE)
|
||||
|
||||
def replace(self, name, *args):
|
||||
"""Replace records. The first argument is always a name. The other
|
||||
"""Replace records.
|
||||
|
||||
The first argument is always a name. The other
|
||||
arguments can be:
|
||||
|
||||
- rdataset...
|
||||
|
@ -181,26 +226,30 @@ class Update(dns.message.Message):
|
|||
- ttl, rdtype, string...
|
||||
|
||||
Note that if you want to replace the entire node, you should do
|
||||
a delete of the name followed by one or more calls to add."""
|
||||
a delete of the name followed by one or more calls to add.
|
||||
"""
|
||||
|
||||
self._add(True, self.authority, name, *args)
|
||||
self._add(True, self.update, name, *args)
|
||||
|
||||
def present(self, name, *args):
|
||||
"""Require that an owner name (and optionally an rdata type,
|
||||
or specific rdataset) exists as a prerequisite to the
|
||||
execution of the update. The first argument is always a name.
|
||||
execution of the update.
|
||||
|
||||
The first argument is always a name.
|
||||
The other arguments can be:
|
||||
|
||||
- rdataset...
|
||||
|
||||
- rdata...
|
||||
|
||||
- rdtype, string..."""
|
||||
- rdtype, string...
|
||||
"""
|
||||
|
||||
if isinstance(name, string_types):
|
||||
if isinstance(name, str):
|
||||
name = dns.name.from_text(name, None)
|
||||
if len(args) == 0:
|
||||
self.find_rrset(self.answer, name,
|
||||
self.find_rrset(self.prerequisite, name,
|
||||
dns.rdataclass.ANY, dns.rdatatype.ANY,
|
||||
dns.rdatatype.NONE, None,
|
||||
True, True)
|
||||
|
@ -211,12 +260,10 @@ class Update(dns.message.Message):
|
|||
# Add a 0 TTL
|
||||
args = list(args)
|
||||
args.insert(0, 0)
|
||||
self._add(False, self.answer, name, *args)
|
||||
self._add(False, self.prerequisite, name, *args)
|
||||
else:
|
||||
rdtype = args[0]
|
||||
if isinstance(rdtype, string_types):
|
||||
rdtype = dns.rdatatype.from_text(rdtype)
|
||||
self.find_rrset(self.answer, name,
|
||||
rdtype = dns.rdatatype.RdataType.make(args[0])
|
||||
self.find_rrset(self.prerequisite, name,
|
||||
dns.rdataclass.ANY, rdtype,
|
||||
dns.rdatatype.NONE, None,
|
||||
True, True)
|
||||
|
@ -225,25 +272,41 @@ class Update(dns.message.Message):
|
|||
"""Require that an owner name (and optionally an rdata type) does
|
||||
not exist as a prerequisite to the execution of the update."""
|
||||
|
||||
if isinstance(name, string_types):
|
||||
if isinstance(name, str):
|
||||
name = dns.name.from_text(name, None)
|
||||
if rdtype is None:
|
||||
self.find_rrset(self.answer, name,
|
||||
self.find_rrset(self.prerequisite, name,
|
||||
dns.rdataclass.NONE, dns.rdatatype.ANY,
|
||||
dns.rdatatype.NONE, None,
|
||||
True, True)
|
||||
else:
|
||||
if isinstance(rdtype, string_types):
|
||||
rdtype = dns.rdatatype.from_text(rdtype)
|
||||
self.find_rrset(self.answer, name,
|
||||
rdtype = dns.rdatatype.RdataType.make(rdtype)
|
||||
self.find_rrset(self.prerequisite, name,
|
||||
dns.rdataclass.NONE, rdtype,
|
||||
dns.rdatatype.NONE, None,
|
||||
True, True)
|
||||
|
||||
def to_wire(self, origin=None, max_size=65535):
|
||||
"""Return a string containing the update in DNS compressed wire
|
||||
format.
|
||||
@rtype: string"""
|
||||
if origin is None:
|
||||
origin = self.origin
|
||||
return super(Update, self).to_wire(origin, max_size)
|
||||
def _get_one_rr_per_rrset(self, value):
|
||||
# Updates are always one_rr_per_rrset
|
||||
return True
|
||||
|
||||
def _parse_rr_header(self, section, name, rdclass, rdtype):
|
||||
deleting = None
|
||||
empty = False
|
||||
if section == UpdateSection.ZONE:
|
||||
if dns.rdataclass.is_metaclass(rdclass) or \
|
||||
rdtype != dns.rdatatype.SOA or \
|
||||
self.zone:
|
||||
raise dns.exception.FormError
|
||||
else:
|
||||
if not self.zone:
|
||||
raise dns.exception.FormError
|
||||
if rdclass in (dns.rdataclass.ANY, dns.rdataclass.NONE):
|
||||
deleting = rdclass
|
||||
rdclass = self.zone[0].rdclass
|
||||
empty = (deleting == dns.rdataclass.ANY or
|
||||
section == UpdateSection.PREREQ)
|
||||
return (rdclass, rdtype, deleting, empty)
|
||||
|
||||
# backwards compatibility
|
||||
Update = UpdateMessage
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue