Skip to content

Releases: libdns/selectel

v1.2.0

Choose a tag to compare

@WEBzaytsev WEBzaytsev released this 29 Jun 03:11

What's changed

Security

  • JSON injection fixed: authentication body now built with encoding/json structs — passwords containing " or \ are correctly escaped (previously text/template was used with no JSON escaping)

Breaking changes

  • KeystoneToken and ZonesCache public fields removed (were leaking internal state; now fully private)
  • OperationLogger *log.Logger replaced by Logger field accepting the new Logger interface (Printf(format string, v ...any)) — satisfied by *log.Logger and any structured-logger adapter

libdns contract compliance

  • AppendRecords: only adds new values, never mutates existing ones; duplicate input values are skipped
  • SetRecords: 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 (empty Type/TTL/Data = match any)

Selectel DNS API v2 contract fixes

  • PATCH payload now contains only {ttl, records} — sending id/name/type could cause 422
  • Record and zone names sent as FQDN with trailing dot (required by the API)
  • AppendRecords uses GET → PATCH/POST instead of relying on 409 Conflict (not returned by the rrset endpoint)
  • Full pagination for /zones and /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 typed httpError
  • 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; ensureTokenNotStale prevents redundant concurrent re-auth calls
  • Per-zone mutexes: operations on different zones now run in parallel (was single global mutex)
  • Shared http.Client with 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 bodies
  • User-Agent header on all requests
  • Concrete libdns types returned (Address, TXT, CNAME, …) via RR.Parse() with RR fallback
  • 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 integration tag

v1.1.0

Choose a tag to compare

@WEBzaytsev WEBzaytsev released this 31 May 00:35
8149084

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 EnableDebugLogging and OperationLogger fields.
  • 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.RR with Data field (was libdns.Record with Value).
  • 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.

v1.0.0

Choose a tag to compare

@jjazzme jjazzme released this 11 Sep 05:27
v1.0.1