binarylane

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 9, 2026 License: MIT Imports: 12 Imported by: 0

README

Binary Lane for libdns

godoc reference

This package implements the libdns interfaces for Binary Lane, an Australian cloud provider whose DNS is managed through the Domains endpoints of its public API.

It has no dependencies beyond libdns itself.

On the import path. The canonical home for a libdns provider is github.com/libdns/<provider>, created by the libdns maintainers when a submission is accepted — libdns/libdns#237 is the submission, and #236 the claim. Until that lands this lives here and is imported from here. Go resolves module paths to repositories, so the path has to match wherever it is hosted.

Authenticating

Create an API token in the Binary Lane control panel under Account → API, and put it in APIToken.

Example

provider := binarylane.Provider{
	APIToken: os.Getenv("BINARYLANE_API_TOKEN"),
}

records, err := provider.GetRecords(context.TODO(), "example.com.")

Configuration

Field JSON Purpose
APIToken api_token API token. Required.
APIBase api_base Overrides the API endpoint, including the version segment. A trailing slash is added if absent. Defaults to DefaultAPIBase (https://api.binarylane.com.au/v2/).
HTTPClient — Supplies your own *http.Client for a custom transport, proxy or timeout. One with a 30s timeout is created on first use when nil.

No environment variables are read.

Supported record types

A, AAAA, CAA, CNAME, MX, NS, SRV and TXT.

Binary Lane keeps part of the RDATA of some types in dedicated API fields (priority, port, weight, flags, tag) while libdns expects Data to hold complete zone-file RDATA, so this package composes it on read and splits it again on write. TestRoundTrip pins that behaviour for every affected type.

Binary Lane also serves SOA, which libdns does not model. Those records are returned as an opaque libdns.RR rather than being dropped from a listing, and are not writable.

Binary Lane does not support SVCB or HTTPS records.

TTL is fixed at 3600

Binary Lane enforces a single TTL for the whole zone and rejects any other value with HTTP 400: The default TTL of 3600 may not be changed.

This package therefore never sends a TTL, letting the API apply its own. A record's TTL field is ignored on write, and reads always report 3600.

This is deliberate rather than an oversight. ACME clients set a short TTL on _acme-challenge records, so forwarding the requested value would fail every DNS-01 challenge. libdns anticipates exactly this: "some providers may reject or silently increase TTLs that are below a certain threshold ... it is recommended to not rely on the exact TTL value."

One consequence worth knowing: DeleteRecords matches on TTL when a non-zero one is given, so a record you constructed with a short TTL will not match the 3600 the zone actually holds. Leave TTL zero to match regardless, or delete records obtained from GetRecords.

Behaviour notes

  • Record identity. GetRecords stores the provider's record ID in each record's ProviderData field. DeleteRecords uses it when present and falls back to matching by value otherwise, following the libdns.RecordDeleter rules: an empty Type, zero TTL or empty Data act as wildcards, and Name is always significant.
  • Atomicity. Binary Lane has no batch endpoint, so AppendRecords, SetRecords and DeleteRecords are not atomic: if a call fails partway, earlier changes remain applied.
  • SetRecords reuses existing records within an RRset where it can, so a record whose value is unchanged keeps its ID.
  • Concurrency. All exported methods are safe for concurrent use.

Using it with Caddy

Caddy does not consume a libdns provider directly: it needs a module registered under dns.providers.<name>, with a Caddyfile unmarshaler. That wrapper is the caddydns subdirectory, which is its own Go module so that importing the provider never drags in Caddy.

github.com/jsjeges/libdns-binarylane/caddydns

Caddyfile:

tls {
	dns binarylane {env.BINARYLANE_API_TOKEN}
}

api_token and api_base are also accepted as subdirectives. Placeholders are resolved at provision time, so the token can come from the environment and stay out of the Caddyfile.

On NixOS the plugin is compiled in with pkgs.caddy.withPlugins, which requires a version on every plugin path — a bare path fails at evaluation with "Plugins must have tags present":

services.caddy.package = pkgs.caddy.withPlugins {
  plugins = [ "github.com/jsjeges/libdns-binarylane/caddydns@v0.1.0" ];
  hash = "sha256-...";          # build once with lib.fakeHash to learn it
};

Testing

go test ./... runs offline. The API layer is covered against an httptest server — authentication, pagination, request paths and methods, zero-valued RDATA fields, and error decoding — and the conversion layer is covered directly.

The live test runs the full record lifecycle against a real zone -- ListZones, AppendRecords, SetRecords growing and shrinking an RRset, and DeleteRecords. It is skipped unless both variables are set, and only touches records under a unique libdns-test-<timestamp> label, which it removes afterwards:

BINARYLANE_API_TOKEN=... BINARYLANE_TEST_ZONE=example.com go test -run TestLive -v

go test -race ./... covers concurrent use of every interface method.

libdns's own libdnstest conformance suite is not wired in yet: it is currently only on libdns master, and pinning an unreleased commit would put this package ahead of the released API it targets.

Documentation

Overview

Package binarylane implements the libdns interfaces for Binary Lane (https://www.binarylane.com.au), an Australian cloud provider whose DNS is managed through the Domains endpoints of its public API.

Index

Constants

View Source
const DefaultAPIBase = "https://api.binarylane.com.au/v2/"

DefaultAPIBase is the root of Binary Lane's API, including the version segment every endpoint sits under.

Variables

This section is empty.

Functions

This section is empty.

Types

type Provider

type Provider struct {
	// APIToken is a Binary Lane API token, created under Account → API in the
	// Binary Lane control panel. Required.
	APIToken string `json:"api_token,omitempty"`

	// APIBase optionally overrides the API endpoint, including the version
	// segment. A trailing slash is added if absent. Defaults to
	// DefaultAPIBase.
	APIBase string `json:"api_base,omitempty"`

	// HTTPClient optionally supplies the client used for API calls, for
	// callers that need their own transport, proxy or timeout. A client with a
	// default timeout is created on first use when this is nil.
	HTTPClient *http.Client `json:"-"`
	// contains filtered or unexported fields
}

Provider implements the libdns interfaces for Binary Lane.

func (*Provider) AppendRecords

func (p *Provider) AppendRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)

AppendRecords creates the given records in the zone and returns them. It never modifies an existing record.

Binary Lane offers no batch endpoint, so this is not atomic: if a later record fails, earlier ones remain created.

func (*Provider) DeleteRecords

func (p *Provider) DeleteRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)

DeleteRecords deletes records from the zone, returning those actually deleted. Records that do not exist are silently ignored.

A record carrying an ID from GetRecords is deleted directly. Otherwise it is matched by value, where an empty Type, zero TTL or empty Data act as wildcards and Name is always significant.

func (*Provider) GetRecords

func (p *Provider) GetRecords(ctx context.Context, zone string) ([]libdns.Record, error)

GetRecords lists all the records in the zone.

Records of types libdns does not model — Binary Lane also serves SOA — are returned as opaque libdns.RR values.

func (*Provider) ListZones

func (p *Provider) ListZones(ctx context.Context) ([]libdns.Zone, error)

ListZones returns the domains available to the API token.

func (*Provider) SetRecords

func (p *Provider) SetRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)

SetRecords makes the zone match the input: for every (name, type) pair present in recs, the records given are afterwards the only members of that RRset. Other RRsets are untouched.

Existing records are reused where an RRset shrinks or grows, so an unchanged record keeps its ID. Binary Lane offers no batch endpoint, so this is not atomic.

Directories

Path Synopsis
caddydns module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL