Tech Debt that keeps Tom up at night
There are a number of non-functional tech-debt projects I'd like to do or find someone to do.
Make IGNORE*/PURGE/NO_PURGE more reliable: (DONE!!!)
- Category: Fix brittle features
- Priority: high
Problem: IGNORE and PURGE are brittle and don't work right in all situations.
Proposal: I have ideas that would make it cleaner, easier to work with/debug, and easier for provider-authors to use. I will rewrite the pkg/diff module from scratch, and retrofit the old providers.
WIP: https://github.com/StackExchange/dnscontrol/pull/1831 (Tom is actively working on this)
Refactor the DNS Provider interface so that writing providers is less work. (DONE!!!)
- Category: Make it easier to write new providers
- Priority: high
Problem: The Go Interface for providers is complex. There are 2 ways to do things. The provider author has to do a lot more work, and include a lot of boilerplate, than intended.
Proposal: The provider interface could be a lot more simple. Authors should simply provide 2 functions: "get all records" and "generate corrections". The framework should handle the rest.
In fact, the interfaces should be pairs of GetRecords/GetRecordsCorrections, GetNameservers/GetNameserversCorrections, etc. That way they're super consistent.
WIP: https://github.com/StackExchange/dnscontrol/pull/1705 is the draft new interface (plus other proposed interfaces).
Standardize provider source code filenames.
- Category: Make it easier to write new providers
- Priority: medium
Problem: Reading provider code is complex because each provider uses different filenames.
Proposal: Standardize some of the filenames. Something like:
- main.go (the main file)
- convert.go (toRC and toNative)
- api.go (talk to the provider and/or provide facades to a library)
- dnsrecords.go (the DNS provider code)
- registrar.go (the Registrar code).
...and update the docs on how to write a provider.
Simplify TXT record support: (DONE!!!)
- Category: Code simplification
- Priority: medium
Problem: We try to be "too smart" in how TXT records are handled. The TXT code is super complex right now. It doesn't need to be.
Proposal: Rewrite TXT record handling to be more simple. Store TXT targets as one long string, even if it was received as a number of segments. Let the providers handle any splitting that is needed. i.e. split the string into 255-octet segments if the API requires it.
BUGID: https://github.com/StackExchange/dnscontrol/issues/1592
Re-do Punycode
- Category: Improve i11n support
- Priority: low
Problem: Punycode was implemented as an after-thought and in hindsight we would have done it different.
Proposal: The general philosophy should be (1) users can enter punycode or unicode in dnsconfig.js, (2) internally everything is handled as punycode, (3) output should magically display domain names either the same way the user entered it (which means tracking how it was entered), or always display PunyCode followed by unicode in parenthesis.
Should models.RecordConfig be more object oriented
Systems like miekg/dns create a Go type for each DNS type. Is that something we should do?
Would there be any benefit?
MSDNS should work on Linux PowerShell
- Category: Code quality
- Priority: low
Problem: The MSDNS provider doesn't work if not run on Windows.
Proposal: Step one is to use conditional compilation to split out the Windows vs. non-Windows version. Step two is to implement the code on the non-Windows side.
WIP: https://github.com/StackExchange/dnscontrol/issues/1731 (Volunteer needed to pick this up)
I am interested in improving your sleep at night. I am subscribing to help where I can even though my time is a bit spotty for the next few weeks.
@onlyhavecans Thanks! (I've updated this with bugids and draft PRs)
P.S. These don't literally keep me up at night. Actually, a better explanation is that this is part of my technique for avoiding distractions. When I'm writing code, I get distracted by other interesting bugs/refactoring that I'd like to do. I find that if I make a list of things I'm NOT doing, it helps me focus on what I am working on. That said, this list is chock full of opportunities for volunteers to step in, or even just comment on things that are on my mind.
The good news is that many of these have been implemented:
- Make IGNORE*/PURGE/NO_PURGE more reliable:
diff2 makes it not just more reliable, but it now works for all providers.
- Refactor the DNS Provider interface so that writing providers is less work.
Done.
- Standardize provider source code filenames.
Not done, but not super important.
Bugs have been filed for these:
- Simplify TXT record support
- Re-do Punycode
- Should models.RecordConfig be more object oriented
- MSDNS should work on Linux PowerShell
I'm mostly concerned about the TXT record support and Punycode.
That said, I think we can close this issue!
Fine! 👍 Then you can sleep peacefully now 😴
Closing this. Most are done, or will soon be done. The rest are minor.
Some other ideas:
Simplify the interface for providers
Why have "registrars" and "dnsproviders"? Users report this is confusing.
This was a design decision that "seemed like a good idea" but didn't pan out.
How about just defining "providers" and if they can also do registrar functions, that's a bonus.
Providers can register themself with an Options{} struct that includes fields for authentication, registrar functions, provider functions, maintainer, etc. Initially the options can feed the legacy functions, but eventually we'll replace it all with a modern system.
Another simplification is how we send options to a provider. The "creds.json" entry it sent unparsed, which the provider has to then parse. This allows maximum flexibility. However, nobody has ever used this flexibility. Instead, we should just deliver a map[string]string.
Zones, not domains
`D() is a misnomer. These are really zones. How about:
ZONE("foo.com",
Registrar("foo"), // "foo" is the key in "creds".
ServedBy("foo"), // "foo" is the key in "creds".
A(),
...
);
NOTE: Registrar() would be optional. You would be able to list as many ServedBy() entries as you wish. It should take a list too.
Other suggestions:
- A "default registrar" that applies to all zones
- A global function that sets the registrar for a domain.
AssignRegistrar("foo.com", "registrarname");AssignServer("foo.com" "dnsprovidername");(Note to self: find a better name for these functions)
Most of this is done. The others are on the list for v5.x