Documentation
¶
Overview ¶
Package dnsrecords builds a provider-agnostic DNS record manager from whichever ACME DNS-01 provider a control plane already has credentials for (Cloudflare or Route53), reusing libdns's own interfaces instead of inventing a second one: github.com/libdns/cloudflare and github.com/libdns/route53, both already a dependency via internal/ingress's Caddy DNS-01 wiring, implement them already.
Index ¶
- Constants
- Variables
- func Candidates(domain string) []string
- func CanonicalRedirect(apex, mode, canonical string) (from, to string)
- func MatchZone(domain string, zones []string) (string, bool)
- func RelativeName(domain, zone string) string
- func TargetFor(ips []string) (recType, value string, err error)
- func ValidCanonical(c string) bool
- func ValidWWWMode(m string) bool
- func ValidateTarget(d Desired, provider string) error
- type ApexWWWItem
- type CloudflareAPI
- func (c *CloudflareAPI) FindZone(ctx context.Context, domain string) (string, error)
- func (c *CloudflareAPI) ProxyDrift(ctx context.Context, zone, fqdn, recType, content string, proxied bool) (found, drifted int, err error)
- func (c *CloudflareAPI) PurgeHosts(ctx context.Context, zone string, hosts []string) error
- func (c *CloudflareAPI) SSLMode(ctx context.Context, zone string) (string, error)
- func (c *CloudflareAPI) SetProxied(ctx context.Context, zone, fqdn, recType, content string, proxied bool) (int, error)
- type Desired
- type Manager
- type ManagerZoneFinder
- type Plan
- type ZoneFinder
- type ZoneManager
- func (m ZoneManager) AppendRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
- func (m ZoneManager) DeleteRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
- func (m ZoneManager) GetRecords(ctx context.Context, zone string) ([]libdns.Record, error)
- func (m ZoneManager) SetRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
Constants ¶
const ( WWWBoth = "both" WWWApexOnly = "apex_only" WWWOnly = "www_only" )
WWW modes: which of apex and www get records.
const ( CanonicalApex = "apex" CanonicalWWW = "www" )
Canonical values: which host visitors end up on.
const ( OutcomeCreated = "created" OutcomeUpdated = "updated" OutcomeUnchanged = "unchanged" OutcomeConflict = "conflict" )
Outcome values a record plan or apply reports per domain.
Variables ¶
var ErrNoTarget = errors.New("dnsrecords: no public address or CNAME target is known for this server")
ErrNoTarget means neither a public address nor a CNAME target is known.
var ErrZoneNotFound = errors.New("dnsrecords: no managed zone contains the domain")
ErrZoneNotFound means no zone the provider manages contains the domain.
Functions ¶
func Candidates ¶
Candidates returns every zone name domain could belong to, longest first, down to two labels (a bare TLD is never a zone).
func CanonicalRedirect ¶
CanonicalRedirect names the 308 the plan implies: from the non-canonical host to the canonical one. Both are empty unless mode serves both hosts.
func MatchZone ¶
MatchZone returns the longest zone in zones that contains domain, with a trailing dot, or false when none does.
func RelativeName ¶
RelativeName is domain's record name inside zone: "@" for the apex.
func TargetFor ¶
TargetFor picks the record type and value pointing at a server reachable at ips: an A record for the first IPv4 address, else AAAA for the first IPv6 one. ips that are not IP literals are ignored.
func ValidCanonical ¶
ValidCanonical reports whether c is a known domains.canonical value.
func ValidWWWMode ¶
ValidWWWMode reports whether m is a known domains.www_mode value.
func ValidateTarget ¶
ValidateTarget rejects a CNAME at a zone apex for providers that cannot flatten it.
Types ¶
type ApexWWWItem ¶
ApexWWWItem is one record of an apex and www plan.
func PlanApexWWW ¶
func PlanApexWWW(apex, mode string, target Desired, existing []libdns.Record, replace bool, ttl time.Duration) ([]ApexWWWItem, error)
PlanApexWWW lists the records a zone-apex domain needs for mode. The apex gets the address record; www follows it with a CNAME so one change moves both, except in www_only mode where www carries the address itself.
type CloudflareAPI ¶
CloudflareAPI is the few direct Cloudflare calls libdns cannot make: an exact zone lookup and the proxied flag. The token is only ever sent as a bearer header and never appears in an error.
func (*CloudflareAPI) FindZone ¶
FindZone asks Cloudflare for each candidate zone name, longest first.
func (*CloudflareAPI) ProxyDrift ¶
func (c *CloudflareAPI) ProxyDrift(ctx context.Context, zone, fqdn, recType, content string, proxied bool) (found, drifted int, err error)
ProxyDrift counts the matching records and how many differ from proxied, without changing anything.
func (*CloudflareAPI) PurgeHosts ¶
PurgeHosts clears Cloudflare's edge cache for every URL under each host in zone. It needs a token with the Cache Purge permission.
func (*CloudflareAPI) SSLMode ¶
SSLMode reads the zone's SSL/TLS encryption mode: off, flexible, full or strict. It needs a token with Zone Settings read.
func (*CloudflareAPI) SetProxied ¶
func (c *CloudflareAPI) SetProxied(ctx context.Context, zone, fqdn, recType, content string, proxied bool) (int, error)
SetProxied sets the proxied flag on the records of recType at fqdn in zone whose content equals content, and returns how many it changed.
type Manager ¶
type Manager interface {
GetRecords(ctx context.Context, zone string) ([]libdns.Record, error)
AppendRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
SetRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
DeleteRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
}
Manager is the subset of libdns's interfaces a DNS records view needs: list, non-destructive add, replace-by-exact-match, and delete. Any provider implementing it already satisfies libdns.RecordGetter, libdns.RecordAppender, libdns.RecordSetter, and libdns.RecordDeleter.
func NewCloudflareManager ¶
NewCloudflareManager wraps github.com/libdns/cloudflare with the same scoped API token (Zone:DNS:Edit) already stored for Cloudflare ACME DNS-01, so records management needs no separate credential.
func NewGoogleCloudManager ¶
NewGoogleCloudManager builds a Manager from a service account JSON key.
func NewRoute53Manager ¶
NewRoute53Manager wraps github.com/libdns/route53 with the same IAM access key pair already stored for Route53 ACME DNS-01. Region and hostedZoneID may be empty: the provider resolves them itself the same way it does for DNS-01 (see internal/reconcile/ingress's own use).
type ManagerZoneFinder ¶
type ManagerZoneFinder struct{ Mgr Manager }
ManagerZoneFinder probes candidate zones through a Manager: a zone exists when it lists and its apex SOA is at "@". It is the only option for Route53, which libdns cannot enumerate zones for.
type Plan ¶
type Plan struct {
Outcome string
// Replace holds the existing records an update removes first; for a
// conflict it lists the records that block the create.
Replace []libdns.RR
}
Plan is what applying Desired would do against a zone's existing records.
func PlanRecord ¶
PlanRecord decides how to bring d into existing. An identical record is unchanged even next to siblings; a different A/AAAA/CNAME at the same name is a conflict unless replace is set, and a foreign TXT or MX is never touched.
type ZoneFinder ¶
type ZoneFinder interface {
// FindZone returns the zone with a trailing dot, or ErrZoneNotFound.
FindZone(ctx context.Context, domain string) (string, error)
}
ZoneFinder resolves the zone a domain's records live in.
type ZoneManager ¶
ZoneManager adapts a dnszones.Provider to Manager, so providers without a libdns module (Google Cloud DNS) serve record automation and DNS-01 TXT writes.
func (ZoneManager) AppendRecords ¶
func (m ZoneManager) AppendRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
AppendRecords implements Manager.
func (ZoneManager) DeleteRecords ¶
func (m ZoneManager) DeleteRecords(ctx context.Context, zone string, recs []libdns.Record) ([]libdns.Record, error)
DeleteRecords implements Manager. An empty Data on the input matches any value of that name and type.
func (ZoneManager) GetRecords ¶
GetRecords implements Manager.