dnspython  1.16.0
About: dnspython is a DNS toolkit (for Python 2.x) that supports almost all record types.
  Fossies Dox: dnspython-1.16.0.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

node.py
Go to the documentation of this file.
1 # Copyright (C) Dnspython Contributors, see LICENSE for text of ISC license
2 
3 # Copyright (C) 2001-2017 Nominum, Inc.
4 #
5 # Permission to use, copy, modify, and distribute this software and its
6 # documentation for any purpose with or without fee is hereby granted,
7 # provided that the above copyright notice and this permission notice
8 # appear in all copies.
9 #
10 # THE SOFTWARE IS PROVIDED "AS IS" AND NOMINUM DISCLAIMS ALL WARRANTIES
11 # WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 # MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL NOMINUM BE LIABLE FOR
13 # ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 # WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 # ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
16 # OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 
18 """DNS nodes. A node is a set of rdatasets."""
19 
20 from io import StringIO
21 
22 import dns.rdataset
23 import dns.rdatatype
24 import dns.renderer
25 
26 
27 class Node(object):
28 
29  """A Node is a set of rdatasets."""
30 
31  __slots__ = ['rdatasets']
32 
33  def __init__(self):
34  #: the set of rdatsets, represented as a list.
35  self.rdatasets = []
36 
37  def to_text(self, name, **kw):
38  """Convert a node to text format.
39 
40  Each rdataset at the node is printed. Any keyword arguments
41  to this method are passed on to the rdataset's to_text() method.
42 
43  *name*, a ``dns.name.Name`` or ``text``, the owner name of the rdatasets.
44 
45  Returns a ``text``.
46  """
47 
48  s = StringIO()
49  for rds in self.rdatasets:
50  if len(rds) > 0:
51  s.write(rds.to_text(name, **kw))
52  s.write(u'\n')
53  return s.getvalue()[:-1]
54 
55  def __repr__(self):
56  return '<DNS node ' + str(id(self)) + '>'
57 
58  def __eq__(self, other):
59  #
60  # This is inefficient. Good thing we don't need to do it much.
61  #
62  for rd in self.rdatasets:
63  if rd not in other.rdatasets:
64  return False
65  for rd in other.rdatasets:
66  if rd not in self.rdatasets:
67  return False
68  return True
69 
70  def __ne__(self, other):
71  return not self.__eq__(other)
72 
73  def __len__(self):
74  return len(self.rdatasets)
75 
76  def __iter__(self):
77  return iter(self.rdatasets)
78 
79  def find_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE,
80  create=False):
81  """Find an rdataset matching the specified properties in the
82  current node.
83 
84  *rdclass*, an ``int``, the class of the rdataset.
85 
86  *rdtype*, an ``int``, the type of the rdataset.
87 
88  *covers*, an ``int``, the covered type. Usually this value is
89  dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
90  dns.rdatatype.RRSIG, then the covers value will be the rdata
91  type the SIG/RRSIG covers. The library treats the SIG and RRSIG
92  types as if they were a family of
93  types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much
94  easier to work with than if RRSIGs covering different rdata
95  types were aggregated into a single RRSIG rdataset.
96 
97  *create*, a ``bool``. If True, create the rdataset if it is not found.
98 
99  Raises ``KeyError`` if an rdataset of the desired type and class does
100  not exist and *create* is not ``True``.
101 
102  Returns a ``dns.rdataset.Rdataset``.
103  """
104 
105  for rds in self.rdatasets:
106  if rds.match(rdclass, rdtype, covers):
107  return rds
108  if not create:
109  raise KeyError
110  rds = dns.rdataset.Rdataset(rdclass, rdtype)
111  self.rdatasets.append(rds)
112  return rds
113 
114  def get_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE,
115  create=False):
116  """Get an rdataset matching the specified properties in the
117  current node.
118 
119  None is returned if an rdataset of the specified type and
120  class does not exist and *create* is not ``True``.
121 
122  *rdclass*, an ``int``, the class of the rdataset.
123 
124  *rdtype*, an ``int``, the type of the rdataset.
125 
126  *covers*, an ``int``, the covered type. Usually this value is
127  dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
128  dns.rdatatype.RRSIG, then the covers value will be the rdata
129  type the SIG/RRSIG covers. The library treats the SIG and RRSIG
130  types as if they were a family of
131  types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much
132  easier to work with than if RRSIGs covering different rdata
133  types were aggregated into a single RRSIG rdataset.
134 
135  *create*, a ``bool``. If True, create the rdataset if it is not found.
136 
137  Returns a ``dns.rdataset.Rdataset`` or ``None``.
138  """
139 
140  try:
141  rds = self.find_rdataset(rdclass, rdtype, covers, create)
142  except KeyError:
143  rds = None
144  return rds
145 
146  def delete_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE):
147  """Delete the rdataset matching the specified properties in the
148  current node.
149 
150  If a matching rdataset does not exist, it is not an error.
151 
152  *rdclass*, an ``int``, the class of the rdataset.
153 
154  *rdtype*, an ``int``, the type of the rdataset.
155 
156  *covers*, an ``int``, the covered type.
157  """
158 
159  rds = self.get_rdataset(rdclass, rdtype, covers)
160  if rds is not None:
161  self.rdatasets.remove(rds)
162 
163  def replace_rdataset(self, replacement):
164  """Replace an rdataset.
165 
166  It is not an error if there is no rdataset matching *replacement*.
167 
168  Ownership of the *replacement* object is transferred to the node;
169  in other words, this method does not store a copy of *replacement*
170  at the node, it stores *replacement* itself.
171 
172  *replacement*, a ``dns.rdataset.Rdataset``.
173 
174  Raises ``ValueError`` if *replacement* is not a
175  ``dns.rdataset.Rdataset``.
176  """
177 
178  if not isinstance(replacement, dns.rdataset.Rdataset):
179  raise ValueError('replacement is not an rdataset')
180  self.delete_rdataset(replacement.rdclass, replacement.rdtype,
181  replacement.covers)
182  self.rdatasets.append(replacement)
dns.rdataset.Rdataset
Definition: rdataset.py:44
dns.node.Node.replace_rdataset
def replace_rdataset(self, replacement)
Definition: node.py:163
dns.rdataset
Definition: rdataset.py:1
dns.node.Node.rdatasets
rdatasets
Definition: node.py:35
dns.node.Node.delete_rdataset
def delete_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE)
Definition: node.py:146
dns.renderer
Definition: renderer.py:1
dns.node.Node.__repr__
def __repr__(self)
Definition: node.py:55
dns.node.Node.__len__
def __len__(self)
Definition: node.py:73
dns.node.Node.find_rdataset
def find_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE, create=False)
Definition: node.py:79
dns.node.Node.to_text
def to_text(self, name, **kw)
Definition: node.py:37
dns.node.Node.__init__
def __init__(self)
Definition: node.py:33
dns.node.Node.__ne__
def __ne__(self, other)
Definition: node.py:70
dns.node.Node.get_rdataset
def get_rdataset(self, rdclass, rdtype, covers=dns.rdatatype.NONE, create=False)
Definition: node.py:114
dns.node.Node
Definition: node.py:27
dns.rdatatype
Definition: rdatatype.py:1
dns.node.Node.__eq__
def __eq__(self, other)
Definition: node.py:58
dns.node.Node.__iter__
def __iter__(self)
Definition: node.py:76