Skip to content

NEW PROVIDER: Netnod primary DNS#4191

Merged
TomOnTime merged 18 commits into
DNSControl:mainfrom
Netnod:add-netnod-provider
May 28, 2026
Merged

NEW PROVIDER: Netnod primary DNS#4191
TomOnTime merged 18 commits into
DNSControl:mainfrom
Netnod:add-netnod-provider

Conversation

@vilhelmprytz

@vilhelmprytz vilhelmprytz commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Add a DNSControl provider for Netnod primary DNS API. Provider is loosely based on the PowerDNS provider.

  • Adds a new DNS provider for Netnod Primary DNS
  • Uses diff2.ByRecordSet(), updates are batched per label+type
  • Supports zone creation with metadata

Capabilities

A, AAAA, ALIAS, CAA, CNAME, HTTPS, MX, NS, PTR, SRV, TLSA, TXT (CanGetZones, DocCreateDomains, DocDualHost)

We can offer an API key for automated testing, if needed.

Please create the GitHub label 'provider-NETNOD'.

Fixes #4192.

Add a DNSControl provider for Netnod primary DNS API.
Provider is loosely based on the PowerDNS provider.
@TomOnTime

Copy link
Copy Markdown
Collaborator

Thanks! Super glad to receive this!

Right now the project is in transition but I hope to be able to address this once we've moved to our new org.

@vilhelmprytz

Copy link
Copy Markdown
Contributor Author

Hi @TomOnTime, thanks for the reply!

Let me know if there is anything I can do to help. Is the project being transitioned away from the StackExchange organization?

@TomOnTime

Copy link
Copy Markdown
Collaborator

Hi @TomOnTime, thanks for the reply!

Let me know if there is anything I can do to help. Is the project being transitioned away from the StackExchange organization?

Yes, it will soon be in the dnscontrol organization.

Tom

@flindeberg

Copy link
Copy Markdown
Contributor

I handled the conflicts due to package update and renames (StackExchange -> DNSControl).

@vilhelmprytz Do double check that I didn't mess something up.

@flindeberg

Copy link
Copy Markdown
Contributor

Oh, wait, I used the web-GUI and obviously something funny happened.

flindeberg added 2 commits May 8, 2026 16:47
Fixed typos / artifacts from web-GUI based merge.
Fixed web-GUI based merge artifacts.

@TomOnTime TomOnTime left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Everything looks good. I'm requesting @cafferata review the docs.

nitpick: Would you please rename providers/netnod/diff.go to providers/netnod/records.go ? Thanks!

@vilhelmprytz

Copy link
Copy Markdown
Contributor Author

@TomOnTime Certainly, now changed.

@TomOnTime

Copy link
Copy Markdown
Collaborator

Thanks!

@TomOnTime

Copy link
Copy Markdown
Collaborator

Greetings! Thank you for your patience while we migrated to the new GitHub org.

Now that the migration is complete, please rebase. Thank you.

@vilhelmprytz

Copy link
Copy Markdown
Contributor Author

@TomOnTime Thanks, now pushed!
Let me know if you want credentials for automated testing towards the API, and how to set this up.

@TomOnTime

Copy link
Copy Markdown
Collaborator

Hi there!

Oops... things move quickly and another rebase to main is needed.

Yes, I'd love to have this added to the automated tests. Please see https://docs.dnscontrol.org/developer-info/byo-secrets for instructions.

@cafferata cafferata left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding Netnod support! A few suggestions on the documentation and one build issue.

Comment thread documentation/provider/netnod.md
Comment thread documentation/provider/netnod.md
Comment thread providers/netnod/auditrecords.go Outdated
Comment thread providers/netnod/auditrecords.go Outdated
@cafferata

Copy link
Copy Markdown
Member

Optionally: since #4208 landed before this PR, would you be open to implementing RegisterCredsMetadata()? That would make Netnod available in dnscontrol init. The PR has examples for simple providers like BIND and more complex ones like TransIP.

@vilhelmprytz

Copy link
Copy Markdown
Contributor Author

The integration tests pass locally when I try them, but only when I change this in pkg/diff2/analyze.go:

--- a/pkg/diff2/analyze.go
+++ b/pkg/diff2/analyze.go
@@ -267,7 +267,7 @@ func diffTargets(existing, desired []targetConfig) ChangeList {
                        var unquoted, quoted string
                        if _, ok := echs[v.rec.NameFQDN]; ok {
                                unquoted = fmt.Sprintf("ech=%s", echs[v.rec.NameFQDN])
-                               quoted = fmt.Sprintf("ech=%q", echs[v.rec.NameFQDN])
+                               quoted = fmt.Sprintf("ech=%s", echs[v.rec.NameFQDN])
                        } else {
                                unquoted = ""
                                quoted = ""

Without this change, TestDNSProviders/dnscontroltest-netnod.com/18:Ech:Ignore_the_ECH_key_while_changing_other_values fails.

@TomOnTime

Copy link
Copy Markdown
Collaborator

The integration tests pass locally when I try them, but only when I change this in pkg/diff2/analyze.go:

--- a/pkg/diff2/analyze.go
+++ b/pkg/diff2/analyze.go
@@ -267,7 +267,7 @@ func diffTargets(existing, desired []targetConfig) ChangeList {
                        var unquoted, quoted string
                        if _, ok := echs[v.rec.NameFQDN]; ok {
                                unquoted = fmt.Sprintf("ech=%s", echs[v.rec.NameFQDN])
-                               quoted = fmt.Sprintf("ech=%q", echs[v.rec.NameFQDN])
+                               quoted = fmt.Sprintf("ech=%s", echs[v.rec.NameFQDN])
                        } else {
                                unquoted = ""
                                quoted = ""

Without this change, TestDNSProviders/dnscontroltest-netnod.com/18:Ech:Ignore_the_ECH_key_while_changing_other_values fails.

@gucci-on-fleek: Any suggestions? (git blame lists you as the last to modify this)

@gucci-on-fleek

Copy link
Copy Markdown
Contributor

@TomOnTime

The integration tests pass locally when I try them, but only when I change this in pkg/diff2/analyze.go:

--- a/pkg/diff2/analyze.go
+++ b/pkg/diff2/analyze.go
@@ -267,7 +267,7 @@ func diffTargets(existing, desired []targetConfig) ChangeList {
                        var unquoted, quoted string
                        if _, ok := echs[v.rec.NameFQDN]; ok {
                                unquoted = fmt.Sprintf("ech=%s", echs[v.rec.NameFQDN])
-                               quoted = fmt.Sprintf("ech=%q", echs[v.rec.NameFQDN])
+                               quoted = fmt.Sprintf("ech=%s", echs[v.rec.NameFQDN])
                        } else {
                                unquoted = ""
                                quoted = ""

Without this change, TestDNSProviders/dnscontroltest-netnod.com/18:Ech:Ignore_the_ECH_key_while_changing_other_values fails.

@gucci-on-fleek: Any suggestions? (git blame lists you as the last to modify this)

The quoted form should definitely be allowed according to RFC 9848 §3, but since this is guaranteed to be base64-encoded text, the syntax in RFC 9460 §A means that it should be safe to omit the quotes.

The version with quotes seems "better" in the sense that it's always safe to use quotes around a string and only sometimes okay to omit them (for SVCB parameters in general). But if this is causing problems with a provider, then as long as it doesn't break the integration tests for any other providers, "ech=%s" seems fine to me.

@TomOnTime

Copy link
Copy Markdown
Collaborator

Looking good so far!

  • The ech= issue has been fiex in another PR
  • Please merge from main: git merge main --
  • Please run bin/generate-all.sh
  • GH is telling me @cafferata requested changes
  • Fix these lint issues:
$ golangci-lint run ./...
providers/netnod/convert.go:10:1: Comment should end in a period (godot)
// toRecordConfig converts a Netnod DNS Record to a RecordConfig. #rtype_variations
^
providers/netnod/dns.go:66:1: Comment should end in a period (godot)
// EnsureZoneExists creates a zone if it does not exist
^
providers/netnod/listzones.go:5:1: Comment should end in a period (godot)
// ListZones returns all the zones in an account
^
providers/netnod/netnodProvider.go:91:15: ST1005: error strings should not be capitalized (staticcheck)
		return nil, errors.New("Netnod API Key is required")

@vilhelmprytz

vilhelmprytz commented May 28, 2026

Copy link
Copy Markdown
Contributor Author

@TomOnTime Thanks! All fixed. The requested changes are from this comment #4191 (comment)
Let me know if I should add anything else, or if it can be resolved.

@TomOnTime TomOnTime merged commit df8e1f3 into DNSControl:main May 28, 2026
3 checks passed
@vilhelmprytz vilhelmprytz deleted the add-netnod-provider branch June 2, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Development

Successfully merging this pull request may close these issues.

Provider request: Netnod Primary DNS

5 participants