~allenap/maas/ipmi-power-confusion--bug-1560830

« back to all changes in this revision

Viewing changes to src/maasserver/models/dnsdata.py

  • Committer: MAAS Lander
  • Author(s): LaMont Jones
  • Date: 2016-04-25 18:06:57 UTC
  • mfrom: (4933.2.9 bug-1571621)
  • Revision ID: maas_lander-20160425180657-flyd1jupqx7ec9zk
[r=mpontillo][bug=1562919,1571621,1573690][author=lamont] Handle delegations for subdomains.  Fix the handling of fqdn in the dns apis when it refers to the top of a domain.

Show diffs side-by-side

added added

removed removed

Lines of Context:
151
151
        sql_query = """
152
152
            SELECT
153
153
                dnsresource.name,
 
154
                domain.name,
154
155
                node.system_id,
155
156
                node.node_type,
156
157
                """ + ttl_clause + """ AS ttl,
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
 
165
            LEFT JOIN
 
166
                (
 
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.
 
171
                     */
 
172
                    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
 
181
                ) AS node ON (
 
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
 
192
                     * the node.
 
193
                     */
 
194
                    (
 
195
                        dnsresource.name = node.hostname AND
 
196
                        dnsresource.domain_id = node.domain_id
 
197
                    ) OR
 
198
                    (
 
199
                        dnsresource.name = '@' AND
 
200
                        node.fqdn = domain.name
 
201
                    )
 
202
                )
166
203
            WHERE
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
 
208
                 * same name.
 
209
                 */
 
210
                (dnsresource.domain_id = %s OR node.fqdn IS NOT NULL) AND
 
211
                (dnsdata.rrtype != 'CNAME' OR node.fqdn IS NULL)
169
212
            ORDER BY
170
213
                dnsresource.name,
171
214
                dnsdata.rrtype,
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))