mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
Switch to Go 1.13 error wrapping (#604)
* Replaced errors.Wrap with fmt.Errorf (#589) * Find: errors\.Wrap\(([^,]+),\s+(["`][^"`]*)(["`])\) Replace: fmt.Errorf($2: %w$3, $1) * Replaced errors.Wrapf with fmt.Errorf (#589) * Find: errors\.Wrapf\(([^,]+),\s+(["`][^"`]*)(["`])\) Replace: fmt.Errorf($2: %w$3, $1) * Find: errors\.Wrapf\(([^,]+),\s+(["`][^"`]*)(["`])(,[^)]+)\) * Replace: fmt.Errorf($2: %w$3$4, $1) * Replaced errors.Errorf with fmt.Errorf (#589) * Find: errors\.Errorf Replace: fmt.Errorf * Cleaned up remaining imports * Cleanup * Regenerate provider support matrix This was broken by #533 ... and it's now the third time this has been missed.
This commit is contained in:
committed by
Tom Limoncelli
parent
cae35a2c8f
commit
825ba2d081
@@ -11,8 +11,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/google/go-github/github"
|
"github.com/google/go-github/github"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -60,7 +58,7 @@ func checkGoFmt() error {
|
|||||||
if fList == "" {
|
if fList == "" {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return errors.Errorf("The following files need to have gofmt run on them:\n%s", fList)
|
return fmt.Errorf("The following files need to have gofmt run on them:\n%s", fList)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkGoGenerate() error {
|
func checkGoGenerate() error {
|
||||||
@@ -76,7 +74,7 @@ func checkGoGenerate() error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if len(modified) != 0 {
|
if len(modified) != 0 {
|
||||||
return errors.Errorf("ERROR: The following files are modified after go generate:\n%s", strings.Join(modified, "\n"))
|
return fmt.Errorf("ERROR: The following files are modified after go generate:\n%s", strings.Join(modified, "\n"))
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -43,11 +43,11 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/bind"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/octodns/octoyaml"
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/miekg/dns/dnsutil"
|
"github.com/miekg/dns/dnsutil"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers/bind"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers/octodns/octoyaml"
|
||||||
)
|
)
|
||||||
|
|
||||||
var flagInfmt = flag.String("in", "zone", "zone|octodns")
|
var flagInfmt = flag.String("in", "zone", "zone|octodns")
|
||||||
@@ -104,7 +104,7 @@ func parseargs(args []string) (zonename string, filename string, r io.Reader, er
|
|||||||
// Anything else returns an error.
|
// Anything else returns an error.
|
||||||
|
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
return "", "", nil, errors.Errorf("no command line parameters. Zone name required")
|
return "", "", nil, fmt.Errorf("no command line parameters. Zone name required")
|
||||||
}
|
}
|
||||||
|
|
||||||
zonename = args[0]
|
zonename = args[0]
|
||||||
@@ -116,10 +116,10 @@ func parseargs(args []string) (zonename string, filename string, r io.Reader, er
|
|||||||
filename = flag.Arg(1)
|
filename = flag.Arg(1)
|
||||||
r, err = os.Open(filename)
|
r, err = os.Open(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", "", nil, errors.Wrapf(err, "Could not open file: %s", filename)
|
return "", "", nil, fmt.Errorf("Could not open file: %s: %w", filename, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return "", "", nil, errors.Errorf("too many command line parameters")
|
return "", "", nil, fmt.Errorf("too many command line parameters")
|
||||||
}
|
}
|
||||||
|
|
||||||
return zonename, filename, r, nil
|
return zonename, filename, r, nil
|
||||||
@@ -142,7 +142,7 @@ func readOctodns(zonename string, r io.Reader, filename string) []dns.RR {
|
|||||||
|
|
||||||
foundRecords, err := octoyaml.ReadYaml(r, zonename)
|
foundRecords, err := octoyaml.ReadYaml(r, zonename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(errors.Wrapf(err, "can not get corrections"))
|
log.Println(fmt.Errorf("can not get corrections: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, x := range foundRecords {
|
for _, x := range foundRecords {
|
||||||
|
@@ -7,10 +7,10 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// categories of commands
|
// categories of commands
|
||||||
@@ -125,7 +125,7 @@ func preloadProviders(cfg *models.DNSConfig, err error) (*models.DNSConfig, erro
|
|||||||
for _, d := range cfg.Domains {
|
for _, d := range cfg.Domains {
|
||||||
reg, ok := cfg.RegistrarsByName[d.RegistrarName]
|
reg, ok := cfg.RegistrarsByName[d.RegistrarName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("Registrar named %s expected for %s, but never registered", d.RegistrarName, d.Name)
|
return nil, fmt.Errorf("Registrar named %s expected for %s, but never registered", d.RegistrarName, d.Name)
|
||||||
}
|
}
|
||||||
d.RegistrarInstance = &models.RegistrarInstance{
|
d.RegistrarInstance = &models.RegistrarInstance{
|
||||||
ProviderBase: models.ProviderBase{
|
ProviderBase: models.ProviderBase{
|
||||||
@@ -136,7 +136,7 @@ func preloadProviders(cfg *models.DNSConfig, err error) (*models.DNSConfig, erro
|
|||||||
for pName, n := range d.DNSProviderNames {
|
for pName, n := range d.DNSProviderNames {
|
||||||
prov, ok := cfg.DNSProvidersByName[pName]
|
prov, ok := cfg.DNSProvidersByName[pName]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("DNS Provider named %s expected for %s, but never registered", pName, d.Name)
|
return nil, fmt.Errorf("DNS Provider named %s expected for %s, but never registered", pName, d.Name)
|
||||||
}
|
}
|
||||||
d.DNSProviderInstances = append(d.DNSProviderInstances, &models.DNSProviderInstance{
|
d.DNSProviderInstances = append(d.DNSProviderInstances, &models.DNSProviderInstance{
|
||||||
ProviderBase: models.ProviderBase{
|
ProviderBase: models.ProviderBase{
|
||||||
|
@@ -5,6 +5,8 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/nameservers"
|
"github.com/StackExchange/dnscontrol/v2/pkg/nameservers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/normalize"
|
"github.com/StackExchange/dnscontrol/v2/pkg/normalize"
|
||||||
@@ -12,8 +14,6 @@ import (
|
|||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/config"
|
"github.com/StackExchange/dnscontrol/v2/providers/config"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = cmd(catMain, func() *cli.Command {
|
var _ = cmd(catMain, func() *cli.Command {
|
||||||
@@ -101,7 +101,7 @@ func run(args PreviewArgs, push bool, interactive bool, out printer.CLI) error {
|
|||||||
}
|
}
|
||||||
errs := normalize.NormalizeAndValidateConfig(cfg)
|
errs := normalize.NormalizeAndValidateConfig(cfg)
|
||||||
if PrintValidationErrors(errs) {
|
if PrintValidationErrors(errs) {
|
||||||
return errors.Errorf("Exiting due to validation errors")
|
return fmt.Errorf("Exiting due to validation errors")
|
||||||
}
|
}
|
||||||
// TODO:
|
// TODO:
|
||||||
notifier, err := InitializeProviders(args.CredsFile, cfg, args.Notify)
|
notifier, err := InitializeProviders(args.CredsFile, cfg, args.Notify)
|
||||||
@@ -169,10 +169,10 @@ DomainLoop:
|
|||||||
notifier.Done()
|
notifier.Done()
|
||||||
out.Printf("Done. %d corrections.\n", totalCorrections)
|
out.Printf("Done. %d corrections.\n", totalCorrections)
|
||||||
if anyErrors {
|
if anyErrors {
|
||||||
return errors.Errorf("Completed with errors")
|
return fmt.Errorf("Completed with errors")
|
||||||
}
|
}
|
||||||
if totalCorrections != 0 && args.WarnChanges {
|
if totalCorrections != 0 && args.WarnChanges {
|
||||||
return errors.Errorf("There are pending changes")
|
return fmt.Errorf("There are pending changes")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@@ -5,11 +5,11 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/urfave/cli"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/js"
|
"github.com/StackExchange/dnscontrol/v2/pkg/js"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/normalize"
|
"github.com/StackExchange/dnscontrol/v2/pkg/normalize"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/urfave/cli"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ = cmd(catDebug, func() *cli.Command {
|
var _ = cmd(catDebug, func() *cli.Command {
|
||||||
@@ -72,7 +72,7 @@ func PrintIR(args PrintIRArgs) error {
|
|||||||
if !args.Raw {
|
if !args.Raw {
|
||||||
errs := normalize.NormalizeAndValidateConfig(cfg)
|
errs := normalize.NormalizeAndValidateConfig(cfg)
|
||||||
if PrintValidationErrors(errs) {
|
if PrintValidationErrors(errs) {
|
||||||
return errors.Errorf("Exiting due to validation errors")
|
return fmt.Errorf("Exiting due to validation errors")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return PrintJSON(args.PrintJSONArgs, cfg)
|
return PrintJSON(args.PrintJSONArgs, cfg)
|
||||||
@@ -98,12 +98,12 @@ func PrintValidationErrors(errs []error) (fatal bool) {
|
|||||||
// ExecuteDSL executes the dnsconfig.js contents.
|
// ExecuteDSL executes the dnsconfig.js contents.
|
||||||
func ExecuteDSL(args ExecuteDSLArgs) (*models.DNSConfig, error) {
|
func ExecuteDSL(args ExecuteDSLArgs) (*models.DNSConfig, error) {
|
||||||
if args.JSFile == "" {
|
if args.JSFile == "" {
|
||||||
return nil, errors.Errorf("No config specified")
|
return nil, fmt.Errorf("No config specified")
|
||||||
}
|
}
|
||||||
|
|
||||||
dnsConfig, err := js.ExecuteJavascript(args.JSFile, args.DevMode)
|
dnsConfig, err := js.ExecuteJavascript(args.JSFile, args.DevMode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("Executing javascript in %s: %s", args.JSFile, err)
|
return nil, fmt.Errorf("Executing javascript in %s: %s", args.JSFile, err)
|
||||||
}
|
}
|
||||||
return dnsConfig, nil
|
return dnsConfig, nil
|
||||||
}
|
}
|
||||||
|
@@ -352,8 +352,8 @@
|
|||||||
</td>
|
</td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
<td class="danger">
|
<td class="success">
|
||||||
<i class="fa fa-times text-danger" aria-hidden="true"></i>
|
<i class="fa fa-check text-success" aria-hidden="true"></i>
|
||||||
</td>
|
</td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
<td><i class="fa fa-minus dim"></i></td>
|
<td><i class="fa fa-minus dim"></i></td>
|
||||||
|
2
go.mod
2
go.mod
@@ -35,7 +35,7 @@ require (
|
|||||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04
|
||||||
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
github.com/ovh/go-ovh v0.0.0-20181109152953-ba5adb4cf014
|
||||||
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d
|
github.com/philhug/opensrs-go v0.0.0-20171126225031-9dfa7433020d
|
||||||
github.com/pkg/errors v0.8.1
|
github.com/pkg/errors v0.8.1 // indirect
|
||||||
github.com/prasmussen/gandi-api v0.0.0-20180224132202-58d3d4205661
|
github.com/prasmussen/gandi-api v0.0.0-20180224132202-58d3d4205661
|
||||||
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect
|
||||||
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d
|
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d
|
||||||
|
@@ -2,20 +2,18 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"testing"
|
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/miekg/dns/dnsutil"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/nameservers"
|
"github.com/StackExchange/dnscontrol/v2/pkg/nameservers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
_ "github.com/StackExchange/dnscontrol/v2/providers/_all"
|
_ "github.com/StackExchange/dnscontrol/v2/providers/_all"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/config"
|
"github.com/StackExchange/dnscontrol/v2/providers/config"
|
||||||
"github.com/miekg/dns/dnsutil"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var providerToRun = flag.String("provider", "", "Provider to run")
|
var providerToRun = flag.String("provider", "", "Provider to run")
|
||||||
@@ -122,7 +120,7 @@ func runTests(t *testing.T, prv providers.DNSServiceProvider, domainName string,
|
|||||||
// get corrections for first time
|
// get corrections for first time
|
||||||
corrections, err := prv.GetDomainCorrections(dom)
|
corrections, err := prv.GetDomainCorrections(dom)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(errors.Wrap(err, "runTests"))
|
t.Fatal(fmt.Errorf("runTests: %w", err))
|
||||||
}
|
}
|
||||||
if !skipVal && i != *startIdx && len(corrections) == 0 {
|
if !skipVal && i != *startIdx && len(corrections) == 0 {
|
||||||
if tst.Desc != "Empty" {
|
if tst.Desc != "Empty" {
|
||||||
|
@@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/miekg/dns/dnsutil"
|
"github.com/miekg/dns/dnsutil"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// RecordConfig stores a DNS record.
|
// RecordConfig stores a DNS record.
|
||||||
@@ -110,10 +109,10 @@ func (rc *RecordConfig) SetLabel(short, origin string) {
|
|||||||
|
|
||||||
// Assertions that make sure the function is being used correctly:
|
// Assertions that make sure the function is being used correctly:
|
||||||
if strings.HasSuffix(origin, ".") {
|
if strings.HasSuffix(origin, ".") {
|
||||||
panic(errors.Errorf("origin (%s) is not supposed to end with a dot", origin))
|
panic(fmt.Errorf("origin (%s) is not supposed to end with a dot", origin))
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(short, ".") {
|
if strings.HasSuffix(short, ".") {
|
||||||
panic(errors.Errorf("short (%s) is not supposed to end with a dot", origin))
|
panic(fmt.Errorf("short (%s) is not supposed to end with a dot", origin))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(tlim): We should add more validation here or in a separate validation
|
// TODO(tlim): We should add more validation here or in a separate validation
|
||||||
@@ -145,10 +144,10 @@ func (rc *RecordConfig) SetLabelFromFQDN(fqdn, origin string) {
|
|||||||
|
|
||||||
// Assertions that make sure the function is being used correctly:
|
// Assertions that make sure the function is being used correctly:
|
||||||
if strings.HasSuffix(origin, ".") {
|
if strings.HasSuffix(origin, ".") {
|
||||||
panic(errors.Errorf("origin (%s) is not supposed to end with a dot", origin))
|
panic(fmt.Errorf("origin (%s) is not supposed to end with a dot", origin))
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(fqdn, "..") {
|
if strings.HasSuffix(fqdn, "..") {
|
||||||
panic(errors.Errorf("fqdn (%s) is not supposed to end with double dots", origin))
|
panic(fmt.Errorf("fqdn (%s) is not supposed to end with double dots", origin))
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasSuffix(fqdn, ".") {
|
if strings.HasSuffix(fqdn, ".") {
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTargetCAA sets the CAA fields.
|
// SetTargetCAA sets the CAA fields.
|
||||||
@@ -20,7 +19,7 @@ func (rc *RecordConfig) SetTargetCAA(flag uint8, tag string, target string) erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
if tag != "issue" && tag != "issuewild" && tag != "iodef" {
|
if tag != "issue" && tag != "issuewild" && tag != "iodef" {
|
||||||
return errors.Errorf("CAA tag (%v) is not one of issue/issuewild/iodef", tag)
|
return fmt.Errorf("CAA tag (%v) is not one of issue/issuewild/iodef", tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -30,7 +29,7 @@ func (rc *RecordConfig) SetTargetCAA(flag uint8, tag string, target string) erro
|
|||||||
func (rc *RecordConfig) SetTargetCAAStrings(flag, tag, target string) error {
|
func (rc *RecordConfig) SetTargetCAAStrings(flag, tag, target string) error {
|
||||||
i64flag, err := strconv.ParseUint(flag, 10, 8)
|
i64flag, err := strconv.ParseUint(flag, 10, 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "CAA flag does not fit in 8 bits")
|
return fmt.Errorf("CAA flag does not fit in 8 bits: %w", err)
|
||||||
}
|
}
|
||||||
return rc.SetTargetCAA(uint8(i64flag), tag, target)
|
return rc.SetTargetCAA(uint8(i64flag), tag, target)
|
||||||
}
|
}
|
||||||
@@ -40,7 +39,7 @@ func (rc *RecordConfig) SetTargetCAAStrings(flag, tag, target string) error {
|
|||||||
func (rc *RecordConfig) SetTargetCAAString(s string) error {
|
func (rc *RecordConfig) SetTargetCAAString(s string) error {
|
||||||
part := strings.Fields(s)
|
part := strings.Fields(s)
|
||||||
if len(part) != 3 {
|
if len(part) != 3 {
|
||||||
return errors.Errorf("CAA value does not contain 3 fields: (%#v)", s)
|
return fmt.Errorf("CAA value does not contain 3 fields: (%#v)", s)
|
||||||
}
|
}
|
||||||
return rc.SetTargetCAAStrings(part[0], part[1], StripQuotes(part[2]))
|
return rc.SetTargetCAAStrings(part[0], part[1], StripQuotes(part[2]))
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTargetMX sets the MX fields.
|
// SetTargetMX sets the MX fields.
|
||||||
@@ -24,7 +23,7 @@ func (rc *RecordConfig) SetTargetMX(pref uint16, target string) error {
|
|||||||
func (rc *RecordConfig) SetTargetMXStrings(pref, target string) error {
|
func (rc *RecordConfig) SetTargetMXStrings(pref, target string) error {
|
||||||
u64pref, err := strconv.ParseUint(pref, 10, 16)
|
u64pref, err := strconv.ParseUint(pref, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "can't parse MX data")
|
return fmt.Errorf("can't parse MX data: %w", err)
|
||||||
}
|
}
|
||||||
return rc.SetTargetMX(uint16(u64pref), target)
|
return rc.SetTargetMX(uint16(u64pref), target)
|
||||||
}
|
}
|
||||||
@@ -33,7 +32,7 @@ func (rc *RecordConfig) SetTargetMXStrings(pref, target string) error {
|
|||||||
func (rc *RecordConfig) SetTargetMXString(s string) error {
|
func (rc *RecordConfig) SetTargetMXString(s string) error {
|
||||||
part := strings.Fields(s)
|
part := strings.Fields(s)
|
||||||
if len(part) != 2 {
|
if len(part) != 2 {
|
||||||
return errors.Errorf("MX value does not contain 2 fields: (%#v)", s)
|
return fmt.Errorf("MX value does not contain 2 fields: (%#v)", s)
|
||||||
}
|
}
|
||||||
return rc.SetTargetMXStrings(part[0], part[1])
|
return rc.SetTargetMXStrings(part[0], part[1])
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTargetNAPTR sets the NAPTR fields.
|
// SetTargetNAPTR sets the NAPTR fields.
|
||||||
@@ -30,11 +29,11 @@ func (rc *RecordConfig) SetTargetNAPTR(order uint16, preference uint16, flags st
|
|||||||
func (rc *RecordConfig) SetTargetNAPTRStrings(order, preference, flags string, service string, regexp string, target string) error {
|
func (rc *RecordConfig) SetTargetNAPTRStrings(order, preference, flags string, service string, regexp string, target string) error {
|
||||||
i64order, err := strconv.ParseUint(order, 10, 16)
|
i64order, err := strconv.ParseUint(order, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "NAPTR order does not fit in 16 bits")
|
return fmt.Errorf("NAPTR order does not fit in 16 bits: %w", err)
|
||||||
}
|
}
|
||||||
i64preference, err := strconv.ParseUint(preference, 10, 16)
|
i64preference, err := strconv.ParseUint(preference, 10, 16)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "NAPTR preference does not fit in 16 bits")
|
return fmt.Errorf("NAPTR preference does not fit in 16 bits: %w", err)
|
||||||
}
|
}
|
||||||
return rc.SetTargetNAPTR(uint16(i64order), uint16(i64preference), flags, service, regexp, target)
|
return rc.SetTargetNAPTR(uint16(i64order), uint16(i64preference), flags, service, regexp, target)
|
||||||
}
|
}
|
||||||
@@ -43,7 +42,7 @@ func (rc *RecordConfig) SetTargetNAPTRStrings(order, preference, flags string, s
|
|||||||
func (rc *RecordConfig) SetTargetNAPTRString(s string) error {
|
func (rc *RecordConfig) SetTargetNAPTRString(s string) error {
|
||||||
part := strings.Fields(s)
|
part := strings.Fields(s)
|
||||||
if len(part) != 6 {
|
if len(part) != 6 {
|
||||||
return errors.Errorf("NAPTR value does not contain 6 fields: (%#v)", s)
|
return fmt.Errorf("NAPTR value does not contain 6 fields: (%#v)", s)
|
||||||
}
|
}
|
||||||
return rc.SetTargetNAPTRStrings(part[0], part[1], part[2], part[3], part[4], StripQuotes(part[5]))
|
return rc.SetTargetNAPTRStrings(part[0], part[1], part[2], part[3], part[4], StripQuotes(part[5]))
|
||||||
}
|
}
|
||||||
|
@@ -1,9 +1,8 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PopulateFromString populates a RecordConfig given a type and string.
|
// PopulateFromString populates a RecordConfig given a type and string.
|
||||||
@@ -15,23 +14,23 @@ import (
|
|||||||
// misunderstood data. We do this panic() at the provider level.
|
// misunderstood data. We do this panic() at the provider level.
|
||||||
// Therefore the typical calling sequence is:
|
// Therefore the typical calling sequence is:
|
||||||
// if err := rc.PopulateFromString(rtype, value, origin); err != nil {
|
// if err := rc.PopulateFromString(rtype, value, origin); err != nil {
|
||||||
// panic(errors.Wrap(err, "unparsable record received from provider"))
|
// panic(fmt.Errorf("unparsable record received from provider: %w", err))
|
||||||
// }
|
// }
|
||||||
func (r *RecordConfig) PopulateFromString(rtype, contents, origin string) error {
|
func (r *RecordConfig) PopulateFromString(rtype, contents, origin string) error {
|
||||||
if r.Type != "" && r.Type != rtype {
|
if r.Type != "" && r.Type != rtype {
|
||||||
panic(errors.Errorf("assertion failed: rtype already set (%s) (%s)", rtype, r.Type))
|
panic(fmt.Errorf("assertion failed: rtype already set (%s) (%s)", rtype, r.Type))
|
||||||
}
|
}
|
||||||
switch r.Type = rtype; rtype { // #rtype_variations
|
switch r.Type = rtype; rtype { // #rtype_variations
|
||||||
case "A":
|
case "A":
|
||||||
ip := net.ParseIP(contents)
|
ip := net.ParseIP(contents)
|
||||||
if ip == nil || ip.To4() == nil {
|
if ip == nil || ip.To4() == nil {
|
||||||
return errors.Errorf("A record with invalid IP: %s", contents)
|
return fmt.Errorf("A record with invalid IP: %s", contents)
|
||||||
}
|
}
|
||||||
return r.SetTargetIP(ip) // Reformat to canonical form.
|
return r.SetTargetIP(ip) // Reformat to canonical form.
|
||||||
case "AAAA":
|
case "AAAA":
|
||||||
ip := net.ParseIP(contents)
|
ip := net.ParseIP(contents)
|
||||||
if ip == nil || ip.To16() == nil {
|
if ip == nil || ip.To16() == nil {
|
||||||
return errors.Errorf("AAAA record with invalid IP: %s", contents)
|
return fmt.Errorf("AAAA record with invalid IP: %s", contents)
|
||||||
}
|
}
|
||||||
return r.SetTargetIP(ip) // Reformat to canonical form.
|
return r.SetTargetIP(ip) // Reformat to canonical form.
|
||||||
case "ANAME", "CNAME", "NS", "PTR":
|
case "ANAME", "CNAME", "NS", "PTR":
|
||||||
@@ -51,7 +50,7 @@ func (r *RecordConfig) PopulateFromString(rtype, contents, origin string) error
|
|||||||
case "TXT":
|
case "TXT":
|
||||||
return r.SetTargetTXTString(contents)
|
return r.SetTargetTXTString(contents)
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("Unknown rtype (%s) when parsing (%s) domain=(%s)",
|
return fmt.Errorf("Unknown rtype (%s) when parsing (%s) domain=(%s)",
|
||||||
rtype, contents, origin)
|
rtype, contents, origin)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTargetSRV sets the SRV fields.
|
// SetTargetSRV sets the SRV fields.
|
||||||
@@ -30,7 +29,7 @@ func (rc *RecordConfig) setTargetSRVIntAndStrings(priority uint16, weight, port,
|
|||||||
return rc.SetTargetSRV(priority, uint16(i64weight), uint16(i64port), target)
|
return rc.SetTargetSRV(priority, uint16(i64weight), uint16(i64port), target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errors.Wrap(err, "SRV value too big for uint16")
|
return fmt.Errorf("SRV value too big for uint16: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTargetSRVStrings is like SetTargetSRV but accepts all parameters as strings.
|
// SetTargetSRVStrings is like SetTargetSRV but accepts all parameters as strings.
|
||||||
@@ -39,7 +38,7 @@ func (rc *RecordConfig) SetTargetSRVStrings(priority, weight, port, target strin
|
|||||||
if i64priority, err = strconv.ParseUint(priority, 10, 16); err == nil {
|
if i64priority, err = strconv.ParseUint(priority, 10, 16); err == nil {
|
||||||
return rc.setTargetSRVIntAndStrings(uint16(i64priority), weight, port, target)
|
return rc.setTargetSRVIntAndStrings(uint16(i64priority), weight, port, target)
|
||||||
}
|
}
|
||||||
return errors.Wrap(err, "SRV value too big for uint16")
|
return fmt.Errorf("SRV value too big for uint16: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTargetSRVPriorityString is like SetTargetSRV but accepts priority as an
|
// SetTargetSRVPriorityString is like SetTargetSRV but accepts priority as an
|
||||||
@@ -54,7 +53,7 @@ func (rc *RecordConfig) SetTargetSRVPriorityString(priority uint16, s string) er
|
|||||||
case 2:
|
case 2:
|
||||||
return rc.setTargetSRVIntAndStrings(priority, part[0], part[1], ".")
|
return rc.setTargetSRVIntAndStrings(priority, part[0], part[1], ".")
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("SRV value does not contain 3 fields: (%#v)", s)
|
return fmt.Errorf("SRV value does not contain 3 fields: (%#v)", s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,7 +61,7 @@ func (rc *RecordConfig) SetTargetSRVPriorityString(priority uint16, s string) er
|
|||||||
func (rc *RecordConfig) SetTargetSRVString(s string) error {
|
func (rc *RecordConfig) SetTargetSRVString(s string) error {
|
||||||
part := strings.Fields(s)
|
part := strings.Fields(s)
|
||||||
if len(part) != 4 {
|
if len(part) != 4 {
|
||||||
return errors.Errorf("SRC value does not contain 4 fields: (%#v)", s)
|
return fmt.Errorf("SRC value does not contain 4 fields: (%#v)", s)
|
||||||
}
|
}
|
||||||
return rc.SetTargetSRVStrings(part[0], part[1], part[2], part[3])
|
return rc.SetTargetSRVStrings(part[0], part[1], part[2], part[3])
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTargetSSHFP sets the SSHFP fields.
|
// SetTargetSSHFP sets the SSHFP fields.
|
||||||
@@ -20,10 +19,10 @@ func (rc *RecordConfig) SetTargetSSHFP(algorithm uint8, fingerprint uint8, targe
|
|||||||
}
|
}
|
||||||
|
|
||||||
if algorithm < 1 && algorithm > 4 {
|
if algorithm < 1 && algorithm > 4 {
|
||||||
return errors.Errorf("SSHFP algorithm (%v) is not one of 1, 2, 3 or 4", algorithm)
|
return fmt.Errorf("SSHFP algorithm (%v) is not one of 1, 2, 3 or 4", algorithm)
|
||||||
}
|
}
|
||||||
if fingerprint < 1 && fingerprint > 2 {
|
if fingerprint < 1 && fingerprint > 2 {
|
||||||
return errors.Errorf("SSHFP fingerprint (%v) is not one of 1 or 2", fingerprint)
|
return fmt.Errorf("SSHFP fingerprint (%v) is not one of 1 or 2", fingerprint)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -33,11 +32,11 @@ func (rc *RecordConfig) SetTargetSSHFP(algorithm uint8, fingerprint uint8, targe
|
|||||||
func (rc *RecordConfig) SetTargetSSHFPStrings(algorithm, fingerprint, target string) error {
|
func (rc *RecordConfig) SetTargetSSHFPStrings(algorithm, fingerprint, target string) error {
|
||||||
i64algorithm, err := strconv.ParseUint(algorithm, 10, 8)
|
i64algorithm, err := strconv.ParseUint(algorithm, 10, 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "SSHFP algorithm does not fit in 8 bits")
|
return fmt.Errorf("SSHFP algorithm does not fit in 8 bits: %w", err)
|
||||||
}
|
}
|
||||||
i64fingerprint, err := strconv.ParseUint(fingerprint, 10, 8)
|
i64fingerprint, err := strconv.ParseUint(fingerprint, 10, 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "SSHFP fingerprint does not fit in 8 bits")
|
return fmt.Errorf("SSHFP fingerprint does not fit in 8 bits: %w", err)
|
||||||
}
|
}
|
||||||
return rc.SetTargetSSHFP(uint8(i64algorithm), uint8(i64fingerprint), target)
|
return rc.SetTargetSSHFP(uint8(i64algorithm), uint8(i64fingerprint), target)
|
||||||
}
|
}
|
||||||
@@ -46,7 +45,7 @@ func (rc *RecordConfig) SetTargetSSHFPStrings(algorithm, fingerprint, target str
|
|||||||
func (rc *RecordConfig) SetTargetSSHFPString(s string) error {
|
func (rc *RecordConfig) SetTargetSSHFPString(s string) error {
|
||||||
part := strings.Fields(s)
|
part := strings.Fields(s)
|
||||||
if len(part) != 3 {
|
if len(part) != 3 {
|
||||||
return errors.Errorf("SSHFP value does not contain 3 fields: (%#v)", s)
|
return fmt.Errorf("SSHFP value does not contain 3 fields: (%#v)", s)
|
||||||
}
|
}
|
||||||
return rc.SetTargetSSHFPStrings(part[0], part[1], StripQuotes(part[2]))
|
return rc.SetTargetSSHFPStrings(part[0], part[1], StripQuotes(part[2]))
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SetTargetTLSA sets the TLSA fields.
|
// SetTargetTLSA sets the TLSA fields.
|
||||||
@@ -32,14 +31,14 @@ func (rc *RecordConfig) SetTargetTLSAStrings(usage, selector, matchingtype, targ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return errors.Wrap(err, "TLSA has value that won't fit in field")
|
return fmt.Errorf("TLSA has value that won't fit in field: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetTargetTLSAString is like SetTargetTLSA but accepts one big string.
|
// SetTargetTLSAString is like SetTargetTLSA but accepts one big string.
|
||||||
func (rc *RecordConfig) SetTargetTLSAString(s string) error {
|
func (rc *RecordConfig) SetTargetTLSAString(s string) error {
|
||||||
part := strings.Fields(s)
|
part := strings.Fields(s)
|
||||||
if len(part) != 4 {
|
if len(part) != 4 {
|
||||||
return errors.Errorf("TLSA value does not contain 4 fields: (%#v)", s)
|
return fmt.Errorf("TLSA value does not contain 4 fields: (%#v)", s)
|
||||||
}
|
}
|
||||||
return rc.SetTargetTLSAStrings(part[0], part[1], part[2], part[3])
|
return rc.SetTargetTLSAStrings(part[0], part[1], part[2], part[3])
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/* .Target is kind of a mess.
|
/* .Target is kind of a mess.
|
||||||
@@ -39,7 +38,7 @@ func (rc *RecordConfig) GetTargetField() string {
|
|||||||
// GetTargetIP returns the net.IP stored in Target.
|
// GetTargetIP returns the net.IP stored in Target.
|
||||||
func (rc *RecordConfig) GetTargetIP() net.IP {
|
func (rc *RecordConfig) GetTargetIP() net.IP {
|
||||||
if rc.Type != "A" && rc.Type != "AAAA" {
|
if rc.Type != "A" && rc.Type != "AAAA" {
|
||||||
panic(errors.Errorf("GetTargetIP called on an inappropriate rtype (%s)", rc.Type))
|
panic(fmt.Errorf("GetTargetIP called on an inappropriate rtype (%s)", rc.Type))
|
||||||
}
|
}
|
||||||
return net.ParseIP(rc.Target)
|
return net.ParseIP(rc.Target)
|
||||||
}
|
}
|
||||||
@@ -101,7 +100,7 @@ func (rc *RecordConfig) GetTargetDebug() string {
|
|||||||
case "R53_ALIAS":
|
case "R53_ALIAS":
|
||||||
content += fmt.Sprintf(" type=%s zone_id=%s", rc.R53Alias["type"], rc.R53Alias["zone_id"])
|
content += fmt.Sprintf(" type=%s zone_id=%s", rc.R53Alias["type"], rc.R53Alias["zone_id"])
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("rc.String rtype %v unimplemented", rc.Type))
|
panic(fmt.Errorf("rc.String rtype %v unimplemented", rc.Type))
|
||||||
// We panic so that we quickly find any switch statements
|
// We panic so that we quickly find any switch statements
|
||||||
// that have not been updated for a new RR type.
|
// that have not been updated for a new RR type.
|
||||||
}
|
}
|
||||||
|
@@ -3,9 +3,8 @@ package models
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/gob"
|
"encoding/gob"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func copyObj(input interface{}, output interface{}) error {
|
func copyObj(input interface{}, output interface{}) error {
|
||||||
@@ -23,7 +22,7 @@ func copyObj(input interface{}, output interface{}) error {
|
|||||||
func atou32(s string) uint32 {
|
func atou32(s string) uint32 {
|
||||||
i64, err := strconv.ParseUint(s, 10, 32)
|
i64, err := strconv.ParseUint(s, 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Errorf("atou32 failed (%v) (err=%v", s, err))
|
panic(fmt.Errorf("atou32 failed (%v) (err=%v", s, err))
|
||||||
}
|
}
|
||||||
return uint32(i64)
|
return uint32(i64)
|
||||||
}
|
}
|
||||||
|
@@ -7,12 +7,12 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/robertkrimen/otto" // load underscore js into vm by default
|
||||||
|
_ "github.com/robertkrimen/otto/underscore" // required by otto
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/transform"
|
"github.com/StackExchange/dnscontrol/v2/pkg/transform"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/robertkrimen/otto" // load underscore js into vm by default
|
|
||||||
_ "github.com/robertkrimen/otto/underscore" // required by otto
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// currentDirectory is the current directory as used by require().
|
// currentDirectory is the current directory as used by require().
|
||||||
@@ -27,7 +27,7 @@ var currentDirectory string
|
|||||||
func ExecuteJavascript(file string, devMode bool) (*models.DNSConfig, error) {
|
func ExecuteJavascript(file string, devMode bool) (*models.DNSConfig, error) {
|
||||||
script, err := ioutil.ReadFile(file)
|
script, err := ioutil.ReadFile(file)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("Reading js file %s: %s", file, err)
|
return nil, fmt.Errorf("Reading js file %s: %s", file, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record the directory path leading up to this file.
|
// Record the directory path leading up to this file.
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
package normalize
|
package normalize
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/spflib"
|
"github.com/StackExchange/dnscontrol/v2/pkg/spflib"
|
||||||
)
|
)
|
||||||
@@ -43,7 +42,7 @@ func flattenSPFs(cfg *models.DNSConfig) []error {
|
|||||||
// now split if needed
|
// now split if needed
|
||||||
if split, ok := txt.Metadata["split"]; ok {
|
if split, ok := txt.Metadata["split"]; ok {
|
||||||
if !strings.Contains(split, "%d") {
|
if !strings.Contains(split, "%d") {
|
||||||
errs = append(errs, Warning{errors.Errorf("Split format `%s` in `%s` is not proper format (should have %%d in it)", split, txt.GetLabelFQDN())})
|
errs = append(errs, Warning{fmt.Errorf("Split format `%s` in `%s` is not proper format (should have %%d in it)", split, txt.GetLabelFQDN())})
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
recs := rec.TXTSplit(split + "." + domain.Name)
|
recs := rec.TXTSplit(split + "." + domain.Name)
|
||||||
@@ -65,7 +64,7 @@ func flattenSPFs(cfg *models.DNSConfig) []error {
|
|||||||
}
|
}
|
||||||
// check if cache is stale
|
// check if cache is stale
|
||||||
for _, e := range cache.ResolveErrors() {
|
for _, e := range cache.ResolveErrors() {
|
||||||
errs = append(errs, Warning{errors.Errorf("problem resolving SPF record: %s", e)})
|
errs = append(errs, Warning{fmt.Errorf("problem resolving SPF record: %s", e)})
|
||||||
}
|
}
|
||||||
if len(cache.ResolveErrors()) == 0 {
|
if len(cache.ResolveErrors()) == 0 {
|
||||||
changed := cache.ChangedRecords()
|
changed := cache.ChangedRecords()
|
||||||
@@ -73,7 +72,7 @@ func flattenSPFs(cfg *models.DNSConfig) []error {
|
|||||||
if err := cache.Save("spfcache.updated.json"); err != nil {
|
if err := cache.Save("spfcache.updated.json"); err != nil {
|
||||||
errs = append(errs, err)
|
errs = append(errs, err)
|
||||||
} else {
|
} else {
|
||||||
errs = append(errs, Warning{errors.Errorf("%d spf record lookups are out of date with cache (%s).\nWrote changes to spfcache.updated.json. Please rename and commit:\n $ mv spfcache.updated.json spfcache.json\n $ git commit -m'Update spfcache.json' spfcache.json", len(changed), strings.Join(changed, ","))})
|
errs = append(errs, Warning{fmt.Errorf("%d spf record lookups are out of date with cache (%s).\nWrote changes to spfcache.updated.json. Please rename and commit:\n $ mv spfcache.updated.json spfcache.json\n $ git commit -m'Update spfcache.json' spfcache.json", len(changed), strings.Join(changed, ","))})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -10,13 +10,12 @@ import (
|
|||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/miekg/dns/dnsutil"
|
"github.com/miekg/dns/dnsutil"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Returns false if target does not validate.
|
// Returns false if target does not validate.
|
||||||
func checkIPv4(label string) error {
|
func checkIPv4(label string) error {
|
||||||
if net.ParseIP(label).To4() == nil {
|
if net.ParseIP(label).To4() == nil {
|
||||||
return errors.Errorf("WARNING: target (%v) is not an IPv4 address", label)
|
return fmt.Errorf("WARNING: target (%v) is not an IPv4 address", label)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -24,7 +23,7 @@ func checkIPv4(label string) error {
|
|||||||
// Returns false if target does not validate.
|
// Returns false if target does not validate.
|
||||||
func checkIPv6(label string) error {
|
func checkIPv6(label string) error {
|
||||||
if net.ParseIP(label).To16() == nil {
|
if net.ParseIP(label).To16() == nil {
|
||||||
return errors.Errorf("WARNING: target (%v) is not an IPv6 address", label)
|
return fmt.Errorf("WARNING: target (%v) is not an IPv6 address", label)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -35,14 +34,14 @@ func checkTarget(target string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(target) < 1 {
|
if len(target) < 1 {
|
||||||
return errors.Errorf("empty target")
|
return fmt.Errorf("empty target")
|
||||||
}
|
}
|
||||||
if strings.ContainsAny(target, `'" +,|!£$%&/()=?^*ç°§;:<>[]()@`) {
|
if strings.ContainsAny(target, `'" +,|!£$%&/()=?^*ç°§;:<>[]()@`) {
|
||||||
return errors.Errorf("target (%v) includes invalid char", target)
|
return fmt.Errorf("target (%v) includes invalid char", target)
|
||||||
}
|
}
|
||||||
// If it containts a ".", it must end in a ".".
|
// If it containts a ".", it must end in a ".".
|
||||||
if strings.ContainsRune(target, '.') && target[len(target)-1] != '.' {
|
if strings.ContainsRune(target, '.') && target[len(target)-1] != '.' {
|
||||||
return errors.Errorf("target (%v) must end with a (.) [https://stackexchange.github.io/dnscontrol/why-the-dot]", target)
|
return fmt.Errorf("target (%v) must end with a (.) [https://stackexchange.github.io/dnscontrol/why-the-dot]", target)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -69,11 +68,11 @@ func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []strin
|
|||||||
if !ok {
|
if !ok {
|
||||||
cType := providers.GetCustomRecordType(rec.Type)
|
cType := providers.GetCustomRecordType(rec.Type)
|
||||||
if cType == nil {
|
if cType == nil {
|
||||||
return errors.Errorf("Unsupported record type (%v) domain=%v name=%v", rec.Type, domain, rec.GetLabel())
|
return fmt.Errorf("Unsupported record type (%v) domain=%v name=%v", rec.Type, domain, rec.GetLabel())
|
||||||
}
|
}
|
||||||
for _, providerType := range pTypes {
|
for _, providerType := range pTypes {
|
||||||
if providerType != cType.Provider {
|
if providerType != cType.Provider {
|
||||||
return errors.Errorf("Custom record type %s is not compatible with provider type %s", rec.Type, providerType)
|
return fmt.Errorf("Custom record type %s is not compatible with provider type %s", rec.Type, providerType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// it is ok. Lets replace the type with real type and add metadata to say we checked it
|
// it is ok. Lets replace the type with real type and add metadata to say we checked it
|
||||||
@@ -105,14 +104,14 @@ func checkLabel(label string, rType string, domain string, meta map[string]strin
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if len(label) < 1 {
|
if len(label) < 1 {
|
||||||
return errors.Errorf("empty %s label in %s", rType, domain)
|
return fmt.Errorf("empty %s label in %s", rType, domain)
|
||||||
}
|
}
|
||||||
if label[len(label)-1] == '.' {
|
if label[len(label)-1] == '.' {
|
||||||
return errors.Errorf("label %s.%s ends with a (.)", label, domain)
|
return fmt.Errorf("label %s.%s ends with a (.)", label, domain)
|
||||||
}
|
}
|
||||||
if strings.HasSuffix(label, domain) {
|
if strings.HasSuffix(label, domain) {
|
||||||
if m := meta["skip_fqdn_check"]; m != "true" {
|
if m := meta["skip_fqdn_check"]; m != "true" {
|
||||||
return errors.Errorf(`label %s ends with domain name %s. Record names should not be fully qualified. Add {skip_fqdn_check:"true"} to this record if you really want to make %s.%s`, label, domain, label, domain)
|
return fmt.Errorf(`label %s ends with domain name %s. Record names should not be fully qualified. Add {skip_fqdn_check:"true"} to this record if you really want to make %s.%s`, label, domain, label, domain)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,7 +132,7 @@ func checkLabel(label string, rType string, domain string, meta map[string]strin
|
|||||||
}
|
}
|
||||||
// Otherwise, warn.
|
// Otherwise, warn.
|
||||||
if strings.ContainsRune(label, '_') {
|
if strings.ContainsRune(label, '_') {
|
||||||
return Warning{errors.Errorf("label %s.%s contains an underscore", label, domain)}
|
return Warning{fmt.Errorf("label %s.%s contains an underscore", label, domain)}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@@ -145,7 +144,7 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
|||||||
target := rec.GetTargetField()
|
target := rec.GetTargetField()
|
||||||
check := func(e error) {
|
check := func(e error) {
|
||||||
if e != nil {
|
if e != nil {
|
||||||
err := errors.Errorf("In %s %s.%s: %s", rec.Type, rec.GetLabel(), domain, e.Error())
|
err := fmt.Errorf("In %s %s.%s: %s", rec.Type, rec.GetLabel(), domain, e.Error())
|
||||||
if _, ok := e.(Warning); ok {
|
if _, ok := e.(Warning); ok {
|
||||||
err = Warning{err}
|
err = Warning{err}
|
||||||
}
|
}
|
||||||
@@ -160,14 +159,14 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
|||||||
case "CNAME":
|
case "CNAME":
|
||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
if label == "@" {
|
if label == "@" {
|
||||||
check(errors.Errorf("cannot create CNAME record for bare domain"))
|
check(fmt.Errorf("cannot create CNAME record for bare domain"))
|
||||||
}
|
}
|
||||||
case "MX":
|
case "MX":
|
||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
case "NS":
|
case "NS":
|
||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
if label == "@" {
|
if label == "@" {
|
||||||
check(errors.Errorf("cannot create NS record for bare domain. Use NAMESERVER instead"))
|
check(fmt.Errorf("cannot create NS record for bare domain. Use NAMESERVER instead"))
|
||||||
}
|
}
|
||||||
case "PTR":
|
case "PTR":
|
||||||
check(checkTarget(target))
|
check(checkTarget(target))
|
||||||
@@ -183,7 +182,7 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
|||||||
// it is a valid custom type. We perform no validation on target
|
// it is a valid custom type. We perform no validation on target
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
errs = append(errs, errors.Errorf("checkTargets: Unimplemented record type (%v) domain=%v name=%v",
|
errs = append(errs, fmt.Errorf("checkTargets: Unimplemented record type (%v) domain=%v name=%v",
|
||||||
rec.Type, domain, rec.GetLabel()))
|
rec.Type, domain, rec.GetLabel()))
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -223,7 +222,7 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []tra
|
|||||||
case "A":
|
case "A":
|
||||||
trs, err := transform.TransformIPToList(net.ParseIP(rec.GetTargetField()), transforms)
|
trs, err := transform.TransformIPToList(net.ParseIP(rec.GetTargetField()), transforms)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("import_transform: TransformIP(%v, %v) returned err=%s", rec.GetTargetField(), transforms, err)
|
return fmt.Errorf("import_transform: TransformIP(%v, %v) returned err=%s", rec.GetTargetField(), transforms, err)
|
||||||
}
|
}
|
||||||
for _, tr := range trs {
|
for _, tr := range trs {
|
||||||
r := newRec()
|
r := newRec()
|
||||||
@@ -238,7 +237,7 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig, transforms []tra
|
|||||||
// Not imported.
|
// Not imported.
|
||||||
continue
|
continue
|
||||||
default:
|
default:
|
||||||
return errors.Errorf("import_transform: Unimplemented record type %v (%v)",
|
return fmt.Errorf("import_transform: Unimplemented record type %v (%v)",
|
||||||
rec.Type, rec.GetLabel())
|
rec.Type, rec.GetLabel())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -270,7 +269,7 @@ func NormalizeAndValidateConfig(config *models.DNSConfig) (errs []error) {
|
|||||||
pType := provider.ProviderType
|
pType := provider.ProviderType
|
||||||
// If NO_PURGE is in use, make sure this *isn't* a provider that *doesn't* support NO_PURGE.
|
// If NO_PURGE is in use, make sure this *isn't* a provider that *doesn't* support NO_PURGE.
|
||||||
if domain.KeepUnknown && providers.ProviderHasCapability(pType, providers.CantUseNOPURGE) {
|
if domain.KeepUnknown && providers.ProviderHasCapability(pType, providers.CantUseNOPURGE) {
|
||||||
errs = append(errs, errors.Errorf("%s uses NO_PURGE which is not supported by %s(%s)", domain.Name, provider.Name, pType))
|
errs = append(errs, fmt.Errorf("%s uses NO_PURGE which is not supported by %s(%s)", domain.Name, provider.Name, pType))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record if any providers do not support TXTMulti:
|
// Record if any providers do not support TXTMulti:
|
||||||
@@ -319,26 +318,26 @@ func NormalizeAndValidateConfig(config *models.DNSConfig) (errs []error) {
|
|||||||
rec.SetLabel(name, domain.Name)
|
rec.SetLabel(name, domain.Name)
|
||||||
} else if rec.Type == "CAA" {
|
} else if rec.Type == "CAA" {
|
||||||
if rec.CaaTag != "issue" && rec.CaaTag != "issuewild" && rec.CaaTag != "iodef" {
|
if rec.CaaTag != "issue" && rec.CaaTag != "issuewild" && rec.CaaTag != "iodef" {
|
||||||
errs = append(errs, errors.Errorf("CAA tag %s is invalid", rec.CaaTag))
|
errs = append(errs, fmt.Errorf("CAA tag %s is invalid", rec.CaaTag))
|
||||||
}
|
}
|
||||||
} else if rec.Type == "TLSA" {
|
} else if rec.Type == "TLSA" {
|
||||||
if rec.TlsaUsage < 0 || rec.TlsaUsage > 3 {
|
if rec.TlsaUsage < 0 || rec.TlsaUsage > 3 {
|
||||||
errs = append(errs, errors.Errorf("TLSA Usage %d is invalid in record %s (domain %s)",
|
errs = append(errs, fmt.Errorf("TLSA Usage %d is invalid in record %s (domain %s)",
|
||||||
rec.TlsaUsage, rec.GetLabel(), domain.Name))
|
rec.TlsaUsage, rec.GetLabel(), domain.Name))
|
||||||
}
|
}
|
||||||
if rec.TlsaSelector < 0 || rec.TlsaSelector > 1 {
|
if rec.TlsaSelector < 0 || rec.TlsaSelector > 1 {
|
||||||
errs = append(errs, errors.Errorf("TLSA Selector %d is invalid in record %s (domain %s)",
|
errs = append(errs, fmt.Errorf("TLSA Selector %d is invalid in record %s (domain %s)",
|
||||||
rec.TlsaSelector, rec.GetLabel(), domain.Name))
|
rec.TlsaSelector, rec.GetLabel(), domain.Name))
|
||||||
}
|
}
|
||||||
if rec.TlsaMatchingType < 0 || rec.TlsaMatchingType > 2 {
|
if rec.TlsaMatchingType < 0 || rec.TlsaMatchingType > 2 {
|
||||||
errs = append(errs, errors.Errorf("TLSA MatchingType %d is invalid in record %s (domain %s)",
|
errs = append(errs, fmt.Errorf("TLSA MatchingType %d is invalid in record %s (domain %s)",
|
||||||
rec.TlsaMatchingType, rec.GetLabel(), domain.Name))
|
rec.TlsaMatchingType, rec.GetLabel(), domain.Name))
|
||||||
}
|
}
|
||||||
} else if rec.Type == "TXT" && len(txtMultiDissenters) != 0 && len(rec.TxtStrings) > 1 {
|
} else if rec.Type == "TXT" && len(txtMultiDissenters) != 0 && len(rec.TxtStrings) > 1 {
|
||||||
// There are providers that don't support TXTMulti yet there is
|
// There are providers that don't support TXTMulti yet there is
|
||||||
// a TXT record with multiple strings:
|
// a TXT record with multiple strings:
|
||||||
errs = append(errs,
|
errs = append(errs,
|
||||||
errors.Errorf("TXT records with multiple strings (label %v domain: %v) not supported by %s",
|
fmt.Errorf("TXT records with multiple strings (label %v domain: %v) not supported by %s",
|
||||||
rec.GetLabel(), domain.Name, strings.Join(txtMultiDissenters, ",")))
|
rec.GetLabel(), domain.Name, strings.Join(txtMultiDissenters, ",")))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -405,14 +404,14 @@ func checkCNAMEs(dc *models.DomainConfig) (errs []error) {
|
|||||||
for _, r := range dc.Records {
|
for _, r := range dc.Records {
|
||||||
if r.Type == "CNAME" {
|
if r.Type == "CNAME" {
|
||||||
if cnames[r.GetLabel()] {
|
if cnames[r.GetLabel()] {
|
||||||
errs = append(errs, errors.Errorf("Cannot have multiple CNAMEs with same name: %s", r.GetLabelFQDN()))
|
errs = append(errs, fmt.Errorf("Cannot have multiple CNAMEs with same name: %s", r.GetLabelFQDN()))
|
||||||
}
|
}
|
||||||
cnames[r.GetLabel()] = true
|
cnames[r.GetLabel()] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, r := range dc.Records {
|
for _, r := range dc.Records {
|
||||||
if cnames[r.GetLabel()] && r.Type != "CNAME" {
|
if cnames[r.GetLabel()] && r.Type != "CNAME" {
|
||||||
errs = append(errs, errors.Errorf("Cannot have CNAME and %s record with same name: %s", r.Type, r.GetLabelFQDN()))
|
errs = append(errs, fmt.Errorf("Cannot have CNAME and %s record with same name: %s", r.Type, r.GetLabelFQDN()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -423,7 +422,7 @@ func checkDuplicates(records []*models.RecordConfig) (errs []error) {
|
|||||||
for _, r := range records {
|
for _, r := range records {
|
||||||
diffable := fmt.Sprintf("%s %s %s", r.GetLabelFQDN(), r.Type, r.ToDiffable())
|
diffable := fmt.Sprintf("%s %s %s", r.GetLabelFQDN(), r.Type, r.ToDiffable())
|
||||||
if seen[diffable] != nil {
|
if seen[diffable] != nil {
|
||||||
errs = append(errs, errors.Errorf("Exact duplicate record found: %s", diffable))
|
errs = append(errs, fmt.Errorf("Exact duplicate record found: %s", diffable))
|
||||||
}
|
}
|
||||||
seen[diffable] = r
|
seen[diffable] = r
|
||||||
}
|
}
|
||||||
@@ -454,7 +453,7 @@ func checkProviderCapabilities(dc *models.DomainConfig) error {
|
|||||||
}
|
}
|
||||||
for _, provider := range dc.DNSProviderInstances {
|
for _, provider := range dc.DNSProviderInstances {
|
||||||
if !providers.ProviderHasCapability(provider.ProviderType, ty.cap) {
|
if !providers.ProviderHasCapability(provider.ProviderType, ty.cap) {
|
||||||
return errors.Errorf("Domain %s uses %s records, but DNS provider type %s does not support them", dc.Name, ty.rType, provider.ProviderType)
|
return fmt.Errorf("Domain %s uses %s records, but DNS provider type %s does not support them", dc.Name, ty.rType, provider.ProviderType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,14 +1,10 @@
|
|||||||
package spflib
|
package spflib
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"strings"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// SPFRecord stores the parts of an SPF record.
|
// SPFRecord stores the parts of an SPF record.
|
||||||
@@ -48,7 +44,7 @@ var qualifiers = map[byte]bool{
|
|||||||
// Parse parses a raw SPF record.
|
// Parse parses a raw SPF record.
|
||||||
func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
||||||
if !strings.HasPrefix(text, "v=spf1 ") {
|
if !strings.HasPrefix(text, "v=spf1 ") {
|
||||||
return nil, errors.Errorf("Not an spf record")
|
return nil, fmt.Errorf("Not an spf record")
|
||||||
}
|
}
|
||||||
parts := strings.Split(text, " ")
|
parts := strings.Split(text, " ")
|
||||||
rec := &SPFRecord{}
|
rec := &SPFRecord{}
|
||||||
@@ -79,7 +75,7 @@ func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
|||||||
// pi + 2: because pi starts at 0 when it iterates starting on parts[1],
|
// pi + 2: because pi starts at 0 when it iterates starting on parts[1],
|
||||||
// and because len(parts) is one bigger than the highest index.
|
// and because len(parts) is one bigger than the highest index.
|
||||||
if (pi + 2) != len(parts) {
|
if (pi + 2) != len(parts) {
|
||||||
return nil, errors.Errorf("%s must be last item", part)
|
return nil, fmt.Errorf("%s must be last item", part)
|
||||||
}
|
}
|
||||||
p.IncludeDomain = strings.TrimPrefix(part, "redirect=")
|
p.IncludeDomain = strings.TrimPrefix(part, "redirect=")
|
||||||
} else {
|
} else {
|
||||||
@@ -93,13 +89,13 @@ func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
|||||||
}
|
}
|
||||||
p.IncludeRecord, err = Parse(subRecord, dnsres)
|
p.IncludeRecord, err = Parse(subRecord, dnsres)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("In included spf: %s", err)
|
return nil, fmt.Errorf("In included spf: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if strings.HasPrefix(part, "exists:") || strings.HasPrefix(part, "ptr:") {
|
} else if strings.HasPrefix(part, "exists:") || strings.HasPrefix(part, "ptr:") {
|
||||||
p.IsLookup = true
|
p.IsLookup = true
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.Errorf("Unsupported spf part %s", part)
|
return nil, fmt.Errorf("Unsupported spf part %s", part)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -2,12 +2,11 @@ package spflib
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Resolver looks up spf txt records associated with a FQDN.
|
// Resolver looks up spf txt records associated with a FQDN.
|
||||||
@@ -28,13 +27,13 @@ func (l LiveResolver) GetSPF(name string) (string, error) {
|
|||||||
for _, v := range vals {
|
for _, v := range vals {
|
||||||
if strings.HasPrefix(v, "v=spf1") {
|
if strings.HasPrefix(v, "v=spf1") {
|
||||||
if spf != "" {
|
if spf != "" {
|
||||||
return "", errors.Errorf("%s has multiple SPF records", name)
|
return "", fmt.Errorf("%s has multiple SPF records", name)
|
||||||
}
|
}
|
||||||
spf = v
|
spf = v
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if spf == "" {
|
if spf == "" {
|
||||||
return "", errors.Errorf("%s has no SPF record", name)
|
return "", fmt.Errorf("%s has no SPF record", name)
|
||||||
}
|
}
|
||||||
return spf, nil
|
return spf, nil
|
||||||
}
|
}
|
||||||
|
@@ -4,8 +4,6 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReverseDomainName turns a CIDR block into a reversed (in-addr) name.
|
// ReverseDomainName turns a CIDR block into a reversed (in-addr) name.
|
||||||
@@ -20,13 +18,13 @@ func ReverseDomainName(cidr string) (string, error) {
|
|||||||
}
|
}
|
||||||
base = strings.TrimRight(base, ".")
|
base = strings.TrimRight(base, ".")
|
||||||
if !a.Equal(c.IP) {
|
if !a.Equal(c.IP) {
|
||||||
return "", errors.Errorf("CIDR %v has 1 bits beyond the mask", cidr)
|
return "", fmt.Errorf("CIDR %v has 1 bits beyond the mask", cidr)
|
||||||
}
|
}
|
||||||
|
|
||||||
bits, total := c.Mask.Size()
|
bits, total := c.Mask.Size()
|
||||||
var toTrim int
|
var toTrim int
|
||||||
if bits == 0 {
|
if bits == 0 {
|
||||||
return "", errors.Errorf("Cannot use /0 in reverse cidr")
|
return "", fmt.Errorf("Cannot use /0 in reverse cidr")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle IPv4 "Classless in-addr.arpa delegation" RFC2317:
|
// Handle IPv4 "Classless in-addr.arpa delegation" RFC2317:
|
||||||
@@ -41,16 +39,16 @@ func ReverseDomainName(cidr string) (string, error) {
|
|||||||
// Handle IPv4 Class-full and IPv6:
|
// Handle IPv4 Class-full and IPv6:
|
||||||
if total == 32 {
|
if total == 32 {
|
||||||
if bits%8 != 0 {
|
if bits%8 != 0 {
|
||||||
return "", errors.Errorf("IPv4 mask must be multiple of 8 bits")
|
return "", fmt.Errorf("IPv4 mask must be multiple of 8 bits")
|
||||||
}
|
}
|
||||||
toTrim = (total - bits) / 8
|
toTrim = (total - bits) / 8
|
||||||
} else if total == 128 {
|
} else if total == 128 {
|
||||||
if bits%4 != 0 {
|
if bits%4 != 0 {
|
||||||
return "", errors.Errorf("IPv6 mask must be multiple of 4 bits")
|
return "", fmt.Errorf("IPv6 mask must be multiple of 4 bits")
|
||||||
}
|
}
|
||||||
toTrim = (total - bits) / 4
|
toTrim = (total - bits) / 4
|
||||||
} else {
|
} else {
|
||||||
return "", errors.Errorf("Address is not IPv4 or IPv6: %v", cidr)
|
return "", fmt.Errorf("Address is not IPv4 or IPv6: %v", cidr)
|
||||||
}
|
}
|
||||||
|
|
||||||
parts := strings.SplitN(base, ".", toTrim+1)
|
parts := strings.SplitN(base, ".", toTrim+1)
|
||||||
|
@@ -6,8 +6,6 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// PtrNameMagic implements the PTR magic.
|
// PtrNameMagic implements the PTR magic.
|
||||||
@@ -22,7 +20,7 @@ func PtrNameMagic(name, domain string) (string, error) {
|
|||||||
if strings.HasSuffix(name, "."+domain+".") {
|
if strings.HasSuffix(name, "."+domain+".") {
|
||||||
return strings.TrimSuffix(name, "."+domain+"."), nil
|
return strings.TrimSuffix(name, "."+domain+"."), nil
|
||||||
}
|
}
|
||||||
return name, errors.Errorf("PTR record %v in wrong domain (%v)", name, domain)
|
return name, fmt.Errorf("PTR record %v in wrong domain (%v)", name, domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the domain is .arpa, we do magic.
|
// If the domain is .arpa, we do magic.
|
||||||
@@ -57,7 +55,7 @@ func ipv4magic(name, domain string) (string, error) {
|
|||||||
return strings.SplitN(rev, ".", 2)[0], nil
|
return strings.SplitN(rev, ".", 2)[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", errors.Errorf("PTR record %v in wrong IPv4 domain (%v)", name, domain)
|
return "", fmt.Errorf("PTR record %v in wrong IPv4 domain (%v)", name, domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
var isRfc2317Format1 = regexp.MustCompile(`(\d{1,3})/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.in-addr\.arpa$`)
|
var isRfc2317Format1 = regexp.MustCompile(`(\d{1,3})/(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.in-addr\.arpa$`)
|
||||||
@@ -112,7 +110,7 @@ func ipv6magic(name, domain string) (string, error) {
|
|||||||
return name, err
|
return name, err
|
||||||
}
|
}
|
||||||
if !strings.HasSuffix(rev, "."+domain) {
|
if !strings.HasSuffix(rev, "."+domain) {
|
||||||
err = errors.Errorf("PTR record %v in wrong IPv6 domain (%v)", name, domain)
|
err = fmt.Errorf("PTR record %v in wrong IPv6 domain (%v)", name, domain)
|
||||||
}
|
}
|
||||||
return strings.TrimSuffix(rev, "."+domain), err
|
return strings.TrimSuffix(rev, "."+domain), err
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,9 @@
|
|||||||
package transform
|
package transform
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// IpConversion describes an IP conversion.
|
// IpConversion describes an IP conversion.
|
||||||
@@ -17,7 +16,7 @@ type IpConversion struct {
|
|||||||
func ipToUint(i net.IP) (uint32, error) {
|
func ipToUint(i net.IP) (uint32, error) {
|
||||||
parts := i.To4()
|
parts := i.To4()
|
||||||
if parts == nil || len(parts) != 4 {
|
if parts == nil || len(parts) != 4 {
|
||||||
return 0, errors.Errorf("%s is not an ipv4 address", parts.String())
|
return 0, fmt.Errorf("%s is not an ipv4 address", parts.String())
|
||||||
}
|
}
|
||||||
r := uint32(parts[0])<<24 | uint32(parts[1])<<16 | uint32(parts[2])<<8 | uint32(parts[3])
|
r := uint32(parts[0])<<24 | uint32(parts[1])<<16 | uint32(parts[2])<<8 | uint32(parts[3])
|
||||||
return r, nil
|
return r, nil
|
||||||
@@ -39,7 +38,7 @@ func DecodeTransformTable(transforms string) ([]IpConversion, error) {
|
|||||||
for ri, row := range rows {
|
for ri, row := range rows {
|
||||||
items := strings.Split(row, "~")
|
items := strings.Split(row, "~")
|
||||||
if len(items) != 4 {
|
if len(items) != 4 {
|
||||||
return nil, errors.Errorf("transform_table rows should have 4 elements. (%v) found in row (%v) of %#v", len(items), ri, transforms)
|
return nil, fmt.Errorf("transform_table rows should have 4 elements. (%v) found in row (%v) of %#v", len(items), ri, transforms)
|
||||||
}
|
}
|
||||||
for i, item := range items {
|
for i, item := range items {
|
||||||
items[i] = strings.TrimSpace(item)
|
items[i] = strings.TrimSpace(item)
|
||||||
@@ -58,7 +57,7 @@ func DecodeTransformTable(transforms string) ([]IpConversion, error) {
|
|||||||
}
|
}
|
||||||
addr := net.ParseIP(ip)
|
addr := net.ParseIP(ip)
|
||||||
if addr == nil {
|
if addr == nil {
|
||||||
return nil, errors.Errorf("%s is not a valid ip address", ip)
|
return nil, fmt.Errorf("%s is not a valid ip address", ip)
|
||||||
}
|
}
|
||||||
ips = append(ips, addr)
|
ips = append(ips, addr)
|
||||||
}
|
}
|
||||||
@@ -75,10 +74,10 @@ func DecodeTransformTable(transforms string) ([]IpConversion, error) {
|
|||||||
low, _ := ipToUint(con.Low)
|
low, _ := ipToUint(con.Low)
|
||||||
high, _ := ipToUint(con.High)
|
high, _ := ipToUint(con.High)
|
||||||
if low > high {
|
if low > high {
|
||||||
return nil, errors.Errorf("transform_table Low should be less than High. row (%v) %v>%v (%v)", ri, con.Low, con.High, transforms)
|
return nil, fmt.Errorf("transform_table Low should be less than High. row (%v) %v>%v (%v)", ri, con.Low, con.High, transforms)
|
||||||
}
|
}
|
||||||
if len(con.NewBases) > 0 && len(con.NewIPs) > 0 {
|
if len(con.NewBases) > 0 && len(con.NewIPs) > 0 {
|
||||||
return nil, errors.Errorf("transform_table_rows should only specify one of NewBases or NewIPs, Not both")
|
return nil, fmt.Errorf("transform_table_rows should only specify one of NewBases or NewIPs, Not both")
|
||||||
}
|
}
|
||||||
result = append(result, con)
|
result = append(result, con)
|
||||||
}
|
}
|
||||||
@@ -93,7 +92,7 @@ func TransformIP(address net.IP, transforms []IpConversion) (net.IP, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if len(ips) != 1 {
|
if len(ips) != 1 {
|
||||||
return nil, errors.Errorf("Expect exactly one ip for TransformIP result. Got: %s", ips)
|
return nil, fmt.Errorf("Expect exactly one ip for TransformIP result. Got: %s", ips)
|
||||||
}
|
}
|
||||||
return ips[0], err
|
return ips[0], err
|
||||||
}
|
}
|
||||||
|
@@ -6,7 +6,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// This is the struct that matches either (or both) of the Registrar and/or DNSProvider interfaces:
|
// This is the struct that matches either (or both) of the Registrar and/or DNSProvider interfaces:
|
||||||
@@ -39,7 +38,7 @@ func newDNS(config map[string]string, metadata json.RawMessage) (providers.DNSSe
|
|||||||
if fVal := config["fakeps"]; fVal == "true" {
|
if fVal := config["fakeps"]; fVal == "true" {
|
||||||
fake = true
|
fake = true
|
||||||
} else if fVal != "" && fVal != "false" {
|
} else if fVal != "" && fVal != "false" {
|
||||||
return nil, errors.Errorf("fakeps value must be 'true' or 'false'")
|
return nil, fmt.Errorf("fakeps value must be 'true' or 'false'")
|
||||||
}
|
}
|
||||||
|
|
||||||
psOut, psLog := config["psout"], config["pslog"]
|
psOut, psLog := config["psout"], config["pslog"]
|
||||||
@@ -57,7 +56,7 @@ func newDNS(config map[string]string, metadata json.RawMessage) (providers.DNSSe
|
|||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
srv := config["ADServer"]
|
srv := config["ADServer"]
|
||||||
if srv == "" {
|
if srv == "" {
|
||||||
return nil, errors.Errorf("ADServer required for Active Directory provider")
|
return nil, fmt.Errorf("ADServer required for Active Directory provider")
|
||||||
}
|
}
|
||||||
p.adServer = srv
|
p.adServer = srv
|
||||||
return p, nil
|
return p, nil
|
||||||
|
@@ -11,7 +11,6 @@ import (
|
|||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/TomOnTime/utfutil"
|
"github.com/TomOnTime/utfutil"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const zoneDumpFilenamePrefix = "adzonedump"
|
const zoneDumpFilenamePrefix = "adzonedump"
|
||||||
@@ -55,7 +54,7 @@ func (c *adProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Co
|
|||||||
// Read foundRecords:
|
// Read foundRecords:
|
||||||
foundRecords, err := c.getExistingRecords(dc.Name)
|
foundRecords, err := c.getExistingRecords(dc.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("c.getExistingRecords(%v) failed: %v", dc.Name, err)
|
return nil, fmt.Errorf("c.getExistingRecords(%v) failed: %v", dc.Name, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Normalize
|
// Normalize
|
||||||
@@ -121,14 +120,14 @@ func (c *adProvider) logErr(e error) error {
|
|||||||
func (c *adProvider) logHelper(s string) error {
|
func (c *adProvider) logHelper(s string) error {
|
||||||
logfile, err := os.OpenFile(c.psLog, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0660)
|
logfile, err := os.OpenFile(c.psLog, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0660)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("error: Can not create/append to %#v: %v", c.psLog, err)
|
return fmt.Errorf("error: Can not create/append to %#v: %v", c.psLog, err)
|
||||||
}
|
}
|
||||||
_, err = fmt.Fprintln(logfile, s)
|
_, err = fmt.Fprintln(logfile, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("Append to %#v failed: %v", c.psLog, err)
|
return fmt.Errorf("Append to %#v failed: %v", c.psLog, err)
|
||||||
}
|
}
|
||||||
if logfile.Close() != nil {
|
if logfile.Close() != nil {
|
||||||
return errors.Errorf("Closing %#v failed: %v", c.psLog, err)
|
return fmt.Errorf("Closing %#v failed: %v", c.psLog, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -137,11 +136,11 @@ func (c *adProvider) logHelper(s string) error {
|
|||||||
func (c *adProvider) powerShellRecord(command string) error {
|
func (c *adProvider) powerShellRecord(command string) error {
|
||||||
recordfile, err := os.OpenFile(c.psOut, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0660)
|
recordfile, err := os.OpenFile(c.psOut, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0660)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("can not create/append to %#v: %v", c.psOut, err)
|
return fmt.Errorf("can not create/append to %#v: %v", c.psOut, err)
|
||||||
}
|
}
|
||||||
_, err = recordfile.WriteString(command)
|
_, err = recordfile.WriteString(command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("append to %#v failed: %v", c.psOut, err)
|
return fmt.Errorf("append to %#v failed: %v", c.psOut, err)
|
||||||
}
|
}
|
||||||
return recordfile.Close()
|
return recordfile.Close()
|
||||||
}
|
}
|
||||||
@@ -150,7 +149,7 @@ func (c *adProvider) getExistingRecords(domainname string) ([]*models.RecordConf
|
|||||||
// Get the JSON either from adzonedump or by running a PowerShell script.
|
// Get the JSON either from adzonedump or by running a PowerShell script.
|
||||||
data, err := c.getRecords(domainname)
|
data, err := c.getRecords(domainname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("getRecords failed on %#v: %v", domainname, err)
|
return nil, fmt.Errorf("getRecords failed on %#v: %v", domainname, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var recs []*RecordConfigJson
|
var recs []*RecordConfigJson
|
||||||
@@ -163,7 +162,7 @@ func (c *adProvider) getExistingRecords(domainname string) ([]*models.RecordConf
|
|||||||
}
|
}
|
||||||
err = json.Unmarshal(data, &recs)
|
err = json.Unmarshal(data, &recs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("json.Unmarshal failed on %#v: %v", domainname, err)
|
return nil, fmt.Errorf("json.Unmarshal failed on %#v: %v", domainname, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make([]*models.RecordConfig, 0, len(recs))
|
result := make([]*models.RecordConfig, 0, len(recs))
|
||||||
@@ -241,7 +240,7 @@ func (c *adProvider) generatePowerShellCreate(domainname string, rec *models.Rec
|
|||||||
case "NS":
|
case "NS":
|
||||||
text += fmt.Sprintf(` -NS -NameServer "%s"`, content)
|
text += fmt.Sprintf(` -NS -NameServer "%s"`, content)
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("generatePowerShellCreate() does not yet handle recType=%s recName=%#v content=%#v)",
|
panic(fmt.Errorf("generatePowerShellCreate() does not yet handle recType=%s recName=%#v content=%#v)",
|
||||||
rec.Type, rec.GetLabel(), content))
|
rec.Type, rec.GetLabel(), content))
|
||||||
// We panic so that we quickly find any switch statements
|
// We panic so that we quickly find any switch statements
|
||||||
// that have not been updated for a new RR type.
|
// that have not been updated for a new RR type.
|
||||||
@@ -265,7 +264,7 @@ func (c *adProvider) generatePowerShellModify(domainname, recName, recType, oldC
|
|||||||
case "NS":
|
case "NS":
|
||||||
queryField = "NameServer"
|
queryField = "NameServer"
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("generatePowerShellModify() does not yet handle recType=%s recName=%#v content=(%#v, %#v)", recType, recName, oldContent, newContent))
|
panic(fmt.Errorf("generatePowerShellModify() does not yet handle recType=%s recName=%#v content=(%#v, %#v)", recType, recName, oldContent, newContent))
|
||||||
// We panic so that we quickly find any switch statements
|
// We panic so that we quickly find any switch statements
|
||||||
// that have not been updated for a new RR type.
|
// that have not been updated for a new RR type.
|
||||||
}
|
}
|
||||||
|
@@ -6,8 +6,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var checkPS sync.Once
|
var checkPS sync.Once
|
||||||
@@ -31,7 +29,7 @@ func (c *adProvider) getRecords(domainname string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
if !psAvailible {
|
if !psAvailible {
|
||||||
return nil, errors.Errorf("powershell module DnsServer not installed")
|
return nil, fmt.Errorf("powershell module DnsServer not installed")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := c.powerShellExec(c.generatePowerShellZoneDump(domainname), true)
|
_, err := c.powerShellExec(c.generatePowerShellZoneDump(domainname), true)
|
||||||
|
@@ -7,14 +7,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
adns "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns"
|
||||||
|
aauth "github.com/Azure/go-autorest/autorest/azure/auth"
|
||||||
"github.com/Azure/go-autorest/autorest/to"
|
"github.com/Azure/go-autorest/autorest/to"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
adns "github.com/Azure/azure-sdk-for-go/services/dns/mgmt/2018-05-01/dns"
|
|
||||||
aauth "github.com/Azure/go-autorest/autorest/azure/auth"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type azureDnsProvider struct {
|
type azureDnsProvider struct {
|
||||||
@@ -258,7 +257,7 @@ func nativeToRecordType(recordType *string) adns.RecordType {
|
|||||||
case "SOA":
|
case "SOA":
|
||||||
return adns.SOA
|
return adns.SOA
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("rc.String rtype %v unimplemented", *recordType))
|
panic(fmt.Errorf("rc.String rtype %v unimplemented", *recordType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -337,7 +336,7 @@ func nativeToRecords(set *adns.RecordSet, origin string) []*models.RecordConfig
|
|||||||
}
|
}
|
||||||
case "Microsoft.Network/dnszones/SOA":
|
case "Microsoft.Network/dnszones/SOA":
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("rc.String rtype %v unimplemented", *set.Type))
|
panic(fmt.Errorf("rc.String rtype %v unimplemented", *set.Type))
|
||||||
}
|
}
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
@@ -389,7 +388,7 @@ func recordToNative(recordKey models.RecordKey, recordConfig []*models.RecordCon
|
|||||||
}
|
}
|
||||||
*recordSet.CaaRecords = append(*recordSet.CaaRecords, adns.CaaRecord{Value: to.StringPtr(rec.Target), Tag: to.StringPtr(rec.CaaTag), Flags: to.Int32Ptr(int32(rec.CaaFlag))})
|
*recordSet.CaaRecords = append(*recordSet.CaaRecords, adns.CaaRecord{Value: to.StringPtr(rec.Target), Tag: to.StringPtr(rec.CaaTag), Flags: to.Int32Ptr(int32(rec.CaaFlag))})
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("rc.String rtype %v unimplemented", recordKey.Type))
|
panic(fmt.Errorf("rc.String rtype %v unimplemented", recordKey.Type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return recordSet, nativeToRecordType(to.StringPtr(recordKey.Type))
|
return recordSet, nativeToRecordType(to.StringPtr(recordKey.Type))
|
||||||
|
@@ -23,7 +23,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/miekg/dns"
|
"github.com/miekg/dns"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
@@ -155,7 +154,7 @@ func rrToRecord(rr dns.RR, origin string, replaceSerial uint32) (models.RecordCo
|
|||||||
|
|
||||||
func panicInvalid(err error) {
|
func panicInvalid(err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from BIND"))
|
panic(fmt.Errorf("unparsable record received from BIND: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -8,13 +8,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/miekg/dns/dnsutil"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/transform"
|
"github.com/StackExchange/dnscontrol/v2/pkg/transform"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/miekg/dns/dnsutil"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -88,7 +88,7 @@ func (c *CloudflareApi) GetNameservers(domain string) ([]*models.Nameserver, err
|
|||||||
}
|
}
|
||||||
ns, ok := c.nameservers[domain]
|
ns, ok := c.nameservers[domain]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("Nameservers for %s not found in cloudflare account", domain)
|
return nil, fmt.Errorf("Nameservers for %s not found in cloudflare account", domain)
|
||||||
}
|
}
|
||||||
return models.StringsToNameservers(ns), nil
|
return models.StringsToNameservers(ns), nil
|
||||||
}
|
}
|
||||||
@@ -102,7 +102,7 @@ func (c *CloudflareApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models
|
|||||||
}
|
}
|
||||||
id, ok := c.domainIndex[dc.Name]
|
id, ok := c.domainIndex[dc.Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%s not listed in zones for cloudflare account", dc.Name)
|
return nil, fmt.Errorf("%s not listed in zones for cloudflare account", dc.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.preprocessConfig(dc); err != nil {
|
if err := c.preprocessConfig(dc); err != nil {
|
||||||
@@ -230,7 +230,7 @@ func checkNSModifications(dc *models.DomainConfig) {
|
|||||||
func (c *CloudflareApi) checkUniversalSSL(dc *models.DomainConfig, id string) (changed bool, newState bool, err error) {
|
func (c *CloudflareApi) checkUniversalSSL(dc *models.DomainConfig, id string) (changed bool, newState bool, err error) {
|
||||||
expected_str := dc.Metadata[metaUniversalSSL]
|
expected_str := dc.Metadata[metaUniversalSSL]
|
||||||
if expected_str == "" {
|
if expected_str == "" {
|
||||||
return false, false, errors.Errorf("Metadata not set.")
|
return false, false, fmt.Errorf("Metadata not set.")
|
||||||
}
|
}
|
||||||
|
|
||||||
if actual, err := c.getUniversalSSL(id); err == nil {
|
if actual, err := c.getUniversalSSL(id); err == nil {
|
||||||
@@ -247,7 +247,7 @@ func (c *CloudflareApi) checkUniversalSSL(dc *models.DomainConfig, id string) (c
|
|||||||
}
|
}
|
||||||
return false, expected, nil
|
return false, expected, nil
|
||||||
}
|
}
|
||||||
return false, false, errors.Errorf("error receiving universal ssl state:")
|
return false, false, fmt.Errorf("error receiving universal ssl state:")
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -261,7 +261,7 @@ const (
|
|||||||
func checkProxyVal(v string) (string, error) {
|
func checkProxyVal(v string) (string, error) {
|
||||||
v = strings.ToLower(v)
|
v = strings.ToLower(v)
|
||||||
if v != "on" && v != "off" && v != "full" {
|
if v != "on" && v != "off" && v != "full" {
|
||||||
return "", errors.Errorf("Bad metadata value for cloudflare_proxy: '%s'. Use on/off/full", v)
|
return "", fmt.Errorf("Bad metadata value for cloudflare_proxy: '%s'. Use on/off/full", v)
|
||||||
}
|
}
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
@@ -284,7 +284,7 @@ func (c *CloudflareApi) preprocessConfig(dc *models.DomainConfig) error {
|
|||||||
if u := dc.Metadata[metaUniversalSSL]; u != "" {
|
if u := dc.Metadata[metaUniversalSSL]; u != "" {
|
||||||
u = strings.ToLower(u)
|
u = strings.ToLower(u)
|
||||||
if u != "on" && u != "off" {
|
if u != "on" && u != "off" {
|
||||||
return errors.Errorf("Bad metadata value for %s: '%s'. Use on/off.", metaUniversalSSL, u)
|
return fmt.Errorf("Bad metadata value for %s: '%s'. Use on/off.", metaUniversalSSL, u)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -310,7 +310,7 @@ func (c *CloudflareApi) preprocessConfig(dc *models.DomainConfig) error {
|
|||||||
|
|
||||||
if rec.Type != "A" && rec.Type != "CNAME" && rec.Type != "AAAA" && rec.Type != "ALIAS" {
|
if rec.Type != "A" && rec.Type != "CNAME" && rec.Type != "AAAA" && rec.Type != "ALIAS" {
|
||||||
if rec.Metadata[metaProxy] != "" {
|
if rec.Metadata[metaProxy] != "" {
|
||||||
return errors.Errorf("cloudflare_proxy set on %v record: %#v cloudflare_proxy=%#v", rec.Type, rec.GetLabel(), rec.Metadata[metaProxy])
|
return fmt.Errorf("cloudflare_proxy set on %v record: %#v cloudflare_proxy=%#v", rec.Type, rec.GetLabel(), rec.Metadata[metaProxy])
|
||||||
}
|
}
|
||||||
// Force it to off.
|
// Force it to off.
|
||||||
rec.Metadata[metaProxy] = "off"
|
rec.Metadata[metaProxy] = "off"
|
||||||
@@ -329,11 +329,11 @@ func (c *CloudflareApi) preprocessConfig(dc *models.DomainConfig) error {
|
|||||||
// CF_REDIRECT record types. Encode target as $FROM,$TO,$PRIO,$CODE
|
// CF_REDIRECT record types. Encode target as $FROM,$TO,$PRIO,$CODE
|
||||||
if rec.Type == "CF_REDIRECT" || rec.Type == "CF_TEMP_REDIRECT" {
|
if rec.Type == "CF_REDIRECT" || rec.Type == "CF_TEMP_REDIRECT" {
|
||||||
if !c.manageRedirects {
|
if !c.manageRedirects {
|
||||||
return errors.Errorf("you must add 'manage_redirects: true' metadata to cloudflare provider to use CF_REDIRECT records")
|
return fmt.Errorf("you must add 'manage_redirects: true' metadata to cloudflare provider to use CF_REDIRECT records")
|
||||||
}
|
}
|
||||||
parts := strings.Split(rec.GetTargetField(), ",")
|
parts := strings.Split(rec.GetTargetField(), ",")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
return errors.Errorf("Invalid data specified for cloudflare redirect record")
|
return fmt.Errorf("Invalid data specified for cloudflare redirect record")
|
||||||
}
|
}
|
||||||
code := 301
|
code := 301
|
||||||
if rec.Type == "CF_TEMP_REDIRECT" {
|
if rec.Type == "CF_TEMP_REDIRECT" {
|
||||||
@@ -356,7 +356,7 @@ func (c *CloudflareApi) preprocessConfig(dc *models.DomainConfig) error {
|
|||||||
}
|
}
|
||||||
ip := net.ParseIP(rec.GetTargetField())
|
ip := net.ParseIP(rec.GetTargetField())
|
||||||
if ip == nil {
|
if ip == nil {
|
||||||
return errors.Errorf("%s is not a valid ip address", rec.GetTargetField())
|
return fmt.Errorf("%s is not a valid ip address", rec.GetTargetField())
|
||||||
}
|
}
|
||||||
newIP, err := transform.TransformIP(ip, c.ipConversions)
|
newIP, err := transform.TransformIP(ip, c.ipConversions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -374,16 +374,16 @@ func newCloudflare(m map[string]string, metadata json.RawMessage) (providers.DNS
|
|||||||
api.ApiUser, api.ApiKey, api.ApiToken = m["apiuser"], m["apikey"], m["apitoken"]
|
api.ApiUser, api.ApiKey, api.ApiToken = m["apiuser"], m["apikey"], m["apitoken"]
|
||||||
// check api keys from creds json file
|
// check api keys from creds json file
|
||||||
if api.ApiToken == "" && (api.ApiKey == "" || api.ApiUser == "") {
|
if api.ApiToken == "" && (api.ApiKey == "" || api.ApiUser == "") {
|
||||||
return nil, errors.Errorf("if cloudflare apitoken is not set, apikey and apiuser must be provided")
|
return nil, fmt.Errorf("if cloudflare apitoken is not set, apikey and apiuser must be provided")
|
||||||
}
|
}
|
||||||
if api.ApiToken != "" && (api.ApiKey != "" || api.ApiUser != "") {
|
if api.ApiToken != "" && (api.ApiKey != "" || api.ApiUser != "") {
|
||||||
return nil, errors.Errorf("if cloudflare apitoken is set, apikey and apiuser should not be provided")
|
return nil, fmt.Errorf("if cloudflare apitoken is set, apikey and apiuser should not be provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check account data if set
|
// Check account data if set
|
||||||
api.AccountID, api.AccountName = m["accountid"], m["accountname"]
|
api.AccountID, api.AccountName = m["accountid"], m["accountname"]
|
||||||
if (api.AccountID != "" && api.AccountName == "") || (api.AccountID == "" && api.AccountName != "") {
|
if (api.AccountID != "" && api.AccountName == "") || (api.AccountID == "" && api.AccountName != "") {
|
||||||
return nil, errors.Errorf("either both cloudflare accountid and accountname must be provided or neither")
|
return nil, fmt.Errorf("either both cloudflare accountid and accountname must be provided or neither")
|
||||||
}
|
}
|
||||||
|
|
||||||
err := api.fetchDomainList()
|
err := api.fetchDomainList()
|
||||||
@@ -525,23 +525,23 @@ func (c *cfRecord) nativeToRecord(domain string) *models.RecordConfig {
|
|||||||
priority = 0
|
priority = 0
|
||||||
} else {
|
} else {
|
||||||
if p, err := c.Priority.Int64(); err != nil {
|
if p, err := c.Priority.Int64(); err != nil {
|
||||||
panic(errors.Wrap(err, "error decoding priority from cloudflare record"))
|
panic(fmt.Errorf("error decoding priority from cloudflare record: %w", err))
|
||||||
} else {
|
} else {
|
||||||
priority = uint16(p)
|
priority = uint16(p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if err := rc.SetTargetMX(priority, c.Content); err != nil {
|
if err := rc.SetTargetMX(priority, c.Content); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable MX record received from cloudflare"))
|
panic(fmt.Errorf("unparsable MX record received from cloudflare: %w", err))
|
||||||
}
|
}
|
||||||
case "SRV":
|
case "SRV":
|
||||||
data := *c.Data
|
data := *c.Data
|
||||||
if err := rc.SetTargetSRV(data.Priority, data.Weight, data.Port,
|
if err := rc.SetTargetSRV(data.Priority, data.Weight, data.Port,
|
||||||
dnsutil.AddOrigin(data.Target.FQDN(), domain)); err != nil {
|
dnsutil.AddOrigin(data.Target.FQDN(), domain)); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable SRV record received from cloudflare"))
|
panic(fmt.Errorf("unparsable SRV record received from cloudflare: %w", err))
|
||||||
}
|
}
|
||||||
default: // "A", "AAAA", "ANAME", "CAA", "CNAME", "NS", "PTR", "TXT"
|
default: // "A", "AAAA", "ANAME", "CAA", "CNAME", "NS", "PTR", "TXT"
|
||||||
if err := rc.PopulateFromString(rType, c.Content, domain); err != nil {
|
if err := rc.PopulateFromString(rType, c.Content, domain); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from cloudflare"))
|
panic(fmt.Errorf("unparsable record received from cloudflare: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -11,7 +11,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -32,10 +31,10 @@ func (c *CloudflareApi) fetchDomainList() error {
|
|||||||
zr := &zoneResponse{}
|
zr := &zoneResponse{}
|
||||||
url := fmt.Sprintf("%s?page=%d&per_page=50", zonesURL, page)
|
url := fmt.Sprintf("%s?page=%d&per_page=50", zonesURL, page)
|
||||||
if err := c.get(url, zr); err != nil {
|
if err := c.get(url, zr); err != nil {
|
||||||
return errors.Errorf("Error fetching domain list from cloudflare: %s", err)
|
return fmt.Errorf("Error fetching domain list from cloudflare: %s", err)
|
||||||
}
|
}
|
||||||
if !zr.Success {
|
if !zr.Success {
|
||||||
return errors.Errorf("Error fetching domain list from cloudflare: %s", stringifyErrors(zr.Errors))
|
return fmt.Errorf("Error fetching domain list from cloudflare: %s", stringifyErrors(zr.Errors))
|
||||||
}
|
}
|
||||||
for _, zone := range zr.Result {
|
for _, zone := range zr.Result {
|
||||||
c.domainIndex[zone.Name] = zone.ID
|
c.domainIndex[zone.Name] = zone.ID
|
||||||
@@ -61,10 +60,10 @@ func (c *CloudflareApi) getRecordsForDomain(id string, domain string) ([]*models
|
|||||||
reqURL := fmt.Sprintf("%s?page=%d&per_page=100", url, page)
|
reqURL := fmt.Sprintf("%s?page=%d&per_page=100", url, page)
|
||||||
var data recordsResponse
|
var data recordsResponse
|
||||||
if err := c.get(reqURL, &data); err != nil {
|
if err := c.get(reqURL, &data); err != nil {
|
||||||
return nil, errors.Errorf("Error fetching record list from cloudflare: %s", err)
|
return nil, fmt.Errorf("Error fetching record list from cloudflare: %s", err)
|
||||||
}
|
}
|
||||||
if !data.Success {
|
if !data.Success {
|
||||||
return nil, errors.Errorf("Error fetching record list cloudflare: %s", stringifyErrors(data.Errors))
|
return nil, fmt.Errorf("Error fetching record list cloudflare: %s", stringifyErrors(data.Errors))
|
||||||
}
|
}
|
||||||
for _, rec := range data.Result {
|
for _, rec := range data.Result {
|
||||||
// fmt.Printf("REC: %+v\n", rec)
|
// fmt.Printf("REC: %+v\n", rec)
|
||||||
@@ -237,7 +236,7 @@ func (c *CloudflareApi) createRec(rec *models.RecordConfig, domainID string) []*
|
|||||||
|
|
||||||
func (c *CloudflareApi) modifyRecord(domainID, recID string, proxied bool, rec *models.RecordConfig) error {
|
func (c *CloudflareApi) modifyRecord(domainID, recID string, proxied bool, rec *models.RecordConfig) error {
|
||||||
if domainID == "" || recID == "" {
|
if domainID == "" || recID == "" {
|
||||||
return errors.Errorf("cannot modify record if domain or record id are empty")
|
return fmt.Errorf("cannot modify record if domain or record id are empty")
|
||||||
}
|
}
|
||||||
type record struct {
|
type record struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
@@ -347,10 +346,10 @@ func handleActionResponse(resp *http.Response, err error) (id string, e error) {
|
|||||||
result := &basicResponse{}
|
result := &basicResponse{}
|
||||||
decoder := json.NewDecoder(resp.Body)
|
decoder := json.NewDecoder(resp.Body)
|
||||||
if err = decoder.Decode(result); err != nil {
|
if err = decoder.Decode(result); err != nil {
|
||||||
return "", errors.Errorf("Unknown error. Status code: %d", resp.StatusCode)
|
return "", fmt.Errorf("Unknown error. Status code: %d", resp.StatusCode)
|
||||||
}
|
}
|
||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
return "", errors.Errorf(stringifyErrors(result.Errors))
|
return "", fmt.Errorf(stringifyErrors(result.Errors))
|
||||||
}
|
}
|
||||||
return result.Result.ID, nil
|
return result.Result.ID, nil
|
||||||
}
|
}
|
||||||
@@ -379,7 +378,7 @@ func (c *CloudflareApi) get(endpoint string, target interface{}) error {
|
|||||||
if resp.StatusCode != 200 {
|
if resp.StatusCode != 200 {
|
||||||
dat, _ := ioutil.ReadAll(resp.Body)
|
dat, _ := ioutil.ReadAll(resp.Body)
|
||||||
fmt.Println(string(dat))
|
fmt.Println(string(dat))
|
||||||
return errors.Errorf("bad status code from cloudflare: %d not 200", resp.StatusCode)
|
return fmt.Errorf("bad status code from cloudflare: %d not 200", resp.StatusCode)
|
||||||
}
|
}
|
||||||
decoder := json.NewDecoder(resp.Body)
|
decoder := json.NewDecoder(resp.Body)
|
||||||
return decoder.Decode(target)
|
return decoder.Decode(target)
|
||||||
@@ -389,10 +388,10 @@ func (c *CloudflareApi) getPageRules(id string, domain string) ([]*models.Record
|
|||||||
url := fmt.Sprintf(pageRulesURL, id)
|
url := fmt.Sprintf(pageRulesURL, id)
|
||||||
data := pageRuleResponse{}
|
data := pageRuleResponse{}
|
||||||
if err := c.get(url, &data); err != nil {
|
if err := c.get(url, &data); err != nil {
|
||||||
return nil, errors.Errorf("Error fetching page rule list from cloudflare: %s", err)
|
return nil, fmt.Errorf("Error fetching page rule list from cloudflare: %s", err)
|
||||||
}
|
}
|
||||||
if !data.Success {
|
if !data.Success {
|
||||||
return nil, errors.Errorf("Error fetching page rule list cloudflare: %s", stringifyErrors(data.Errors))
|
return nil, fmt.Errorf("Error fetching page rule list cloudflare: %s", stringifyErrors(data.Errors))
|
||||||
}
|
}
|
||||||
recs := []*models.RecordConfig{}
|
recs := []*models.RecordConfig{}
|
||||||
for _, pr := range data.Result {
|
for _, pr := range data.Result {
|
||||||
|
@@ -2,7 +2,7 @@ package cloudns
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/pkg/errors"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
@@ -86,7 +86,7 @@ func (c *api) fetchAvailableNameservers() error {
|
|||||||
|
|
||||||
var bodyString, err = c.get("/dns/available-name-servers.json", requestParams{})
|
var bodyString, err = c.get("/dns/available-name-servers.json", requestParams{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("Error fetching available nameservers list from ClouDNS: %s", err)
|
return fmt.Errorf("Error fetching available nameservers list from ClouDNS: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var nr nameserverResponse
|
var nr nameserverResponse
|
||||||
@@ -114,7 +114,7 @@ func (c *api) fetchDomainList() error {
|
|||||||
endpoint := "/dns/list-zones.json"
|
endpoint := "/dns/list-zones.json"
|
||||||
var bodyString, err = c.get(endpoint, params)
|
var bodyString, err = c.get(endpoint, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Errorf("Error fetching domain list from ClouDNS: %s", err)
|
return fmt.Errorf("Error fetching domain list from ClouDNS: %s", err)
|
||||||
}
|
}
|
||||||
json.Unmarshal(bodyString, &dr)
|
json.Unmarshal(bodyString, &dr)
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ func (c *api) createDomain(domain string) error {
|
|||||||
"zone-type": "master",
|
"zone-type": "master",
|
||||||
}
|
}
|
||||||
if _, err := c.get("/dns/register.json", params); err != nil {
|
if _, err := c.get("/dns/register.json", params); err != nil {
|
||||||
return errors.Errorf("Error create domain ClouDNS: %s", err)
|
return fmt.Errorf("Error create domain ClouDNS: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -143,7 +143,7 @@ func (c *api) createDomain(domain string) error {
|
|||||||
func (c *api) createRecord(domainID string, rec requestParams) error {
|
func (c *api) createRecord(domainID string, rec requestParams) error {
|
||||||
rec["domain-name"] = domainID
|
rec["domain-name"] = domainID
|
||||||
if _, err := c.get("/dns/add-record.json", rec); err != nil {
|
if _, err := c.get("/dns/add-record.json", rec); err != nil {
|
||||||
return errors.Errorf("Error create record ClouDNS: %s", err)
|
return fmt.Errorf("Error create record ClouDNS: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -154,7 +154,7 @@ func (c *api) deleteRecord(domainID string, recordID string) error {
|
|||||||
"record-id": recordID,
|
"record-id": recordID,
|
||||||
}
|
}
|
||||||
if _, err := c.get("/dns/delete-record.json", params); err != nil {
|
if _, err := c.get("/dns/delete-record.json", params); err != nil {
|
||||||
return errors.Errorf("Error delete record ClouDNS: %s", err)
|
return fmt.Errorf("Error delete record ClouDNS: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -163,7 +163,7 @@ func (c *api) modifyRecord(domainID string, recordID string, rec requestParams)
|
|||||||
rec["domain-name"] = domainID
|
rec["domain-name"] = domainID
|
||||||
rec["record-id"] = recordID
|
rec["record-id"] = recordID
|
||||||
if _, err := c.get("/dns/mod-record.json", rec); err != nil {
|
if _, err := c.get("/dns/mod-record.json", rec); err != nil {
|
||||||
return errors.Errorf("Error create update ClouDNS: %s", err)
|
return fmt.Errorf("Error create update ClouDNS: %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -173,7 +173,7 @@ func (c *api) getRecords(id string) ([]domainRecord, error) {
|
|||||||
|
|
||||||
var bodyString, err = c.get("/dns/records.json", params)
|
var bodyString, err = c.get("/dns/records.json", params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("Error fetching record list from ClouDNS: %s", err)
|
return nil, fmt.Errorf("Error fetching record list from ClouDNS: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var dr recordResponse
|
var dr recordResponse
|
||||||
@@ -213,7 +213,7 @@ func (c *api) get(endpoint string, params requestParams) ([]byte, error) {
|
|||||||
var errResp errorResponse
|
var errResp errorResponse
|
||||||
err = json.Unmarshal(bodyString, &errResp)
|
err = json.Unmarshal(bodyString, &errResp)
|
||||||
if errResp.Status == "Failed" {
|
if errResp.Status == "Failed" {
|
||||||
return bodyString, errors.Errorf("ClouDNS API error: %s URL:%s%s ", errResp.Description, req.Host, req.URL.RequestURI())
|
return bodyString, fmt.Errorf("ClouDNS API error: %s URL:%s%s ", errResp.Description, req.Host, req.URL.RequestURI())
|
||||||
}
|
}
|
||||||
|
|
||||||
return bodyString, nil
|
return bodyString, nil
|
||||||
|
@@ -3,12 +3,13 @@ package cloudns
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/miekg/dns/dnsutil"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/miekg/dns/dnsutil"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"strconv"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -27,7 +28,7 @@ func NewCloudns(m map[string]string, metadata json.RawMessage) (providers.DNSSer
|
|||||||
|
|
||||||
c.creds.id, c.creds.password = m["auth-id"], m["auth-password"]
|
c.creds.id, c.creds.password = m["auth-id"], m["auth-password"]
|
||||||
if c.creds.id == "" || c.creds.password == "" {
|
if c.creds.id == "" || c.creds.password == "" {
|
||||||
return nil, errors.Errorf("missing ClouDNS auth-id and auth-password")
|
return nil, fmt.Errorf("missing ClouDNS auth-id and auth-password")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a domain to validate authentication
|
// Get a domain to validate authentication
|
||||||
@@ -78,7 +79,7 @@ func (c *api) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correctio
|
|||||||
}
|
}
|
||||||
domainID, ok := c.domainIndex[dc.Name]
|
domainID, ok := c.domainIndex[dc.Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%s not listed in domains for ClouDNS account", dc.Name)
|
return nil, fmt.Errorf("%s not listed in domains for ClouDNS account", dc.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
records, err := c.getRecords(domainID)
|
records, err := c.getRecords(domainID)
|
||||||
|
@@ -12,7 +12,6 @@ import (
|
|||||||
|
|
||||||
"github.com/DisposaBoy/JsonConfigReader"
|
"github.com/DisposaBoy/JsonConfigReader"
|
||||||
"github.com/TomOnTime/utfutil"
|
"github.com/TomOnTime/utfutil"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// LoadProviderConfigs will open the specified file name, and parse its contents. It will replace environment variables it finds if any value matches $[A-Za-z_-0-9]+
|
// LoadProviderConfigs will open the specified file name, and parse its contents. It will replace environment variables it finds if any value matches $[A-Za-z_-0-9]+
|
||||||
@@ -25,13 +24,13 @@ func LoadProviderConfigs(fname string) (map[string]map[string]string, error) {
|
|||||||
fmt.Printf("INFO: Config file %q does not exist. Skipping.\n", fname)
|
fmt.Printf("INFO: Config file %q does not exist. Skipping.\n", fname)
|
||||||
return results, nil
|
return results, nil
|
||||||
}
|
}
|
||||||
return nil, errors.Errorf("While reading provider credentials file %v: %v", fname, err)
|
return nil, fmt.Errorf("While reading provider credentials file %v: %v", fname, err)
|
||||||
}
|
}
|
||||||
s := string(dat)
|
s := string(dat)
|
||||||
r := JsonConfigReader.New(strings.NewReader(s))
|
r := JsonConfigReader.New(strings.NewReader(s))
|
||||||
err = json.NewDecoder(r).Decode(&results)
|
err = json.NewDecoder(r).Decode(&results)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("While parsing provider credentials file %v: %v", fname, err)
|
return nil, fmt.Errorf("While parsing provider credentials file %v: %v", fname, err)
|
||||||
}
|
}
|
||||||
if err = replaceEnvVars(results); err != nil {
|
if err = replaceEnvVars(results); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/miekg/dns/dnsutil"
|
"github.com/miekg/dns/dnsutil"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/digitalocean/godo"
|
"github.com/digitalocean/godo"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
@@ -39,7 +38,7 @@ var defaultNameServerNames = []string{
|
|||||||
// NewDo creates a DO-specific DNS provider.
|
// NewDo creates a DO-specific DNS provider.
|
||||||
func NewDo(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
func NewDo(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||||
if m["token"] == "" {
|
if m["token"] == "" {
|
||||||
return nil, errors.Errorf("no DigitalOcean token provided")
|
return nil, fmt.Errorf("no DigitalOcean token provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@@ -57,7 +56,7 @@ func NewDo(m map[string]string, metadata json.RawMessage) (providers.DNSServiceP
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if resp.StatusCode != http.StatusOK {
|
if resp.StatusCode != http.StatusOK {
|
||||||
return nil, errors.Errorf("token for digitalocean is not valid")
|
return nil, fmt.Errorf("token for digitalocean is not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
return api, nil
|
return api, nil
|
||||||
|
@@ -8,13 +8,12 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
dnsimpleapi "github.com/dnsimple/dnsimple-go/dnsimple"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"golang.org/x/oauth2"
|
|
||||||
|
|
||||||
dnsimpleapi "github.com/dnsimple/dnsimple-go/dnsimple"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var features = providers.DocumentationNotes{
|
var features = providers.DocumentationNotes{
|
||||||
@@ -90,7 +89,7 @@ func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
|
|||||||
rec.SetTarget(r.Content)
|
rec.SetTarget(r.Content)
|
||||||
case "MX":
|
case "MX":
|
||||||
if err := rec.SetTargetMX(uint16(r.Priority), r.Content); err != nil {
|
if err := rec.SetTargetMX(uint16(r.Priority), r.Content); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from dnsimple"))
|
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
||||||
}
|
}
|
||||||
case "SRV":
|
case "SRV":
|
||||||
parts := strings.Fields(r.Content)
|
parts := strings.Fields(r.Content)
|
||||||
@@ -98,11 +97,11 @@ func (c *DnsimpleApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
|
|||||||
r.Content += "."
|
r.Content += "."
|
||||||
}
|
}
|
||||||
if err := rec.SetTargetSRVPriorityString(uint16(r.Priority), r.Content); err != nil {
|
if err := rec.SetTargetSRVPriorityString(uint16(r.Priority), r.Content); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from dnsimple"))
|
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if err := rec.PopulateFromString(r.Type, r.Content, dc.Name); err != nil {
|
if err := rec.PopulateFromString(r.Type, r.Content, dc.Name); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from dnsimple"))
|
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
actual = append(actual, rec)
|
actual = append(actual, rec)
|
||||||
@@ -197,7 +196,7 @@ func (c *DnsimpleApi) getAccountID() (string, error) {
|
|||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
if whoamiResponse.Data.User != nil && whoamiResponse.Data.Account == nil {
|
if whoamiResponse.Data.User != nil && whoamiResponse.Data.Account == nil {
|
||||||
return "", errors.Errorf("DNSimple token appears to be a user token. Please supply an account token")
|
return "", fmt.Errorf("DNSimple token appears to be a user token. Please supply an account token")
|
||||||
}
|
}
|
||||||
c.accountID = strconv.FormatInt(whoamiResponse.Data.Account.ID, 10)
|
c.accountID = strconv.FormatInt(whoamiResponse.Data.Account.ID, 10)
|
||||||
}
|
}
|
||||||
@@ -366,7 +365,7 @@ func newProvider(m map[string]string, metadata json.RawMessage) (*DnsimpleApi, e
|
|||||||
api := &DnsimpleApi{}
|
api := &DnsimpleApi{}
|
||||||
api.AccountToken = m["token"]
|
api.AccountToken = m["token"]
|
||||||
if api.AccountToken == "" {
|
if api.AccountToken == "" {
|
||||||
return nil, errors.Errorf("missing DNSimple token")
|
return nil, fmt.Errorf("missing DNSimple token")
|
||||||
}
|
}
|
||||||
|
|
||||||
if m["baseurl"] != "" {
|
if m["baseurl"] != "" {
|
||||||
|
@@ -6,7 +6,6 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/exoscale/egoscale"
|
"github.com/exoscale/egoscale"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
@@ -92,11 +91,11 @@ func (c *exoscaleProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*mod
|
|||||||
rec.SetTarget(r.Content)
|
rec.SetTarget(r.Content)
|
||||||
case "MX":
|
case "MX":
|
||||||
if err := rec.SetTargetMX(uint16(r.Prio), r.Content); err != nil {
|
if err := rec.SetTargetMX(uint16(r.Prio), r.Content); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from dnsimple"))
|
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if err := rec.PopulateFromString(r.RecordType, r.Content, dc.Name); err != nil {
|
if err := rec.PopulateFromString(r.RecordType, r.Content, dc.Name); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from dnsimple"))
|
panic(fmt.Errorf("unparsable record received from dnsimple: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
existingRecords = append(existingRecords, rec)
|
existingRecords = append(existingRecords, rec)
|
||||||
|
@@ -4,17 +4,15 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
gandidomain "github.com/prasmussen/gandi-api/domain"
|
||||||
|
gandirecord "github.com/prasmussen/gandi-api/domain/zone/record"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
gandidomain "github.com/prasmussen/gandi-api/domain"
|
|
||||||
gandirecord "github.com/prasmussen/gandi-api/domain/zone/record"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -60,7 +58,7 @@ func (c *GandiApi) getDomainInfo(domain string) (*gandidomain.DomainInfo, error)
|
|||||||
}
|
}
|
||||||
_, ok := c.domainIndex[domain]
|
_, ok := c.domainIndex[domain]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%s not listed in zones for gandi account", domain)
|
return nil, fmt.Errorf("%s not listed in zones for gandi account", domain)
|
||||||
}
|
}
|
||||||
return c.fetchDomainInfo(domain)
|
return c.fetchDomainInfo(domain)
|
||||||
}
|
}
|
||||||
@@ -98,7 +96,7 @@ func (c *GandiApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Corr
|
|||||||
rec.TTL = 300
|
rec.TTL = 300
|
||||||
}
|
}
|
||||||
if rec.TTL > 2592000 {
|
if rec.TTL > 2592000 {
|
||||||
return nil, errors.Errorf("ERROR: Gandi does not support TTLs > 30 days (TTL=%d)", rec.TTL)
|
return nil, fmt.Errorf("ERROR: Gandi does not support TTLs > 30 days (TTL=%d)", rec.TTL)
|
||||||
}
|
}
|
||||||
if rec.Type == "TXT" {
|
if rec.Type == "TXT" {
|
||||||
rec.SetTarget("\"" + rec.GetTargetField() + "\"") // FIXME(tlim): Should do proper quoting.
|
rec.SetTarget("\"" + rec.GetTargetField() + "\"") // FIXME(tlim): Should do proper quoting.
|
||||||
@@ -174,7 +172,7 @@ func newGandi(m map[string]string, metadata json.RawMessage) (*GandiApi, error)
|
|||||||
api := &GandiApi{}
|
api := &GandiApi{}
|
||||||
api.ApiKey = m["apikey"]
|
api.ApiKey = m["apikey"]
|
||||||
if api.ApiKey == "" {
|
if api.ApiKey == "" {
|
||||||
return nil, errors.Errorf("missing Gandi apikey")
|
return nil, fmt.Errorf("missing Gandi apikey")
|
||||||
}
|
}
|
||||||
|
|
||||||
return api, nil
|
return api, nil
|
||||||
|
@@ -7,16 +7,16 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/pkg/errors"
|
|
||||||
gandiclient "github.com/prasmussen/gandi-api/client"
|
gandiclient "github.com/prasmussen/gandi-api/client"
|
||||||
gandilivedomain "github.com/prasmussen/gandi-api/live_dns/domain"
|
gandilivedomain "github.com/prasmussen/gandi-api/live_dns/domain"
|
||||||
gandiliverecord "github.com/prasmussen/gandi-api/live_dns/record"
|
gandiliverecord "github.com/prasmussen/gandi-api/live_dns/record"
|
||||||
gandilivezone "github.com/prasmussen/gandi-api/live_dns/zone"
|
gandilivezone "github.com/prasmussen/gandi-api/live_dns/zone"
|
||||||
|
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
)
|
)
|
||||||
|
|
||||||
var liveFeatures = providers.DocumentationNotes{
|
var liveFeatures = providers.DocumentationNotes{
|
||||||
@@ -36,7 +36,7 @@ func init() {
|
|||||||
func newLiveDsp(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
func newLiveDsp(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||||
APIKey := m["apikey"]
|
APIKey := m["apikey"]
|
||||||
if APIKey == "" {
|
if APIKey == "" {
|
||||||
return nil, errors.Errorf("missing Gandi apikey")
|
return nil, fmt.Errorf("missing Gandi apikey")
|
||||||
}
|
}
|
||||||
|
|
||||||
return newLiveClient(APIKey), nil
|
return newLiveClient(APIKey), nil
|
||||||
@@ -74,7 +74,7 @@ func (c *liveClient) GetNameservers(domain string) ([]*models.Nameserver, error)
|
|||||||
domains := []string{}
|
domains := []string{}
|
||||||
response, err := c.client.Get("/nameservers/"+domain, &domains)
|
response, err := c.client.Get("/nameservers/"+domain, &domains)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("failed to get nameservers for domain %s", domain)
|
return nil, fmt.Errorf("failed to get nameservers for domain %s", domain)
|
||||||
}
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
|
||||||
@@ -201,7 +201,7 @@ func (c *liveClient) recordConfigFromInfo(infos []*gandiliverecord.Info, origin
|
|||||||
}
|
}
|
||||||
err := rc.SetTargetTXTs(parsed)
|
err := rc.SetTargetTXTs(parsed)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Wrapf(err, "recordConfigFromInfo=TXT failed"))
|
panic(fmt.Errorf("recordConfigFromInfo=TXT failed: %w", err))
|
||||||
}
|
}
|
||||||
rcs = append(rcs, rc)
|
rcs = append(rcs, rc)
|
||||||
} else {
|
} else {
|
||||||
@@ -218,7 +218,7 @@ func (c *liveClient) recordConfigFromInfo(infos []*gandiliverecord.Info, origin
|
|||||||
default:
|
default:
|
||||||
err := rc.PopulateFromString(rtype, value, origin)
|
err := rc.PopulateFromString(rtype, value, origin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(errors.Wrapf(err, "recordConfigFromInfo failed"))
|
panic(fmt.Errorf("recordConfigFromInfo failed: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rcs = append(rcs, rc)
|
rcs = append(rcs, rc)
|
||||||
@@ -240,7 +240,7 @@ func (c *liveClient) recordsToInfo(records models.Records) (models.Records, []*g
|
|||||||
rec.TTL = 300
|
rec.TTL = 300
|
||||||
}
|
}
|
||||||
if rec.TTL > 2592000 {
|
if rec.TTL > 2592000 {
|
||||||
return nil, nil, errors.Errorf("ERROR: Gandi does not support TTLs > 30 days (TTL=%d)", rec.TTL)
|
return nil, nil, fmt.Errorf("ERROR: Gandi does not support TTLs > 30 days (TTL=%d)", rec.TTL)
|
||||||
}
|
}
|
||||||
if rec.Type == "NS" && rec.GetLabel() == "@" {
|
if rec.Type == "NS" && rec.GetLabel() == "@" {
|
||||||
if !strings.HasSuffix(rec.GetTargetField(), ".gandi.net.") {
|
if !strings.HasSuffix(rec.GetTargetField(), ".gandi.net.") {
|
||||||
|
@@ -3,7 +3,6 @@ package gandi
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
gandiclient "github.com/prasmussen/gandi-api/client"
|
gandiclient "github.com/prasmussen/gandi-api/client"
|
||||||
gandidomain "github.com/prasmussen/gandi-api/domain"
|
gandidomain "github.com/prasmussen/gandi-api/domain"
|
||||||
gandinameservers "github.com/prasmussen/gandi-api/domain/nameservers"
|
gandinameservers "github.com/prasmussen/gandi-api/domain/nameservers"
|
||||||
@@ -78,7 +77,7 @@ func nativeToRecord(r *gandirecord.RecordInfo, origin string) *models.RecordConf
|
|||||||
switch rtype := r.Type; rtype {
|
switch rtype := r.Type; rtype {
|
||||||
default: // "A", "AAAA", "CAA", "NS", "CNAME", "MX", "PTR", "SRV", "TXT"
|
default: // "A", "AAAA", "CAA", "NS", "CNAME", "MX", "PTR", "SRV", "TXT"
|
||||||
if err := rc.PopulateFromString(rtype, r.Value, origin); err != nil {
|
if err := rc.PopulateFromString(rtype, r.Value, origin); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from gandi"))
|
panic(fmt.Errorf("unparsable record received from gandi: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc
|
return rc
|
||||||
|
@@ -3,10 +3,12 @@ package gandi5
|
|||||||
// Convert the provider's native record description to models.RecordConfig.
|
// Convert the provider's native record description to models.RecordConfig.
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/tiramiseb/go-gandi/livedns"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/tiramiseb/go-gandi/livedns"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// nativeToRecord takes a DNS record from Gandi and returns a native RecordConfig struct.
|
// nativeToRecord takes a DNS record from Gandi and returns a native RecordConfig struct.
|
||||||
@@ -26,7 +28,7 @@ func nativeToRecords(n livedns.DomainRecord, origin string) (rcs []*models.Recor
|
|||||||
switch rtype := n.RrsetType; rtype {
|
switch rtype := n.RrsetType; rtype {
|
||||||
default: // "A", "AAAA", "CAA", "NS", "CNAME", "MX", "PTR", "SRV", "TXT"
|
default: // "A", "AAAA", "CAA", "NS", "CNAME", "MX", "PTR", "SRV", "TXT"
|
||||||
if err := rc.PopulateFromString(rtype, value, origin); err != nil {
|
if err := rc.PopulateFromString(rtype, value, origin); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from gandi"))
|
panic(fmt.Errorf("unparsable record received from gandi: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rcs = append(rcs, rc)
|
rcs = append(rcs, rc)
|
||||||
|
@@ -21,15 +21,13 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
gandi "github.com/tiramiseb/go-gandi"
|
|
||||||
|
|
||||||
"github.com/miekg/dns/dnsutil"
|
"github.com/miekg/dns/dnsutil"
|
||||||
|
gandi "github.com/tiramiseb/go-gandi"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Section 1: Register this provider in the system.
|
// Section 1: Register this provider in the system.
|
||||||
@@ -74,7 +72,7 @@ func newHelper(m map[string]string, metadata json.RawMessage) (*api, error) {
|
|||||||
api := &api{}
|
api := &api{}
|
||||||
api.apikey = m["apikey"]
|
api.apikey = m["apikey"]
|
||||||
if api.apikey == "" {
|
if api.apikey == "" {
|
||||||
return nil, errors.Errorf("missing Gandi apikey")
|
return nil, fmt.Errorf("missing Gandi apikey")
|
||||||
}
|
}
|
||||||
api.sharingid = m["sharing_id"]
|
api.sharingid = m["sharing_id"]
|
||||||
debug, err := strconv.ParseBool(os.Getenv("GANDI_V5_DEBUG"))
|
debug, err := strconv.ParseBool(os.Getenv("GANDI_V5_DEBUG"))
|
||||||
@@ -239,7 +237,7 @@ func (client *api) GenerateDomainCorrections(dc *models.DomainConfig, existing m
|
|||||||
F: func() error {
|
F: func() error {
|
||||||
res, err := g.ChangeDomainRecordsWithName(domain, shortname, ns)
|
res, err := g.ChangeDomainRecordsWithName(domain, shortname, ns)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "%+v", res)
|
return fmt.Errorf("%+v: %w", res, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
@@ -262,7 +260,7 @@ func (client *api) GenerateDomainCorrections(dc *models.DomainConfig, existing m
|
|||||||
F: func() error {
|
F: func() error {
|
||||||
res, err := g.CreateDomainRecord(domain, shortname, rtype, ttl, values)
|
res, err := g.CreateDomainRecord(domain, shortname, rtype, ttl, values)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrapf(err, "%+v", res)
|
return fmt.Errorf("%+v: %w", res, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
|
@@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var features = providers.DocumentationNotes{
|
var features = providers.DocumentationNotes{
|
||||||
@@ -204,7 +203,7 @@ func nativeToRecord(set *gdns.ResourceRecordSet, rec, origin string) *models.Rec
|
|||||||
r.SetLabelFromFQDN(set.Name, origin)
|
r.SetLabelFromFQDN(set.Name, origin)
|
||||||
r.TTL = uint32(set.Ttl)
|
r.TTL = uint32(set.Ttl)
|
||||||
if err := r.PopulateFromString(set.Type, rec, origin); err != nil {
|
if err := r.PopulateFromString(set.Type, rec, origin); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from GCLOUD"))
|
panic(fmt.Errorf("unparsable record received from GCLOUD: %w", err))
|
||||||
}
|
}
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
package hexonet
|
package hexonet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
lr "github.com/hexonet/go-sdk/response/listresponse"
|
lr "github.com/hexonet/go-sdk/response/listresponse"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GetHXApiError returns an error including API error code and error description.
|
// GetHXApiError returns an error including API error code and error description.
|
||||||
func (n *HXClient) GetHXApiError(format string, objectid string, r *lr.ListResponse) error {
|
func (n *HXClient) GetHXApiError(format string, objectid string, r *lr.ListResponse) error {
|
||||||
return errors.Errorf(format+" %s. [%s %s]", objectid, r.Code(), r.Description())
|
return fmt.Errorf(format+" %s. [%s %s]", objectid, r.Code(), r.Description())
|
||||||
}
|
}
|
||||||
|
@@ -8,8 +8,6 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
)
|
)
|
||||||
@@ -121,15 +119,15 @@ func toRecord(r *HXRecord, origin string) *models.RecordConfig {
|
|||||||
rc.SetTargetTXTs(decodeTxt(r.Answer))
|
rc.SetTargetTXTs(decodeTxt(r.Answer))
|
||||||
case "MX":
|
case "MX":
|
||||||
if err := rc.SetTargetMX(uint16(r.Priority), r.Answer); err != nil {
|
if err := rc.SetTargetMX(uint16(r.Priority), r.Answer); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable MX record received from hexonet api"))
|
panic(fmt.Errorf("unparsable MX record received from hexonet api: %w", err))
|
||||||
}
|
}
|
||||||
case "SRV":
|
case "SRV":
|
||||||
if err := rc.SetTargetSRVPriorityString(uint16(r.Priority), r.Answer); err != nil {
|
if err := rc.SetTargetSRVPriorityString(uint16(r.Priority), r.Answer); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable SRV record received from hexonet api"))
|
panic(fmt.Errorf("unparsable SRV record received from hexonet api: %w", err))
|
||||||
}
|
}
|
||||||
default: // "A", "AAAA", "ANAME", "CNAME", "NS"
|
default: // "A", "AAAA", "ANAME", "CNAME", "NS"
|
||||||
if err := rc.PopulateFromString(rtype, r.Answer, r.Fqdn); err != nil {
|
if err := rc.PopulateFromString(rtype, r.Answer, r.Fqdn); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from hexonet api"))
|
panic(fmt.Errorf("unparsable record received from hexonet api: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc
|
return rc
|
||||||
|
@@ -2,7 +2,7 @@ package internetbs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/pkg/errors"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -31,7 +31,7 @@ type domainRecord struct {
|
|||||||
func (c *api) getNameservers(domain string) ([]string, error) {
|
func (c *api) getNameservers(domain string) ([]string, error) {
|
||||||
var bodyString, err = c.get("/Domain/Info", requestParams{"Domain": domain})
|
var bodyString, err = c.get("/Domain/Info", requestParams{"Domain": domain})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []string{}, errors.Errorf("Error fetching nameservers list from Internet.bs: %s", err)
|
return []string{}, fmt.Errorf("Error fetching nameservers list from Internet.bs: %s", err)
|
||||||
}
|
}
|
||||||
var dr domainRecord
|
var dr domainRecord
|
||||||
json.Unmarshal(bodyString, &dr)
|
json.Unmarshal(bodyString, &dr)
|
||||||
@@ -47,7 +47,7 @@ func (c *api) updateNameservers(ns []string, domain string) error {
|
|||||||
rec["Domain"] = domain
|
rec["Domain"] = domain
|
||||||
rec["Ns_list"] = strings.Join(ns, ",")
|
rec["Ns_list"] = strings.Join(ns, ",")
|
||||||
if _, err := c.get("/Domain/Update", rec); err != nil {
|
if _, err := c.get("/Domain/Update", rec); err != nil {
|
||||||
return errors.Errorf("Internet.ns: Error update NS : %s", err)
|
return fmt.Errorf("Internet.ns: Error update NS : %s", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -79,7 +79,7 @@ func (c *api) get(endpoint string, params requestParams) ([]byte, error) {
|
|||||||
var errResp errorResponse
|
var errResp errorResponse
|
||||||
err = json.Unmarshal(bodyString, &errResp)
|
err = json.Unmarshal(bodyString, &errResp)
|
||||||
if errResp.Status == "FAILURE" {
|
if errResp.Status == "FAILURE" {
|
||||||
return bodyString, errors.Errorf("Internet.bs API error: %s code: %d transactid: %s URL:%s%s ",
|
return bodyString, fmt.Errorf("Internet.bs API error: %s code: %d transactid: %s URL:%s%s ",
|
||||||
errResp.Message, errResp.Code, errResp.TransactID,
|
errResp.Message, errResp.Code, errResp.TransactID,
|
||||||
req.Host, req.URL.RequestURI())
|
req.Host, req.URL.RequestURI())
|
||||||
}
|
}
|
||||||
|
@@ -2,11 +2,11 @@ package internetbs
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -28,7 +28,7 @@ func newInternetBs(m map[string]string) (providers.Registrar, error) {
|
|||||||
|
|
||||||
api.key, api.password = m["api-key"], m["password"]
|
api.key, api.password = m["api-key"], m["password"]
|
||||||
if api.key == "" || api.password == "" {
|
if api.key == "" || api.password == "" {
|
||||||
return nil, errors.Errorf("missing Internet.bs api-key and password")
|
return nil, fmt.Errorf("missing Internet.bs api-key and password")
|
||||||
}
|
}
|
||||||
|
|
||||||
return api, nil
|
return api, nil
|
||||||
|
@@ -3,11 +3,10 @@ package linode
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -23,7 +22,7 @@ func (c *LinodeApi) fetchDomainList() error {
|
|||||||
dr := &domainResponse{}
|
dr := &domainResponse{}
|
||||||
endpoint := fmt.Sprintf("%s?page=%d", domainsPath, page)
|
endpoint := fmt.Sprintf("%s?page=%d", domainsPath, page)
|
||||||
if err := c.get(endpoint, dr); err != nil {
|
if err := c.get(endpoint, dr); err != nil {
|
||||||
return errors.Errorf("Error fetching domain list from Linode: %s", err)
|
return fmt.Errorf("Error fetching domain list from Linode: %s", err)
|
||||||
}
|
}
|
||||||
for _, domain := range dr.Data {
|
for _, domain := range dr.Data {
|
||||||
c.domainIndex[domain.Domain] = domain.ID
|
c.domainIndex[domain.Domain] = domain.ID
|
||||||
@@ -43,7 +42,7 @@ func (c *LinodeApi) getRecords(id int) ([]domainRecord, error) {
|
|||||||
dr := &recordResponse{}
|
dr := &recordResponse{}
|
||||||
endpoint := fmt.Sprintf("%s/%d/records?page=%d", domainsPath, id, page)
|
endpoint := fmt.Sprintf("%s/%d/records?page=%d", domainsPath, id, page)
|
||||||
if err := c.get(endpoint, dr); err != nil {
|
if err := c.get(endpoint, dr); err != nil {
|
||||||
return nil, errors.Errorf("Error fetching record list from Linode: %s", err)
|
return nil, fmt.Errorf("Error fetching record list from Linode: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
records = append(records, dr.Data...)
|
records = append(records, dr.Data...)
|
||||||
@@ -174,7 +173,7 @@ func (c *LinodeApi) handleErrors(resp *http.Response) error {
|
|||||||
errs := &errorResponse{}
|
errs := &errorResponse{}
|
||||||
|
|
||||||
if err := decoder.Decode(errs); err != nil {
|
if err := decoder.Decode(errs); err != nil {
|
||||||
return errors.Errorf("bad status code from Linode: %d not 200. Failed to decode response", resp.StatusCode)
|
return fmt.Errorf("bad status code from Linode: %d not 200. Failed to decode response", resp.StatusCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
buf := bytes.NewBufferString(fmt.Sprintf("bad status code from Linode: %d not 200", resp.StatusCode))
|
buf := bytes.NewBufferString(fmt.Sprintf("bad status code from Linode: %d not 200", resp.StatusCode))
|
||||||
|
@@ -5,19 +5,16 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/miekg/dns/dnsutil"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/miekg/dns/dnsutil"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"net/url"
|
|
||||||
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"golang.org/x/oauth2"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -64,7 +61,7 @@ var defaultNameServerNames = []string{
|
|||||||
// NewLinode creates the provider.
|
// NewLinode creates the provider.
|
||||||
func NewLinode(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
func NewLinode(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||||
if m["token"] == "" {
|
if m["token"] == "" {
|
||||||
return nil, errors.Errorf("Missing Linode token")
|
return nil, fmt.Errorf("Missing Linode token")
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
@@ -75,7 +72,7 @@ func NewLinode(m map[string]string, metadata json.RawMessage) (providers.DNSServ
|
|||||||
|
|
||||||
baseURL, err := url.Parse(defaultBaseURL)
|
baseURL, err := url.Parse(defaultBaseURL)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("Linode base URL not valid")
|
return nil, fmt.Errorf("Linode base URL not valid")
|
||||||
}
|
}
|
||||||
|
|
||||||
api := &LinodeApi{client: client, baseURL: baseURL}
|
api := &LinodeApi{client: client, baseURL: baseURL}
|
||||||
@@ -119,7 +116,7 @@ func (api *LinodeApi) GetDomainCorrections(dc *models.DomainConfig) ([]*models.C
|
|||||||
}
|
}
|
||||||
domainID, ok := api.domainIndex[dc.Name]
|
domainID, ok := api.domainIndex[dc.Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%s not listed in domains for Linode account", dc.Name)
|
return nil, fmt.Errorf("%s not listed in domains for Linode account", dc.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
records, err := api.getRecords(domainID)
|
records, err := api.getRecords(domainID)
|
||||||
@@ -277,7 +274,7 @@ func toReq(dc *models.DomainConfig, rc *models.RecordConfig) (*recordEditRequest
|
|||||||
result := srvRegexp.FindStringSubmatch(req.Name)
|
result := srvRegexp.FindStringSubmatch(req.Name)
|
||||||
|
|
||||||
if len(result) != 3 {
|
if len(result) != 3 {
|
||||||
return nil, errors.Errorf("SRV Record must match format \"_service._protocol\" not %s", req.Name)
|
return nil, fmt.Errorf("SRV Record must match format \"_service._protocol\" not %s", req.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
var serviceName, protocol string = result[1], strings.ToLower(result[2])
|
var serviceName, protocol string = result[1], strings.ToLower(result[2])
|
||||||
|
@@ -7,14 +7,13 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
nc "github.com/billputer/go-namecheap"
|
||||||
"golang.org/x/net/publicsuffix"
|
"golang.org/x/net/publicsuffix"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
"github.com/StackExchange/dnscontrol/v2/pkg/printer"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
nc "github.com/billputer/go-namecheap"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// NamecheapDefaultNs lists the default nameservers for this provider.
|
// NamecheapDefaultNs lists the default nameservers for this provider.
|
||||||
@@ -59,7 +58,7 @@ func newProvider(m map[string]string, metadata json.RawMessage) (*Namecheap, err
|
|||||||
api := &Namecheap{}
|
api := &Namecheap{}
|
||||||
api.ApiUser, api.ApiKey = m["apiuser"], m["apikey"]
|
api.ApiUser, api.ApiKey = m["apiuser"], m["apikey"]
|
||||||
if api.ApiKey == "" || api.ApiUser == "" {
|
if api.ApiKey == "" || api.ApiUser == "" {
|
||||||
return nil, errors.Errorf("missing Namecheap apikey and apiuser")
|
return nil, fmt.Errorf("missing Namecheap apikey and apiuser")
|
||||||
}
|
}
|
||||||
api.client = nc.NewClient(api.ApiUser, api.ApiKey, api.ApiUser)
|
api.client = nc.NewClient(api.ApiUser, api.ApiKey, api.ApiUser)
|
||||||
// if BaseURL is specified in creds, use that url
|
// if BaseURL is specified in creds, use that url
|
||||||
|
@@ -3,10 +3,11 @@ package namedotcom
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/namedotcom/go/namecom"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/namedotcom/go/namecom"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const defaultAPIBase = "api.name.com"
|
const defaultAPIBase = "api.name.com"
|
||||||
@@ -44,7 +45,7 @@ func newProvider(conf map[string]string) (*NameCom, error) {
|
|||||||
api.client.Server = conf["apiurl"]
|
api.client.Server = conf["apiurl"]
|
||||||
api.APIUser, api.APIKey, api.APIUrl = conf["apiuser"], conf["apikey"], conf["apiurl"]
|
api.APIUser, api.APIKey, api.APIUrl = conf["apiuser"], conf["apikey"], conf["apiurl"]
|
||||||
if api.APIKey == "" || api.APIUser == "" {
|
if api.APIKey == "" || api.APIUser == "" {
|
||||||
return nil, errors.Errorf("missing Name.com apikey or apiuser")
|
return nil, fmt.Errorf("missing Name.com apikey or apiuser")
|
||||||
}
|
}
|
||||||
if api.APIUrl == "" {
|
if api.APIUrl == "" {
|
||||||
api.APIUrl = defaultAPIBase
|
api.APIUrl = defaultAPIBase
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
package namedotcom
|
package namedotcom
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/namedotcom/go/namecom"
|
"github.com/namedotcom/go/namecom"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
@@ -89,7 +89,7 @@ func toRecord(r *namecom.Record, origin string) *models.RecordConfig {
|
|||||||
Original: r,
|
Original: r,
|
||||||
}
|
}
|
||||||
if !strings.HasSuffix(r.Fqdn, ".") {
|
if !strings.HasSuffix(r.Fqdn, ".") {
|
||||||
panic(errors.Errorf("namedotcom suddenly changed protocol. Bailing. (%v)", r.Fqdn))
|
panic(fmt.Errorf("namedotcom suddenly changed protocol. Bailing. (%v)", r.Fqdn))
|
||||||
}
|
}
|
||||||
fqdn := r.Fqdn[:len(r.Fqdn)-1]
|
fqdn := r.Fqdn[:len(r.Fqdn)-1]
|
||||||
rc.SetLabelFromFQDN(fqdn, origin)
|
rc.SetLabelFromFQDN(fqdn, origin)
|
||||||
@@ -98,15 +98,15 @@ func toRecord(r *namecom.Record, origin string) *models.RecordConfig {
|
|||||||
rc.SetTargetTXTs(decodeTxt(r.Answer))
|
rc.SetTargetTXTs(decodeTxt(r.Answer))
|
||||||
case "MX":
|
case "MX":
|
||||||
if err := rc.SetTargetMX(uint16(r.Priority), r.Answer); err != nil {
|
if err := rc.SetTargetMX(uint16(r.Priority), r.Answer); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable MX record received from ndc"))
|
panic(fmt.Errorf("unparsable MX record received from ndc: %w", err))
|
||||||
}
|
}
|
||||||
case "SRV":
|
case "SRV":
|
||||||
if err := rc.SetTargetSRVPriorityString(uint16(r.Priority), r.Answer+"."); err != nil {
|
if err := rc.SetTargetSRVPriorityString(uint16(r.Priority), r.Answer+"."); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable SRV record received from ndc"))
|
panic(fmt.Errorf("unparsable SRV record received from ndc: %w", err))
|
||||||
}
|
}
|
||||||
default: // "A", "AAAA", "ANAME", "CNAME", "NS"
|
default: // "A", "AAAA", "ANAME", "CNAME", "NS"
|
||||||
if err := rc.PopulateFromString(rtype, r.Answer, r.Fqdn); err != nil {
|
if err := rc.PopulateFromString(rtype, r.Answer, r.Fqdn); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from ndc"))
|
panic(fmt.Errorf("unparsable record received from ndc: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return rc
|
return rc
|
||||||
|
@@ -2,20 +2,16 @@ package ns1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"gopkg.in/ns1/ns1-go.v2/rest"
|
||||||
|
"gopkg.in/ns1/ns1-go.v2/rest/model/dns"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"gopkg.in/ns1/ns1-go.v2/rest"
|
|
||||||
"gopkg.in/ns1/ns1-go.v2/rest/model/dns"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var docNotes = providers.DocumentationNotes{
|
var docNotes = providers.DocumentationNotes{
|
||||||
@@ -34,7 +30,7 @@ type nsone struct {
|
|||||||
|
|
||||||
func newProvider(creds map[string]string, meta json.RawMessage) (providers.DNSServiceProvider, error) {
|
func newProvider(creds map[string]string, meta json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||||
if creds["api_token"] == "" {
|
if creds["api_token"] == "" {
|
||||||
return nil, errors.Errorf("api_token required for ns1")
|
return nil, fmt.Errorf("api_token required for ns1")
|
||||||
}
|
}
|
||||||
return &nsone{rest.NewClient(http.DefaultClient, rest.SetAPIKey(creds["api_token"]))}, nil
|
return &nsone{rest.NewClient(http.DefaultClient, rest.SetAPIKey(creds["api_token"]))}, nil
|
||||||
}
|
}
|
||||||
@@ -148,7 +144,7 @@ func convert(zr *dns.ZoneRecord, domain string) ([]*models.RecordConfig, error)
|
|||||||
switch rtype := zr.Type; rtype {
|
switch rtype := zr.Type; rtype {
|
||||||
default:
|
default:
|
||||||
if err := rec.PopulateFromString(rtype, ans, domain); err != nil {
|
if err := rec.PopulateFromString(rtype, ans, domain); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from ns1"))
|
panic(fmt.Errorf("unparsable record received from ns1: %w", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
found = append(found, rec)
|
found = append(found, rec)
|
||||||
|
@@ -31,7 +31,6 @@ import (
|
|||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/octodns/octoyaml"
|
"github.com/StackExchange/dnscontrol/v2/providers/octodns/octoyaml"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var features = providers.DocumentationNotes{
|
var features = providers.DocumentationNotes{
|
||||||
@@ -104,12 +103,12 @@ func (c *Provider) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Corr
|
|||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
zoneFileFound = false
|
zoneFileFound = false
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.Wrapf(err, "can't open %s:", zoneFileName)
|
return nil, fmt.Errorf("can't open %s:: %w", zoneFileName, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
foundRecords, err = octoyaml.ReadYaml(foundFH, dc.Name)
|
foundRecords, err = octoyaml.ReadYaml(foundFH, dc.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "can not get corrections")
|
return nil, fmt.Errorf("can not get corrections: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -9,15 +9,16 @@ data we output models.RecordConfig objects.
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math"
|
"math"
|
||||||
"reflect"
|
"reflect"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
|
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ReadYaml parses a yaml input and returns a list of RecordConfigs
|
// ReadYaml parses a yaml input and returns a list of RecordConfigs
|
||||||
@@ -27,14 +28,14 @@ func ReadYaml(r io.Reader, origin string) (models.Records, error) {
|
|||||||
// Slurp the YAML into a string.
|
// Slurp the YAML into a string.
|
||||||
ydata, err := ioutil.ReadAll(r)
|
ydata, err := ioutil.ReadAll(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "can not read yaml filehandle")
|
return nil, fmt.Errorf("can not read yaml filehandle: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unmarshal the mystery data into a structure we can relect into.
|
// Unmarshal the mystery data into a structure we can relect into.
|
||||||
var mysterydata map[string]interface{}
|
var mysterydata map[string]interface{}
|
||||||
err = yaml.Unmarshal(ydata, &mysterydata)
|
err = yaml.Unmarshal(ydata, &mysterydata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(err, "could not unmarshal yaml")
|
return nil, fmt.Errorf("could not unmarshal yaml: %w", err)
|
||||||
}
|
}
|
||||||
//fmt.Printf("ReadYaml: mysterydata == %v\n", mysterydata)
|
//fmt.Printf("ReadYaml: mysterydata == %v\n", mysterydata)
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ func ReadYaml(r io.Reader, origin string) (models.Records, error) {
|
|||||||
// value: foo.example.com.
|
// value: foo.example.com.
|
||||||
results, err = parseLeaf(results, k, v, origin)
|
results, err = parseLeaf(results, k, v, origin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return results, errors.Wrapf(err, "leaf (%v) error", v)
|
return results, fmt.Errorf("leaf (%v) error: %w", v, err)
|
||||||
}
|
}
|
||||||
case []interface{}:
|
case []interface{}:
|
||||||
// The value is a list. This means we have a label with
|
// The value is a list. This means we have a label with
|
||||||
@@ -88,15 +89,15 @@ func ReadYaml(r io.Reader, origin string) (models.Records, error) {
|
|||||||
//fmt.Printf("ReadYaml: v3=%v\n", v3)
|
//fmt.Printf("ReadYaml: v3=%v\n", v3)
|
||||||
results, err = parseLeaf(results, k, v3, origin)
|
results, err = parseLeaf(results, k, v3, origin)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return results, errors.Wrapf(err, "leaf v3=%v", v3)
|
return results, fmt.Errorf("leaf v3=%v: %w", v3, err)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("unknown type in list3: k=%s v.(type)=%T v=%v", k, v, v)
|
return nil, fmt.Errorf("unknown type in list3: k=%s v.(type)=%T v=%v", k, v, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("unknown type in list1: k=%s v.(type)=%T v=%v", k, v, v)
|
return nil, fmt.Errorf("unknown type in list1: k=%s v.(type)=%T v=%v", k, v, v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -126,7 +127,7 @@ func parseLeaf(results models.Records, k string, v interface{}, origin string) (
|
|||||||
var err error
|
var err error
|
||||||
rTTL, err = decodeTTL(v2)
|
rTTL, err = decodeTTL(v2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Errorf("parseLeaf: can not parse ttl (%v)", v2)
|
return nil, fmt.Errorf("parseLeaf: can not parse ttl (%v)", v2)
|
||||||
}
|
}
|
||||||
case "value":
|
case "value":
|
||||||
rTarget = v2.(string)
|
rTarget = v2.(string)
|
||||||
@@ -135,7 +136,7 @@ func parseLeaf(results models.Records, k string, v interface{}, origin string) (
|
|||||||
case string:
|
case string:
|
||||||
rTarget = v2.(string)
|
rTarget = v2.(string)
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("parseLeaf: unknown type in values: rtpe=%s k=%s k2=%s v2.(type)=%T v2=%v", rType, k, k2, v2, v2)
|
return nil, fmt.Errorf("parseLeaf: unknown type in values: rtpe=%s k=%s k2=%s v2.(type)=%T v2=%v", rType, k, k2, v2, v2)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic("Should not happen")
|
panic("Should not happen")
|
||||||
@@ -184,11 +185,11 @@ func parseLeaf(results models.Records, k string, v interface{}, origin string) (
|
|||||||
//fmt.Printf("parseLeaf: append %v\n", newRc)
|
//fmt.Printf("parseLeaf: append %v\n", newRc)
|
||||||
someresults = append(someresults, newRc)
|
someresults = append(someresults, newRc)
|
||||||
default:
|
default:
|
||||||
return nil, errors.Errorf("parseLeaf: unknown type in map: rtype=%s k=%s v3.(type)=%T v3=%v", rType, k, v3, v3)
|
return nil, fmt.Errorf("parseLeaf: unknown type in map: rtype=%s k=%s v3.(type)=%T v3=%v", rType, k, v3, v3)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return nil, errors.Errorf("parseLeaf: unknown type in level 2: k=%s k2=%s v.2(type)=%T v2=%v", k, k2, v2, v2)
|
return nil, fmt.Errorf("parseLeaf: unknown type in level 2: k=%s k2=%s v.2(type)=%T v2=%v", k, k2, v2, v2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// fmt.Printf("parseLeaf: Target=(%v)\n", rTarget)
|
// fmt.Printf("parseLeaf: Target=(%v)\n", rTarget)
|
||||||
@@ -259,11 +260,11 @@ func decodeTTL(ttl interface{}) (uint32, error) {
|
|||||||
case string:
|
case string:
|
||||||
s := ttl.(string)
|
s := ttl.(string)
|
||||||
t, err := strconv.ParseUint(s, 10, 32)
|
t, err := strconv.ParseUint(s, 10, 32)
|
||||||
return uint32(t), errors.Wrapf(err, "decodeTTL failed to parse (%s)", s)
|
return uint32(t), fmt.Errorf("decodeTTL failed to parse (%s): %w", s, err)
|
||||||
case int:
|
case int:
|
||||||
i := ttl.(int)
|
i := ttl.(int)
|
||||||
if i < 0 || i > math.MaxUint32 {
|
if i < 0 || i > math.MaxUint32 {
|
||||||
return 0, errors.Errorf("ttl won't fit in 32-bits (%d)", i)
|
return 0, fmt.Errorf("ttl won't fit in 32-bits (%d)", i)
|
||||||
}
|
}
|
||||||
return uint32(i), nil
|
return uint32(i), nil
|
||||||
}
|
}
|
||||||
|
@@ -8,7 +8,6 @@ import (
|
|||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/miekg/dns/dnsutil"
|
"github.com/miekg/dns/dnsutil"
|
||||||
"github.com/pkg/errors"
|
|
||||||
yaml "gopkg.in/yaml.v2"
|
yaml "gopkg.in/yaml.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -178,7 +177,7 @@ func oneLabel(records models.Records) yaml.MapItem {
|
|||||||
case "MX", "SRV":
|
case "MX", "SRV":
|
||||||
// Always processed as a complex{}
|
// Always processed as a complex{}
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("yamlwrite:oneLabel:len1 rtype not implemented: %s", rtype))
|
panic(fmt.Errorf("yamlwrite:oneLabel:len1 rtype not implemented: %s", rtype))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,7 +198,7 @@ func oneLabel(records models.Records) yaml.MapItem {
|
|||||||
case "MX", "SRV":
|
case "MX", "SRV":
|
||||||
// Always processed as a complex{}
|
// Always processed as a complex{}
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("oneLabel:many rtype not implemented: %s", rtype))
|
panic(fmt.Errorf("oneLabel:many rtype not implemented: %s", rtype))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,7 +285,7 @@ func oneType(records models.Records) interface{} {
|
|||||||
return vv
|
return vv
|
||||||
|
|
||||||
default:
|
default:
|
||||||
panic(errors.Errorf("yamlwrite:oneType rtype=%s not implemented", rtype))
|
panic(fmt.Errorf("yamlwrite:oneType rtype=%s not implemented", rtype))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/ovh/go-ovh/ovh"
|
"github.com/ovh/go-ovh/ovh"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ovhProvider struct {
|
type ovhProvider struct {
|
||||||
@@ -61,7 +60,7 @@ func init() {
|
|||||||
func (c *ovhProvider) GetNameservers(domain string) ([]*models.Nameserver, error) {
|
func (c *ovhProvider) GetNameservers(domain string) ([]*models.Nameserver, error) {
|
||||||
_, ok := c.zones[domain]
|
_, ok := c.zones[domain]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("%s not listed in zones for ovh account", domain)
|
return nil, fmt.Errorf("%s not listed in zones for ovh account", domain)
|
||||||
}
|
}
|
||||||
|
|
||||||
ns, err := c.fetchRegistrarNS(domain)
|
ns, err := c.fetchRegistrarNS(domain)
|
||||||
@@ -164,7 +163,7 @@ func nativeToRecord(r *Record, origin string) *models.RecordConfig {
|
|||||||
|
|
||||||
rec.SetLabel(r.SubDomain, origin)
|
rec.SetLabel(r.SubDomain, origin)
|
||||||
if err := rec.PopulateFromString(rtype, r.Target, origin); err != nil {
|
if err := rec.PopulateFromString(rtype, r.Target, origin); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from ovh"))
|
panic(fmt.Errorf("unparsable record received from ovh: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ovh default is 3600
|
// ovh default is 3600
|
||||||
|
@@ -6,7 +6,6 @@ import (
|
|||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/miekg/dns/dnsutil"
|
"github.com/miekg/dns/dnsutil"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Void an empty structure.
|
// Void an empty structure.
|
||||||
@@ -271,7 +270,7 @@ func (c *ovhProvider) updateNS(fqdn string, ns []string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if task.Status == "error" {
|
if task.Status == "error" {
|
||||||
return errors.Errorf("API error while updating ns for %s: %s", fqdn, task.Comment)
|
return fmt.Errorf("API error while updating ns for %s: %s", fqdn, task.Comment)
|
||||||
}
|
}
|
||||||
|
|
||||||
// we don't wait for the task execution. One of the reason is that
|
// we don't wait for the task execution. One of the reason is that
|
||||||
|
@@ -2,10 +2,10 @@ package providers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/pkg/errors"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Registrar is an interface for a domain registrar. It can return a list of needed corrections to be applied in the future. Implement this only if the provider is a "registrar" (i.e. can update the NS records of the parent to a domain).
|
// Registrar is an interface for a domain registrar. It can return a list of needed corrections to be applied in the future. Implement this only if the provider is a "registrar" (i.e. can update the NS records of the parent to a domain).
|
||||||
@@ -58,7 +58,7 @@ func RegisterDomainServiceProviderType(name string, init DspInitializer, pm ...P
|
|||||||
func CreateRegistrar(rType string, config map[string]string) (Registrar, error) {
|
func CreateRegistrar(rType string, config map[string]string) (Registrar, error) {
|
||||||
initer, ok := RegistrarTypes[rType]
|
initer, ok := RegistrarTypes[rType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("registrar type %s not declared", rType)
|
return nil, fmt.Errorf("registrar type %s not declared", rType)
|
||||||
}
|
}
|
||||||
return initer(config)
|
return initer(config)
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ func CreateRegistrar(rType string, config map[string]string) (Registrar, error)
|
|||||||
func CreateDNSProvider(dType string, config map[string]string, meta json.RawMessage) (DNSServiceProvider, error) {
|
func CreateDNSProvider(dType string, config map[string]string, meta json.RawMessage) (DNSServiceProvider, error) {
|
||||||
initer, ok := DNSProviderTypes[dType]
|
initer, ok := DNSProviderTypes[dType]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.Errorf("DSP type %s not declared", dType)
|
return nil, fmt.Errorf("DSP type %s not declared", dType)
|
||||||
}
|
}
|
||||||
return initer(config, meta)
|
return initer(config, meta)
|
||||||
}
|
}
|
||||||
|
@@ -2,20 +2,21 @@ package route53
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
|
||||||
"github.com/aws/aws-sdk-go/aws"
|
"github.com/aws/aws-sdk-go/aws"
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
"github.com/aws/aws-sdk-go/aws/session"
|
"github.com/aws/aws-sdk-go/aws/session"
|
||||||
r53 "github.com/aws/aws-sdk-go/service/route53"
|
r53 "github.com/aws/aws-sdk-go/service/route53"
|
||||||
r53d "github.com/aws/aws-sdk-go/service/route53domains"
|
r53d "github.com/aws/aws-sdk-go/service/route53domains"
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
)
|
)
|
||||||
|
|
||||||
type route53Provider struct {
|
type route53Provider struct {
|
||||||
@@ -351,7 +352,7 @@ func nativeToRecords(set *r53.ResourceRecordSet, origin string) []*models.Record
|
|||||||
rc := &models.RecordConfig{TTL: uint32(*set.TTL)}
|
rc := &models.RecordConfig{TTL: uint32(*set.TTL)}
|
||||||
rc.SetLabelFromFQDN(unescape(set.Name), origin)
|
rc.SetLabelFromFQDN(unescape(set.Name), origin)
|
||||||
if err := rc.PopulateFromString(*set.Type, *rec.Value, origin); err != nil {
|
if err := rc.PopulateFromString(*set.Type, *rec.Value, origin); err != nil {
|
||||||
panic(errors.Wrap(err, "unparsable record received from R53"))
|
panic(fmt.Errorf("unparsable record received from R53: %w", err))
|
||||||
}
|
}
|
||||||
results = append(results, rc)
|
results = append(results, rc)
|
||||||
}
|
}
|
||||||
|
@@ -6,15 +6,14 @@ import (
|
|||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
|
|
||||||
"github.com/softlayer/softlayer-go/datatypes"
|
"github.com/softlayer/softlayer-go/datatypes"
|
||||||
"github.com/softlayer/softlayer-go/filter"
|
"github.com/softlayer/softlayer-go/filter"
|
||||||
"github.com/softlayer/softlayer-go/services"
|
"github.com/softlayer/softlayer-go/services"
|
||||||
"github.com/softlayer/softlayer-go/session"
|
"github.com/softlayer/softlayer-go/session"
|
||||||
|
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SoftLayer is the protocol handle for this provider.
|
// SoftLayer is the protocol handle for this provider.
|
||||||
@@ -34,7 +33,7 @@ func newReg(conf map[string]string, _ json.RawMessage) (providers.DNSServiceProv
|
|||||||
s := session.New(conf["username"], conf["api_key"], conf["endpoint_url"], conf["timeout"])
|
s := session.New(conf["username"], conf["api_key"], conf["endpoint_url"], conf["timeout"])
|
||||||
|
|
||||||
if len(s.UserName) == 0 || len(s.APIKey) == 0 {
|
if len(s.UserName) == 0 || len(s.APIKey) == 0 {
|
||||||
return nil, errors.Errorf("SoftLayer UserName and APIKey must be provided")
|
return nil, fmt.Errorf("SoftLayer UserName and APIKey must be provided")
|
||||||
}
|
}
|
||||||
|
|
||||||
// s.Debug = true
|
// s.Debug = true
|
||||||
@@ -108,9 +107,9 @@ func (s *SoftLayer) getDomain(name *string) (*datatypes.Dns_Domain, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(domains) == 0 {
|
if len(domains) == 0 {
|
||||||
return nil, errors.Errorf("Didn't find a domain matching %s", *name)
|
return nil, fmt.Errorf("Didn't find a domain matching %s", *name)
|
||||||
} else if len(domains) > 1 {
|
} else if len(domains) > 1 {
|
||||||
return nil, errors.Errorf("Found %d domains matching %s", len(domains), *name)
|
return nil, fmt.Errorf("Found %d domains matching %s", len(domains), *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &domains[0], nil
|
return &domains[0], nil
|
||||||
@@ -205,7 +204,7 @@ func (s *SoftLayer) createRecordFunc(desired *models.RecordConfig, domain *datat
|
|||||||
result := srvRegexp.FindStringSubmatch(host)
|
result := srvRegexp.FindStringSubmatch(host)
|
||||||
|
|
||||||
if len(result) != 3 {
|
if len(result) != 3 {
|
||||||
return errors.Errorf("SRV Record must match format \"_service._protocol\" not %s", host)
|
return fmt.Errorf("SRV Record must match format \"_service._protocol\" not %s", host)
|
||||||
}
|
}
|
||||||
|
|
||||||
var serviceName, protocol string = result[1], strings.ToLower(result[2])
|
var serviceName, protocol string = result[1], strings.ToLower(result[2])
|
||||||
@@ -277,7 +276,7 @@ func (s *SoftLayer) updateRecordFunc(existing *datatypes.Dns_Domain_ResourceReco
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !changes {
|
if !changes {
|
||||||
return errors.Errorf("didn't find changes when I expect some")
|
return fmt.Errorf("didn't find changes when I expect some")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = service.Id(*existing.Id).EditObject(&updated)
|
_, err = service.Id(*existing.Id).EditObject(&updated)
|
||||||
@@ -322,7 +321,7 @@ func (s *SoftLayer) updateRecordFunc(existing *datatypes.Dns_Domain_ResourceReco
|
|||||||
// delete and recreate?
|
// delete and recreate?
|
||||||
|
|
||||||
if !changes {
|
if !changes {
|
||||||
return errors.Errorf("didn't find changes when I expect some")
|
return fmt.Errorf("didn't find changes when I expect some")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = service.Id(*existing.Id).EditObject(&updated)
|
_, err = service.Id(*existing.Id).EditObject(&updated)
|
||||||
@@ -349,7 +348,7 @@ func (s *SoftLayer) updateRecordFunc(existing *datatypes.Dns_Domain_ResourceReco
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !changes {
|
if !changes {
|
||||||
return errors.Errorf("didn't find changes when I expect some")
|
return fmt.Errorf("didn't find changes when I expect some")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = service.Id(*existing.Id).EditObject(&updated)
|
_, err = service.Id(*existing.Id).EditObject(&updated)
|
||||||
|
@@ -3,16 +3,17 @@ package vultr
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/miekg/dns/dnsutil"
|
||||||
|
"github.com/vultr/govultr"
|
||||||
|
|
||||||
"github.com/StackExchange/dnscontrol/v2/models"
|
"github.com/StackExchange/dnscontrol/v2/models"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers"
|
"github.com/StackExchange/dnscontrol/v2/providers"
|
||||||
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
"github.com/StackExchange/dnscontrol/v2/providers/diff"
|
||||||
"github.com/miekg/dns/dnsutil"
|
|
||||||
"github.com/pkg/errors"
|
|
||||||
"github.com/vultr/govultr"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -55,7 +56,7 @@ var defaultNS = []string{
|
|||||||
func NewProvider(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
func NewProvider(m map[string]string, metadata json.RawMessage) (providers.DNSServiceProvider, error) {
|
||||||
token := m["token"]
|
token := m["token"]
|
||||||
if token == "" {
|
if token == "" {
|
||||||
return nil, errors.Errorf("Vultr API token is required")
|
return nil, fmt.Errorf("Vultr API token is required")
|
||||||
}
|
}
|
||||||
|
|
||||||
client := govultr.NewClient(nil, token)
|
client := govultr.NewClient(nil, token)
|
||||||
|
Reference in New Issue
Block a user