dnsexit

package module
v1.0.3 Latest Latest
Warning

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

Go to latest
Published: May 15, 2025 License: MIT Imports: 13 Imported by: 2

README

DNSExit for libdns

Go Reference

This package implements the libdns interfaces for DNSExit, allowing you to manage DNS records.

Configuration

DNSExit API documentation details the process of getting an API key.

To run clone the .env_template to a file named .env and populate with the API key and zone. Note that setting the environment variable 'LIBDNS_DNSEXIT_DEBUG=TRUE' will output the request body, which includes the API key.

Example

package main

import (
	"context"
	"fmt"
	"os"

	"github.com/libdns/dnsexit"
	"github.com/libdns/libdns"
)

func main() {
	key := os.Getenv("LIBDNS_DNSEXIT_API_KEY")
	if key == "" {
		fmt.Println("LIBDNS_DNSEXIT_API_KEY not set")
		return
	}

	zone := os.Getenv("LIBDNS_DNSEXIT_ZONE")
	if zone == "" {
		fmt.Println("LIBDNS_DNSEXIT_ZONE not set")
		return
	}

	p := &dnsexit.Provider{
		APIKey: key,
	}

	records := []libdns.Record{
		{
			Type:  "A",
			Name:  "test",
			Value: "198.51.100.1",
		},
		{
			Type:  "AAAA",
			Name:  "test",
			Value: "2001:0db8::1",
		},
		{
			Type:  "TXT",
			Name:  "test",
			Value: "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
		},
	}

	ctx := context.Background()
	_, err := p.SetRecords(ctx, zone, records)
	if err != nil {
		fmt.Printf("Error: %v", err)
		return
	}
}

Caveats

The API does not include a GET method, so fetching records is done via Google DNS. There will be some latency.

If an 'A' and 'AAAA' record have the same name, deleting either of them will remove both records.

If multiple record updates are sent in one request, the API may return a code other than 0, to indicate partial success. This is currently judged as a fail and API error message is returned instead of the successfully amended records.

MX records have mail-zone and mail-server properties, which do not exist in the LibDNS record type, so updating these has not been fully implemented. 'name' can be used instead to specify the mail server, but there is no way to specify the mail-zone. See https://dnsexit.com/dns/dns-api/#example-update-mx

For Dynamic DNS DNSExit recommend their dedicated GET endpoint, which can set the domain's IP to the one making the request. That is not implemented in this library.

Documentation

Overview

Package libdns defines core interfaces that should be implemented by DNS provider clients. They are small and idiomatic Go interfaces with well-defined semantics.

Records are described independently of any particular zone, a convention that grants Record structs portability across zones. As such, record names are partially qualified, i.e. relative to the zone. For example, an A record called "sub" in zone "example.com." represents a fully-qualified domain name (FQDN) of "sub.example.com.". Implementations should expect that input records conform to this standard, while also ensuring that output records do; adjustments to record names may need to be made before or after provider API calls, for example, to maintain consistency with all other libdns packages. Helper functions are available in this package to convert between relative and absolute names.

Although zone names are a required input, libdns does not coerce any particular representation of DNS zones; only records. Since zone name and records are separate inputs in libdns interfaces, it is up to the caller to pair a zone's name with its records in a way that works for them.

All interface implementations must be safe for concurrent/parallel use, meaning 1) no data races, and 2) simultaneous method calls must result in either both their expected outcomes or an error.

For example, if AppendRecords() is called at the same time and two API requests are made to the provider at the same time, the result of both requests must be visible after they both complete; if the provider does not synchronize the writing of the zone file and one request overwrites the other, then the client implementation must take care to synchronize on behalf of the incompetent provider. This synchronization need not be global; for example: the scope of synchronization might only need to be within the same zone, allowing multiple requests at once as long as all of them are for different zones. (Exact logic depends on the provider.)

Package dnsexit implements a DNS record management client compatible with the libdns interfaces for DNSExit.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

func AbsoluteName

func AbsoluteName(name, zone string) string

AbsoluteName makes name into a fully-qualified domain name (FQDN) by prepending it to zone and tidying up the dots. For example, an input of name "sub" and zone "example.com." will return "sub.example.com.".

Example
fmt.Println(AbsoluteName("sub", "example.com."))
Output:

sub.example.com.

func RelativeName

func RelativeName(fqdn, zone string) string

RelativeName makes fqdn relative to zone. For example, for a FQDN of "sub.example.com" and a zone of "example.com", it outputs "sub".

If fqdn cannot be expressed relative to zone, the input fqdn is returned.

Example
fmt.Println(RelativeName("sub.example.com.", "example.com."))
Output:

sub

Types

type Action

type Action int64

type Provider

type Provider struct {
	APIKey string `json:"api_key,omitempty"`
	// contains filtered or unexported fields
}

Provider facilitates DNS record manipulation with DNSExit.

func (*Provider) AppendRecords

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

AppendRecords adds records to the zone. It returns the records that were added. This function will fail if a record with the same name already exists.

func (*Provider) DeleteRecords

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

DeleteRecords deletes the records from the zone. It returns the records that were deleted.

func (*Provider) GetRecords

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

GetRecords lists all the records in the zone. NOTE: DNSExit API does not facilitate this, so Google DNS is used.

func (*Provider) SetRecords

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

SetRecords sets the records in the zone, either by updating existing records or creating new ones. It returns the updated records.

type Record

type Record struct {
	// provider-specific metadata
	ID string

	// general record fields
	Type  string
	Name  string // partially-qualified (relative to zone)
	Value string
	TTL   time.Duration

	// type-dependent record fields
	Priority uint // HTTPS, MX, SRV, and URI records
	Weight   uint // SRV and URI records
}

Record is a generalized representation of a DNS record.

The values of this struct should be free of zone-file-specific syntax, except if this struct's fields do not sufficiently represent all the fields of a certain record type; in that case, the remaining data for which there are not specific fields should be stored in the Value as it appears in the zone file.

func (Record) ToSRV

func (r Record) ToSRV() (SRV, error)

ToSRV parses the record into a SRV struct with fully-parsed, literal values.

EXPERIMENTAL; subject to change or removal.

type RecordAppender

type RecordAppender interface {
	// AppendRecords creates the requested records in the given zone
	// and returns the populated records that were created. It never
	// changes existing records.
	//
	// Implementations must honor context cancellation and be safe for
	// concurrent use.
	AppendRecords(ctx context.Context, zone string, recs []Record) ([]Record, error)
}

RecordAppender can non-destructively add new records to a DNS zone.

type RecordDeleter

type RecordDeleter interface {
	// DeleteRecords deletes the given records from the zone if they exist.
	// It returns the records that were deleted.
	//
	// Records that have an ID to associate it with a particular resource on
	// the provider will be directly deleted. If no ID is given, this method
	// may use what information is given to do lookups and delete only
	// matching records.
	//
	// Implementations must honor context cancellation and be safe for
	// concurrent use.
	DeleteRecords(ctx context.Context, zone string, recs []Record) ([]Record, error)
}

RecordDeleter can delete records from a DNS zone.

type RecordGetter

type RecordGetter interface {
	// GetRecords returns all the records in the DNS zone.
	//
	// Implementations must honor context cancellation and be safe for
	// concurrent use.
	GetRecords(ctx context.Context, zone string) ([]Record, error)
}

RecordGetter can get records from a DNS zone.

type RecordSetter

type RecordSetter interface {
	// SetRecords updates the zone so that the records described in the
	// input are reflected in the output. It may create or overwrite
	// records or -- depending on the record type -- delete records to
	// maintain parity with the input. No other records are affected.
	// It returns the records which were set.
	//
	// Records that have an ID associating it with a particular resource
	// on the provider will be directly replaced. If no ID is given, this
	// method may use what information is given to do lookups and will
	// ensure that only necessary changes are made to the zone.
	//
	// Implementations must honor context cancellation and be safe for
	// concurrent use.
	SetRecords(ctx context.Context, zone string, recs []Record) ([]Record, error)
}

RecordSetter can set new or update existing records in a DNS zone.

type SRV

type SRV struct {
	Service  string // no leading "_"
	Proto    string // no leading "_"
	Name     string
	Priority uint
	Weight   uint
	Port     uint
	Target   string
}

SRV contains all the parsed data of an SRV record.

EXPERIMENTAL; subject to change or removal.

func (SRV) ToRecord

func (s SRV) ToRecord() Record

ToRecord converts the parsed SRV data to a Record struct.

EXPERIMENTAL; subject to change or removal.

type Zone

type Zone struct {
	Name string
}

Zone is a generalized representation of a DNS zone.

type ZoneLister

type ZoneLister interface {
	// ListZones returns the list of available DNS zones for use by
	// other libdns methods.
	//
	// Implementations must honor context cancellation and be safe for
	// concurrent use.
	ListZones(ctx context.Context) ([]Zone, error)
}

ZoneLister can list available DNS zones.

Jump to

Keyboard shortcuts

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