kruno fe60331474 Add gibdns/draft-02: rrset.batch, precondition levels, bounded rate-limit waits.
The runtime now serves gibdns/draft-01 and gibdns/draft-02 from one program
and answers each request in its own version, so draft-01 hosts such as
gibcert v0.2 are unaffected.

- rrset.batch applies several RRset mutations to one zone. Operations share
  one parse/evaluate path with rrset.patch and rrset.replace. atomic is
  required; a provider commits all-or-nothing through BatchWriter or applies
  operations one RRset at a time and stops at the first failure.
- BatchReader, BatchWriter, RRsetWrite and BatchOpError let backends read and
  commit several RRsets in one provider request.
- draft-02 capabilities report precondition enforcement levels, features.batch
  and constraints.maximum_batch_ops.
- unsupported_version answers in the newest format and lists every version.
- RateLimiter waits on upstream limits only when the delay fits the request
  deadline and a 30 second budget, otherwise it returns rate_limited.

gibdns.ProtocolVersion is replaced by ProtocolDraft01, ProtocolDraft02,
LatestVersion and SupportedVersions.
2026-10-27 20:07:36 +01:00

gibdns-go

Go runtime for gibdns provider programs. It implements the exec-json binding, DNS presentation and equality, patch/replace semantics, preconditions, and TTL policy so individual DNS providers can stay small.

This is a library, not a DNS provider you install and run. Operators should install a provider from the catalog and follow Using gibdns. Use this module when writing a new provider.

Protocol Status
gibdns/draft-01 Supported
gibdns/draft-02 Supported, including rrset.batch

The runtime serves every supported protocol identifier from one program. A response uses the version of the request, so hosts that speak only gibdns/draft-01 keep working unchanged.

Official providers (Cloudflare, deSEC, Gcore, LuaDNS) are built on this runtime.

Use

package main

import (
	"gitfield.org/gibdns/gibdns-go"
	"gitfield.org/gibdns/gibdns-go/provider"
)

func main() {
	provider.Main(provider.Implementation{
		Name:          "example-dns",
		Version:       "1.0.0",
		RecordTypes:   []string{"TXT", "TLSA", "HTTPS"},
		ZoneDiscovery: true,
		Preconditions: map[string][]string{
			gibdns.MethodRRSetPatch:   {gibdns.PreconditionIfRevision, gibdns.PreconditionIfAbsent},
			gibdns.MethodRRSetReplace: {gibdns.PreconditionIfRevision, gibdns.PreconditionIfAbsent},
		},
		NewBackend: func(config map[string]any, secrets map[string]string) (provider.Backend, error) {
			return newBackend(config, secrets)
		},
	})
}

A backend only needs GetRRset and PutRRset. Optional interfaces:

  • ZoneDiscoverer when ZoneDiscovery is true
  • MemberPatcher when ConcurrentSafePatch is true
  • BatchReader to read several RRsets in fewer provider requests
  • BatchWriter to commit several RRsets in one request; set Implementation.AtomicBatch only when that commit is all-or-nothing

rrset.batch works for every backend. Without BatchWriter the runtime applies the operations one RRset at a time, so such a provider reports features.batch.atomic: false and rejects atomic: true. Set Implementation.MaxBatchOps to advertise and enforce a size limit.

A provider that waits on an upstream rate limit should use provider.RateLimiter rather than sleeping on Retry-After: it waits only for short delays that fit the request deadline and otherwise returns rate_limited with retry_after_seconds.

Advertise TXT for ACME DNS-01 hosts such as gibcert, and TLSA if the DNS service can publish DANE records. See the protocol specification for the request model.

When a provider is ready, add it to the catalog.

Development

make test
make lint
S
Description
gibdns library for Go
Readme 0BSD
108 KiB
0 Stars 1 Watchers 0 Forks
Languages
Go 99.4%
Makefile 0.6%