Repository navigation
Fix DNS driver API inconsistencies - #2066
aaron-sierra wants to merge 52 commits into
Conversation
The Zerigo DNS service was permanently shut down on April 30, 2017.
The DNSimple v1 API was shutdown on May 31, 2018:
https://blog.dnsimple.com/2018/03/api-v1-shutdown-notice/
The RcodeZero v1 API has been shutdown:
https://my.rcodezero.at/openapi/
0fe8ec0 to
46c0e4f
Compare
|
The latest batch of updates includes changes from |
Enable unit tests to verify HTTP requests they submit.
* Fix test_create_zone_success * Fix test_get_record_success
* Fix test_update_zone
Leverage the existing get_record.json for this test.
Previously, test_get_record_success() succeeded when receiving a record completely unrelated to the originating .get_record() request. Update the request to align with the expected response.
Previously, test_list_records_success() succeeded when receiving records completely unrelated to the originating .list_records() request. Update the request to align with the expected response.
Make NSOneResponse.errors and NSOneResponse.objects instance variables, rather than class variables. This was found due to errors in NSOneDNSDriver unit testing that only appeared when tests were run together, not when tests were run individually.
Add .hostname(), .fqdn(), and .prefix() helpers to the Zone class. Each of these functions accepts a host prefix, complete name (unrooted hostname), or FQDN (rooted hostname) associated with the Zone object and returns the format implied by the function name.
Add .to_default_id() and .from_default_id() functions to the DNSDriver class. These functions support the <type>[:<name>] (e.g. "A:www") record ID format used by many of the drivers.
Previously, our NsOneDNSDriver.get_record() function performed lookups
using a `record_id` format that differed from the ID embedded within the
returned Record instance, so the driver leveraged two independent
record ID concepts simultaneously.
The NS1 API returns an ID when records are created, but that ID has no
local relevance. For example, it cannot be used to request the record
from the NS1 API.
Make the Record class .id value consistent between create_record() and
get_record(z.id, r.id).
| zone_id | z.id | r.id | record_id |
---------|----------|----------|---------------|---------------|
previous | z.domain | random* | random* | r.type |
next | z.domain | z.domain | r.type:r.name | r.type:r.name |
* no meaning, effectively random
* Fix TTL in test_create_record_success() request
* Align record update with parent zone in test_update_record_success()
* Fix record_id in test_get_record_success() request
DNS AAAA records are associated with IPv6 addresses.
* Fix "ttle" typo in test_update_record()
Previously, the Zonomi DNS driver could only return the first record for a given host, because it used the name of the host as Record.id. Now, use the new default, <type>[:<name>], format to allow various records to be differentiated for a given host.
DNS drivers share the need to manipulate host/domain names, so let's add utility functions to the common Record and Zone classes to allow redundant code scattered throughout the various drivers to be consolidated into common and consistent implementations. * Record.name - no longer driver-dependent, now the host prefix or "" * Record.hostname - the complete host name, including domain part * Record.fqdn - the fully qualified domain name, including root dot * Zone.domain - no longer driver-dependent, now the unrooted domain * Zone.rooted() - format a (un)rooted domain as a rooted domain * Zone.rooted() - format a (un)rooted domain as an unrooted domain
Update testing inputs to conform to spec'ed usage.
Leverage common code from DNSDriver, Record, and Zone classes for host name and record ID handling.
Drop RackspaceDNSDriver._to_partial_record_name() and RackspaceDNSDriver._to_full_record_name() in favor of the common support provided by the Record and Zone classes.
46c0e4f to
fcaf113
Compare
|
The latest changes have been through |
micafer
left a comment
There was a problem hiding this comment.
Thanks for the extensive work on making the DNS driver APIs more consistent. The additional HTTP request assertions are particularly valuable.
I found an issue in the new Zone.prefix() implementation that should be addressed before merging.
The expression:
subname.rstrip(".").removesuffix(self.domain).rstrip(".")
removes the zone domain even when it is not preceded by a DNS label separator.
For example, with self.domain == "example.com", calling prefix("notexample.com") returns "not", even though notexample.com is not a hostname within the example.com zone.
Since Zone.hostname() and Zone.fqdn() depend on this method, the issue can silently produce incorrect DNS names.
I suggest checking for an exact domain match or the suffix "." + self.domain before stripping it, and adding regression tests for hostnames that merely share a textual suffix with the zone domain.
Additionally, this PR changes public-facing Record.id, Record.name, and Zone.domain semantics across multiple providers. As we are going to merge this to the new major version these compatibility changes will be explicitly documented and it is not majot issue.
|
Hi Miguel, Thanks for your review. In the example that you described regarding
Presumably all three of the |
|
I probably prefer to return |
I thought a bit on this and probably returning the full DNS name can be the best solution: as in the example |
|
I'm still checking this and I found two issues: Google Cloud DNS — get_record() uses a relative name in the API query. After parsing the normalized record ID, parts.name contains a relative name such as foo. However, the Cloud DNS API expects a fully qualified name such as foo.example.com. in the name query parameter. I believe this should use zone.fqdn(parts.name) instead. The corresponding test currently checks the endpoint URL but does not assert the query parameters. World Wide DNS — update_record() fails when extra=None. The new condition if "entry" in extra raises TypeError when the optional extra argument is omitted. Please guard against None and add a regression test covering an update without extra. |
You're right! I've added API parameter checking to |
I think we need to clarify what should happen when a hostname (unrooted) and an FQDN (rooted) are passed into these functions. In the following examples,
I think that I prefer raising an exception in the unrelated FQDN case, considering how #2065 notes inconsistent usage of |
Ok, so let's go in that direction. But we can create an specific exception (something like |
|
So please make this changes and merge the trunk branch. |
|
FYI from #2216 (micafer's review thread): your |
How's |
Fix DNS driver API inconsistencies
Description
Implement #2065
Summary
In general, commit messages provide necessary background regarding the changes made and why.
<type>[:<name>]-style record IDsRecord.idformat for NS1 and Zonomi providersRecord.idinterpretation for World Wide DNSStatus
Checklist (tick everything that applies)