You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I briefly ran this idea past @TomOnTime today in a short video call and mentioned that an upcoming holiday period should give me time to pick this work back up. Before going further I want to surface it here so other maintainers and long time contributors can weigh in. Feedback on scope, UX, the metadata schema and naming is very welcome.
In my own experience helping developers try DNSControl (and from my own start back in November 2023), every newcomer hits the same wall: how and where do I start?@Aartsie was one of those developers, and like most newcomers they arrived with:
I want to import my existing DNS records and domains into DNSControl so I can experience its real strength: DNS as code, reviewable diffs, safe previews before anything goes live, a full change history in git and the freedom to switch providers later without rewriting my zones. Help me get there quickly.
Today that path involves reading the docs, tracing the provider Go source for the exact field names, hand writing creds.json and on top of that building a dnsconfig.js from scratch while having to learn an entirely new JavaScript DSL. This proposal is about removing that cold start.
Pinging the maintainers listed in OWNERS. Most of you look after these providers as fellow users rather than on behalf of the vendor, so a smoother onboarding directly helps the people who come after you. Feedback and pushback both welcome:
A new user of DNSControl has to hand write creds.json before they can run preview or push. The information needed to fill that file correctly is scattered across at least three places:
The provider doc page in documentation/provider/
The provider Go source where field names are read
.github/workflows/pr_integration_tests.yml where CI credentials are mapped
Field names are inconsistent across providers (apitoken, api_token, KeyId, AccountName, and so on) and the portal URL where you create an API token is not discoverable from the CLI. For a first time user that means a round trip through the docs before they can get to preview.
Proposal
Add an interactive command:
dnscontrol init
It walks the user through:
Pick a DNS provider (NONE to defer).
If the DNS provider also acts as a registrar, offer to reuse the same account. Otherwise pick a registrar ( NONE is available).
Open the provider's API settings page in the default browser on request.
Prompt per credential field, with password masking for secrets and $EDITOR for multi line values (PEM blocks).
Ask for one or more domains for a starter dnsconfig.js.
Optionally call dnscontrol get-zones --format=nameonly and show which configured domains exist at the provider, which are only in the config and which are only at the provider.
Optionally run dnscontrol preview as a final sanity check.
Driving it from the provider
To keep the onboarding data next to the provider code, each provider would register its metadata from the same init() where it already calls RegisterMaintainer. The TransIP registration is a good showcase because it covers the expressive end of the API (two auth methods, a multi line PEM field and a second URL for domain management):
providers.RegisterCredsMetadata("TRANSIP", providers.CredsMetadata{
DisplayName: "TransIP",
Kind: providers.KindDNS,
DocsURL: "https://docs.dnscontrol.org/provider/transip",
PortalURL: "https://www.transip.nl/cp/account/api/",
DomainsURL: "https://www.transip.nl/cp/domein-hosting/",
Notes: "TransIP supports two auth methods: a short lived access token, or an account name paired with a long lived private key.",
Fields: []providers.CredsField{
{
Key: "_authMethod",
Label: "Which authentication method do you want to use?",
Choices: []string{"Access token", "Account name + private key"},
Required: true,
Internal: true,
},
{
Key: "AccessToken",
Label: "Access token",
Required: true,
Secret: true,
ShowIf: map[string]string{"_authMethod": "Access token"},
},
{
Key: "AccountName",
Label: "Account name",
Required: true,
ShowIf: map[string]string{"_authMethod": "Account name + private key"},
},
{
Key: "PrivateKey",
Label: "Private key (opens $EDITOR)",
Required: true,
Multiline: true,
ShowIf: map[string]string{"_authMethod": "Account name + private key"},
},
},
})
Fields can declare Required, Secret, Multiline, Choices, EnvVar, Default, plus an Internal selector with ShowIf branching. That lets providers with multiple auth methods (TransIP as shown above, or Route53 static keys versus assume role) ask the right question first and only prompt for the relevant fields. Simpler providers reduce to just PortalURL and a few Fields entries.
Providers without registered metadata still work: the init flow falls back to a generic key/value loop and prints the doc URL.
Sample transcript: Cloudflare with a single account
? Which DNS service provider do you want to configure? CLOUDFLAREAPI
? Use the same Cloudflare account as your registrar? Yes
== DNS provider: Cloudflare ==
API settings for Cloudflare: https://dash.cloudflare.com/profile/api-tokens
? Open the API settings page in your browser? Yes
? API Token (required) **********? Account ID (optional) 0123456789abcdef
? creds.json entry name for this provider cloudflare
? First domain name for dnsconfig.js example.com
? Write these files? Yes
Done.
? Compare domains in dnsconfig.js with zones at Cloudflare? Yes
Zones at Cloudflare compared with dnsconfig.js:
In both : example.com
Only in config : (none)
Only at provider : other.com
? Run `dnscontrol preview` now? Yes
Sample transcript: TransIP with two auth methods
? Which DNS service provider do you want to configure? TRANSIP
== DNS provider: TransIP ==
API settings for TransIP: https://www.transip.nl/cp/account/api/
Manage domains at TransIP: https://www.transip.nl/cp/domein-hosting/
TransIP supports two auth methods: a short lived access token, or an
account name paired with a long lived private key.
? Which authentication method do you want to use? Account name + private key
? Account name my-account
? Private key (opens $EDITOR) [Enter to launch editor]
...
Open questions
Rollout: a generic fallback means metadata can land per provider in separate PRs. Would a tracking issue with a checkbox per provider help maintainers claim theirs?
Documentation: should the same metadata drive a generated "credentials reference" page in documentation/? Or do we remove this information from the per provider doc pages entirely and make init (plus the metadata registered in Go) the single source of truth?
I have a working draft locally but would like to gauge interest and catch pushback before opening a PR. Feedback on the metadata schema, UX and rollout is very welcome.
I briefly ran this idea past @TomOnTime today in a short video call and mentioned that an upcoming holiday period should give me time to pick this work back up. Before going further I want to surface it here so other maintainers and long time contributors can weigh in. Feedback on scope, UX, the metadata schema and naming is very welcome.
In my own experience helping developers try DNSControl (and from my own start back in November 2023), every newcomer hits the same wall:
how and where do I start? @Aartsie was one of those developers, and like most newcomers they arrived with:
Today that path involves reading the docs, tracing the provider Go source for the exact field names, hand writing
creds.jsonand on top of that building adnsconfig.jsfrom scratch while having to learn an entirely new JavaScript DSL. This proposal is about removing that cold start.Pinging the maintainers listed in
OWNERS. Most of you look after these providers as fellow users rather than on behalf of the vendor, so a smoother onboarding directly helps the people who come after you. Feedback and pushback both welcome:@arnoschoon @atrull @blackshadev @bytemain @chicks-net @costasd @D3luxee @das7pad @dnscale-ops @e-im @edglynes @hamptonmoore @hedger @hnrgrgr @huihuimoe @imlonghao @ishanjain28 @jbelien @jpbede @juliusrickert @KaiSchwarz-cnic @kallsyms @KlettIT @koesie10 @kordianbruck @masterzen @matthewmgamble @mikenz @MisterErwin @onlyhavecans @patschi @pgaskin @pierre-emmanuelJ @PJEilers @ppmathis @pragmaton @rblenkinsopp @riku22 @riyadhalnur @SimenBai @SphericalKat @SukkaW @systemcrash @tlimoncelli @tomfitzhenry @tresni @ttkzw @vatsalyagoel @vojtad @willpower232 @xddxdd @zupolgec
Context
A new user of DNSControl has to hand write
creds.jsonbefore they can runprevieworpush. The information needed to fill that file correctly is scattered across at least three places:documentation/provider/.github/workflows/pr_integration_tests.ymlwhere CI credentials are mappedField names are inconsistent across providers (
apitoken,api_token,KeyId,AccountName, and so on) and the portal URL where you create an API token is not discoverable from the CLI. For a first time user that means a round trip through the docs before they can get topreview.Proposal
Add an interactive command:
It walks the user through:
NONEto defer).NONEis available).$EDITORfor multi line values (PEM blocks).dnsconfig.js.dnscontrol get-zones --format=nameonlyand show which configured domains exist at the provider, which are only in the config and which are only at the provider.dnscontrol previewas a final sanity check.Driving it from the provider
To keep the onboarding data next to the provider code, each provider would register its metadata from the same
init()where it already callsRegisterMaintainer. The TransIP registration is a good showcase because it covers the expressive end of the API (two auth methods, a multi line PEM field and a second URL for domain management):Fields can declare
Required,Secret,Multiline,Choices,EnvVar,Default, plus anInternalselector withShowIfbranching. That lets providers with multiple auth methods (TransIP as shown above, or Route53 static keys versus assume role) ask the right question first and only prompt for the relevant fields. Simpler providers reduce to justPortalURLand a fewFieldsentries.Providers without registered metadata still work: the init flow falls back to a generic key/value loop and prints the doc URL.
Sample transcript: Cloudflare with a single account
Sample transcript: TransIP with two auth methods
Open questions
documentation/? Or do we remove this information from the per provider doc pages entirely and makeinit(plus the metadata registered in Go) the single source of truth?I have a working draft locally but would like to gauge interest and catch pushback before opening a PR. Feedback on the metadata schema, UX and rollout is very welcome.
interactive-onboarding-command-dnscontrol-init-demo.mp4