161
162
dnsdata.dnsresource_id = dnsresource.id
162
163
JOIN maasserver_domain as domain ON
163
164
dnsresource.domain_id = domain.id
164
LEFT JOIN maasserver_node AS node ON
165
node.hostname = dnsresource.name
167
/* Create a "node" that has the fields we care about and
168
* also has a "fqdn" field.
169
* The fqdn requires that we fetch domain[node.domain_id]
170
* which, in turn, means that we need this inner select.
173
nd.hostname AS hostname,
174
nd.system_id AS system_id,
175
nd.node_type AS node_type,
176
nd.domain_id AS domain_id,
177
CONCAT(nd.hostname, '.', dom.name) AS fqdn
178
FROM maasserver_node AS nd
179
JOIN maasserver_domain AS dom ON
180
nd.domain_id = dom.id
182
/* We get the various node fields in the final result for
183
* any resource records that have an FQDN equal to the
184
* respective node. Because of how names at the top of a
185
* domain are handled (we hide the fact from the user and
186
* put the node in the parent domain, but all the actual
187
* data lives in the child domain), we need to merge the
188
* two views of the world.
189
* If either this is the right node (node name and domain
190
* match, or dnsresource name is '@' and the node fqdn is
191
* the domain name), then we include the information about
195
dnsresource.name = node.hostname AND
196
dnsresource.domain_id = node.domain_id
199
dnsresource.name = '@' AND
200
node.fqdn = domain.name
167
dnsresource.domain_id = %s AND (
168
dnsdata.rrtype != 'CNAME' OR node.hostname IS NULL)
204
/* The entries must be in this domain (though node.domain_id
205
* may be out-of-domain and that's OK.
206
* Additionally, if there is a CNAME and a node, then the node
207
* wins, and we drop the CNAME until the node no longer has the
210
(dnsresource.domain_id = %s OR node.fqdn IS NOT NULL) AND
211
(dnsdata.rrtype != 'CNAME' OR node.fqdn IS NULL)
170
213
dnsresource.name,
176
219
# not spill CNAME and other data.
177
220
mapping = defaultdict(HostnameRRsetMapping)
178
221
cursor.execute(sql_query, (domain.id,))
179
for (name, system_id, node_type,
222
for (name, d_name, system_id, node_type,
180
223
ttl, rrtype, rrdata) in cursor.fetchall():
224
if name == '@' and d_name != domain.name:
225
name, d_name = d_name.split('.', 1)
226
# Since we don't allow more than one label in dnsresource
227
# names, we should never ever be wrong in this assertion.
228
assert d_name == domain.name, (
229
"Invalid domain; expected '%s' == '%s'" % (
230
d_name, domain.name))
181
231
mapping[name].node_type = node_type
182
232
mapping[name].system_id = system_id
183
233
mapping[name].rrset.add((ttl, rrtype, rrdata))