AGENTS.md 4.2 KB

AGENTS.md

CLI for Schlundtech DNS. Go, cobra. Read README.md first — it is the source of truth for what the tool does.

Rules

  • Docs and code must never contradict. Every command in README.md must exist, with the flags and output described. If you change the CLI, update README.md in the same change. Verify with go run . <command> --help.
  • Go only. No other language, no script substitutes.
  • gopls is the diagnostic source of truth. Do not guess at type errors. Run gopls check <file> (or gopls definition / gopls references when you need to navigate). Fix what gopls reports; do not suppress.
  • cobra for the CLI. One command per file under cmd/. Every command needs Short, Long, and a complete Example in its help text. No hand-rolled flag parsing.
  • Errors go to stderr, data goes to stdout. Anything pipeable must not be polluted by log output.
  • Never log or echo credentials.

Layout

main.go          entrypoint
cmd/             one cobra command per file
internal/        packages; api/ holds the gateway client

internal/api is the only place that speaks HTTP to the gateway. Commands must not build requests themselves.

Workflow

go build ./...
go test ./...
gopls check ./...        # must be clean before you stop

Credentials

Read from the environment (SCHLUNDTECH_USER, SCHLUNDTECH_PASSWORD, SCHLUNDTECH_CONTEXT) or a config file. Never commit them. Writes to DNS are public and propagate immediately — every mutating command needs a --dry-run flag.

Generated files

.opencode/skill/, .opencode/agent/, .opencode/command/ are generated from the maister submodule. Never edit them; run node tools/build-maister-opencode.mjs and node tools/verify-maister-opencode.mjs after git -C maister pull.

References

  • The gateway is AutoDNS. gateway.schlundtech.de is Schlundtech's hostname for InterNetX's AutoDNS platform — same host as gateway.autodns.com (the IP reverse-resolves to it). Use gateway.schlundtech.de as the default endpoint.
  • XML is the transport. Schlundtech's own web portal is also built on the AutoDNS JSON API (cloud.schlundtech.com/services/backend/zone/... returns the documented stid/status/object/data envelope with the same task codes: S0205 zone inquire, S0210 axfr, S0225 zone list). Do not mistake that for a public API: it authenticates by portal session cookie only — no BasicAuth — so it is the frontend's private backend, versioned with Schlundtech's release cycle, and unusable without driving a browser login plus 2FA. api.autodns.com/v1 is the documented JSON API but rejects a Schlundtech login with EF1322002 "Application could not be found.": the BasicAuth username must be a registered application on InterNetX's side (x-autodns-agent: PHOENIX does not change this). Build against the XML gateway, which takes the credentials a Schlundtech customer actually has.
  • Context ID is 10. Verified against the real account: zone responses carry "owner":{"context":10,"user":"<id>"}.
  • The XML gateway answers HTTP 200 even on failure. Verified: a request with bad credentials returns HTTP 200 and this body: response/result/msg/{code:EF00202, text:"User does not exist or password incorrect.", object:{type:user, value:<user>}}, with the sibling status/{code:E00000, type:error} staying generic. Never branch on the HTTP status code — parse the body, treat result/msg/code as the real error and result/status/type as the success flag. Non-2xx from this host is an nginx 404 (wrong path), never an application error. Whether the 3 req/s limit comes back as an HTTP 429 or as an in-body error is still unverified.
  • Zone read = task 0205. Record replace = task 0202001 (rr_rem + rr_add in one transaction, system_ns required). Zone's own NS is the first NS in nameServers (a.k.a. virtualNameServer).
  • Record shape is {name, type, value} plus ttl, where the apex is the empty name. nameServers is the NS set. Task 0210 returns a plain zone file.
  • Working implementations: https://github.com/jurica/ddns-schlundtech (Go), https://github.com/couchtyp/certbot-dns-schlundtech, https://github.com/wosc/schlund-ddns