Releases: libdns/selectel
Releases · libdns/selectel
Release list
v1.2.0
What's changed
Security
- JSON injection fixed: authentication body now built with
encoding/jsonstructs — passwords containing"or\are correctly escaped (previouslytext/templatewas used with no JSON escaping)
Breaking changes
KeystoneTokenandZonesCachepublic fields removed (were leaking internal state; now fully private)OperationLogger *log.Loggerreplaced byLoggerfield accepting the newLoggerinterface (Printf(format string, v ...any)) — satisfied by*log.Loggerand any structured-logger adapter
libdns contract compliance
AppendRecords: only adds new values, never mutates existing ones; duplicate input values are skippedSetRecords: replaces exactly the input set per(name, type)pair (was processing records individually, causing values to overwrite each other)DeleteRecords: removes specific values with wildcard support (emptyType/TTL/Data= match any)
Selectel DNS API v2 contract fixes
PATCHpayload now contains only{ttl, records}— sendingid/name/typecould cause 422- Record and zone names sent as FQDN with trailing dot (required by the API)
AppendRecordsusesGET → PATCH/POSTinstead of relying on 409 Conflict (not returned by the rrset endpoint)- Full pagination for
/zonesand/zones/{id}/rrset(count/next_offset) - Zone resolved by exact FQDN match instead of
Zones[0](prevented selecting wrong zone) - Structured error body
{error, description, location}parsed into typedhttpError - TTL clamped to
[60, 604800](both bounds; previously only lower bound was enforced)
Improvements
- Token management: expiry parsed from Keystone response body; token refreshed proactively 5 min before expiry and on every 401;
ensureTokenNotStaleprevents redundant concurrent re-auth calls - Per-zone mutexes: operations on different zones now run in parallel (was single global mutex)
- Shared
http.Clientwith connection pooling and idle-connection timeout - Typed retry logic: uses
errors.Is/net.Error.Timeout()/errors.As(*net.OpError)instead of string matching io.LimitReader(1 MiB)on all response bodiesUser-Agentheader on all requests- Concrete libdns types returned (
Address,TXT,CNAME, …) viaRR.Parse()withRRfallback ListZones(libdns.ZoneLister) with pagination
Tests
- 37 unit tests covering: JSON safety, zone ID resolution + caching, pagination, Append create/merge/dedup, Set replace, Delete partial/full/non-existent/wildcard-TTL, PATCH contract, ListZones
- Integration tests isolated behind
//go:build integrationtag
v1.1.0
What's changed
Bug fixes
- Fixed minimum TTL: Selectel API rejects values below 60 s. Records with TTL below 60 s are now clamped to 60 s (API minimum).
- Fixed 409 Conflict handling in
AppendRecords: the provider now updates an existing record in-place instead of failing.
New features
- HTTP retry with exponential backoff for transient failures (timeouts, 429, 5xx). Configurable via
HTTPRequestRetryConfiguration. - Optional debug logging via
EnableDebugLoggingandOperationLoggerfields. - IDN domain support via
golang.org/x/net/idna. - HTTP client timeout set to 30 s.
API migration
- Updated to libdns v1.1.1:
libdns.RRwithDatafield (waslibdns.RecordwithValue). - Go version updated to 1.24.
Tests
- Added unit tests for
nameNormalizer, TTL clamping, retry logic, and logging (internal_test.go). - Integration tests now skip cleanly when credentials are absent.