Skip to content

FEATURE: Init command#4208

Open
cafferata wants to merge 11 commits intoDNSControl:mainfrom
cafferata:init-command
Open

FEATURE: Init command#4208
cafferata wants to merge 11 commits intoDNSControl:mainfrom
cafferata:init-command

Conversation

@cafferata
Copy link
Copy Markdown
Member

@cafferata cafferata commented Apr 25, 2026

Add interactive dnscontrol init onboarding wizard

Closes #4205

Summary

A new user can run dnscontrol init and have a working creds.json plus a starter dnsconfig.js within a minute. The wizard asks the right questions for the chosen provider and writes both files for them. Existing workflows are unaffected; users who prefer to hand edit creds.json can keep doing exactly that.

Why

DNSControl's biggest entry barrier is the very first ten minutes. Newcomers have to discover, on their own, what fields belong in creds.json for their provider, where to create the API token, whether a value should be a secret, whether it spans multiple lines. That information lives in three places (the provider documentation, the provider's source, and the integration tests workflow) and rarely all in the same form. After helping multiple developers through that ramp myself, the friction is recognisable every time.

The wizard collapses that into a single guided session. A maintainer describes their provider's credential fields once via RegisterCredsMetadata, and from then on every newcomer reuses that knowledge.

What this gives users

  • A guided start. Pick a DNS provider, optionally a registrar, type or paste your credentials, name a domain. Done.
  • Sensible defaults. Where the DNS provider can also act as a registrar, the wizard offers to reuse the same credentials. Pressing Enter accepts the suggested defaults where they exist. PEM blocks open the user's $EDITOR so multiline values stay intact.
  • Immediate feedback. Right after writing, the wizard offers to compare the user's dnsconfig.js with the live zones at the provider, and to run dnscontrol preview as a sanity check.
  • A community welcome. The flow closes with pointers to the documentation, GitHub Discussions, and the monthly community video call.

What this gives provider maintainers

A small registration block next to the existing RegisterMaintainer call:

providers.RegisterCredsMetadata("MYPROVIDER", providers.CredsMetadata{
    DisplayName: "My Provider",
    Kind:        providers.KindDNS,
    PortalURL:   "https://portal.example.com/api-tokens",
    Fields: []providers.CredsField{
        {Key: "apitoken", Label: "API Token", Required: true, Secret: true},
    },
})

That is enough for the provider to appear in the wizard. Providers with multiple auth methods (TransIP access token versus account name plus private key, or Route53 static keys versus assume role) can branch with Internal and ShowIf.

Three providers ship with metadata in this PR as a starting point and a worked example: NONE, BIND, and TransIP. The remaining providers can land incrementally in follow up PRs, one per maintainer.

Scope and follow ups

  • In scope here: the wizard, the metadata mechanism, three reference providers, documentation, and tests.
  • Follow up: metadata registrations for the remaining providers, landing incrementally one per maintainer.
  • Possibly later: generating the credentials section of provider documentation pages from the same metadata, parked for a later PR.

Try it

Check out the branch:

gh pr checkout 4208
# or, without the GitHub CLI:
git fetch origin pull/4208/head:init-command && git checkout init-command

Build and run the wizard against an empty directory:

go build -o /tmp/dnscontrol .
mkdir /tmp/init-demo && cd /tmp/init-demo
/tmp/dnscontrol init

Try one of the included providers (NONE, BIND, TransIP) to see the full flow including the optional zone comparison and dnscontrol preview step.

Test plan

  • go build ./...
  • go test ./...
  • Manual run with NONE registrar plus BIND DNS in an empty directory.
  • Manual run with TransIP, both auth methods (access token, and account name plus private key with $EDITOR=nano).
  • Reviewer: walk through the GitBook documentation preview below.

Documentation preview (GitBook)

The new and updated pages render through the GitBook Git Sync. Preview URLs:

Linked discussion

Initial proposal and feedback live in #4205. Earlier consensus there: drop DomainsURL, keep the auth method picker, drop the generic fallback for the first version of the PR, and keep the per provider documentation pages intact.

Copy link
Copy Markdown
Contributor

@chicks-net chicks-net left a comment

Choose a reason for hiding this comment

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

Very clean and useful.

provider reduces to a few lines:

```go
providers.RegisterCredsMetadata("MYPROVIDER", providers.CredsMetadata{
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This example is good and I wouldn't replace it, but it would be nice if the longer example from the github issue were also included. Another way to accomplish this without writing so much in this doc would be pointing at the other working examples you've done.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Good call. Went with your second suggestion (point at the working examples) so the doc stays compact and does not drift when the providers evolve. The bind and transip references are now clickable links plus a one line description of what each example demonstrates (16e5e1f).

Copy link
Copy Markdown
Collaborator

@TomOnTime TomOnTime left a comment

Choose a reason for hiding this comment

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

Wow! This is really going to make onboarding a lot easier!

Comment thread documentation/commands/init.md Outdated
Comment thread pkg/providers/providers.go Outdated
@cafferata cafferata force-pushed the init-command branch 2 times, most recently from 8f7f6bc to fabc46c Compare May 2, 2026 16:49
@cafferata cafferata marked this pull request as draft May 2, 2026 16:55
@cafferata
Copy link
Copy Markdown
Member Author

Heads up: the lint job is failing on three govet inline warnings in commands/ppreviewPush.go. See the failing job: https://github.com/DNSControl/dnscontrol/actions/runs/25256731676/job/74057255560. I'll fix those locally and push an update before this PR is ready for another review pass.

@cafferata
Copy link
Copy Markdown
Member Author

cafferata commented May 2, 2026

@TomOnTime thanks for the wording suggestions on the documentation.

I've processed your textual feedback in 0d23b6b, so the onboarding docs and the dnscontrol init surfacing should now read more naturally and consistently with the rest of the project.

On top of that, I fixed the failing lint job in 371f05e by migrating from golang.org/x/exp/slices to the stdlib slices package in commands/ppreviewPush.go and providers/bunnydns/, which resolves the govet inline check that was failing on CI.

From my side this is ready for another review pass. Let me know if you'd like any further tweaks!

@cafferata cafferata marked this pull request as ready for review May 2, 2026 17:07
@cafferata cafferata requested a review from TomOnTime May 2, 2026 17:07
@TomOnTime
Copy link
Copy Markdown
Collaborator

Ah! We were both working on the golangci-lint issue at the same time! I will revert #4215 and use your solution.

@cafferata
Copy link
Copy Markdown
Member Author

cafferata commented May 3, 2026

@TomOnTime I've re-resolved the merge conflict with #4222 in go.mod and go.sum. The branch is now rebased on top of the latest main.

@cafferata
Copy link
Copy Markdown
Member Author

cafferata commented May 3, 2026

@TomOnTime I've added an additional commit f25ce33 to apply the renamed import paths from github.com/StackExchange/dnscontrol/v4 to github.com/DNSControl/dnscontrol/v4 introduced in #4214. The CI failures on the previous run were caused by the init command files still pointing at the old module path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Interactive onboarding command: dnscontrol init

3 participants