1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """DNS nodes. A node is a set of rdatasets."""
17
18 from io import StringIO
19
20 import dns.rdataset
21 import dns.rdatatype
22 import dns.renderer
23
24
26
27 """A DNS node.
28
29 A node is a set of rdatasets
30
31 @ivar rdatasets: the node's rdatasets
32 @type rdatasets: list of dns.rdataset.Rdataset objects"""
33
34 __slots__ = ['rdatasets']
35
37 """Initialize a DNS node.
38 """
39
40 self.rdatasets = []
41
42 - def to_text(self, name, **kw):
43 """Convert a node to text format.
44
45 Each rdataset at the node is printed. Any keyword arguments
46 to this method are passed on to the rdataset's to_text() method.
47 @param name: the owner name of the rdatasets
48 @type name: dns.name.Name object
49 @rtype: string
50 """
51
52 s = StringIO()
53 for rds in self.rdatasets:
54 if len(rds) > 0:
55 s.write(rds.to_text(name, **kw))
56 s.write(u'\n')
57 return s.getvalue()[:-1]
58
60 return '<DNS node ' + str(id(self)) + '>'
61
63 """Two nodes are equal if they have the same rdatasets.
64
65 @rtype: bool
66 """
67
68
69
70 for rd in self.rdatasets:
71 if rd not in other.rdatasets:
72 return False
73 for rd in other.rdatasets:
74 if rd not in self.rdatasets:
75 return False
76 return True
77
79 return not self.__eq__(other)
80
83
86
89 """Find an rdataset matching the specified properties in the
90 current node.
91
92 @param rdclass: The class of the rdataset
93 @type rdclass: int
94 @param rdtype: The type of the rdataset
95 @type rdtype: int
96 @param covers: The covered type. Usually this value is
97 dns.rdatatype.NONE, but if the rdtype is dns.rdatatype.SIG or
98 dns.rdatatype.RRSIG, then the covers value will be the rdata
99 type the SIG/RRSIG covers. The library treats the SIG and RRSIG
100 types as if they were a family of
101 types, e.g. RRSIG(A), RRSIG(NS), RRSIG(SOA). This makes RRSIGs much
102 easier to work with than if RRSIGs covering different rdata
103 types were aggregated into a single RRSIG rdataset.
104 @type covers: int
105 @param create: If True, create the rdataset if it is not found.
106 @type create: bool
107 @raises KeyError: An rdataset of the desired type and class does
108 not exist and I{create} is not True.
109 @rtype: dns.rdataset.Rdataset object
110 """
111
112 for rds in self.rdatasets:
113 if rds.match(rdclass, rdtype, covers):
114 return rds
115 if not create:
116 raise KeyError
117 rds = dns.rdataset.Rdataset(rdclass, rdtype)
118 self.rdatasets.append(rds)
119 return rds
120
123 """Get an rdataset matching the specified properties in the
124 current node.
125
126 None is returned if an rdataset of the specified type and
127 class does not exist and I{create} is not True.
128
129 @param rdclass: The class of the rdataset
130 @type rdclass: int
131 @param rdtype: The type of the rdataset
132 @type rdtype: int
133 @param covers: The covered type.
134 @type covers: int
135 @param create: If True, create the rdataset if it is not found.
136 @type create: bool
137 @rtype: dns.rdataset.Rdataset object 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
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 @param rdclass: The class of the rdataset
153 @type rdclass: int
154 @param rdtype: The type of the rdataset
155 @type rdtype: int
156 @param covers: The covered type.
157 @type covers: int
158 """
159
160 rds = self.get_rdataset(rdclass, rdtype, covers)
161 if rds is not None:
162 self.rdatasets.remove(rds)
163
179