Update dependencies and go version
This commit is contained in:
parent
c2fc6d587d
commit
bc1c3842ee
@ -39,7 +39,7 @@ Usage of cloudflare-dns-cli:
|
|||||||
IP address (default 127.0.0.1)
|
IP address (default 127.0.0.1)
|
||||||
-m Set mx record with cname value
|
-m Set mx record with cname value
|
||||||
-o string
|
-o string
|
||||||
Path to save all records as json, e.g. ./records.json
|
Path to save all records as json, e.g. ./records.json, '-' for stdout
|
||||||
-s string
|
-s string
|
||||||
Subdomain, e.g. blog. Use @ for root (default "<UNSET>")
|
Subdomain, e.g. blog. Use @ for root (default "<UNSET>")
|
||||||
-x Delete records of subdomain
|
-x Delete records of subdomain
|
||||||
|
6
go.mod
6
go.mod
@ -1,8 +1,8 @@
|
|||||||
module go.balki.me/cloudflare-dns-cli
|
module go.balki.me/cloudflare-dns-cli
|
||||||
|
|
||||||
go 1.21
|
go 1.22.1
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/libdns/cloudflare v0.1.0
|
github.com/libdns/cloudflare v0.1.1
|
||||||
github.com/libdns/libdns v0.2.1
|
github.com/libdns/libdns v0.2.2
|
||||||
)
|
)
|
||||||
|
9
go.sum
9
go.sum
@ -1,5 +1,4 @@
|
|||||||
github.com/libdns/cloudflare v0.1.0 h1:93WkJaGaiXCe353LHEP36kAWCUw0YjFqwhkBkU2/iic=
|
github.com/libdns/cloudflare v0.1.1 h1:FVPfWwP8zZCqj268LZjmkDleXlHPlFU9KC4OJ3yn054=
|
||||||
github.com/libdns/cloudflare v0.1.0/go.mod h1:a44IP6J1YH6nvcNl1PverfJviADgXUnsozR3a7vBKN8=
|
github.com/libdns/cloudflare v0.1.1/go.mod h1:9VK91idpOjg6v7/WbjkEW49bSCxj00ALesIFDhJ8PBU=
|
||||||
github.com/libdns/libdns v0.2.0/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
github.com/libdns/libdns v0.2.2 h1:O6ws7bAfRPaBsgAYt8MDe2HcNBGC29hkZ9MX2eUSX3s=
|
||||||
github.com/libdns/libdns v0.2.1 h1:Wu59T7wSHRgtA0cfxC+n1c/e+O3upJGWytknkmFEDis=
|
github.com/libdns/libdns v0.2.2/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
|
||||||
github.com/libdns/libdns v0.2.1/go.mod h1:yQCXzk1lEZmmCPa857bnk4TsOiqYasqpyOEeSObbb40=
|
|
||||||
|
4
main.go
4
main.go
@ -63,9 +63,9 @@ func genRecord() (libdns.Record, error) {
|
|||||||
func selectRecordsToDelete(recs []libdns.Record) []libdns.Record {
|
func selectRecordsToDelete(recs []libdns.Record) []libdns.Record {
|
||||||
name := func() string {
|
name := func() string {
|
||||||
if sub == "@" {
|
if sub == "@" {
|
||||||
return domain
|
return ""
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%s.%s", sub, domain)
|
return sub
|
||||||
}()
|
}()
|
||||||
recs = func() (result []libdns.Record) {
|
recs = func() (result []libdns.Record) {
|
||||||
for _, r := range recs {
|
for _, r := range recs {
|
||||||
|
6
vendor/github.com/libdns/cloudflare/client.go
generated
vendored
6
vendor/github.com/libdns/cloudflare/client.go
generated
vendored
@ -12,7 +12,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (p *Provider) createRecord(ctx context.Context, zoneInfo cfZone, record libdns.Record) (cfDNSRecord, error) {
|
func (p *Provider) createRecord(ctx context.Context, zoneInfo cfZone, record libdns.Record) (cfDNSRecord, error) {
|
||||||
jsonBytes, err := json.Marshal(cloudflareRecord(record))
|
cfRec, err := cloudflareRecord(record)
|
||||||
|
if err != nil {
|
||||||
|
return cfDNSRecord{}, err
|
||||||
|
}
|
||||||
|
jsonBytes, err := json.Marshal(cfRec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cfDNSRecord{}, err
|
return cfDNSRecord{}, err
|
||||||
}
|
}
|
||||||
|
60
vendor/github.com/libdns/cloudflare/models.go
generated
vendored
60
vendor/github.com/libdns/cloudflare/models.go
generated
vendored
@ -2,6 +2,7 @@ package cloudflare
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/libdns/libdns"
|
"github.com/libdns/libdns"
|
||||||
@ -61,7 +62,7 @@ type cfDNSRecord struct {
|
|||||||
ZoneName string `json:"zone_name,omitempty"`
|
ZoneName string `json:"zone_name,omitempty"`
|
||||||
CreatedOn time.Time `json:"created_on,omitempty"`
|
CreatedOn time.Time `json:"created_on,omitempty"`
|
||||||
ModifiedOn time.Time `json:"modified_on,omitempty"`
|
ModifiedOn time.Time `json:"modified_on,omitempty"`
|
||||||
Data *struct {
|
Data struct {
|
||||||
// LOC
|
// LOC
|
||||||
LatDegrees int `json:"lat_degrees,omitempty"`
|
LatDegrees int `json:"lat_degrees,omitempty"`
|
||||||
LatMinutes int `json:"lat_minutes,omitempty"`
|
LatMinutes int `json:"lat_minutes,omitempty"`
|
||||||
@ -80,9 +81,9 @@ type cfDNSRecord struct {
|
|||||||
Service string `json:"service,omitempty"`
|
Service string `json:"service,omitempty"`
|
||||||
Proto string `json:"proto,omitempty"`
|
Proto string `json:"proto,omitempty"`
|
||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
Priority int `json:"priority,omitempty"`
|
Priority uint `json:"priority,omitempty"`
|
||||||
Weight int `json:"weight,omitempty"`
|
Weight uint `json:"weight,omitempty"`
|
||||||
Port int `json:"port,omitempty"`
|
Port uint `json:"port,omitempty"`
|
||||||
Target string `json:"target,omitempty"`
|
Target string `json:"target,omitempty"`
|
||||||
|
|
||||||
// DNSKEY
|
// DNSKEY
|
||||||
@ -109,6 +110,18 @@ type cfDNSRecord struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r cfDNSRecord) libdnsRecord(zone string) libdns.Record {
|
func (r cfDNSRecord) libdnsRecord(zone string) libdns.Record {
|
||||||
|
if r.Type == "SRV" {
|
||||||
|
srv := libdns.SRV{
|
||||||
|
Service: strings.TrimPrefix(r.Data.Service, "_"),
|
||||||
|
Proto: strings.TrimPrefix(r.Data.Proto, "_"),
|
||||||
|
Name: r.Data.Name,
|
||||||
|
Priority: r.Data.Priority,
|
||||||
|
Weight: r.Data.Weight,
|
||||||
|
Port: r.Data.Port,
|
||||||
|
Target: r.Data.Target,
|
||||||
|
}
|
||||||
|
return srv.ToRecord()
|
||||||
|
}
|
||||||
return libdns.Record{
|
return libdns.Record{
|
||||||
Type: r.Type,
|
Type: r.Type,
|
||||||
Name: libdns.RelativeName(r.Name, zone),
|
Name: libdns.RelativeName(r.Name, zone),
|
||||||
@ -118,14 +131,29 @@ func (r cfDNSRecord) libdnsRecord(zone string) libdns.Record {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func cloudflareRecord(r libdns.Record) cfDNSRecord {
|
func cloudflareRecord(r libdns.Record) (cfDNSRecord, error) {
|
||||||
return cfDNSRecord{
|
rec := cfDNSRecord{
|
||||||
ID: r.ID,
|
ID: r.ID,
|
||||||
Type: r.Type,
|
Type: r.Type,
|
||||||
Name: r.Name,
|
TTL: int(r.TTL.Seconds()),
|
||||||
Content: r.Value,
|
|
||||||
TTL: int(r.TTL.Seconds()),
|
|
||||||
}
|
}
|
||||||
|
if r.Type == "SRV" {
|
||||||
|
srv, err := r.ToSRV()
|
||||||
|
if err != nil {
|
||||||
|
return cfDNSRecord{}, err
|
||||||
|
}
|
||||||
|
rec.Data.Service = "_" + srv.Service
|
||||||
|
rec.Data.Priority = srv.Priority
|
||||||
|
rec.Data.Weight = srv.Weight
|
||||||
|
rec.Data.Proto = "_" + srv.Proto
|
||||||
|
rec.Data.Name = srv.Name
|
||||||
|
rec.Data.Port = srv.Port
|
||||||
|
rec.Data.Target = srv.Target
|
||||||
|
} else {
|
||||||
|
rec.Name = r.Name
|
||||||
|
rec.Content = r.Value
|
||||||
|
}
|
||||||
|
return rec, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// All API responses have this structure.
|
// All API responses have this structure.
|
||||||
@ -133,10 +161,14 @@ type cfResponse struct {
|
|||||||
Result json.RawMessage `json:"result,omitempty"`
|
Result json.RawMessage `json:"result,omitempty"`
|
||||||
Success bool `json:"success"`
|
Success bool `json:"success"`
|
||||||
Errors []struct {
|
Errors []struct {
|
||||||
Code int `json:"code"`
|
Code int `json:"code"`
|
||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
|
ErrorChain []struct {
|
||||||
|
Code int `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
} `json:"error_chain,omitempty"`
|
||||||
} `json:"errors,omitempty"`
|
} `json:"errors,omitempty"`
|
||||||
Messages []interface{} `json:"messages,omitempty"`
|
Messages []any `json:"messages,omitempty"`
|
||||||
ResultInfo *cfResultInfo `json:"result_info,omitempty"`
|
ResultInfo *cfResultInfo `json:"result_info,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
vendor/github.com/libdns/cloudflare/provider.go
generated
vendored
11
vendor/github.com/libdns/cloudflare/provider.go
generated
vendored
@ -131,7 +131,10 @@ func (p *Provider) SetRecords(ctx context.Context, zone string, records []libdns
|
|||||||
|
|
||||||
var results []libdns.Record
|
var results []libdns.Record
|
||||||
for _, rec := range records {
|
for _, rec := range records {
|
||||||
oldRec := cloudflareRecord(rec)
|
oldRec, err := cloudflareRecord(rec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
oldRec.ZoneID = zoneInfo.ID
|
oldRec.ZoneID = zoneInfo.ID
|
||||||
if rec.ID == "" {
|
if rec.ID == "" {
|
||||||
// the record might already exist, even if we don't know the ID yet
|
// the record might already exist, even if we don't know the ID yet
|
||||||
@ -155,7 +158,11 @@ func (p *Provider) SetRecords(ctx context.Context, zone string, records []libdns
|
|||||||
oldRec.ID = matches[0].ID
|
oldRec.ID = matches[0].ID
|
||||||
}
|
}
|
||||||
// record exists; update it
|
// record exists; update it
|
||||||
result, err := p.updateRecord(ctx, oldRec, cloudflareRecord(rec))
|
cfRec, err := cloudflareRecord(rec)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
result, err := p.updateRecord(ctx, oldRec, cfRec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
18
vendor/github.com/libdns/libdns/README.md
generated
vendored
18
vendor/github.com/libdns/libdns/README.md
generated
vendored
@ -41,14 +41,18 @@ recs, err := provider.GetRecords(ctx, zone)
|
|||||||
|
|
||||||
// create records (AppendRecords is similar)
|
// create records (AppendRecords is similar)
|
||||||
newRecs, err := provider.SetRecords(ctx, zone, []libdns.Record{
|
newRecs, err := provider.SetRecords(ctx, zone, []libdns.Record{
|
||||||
Type: "A",
|
{
|
||||||
Name: "sub",
|
Type: "A",
|
||||||
Value: "1.2.3.4",
|
Name: "sub",
|
||||||
|
Value: "1.2.3.4",
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// delete records (this example uses provider-assigned ID)
|
// delete records (this example uses provider-assigned ID)
|
||||||
deletedRecs, err := provider.DeleteRecords(ctx, zone, []libdns.Record{
|
deletedRecs, err := provider.DeleteRecords(ctx, zone, []libdns.Record{
|
||||||
ID: "foobar",
|
{
|
||||||
|
ID: "foobar",
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
// no matter which provider you use, the code stays the same!
|
// no matter which provider you use, the code stays the same!
|
||||||
@ -56,11 +60,11 @@ deletedRecs, err := provider.DeleteRecords(ctx, zone, []libdns.Record{
|
|||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Implementing new providers
|
## Implementing new provider packages
|
||||||
|
|
||||||
Providers are 100% written and maintained by the community! We all maintain just the packages for providers we use.
|
Provider packages are 100% written and maintained by the community! Collectively, we all maintain the packages for providers we individually use.
|
||||||
|
|
||||||
**[Instructions for adding new providers](https://github.com/libdns/libdns/wiki/Implementing-providers)** are on this repo's wiki. Please feel free to contribute.
|
**[Instructions for adding new libdns packages](https://github.com/libdns/libdns/wiki/Implementing-a-libdns-package)** are on this repo's wiki. Please feel free to contribute yours!
|
||||||
|
|
||||||
|
|
||||||
## Similar projects
|
## Similar projects
|
||||||
|
106
vendor/github.com/libdns/libdns/libdns.go
generated
vendored
106
vendor/github.com/libdns/libdns/libdns.go
generated
vendored
@ -10,15 +10,18 @@
|
|||||||
// that input records conform to this standard, while also ensuring that
|
// that input records conform to this standard, while also ensuring that
|
||||||
// output records do; adjustments to record names may need to be made before
|
// output records do; adjustments to record names may need to be made before
|
||||||
// or after provider API calls, for example, to maintain consistency with
|
// or after provider API calls, for example, to maintain consistency with
|
||||||
// all other libdns provider implementations. Helper functions are available
|
// all other libdns packages. Helper functions are available in this package
|
||||||
// in this package to convert between relative and absolute names.
|
// to convert between relative and absolute names.
|
||||||
//
|
//
|
||||||
// Although zone names are a required input, libdns does not coerce any
|
// Although zone names are a required input, libdns does not coerce any
|
||||||
// particular representation of DNS zones; only records. Since zone name and
|
// particular representation of DNS zones; only records. Since zone name and
|
||||||
// records are separate inputs in libdns interfaces, it is up to the caller
|
// 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.
|
// 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.
|
// 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
|
// 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 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
|
// requests must be visible after they both complete; if the provider does
|
||||||
@ -32,6 +35,8 @@ package libdns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
@ -89,7 +94,23 @@ type RecordDeleter interface {
|
|||||||
DeleteRecords(ctx context.Context, zone string, recs []Record) ([]Record, error)
|
DeleteRecords(ctx context.Context, zone string, recs []Record) ([]Record, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ZoneLister can list available DNS zones.
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
// Record is a generalized representation of a DNS record.
|
// 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.
|
||||||
type Record struct {
|
type Record struct {
|
||||||
// provider-specific metadata
|
// provider-specific metadata
|
||||||
ID string
|
ID string
|
||||||
@ -101,7 +122,76 @@ type Record struct {
|
|||||||
TTL time.Duration
|
TTL time.Duration
|
||||||
|
|
||||||
// type-dependent record fields
|
// type-dependent record fields
|
||||||
Priority int // used by MX, SRV, and URI records
|
Priority uint // HTTPS, MX, SRV, and URI records
|
||||||
|
Weight uint // SRV and URI records
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zone is a generalized representation of a DNS zone.
|
||||||
|
type Zone struct {
|
||||||
|
Name string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToSRV parses the record into a SRV struct with fully-parsed, literal values.
|
||||||
|
//
|
||||||
|
// EXPERIMENTAL; subject to change or removal.
|
||||||
|
func (r Record) ToSRV() (SRV, error) {
|
||||||
|
if r.Type != "SRV" {
|
||||||
|
return SRV{}, fmt.Errorf("record type not SRV: %s", r.Type)
|
||||||
|
}
|
||||||
|
|
||||||
|
fields := strings.Fields(r.Value)
|
||||||
|
if len(fields) != 2 {
|
||||||
|
return SRV{}, fmt.Errorf("malformed SRV value; expected: '<port> <target>'")
|
||||||
|
}
|
||||||
|
|
||||||
|
port, err := strconv.Atoi(fields[0])
|
||||||
|
if err != nil {
|
||||||
|
return SRV{}, fmt.Errorf("invalid port %s: %v", fields[0], err)
|
||||||
|
}
|
||||||
|
if port < 0 {
|
||||||
|
return SRV{}, fmt.Errorf("port cannot be < 0: %d", port)
|
||||||
|
}
|
||||||
|
|
||||||
|
parts := strings.SplitN(r.Name, ".", 3)
|
||||||
|
if len(parts) < 3 {
|
||||||
|
return SRV{}, fmt.Errorf("name %v does not contain enough fields; expected format: '_service._proto.name'", r.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return SRV{
|
||||||
|
Service: strings.TrimPrefix(parts[0], "_"),
|
||||||
|
Proto: strings.TrimPrefix(parts[1], "_"),
|
||||||
|
Name: parts[2],
|
||||||
|
Priority: r.Priority,
|
||||||
|
Weight: r.Weight,
|
||||||
|
Port: uint(port),
|
||||||
|
Target: fields[1],
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SRV contains all the parsed data of an SRV record.
|
||||||
|
//
|
||||||
|
// EXPERIMENTAL; subject to change or removal.
|
||||||
|
type SRV struct {
|
||||||
|
Service string // no leading "_"
|
||||||
|
Proto string // no leading "_"
|
||||||
|
Name string
|
||||||
|
Priority uint
|
||||||
|
Weight uint
|
||||||
|
Port uint
|
||||||
|
Target string
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToRecord converts the parsed SRV data to a Record struct.
|
||||||
|
//
|
||||||
|
// EXPERIMENTAL; subject to change or removal.
|
||||||
|
func (s SRV) ToRecord() Record {
|
||||||
|
return Record{
|
||||||
|
Type: "SRV",
|
||||||
|
Name: fmt.Sprintf("_%s._%s.%s", s.Service, s.Proto, s.Name),
|
||||||
|
Priority: s.Priority,
|
||||||
|
Weight: s.Weight,
|
||||||
|
Value: fmt.Sprintf("%d %s", s.Port, s.Target),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// RelativeName makes fqdn relative to zone. For example, for a FQDN of
|
// RelativeName makes fqdn relative to zone. For example, for a FQDN of
|
||||||
@ -109,7 +199,13 @@ type Record struct {
|
|||||||
//
|
//
|
||||||
// If fqdn cannot be expressed relative to zone, the input fqdn is returned.
|
// If fqdn cannot be expressed relative to zone, the input fqdn is returned.
|
||||||
func RelativeName(fqdn, zone string) string {
|
func RelativeName(fqdn, zone string) string {
|
||||||
return strings.TrimSuffix(strings.TrimSuffix(fqdn, zone), ".")
|
// liberally ignore trailing dots on both fqdn and zone, because
|
||||||
|
// the relative name won't have a trailing dot anyway; I assume
|
||||||
|
// this won't be problematic...?
|
||||||
|
// (initially implemented because Cloudflare returns "fully-
|
||||||
|
// qualified" domains in their records without a trailing dot,
|
||||||
|
// but the input zone typically has a trailing dot)
|
||||||
|
return strings.TrimSuffix(strings.TrimSuffix(strings.TrimSuffix(fqdn, "."), strings.TrimSuffix(zone, ".")), ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
// AbsoluteName makes name into a fully-qualified domain name (FQDN) by
|
// AbsoluteName makes name into a fully-qualified domain name (FQDN) by
|
||||||
|
8
vendor/modules.txt
vendored
8
vendor/modules.txt
vendored
@ -1,6 +1,6 @@
|
|||||||
# github.com/libdns/cloudflare v0.1.0
|
# github.com/libdns/cloudflare v0.1.1
|
||||||
## explicit; go 1.14
|
## explicit; go 1.18
|
||||||
github.com/libdns/cloudflare
|
github.com/libdns/cloudflare
|
||||||
# github.com/libdns/libdns v0.2.1
|
# github.com/libdns/libdns v0.2.2
|
||||||
## explicit; go 1.14
|
## explicit; go 1.18
|
||||||
github.com/libdns/libdns
|
github.com/libdns/libdns
|
||||||
|
Loading…
Reference in New Issue
Block a user