mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2025-10-17 09:15:57 +08:00
CHORE: Fix lint warnings from golangci-lint (#3311)
This commit is contained in:
parent
b5b2873c62
commit
5dbe5e84c9
235 changed files with 1774 additions and 1589 deletions
|
@ -68,6 +68,5 @@ func generateDTSFile(funcs string) error {
|
|||
fileContent += strings.TrimRight(line, " \t") + "\n"
|
||||
}
|
||||
fileContent = strings.TrimRight(fileContent, "\n")
|
||||
os.WriteFile(join("commands", "types", "dnscontrol.d.ts"), []byte(fileContent+"\n"), 0644)
|
||||
return nil
|
||||
return os.WriteFile(join("commands", "types", "dnscontrol.d.ts"), []byte(fileContent+"\n"), 0o644)
|
||||
}
|
||||
|
|
|
@ -13,7 +13,6 @@ import (
|
|||
func generateFeatureMatrix() error {
|
||||
matrix := matrixData()
|
||||
markdownTable, err := markdownTable(matrix)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -45,7 +44,7 @@ func markdownTable(matrix *FeatureMatrix) (string, error) {
|
|||
tableData = append(tableData, tableDataRow)
|
||||
}
|
||||
|
||||
var markdownTable, err = markdown.NewTableFormatterBuilder().
|
||||
markdownTable, err := markdown.NewTableFormatterBuilder().
|
||||
Build(tableHeaders...).
|
||||
Format(tableData)
|
||||
if err != nil {
|
||||
|
@ -123,7 +122,7 @@ func matrixData() *FeatureMatrix {
|
|||
DomainModifierDnskey,
|
||||
DualHost,
|
||||
CreateDomains,
|
||||
//NoPurge,
|
||||
// NoPurge,
|
||||
GetZones,
|
||||
},
|
||||
}
|
||||
|
@ -346,7 +345,7 @@ func replaceInlineContent(
|
|||
contentBytes = []byte(content)
|
||||
contentBytes = append(contentBytes[:start], append(newContentBytes, contentBytes[end+len(endMarker):]...)...)
|
||||
|
||||
err = os.WriteFile(file, contentBytes, 0644)
|
||||
err = os.WriteFile(file, contentBytes, 0o644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func readDocFile(fPath string) (map[string]interface{}, string, error) {
|
|||
func parseFrontMatter(content string) (map[string]interface{}, string, error) {
|
||||
delimiterIndices := delimiterRegex.FindAllStringIndex(content, 2)
|
||||
if len(delimiterIndices) < 1 {
|
||||
return nil, "", fmt.Errorf("failed to parse file. Remove it and try again")
|
||||
return nil, "", errors.New("failed to parse file. Remove it and try again")
|
||||
}
|
||||
startIndex := delimiterIndices[0][0]
|
||||
endIndex := delimiterIndices[1][0]
|
||||
|
@ -126,7 +126,6 @@ func generateFunctionTypes() (string, error) {
|
|||
if err != nil {
|
||||
println("Error parsing front matter in", fPath, "error: ", err.Error())
|
||||
continue
|
||||
|
||||
}
|
||||
if frontMatter["ts_ignore"] == true {
|
||||
continue
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/StackExchange/dnscontrol/v4/providers"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/providers"
|
||||
)
|
||||
|
||||
func generateOwnersFile() error {
|
||||
|
|
|
@ -11,9 +11,8 @@ import (
|
|||
"github.com/StackExchange/dnscontrol/v4/pkg/diff2"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/js"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/printer"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// categories of commands
|
||||
|
@ -165,7 +164,7 @@ func GetDNSConfig(args GetDNSConfigArgs) (*models.DNSConfig, error) {
|
|||
// convenient access patterns. Does everything we need to prepare for the validation phase, but
|
||||
// cannot do anything that requires the credentials file yet.
|
||||
func preloadProviders(cfg *models.DNSConfig) (*models.DNSConfig, error) {
|
||||
//build name to type maps
|
||||
// build name to type maps
|
||||
cfg.RegistrarsByName = map[string]*models.RegistrarConfig{}
|
||||
cfg.DNSProvidersByName = map[string]*models.DNSProviderConfig{}
|
||||
for _, reg := range cfg.Registrars {
|
||||
|
|
|
@ -30,7 +30,9 @@ func shellCompletionCommand() *cli.Command {
|
|||
BashComplete: func(ctx *cli.Context) {
|
||||
for _, shell := range supportedShells {
|
||||
if strings.HasPrefix(shell, ctx.Args().First()) {
|
||||
ctx.App.Writer.Write([]byte(shell + "\n"))
|
||||
if _, err := ctx.App.Writer.Write([]byte(shell + "\n")); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -3,14 +3,13 @@ package commands
|
|||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"text/template"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
type shellTestDataItem struct {
|
||||
|
@ -99,7 +98,7 @@ func TestShellCompletionCommand(t *testing.T) {
|
|||
t.Fatal("expected error, but didn't get one")
|
||||
}
|
||||
|
||||
want := fmt.Sprintf("unknown shell: %s", invalidShellTestDataItem.shellName)
|
||||
want := "unknown shell: " + invalidShellTestDataItem.shellName
|
||||
got := strings.TrimSpace(appErrWriterBuffer.String())
|
||||
if diff := cmp.Diff(got, want); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
|
@ -153,7 +152,7 @@ func TestShellCompletionCommand(t *testing.T) {
|
|||
t.Fatal("expected error, but didn't get one")
|
||||
}
|
||||
|
||||
want := fmt.Sprintf("unknown shell: %s", invalidShellTestDataItem.shellPath)
|
||||
want := "unknown shell: " + invalidShellTestDataItem.shellPath
|
||||
got := strings.TrimSpace(appErrWriterBuffer.String())
|
||||
if diff := cmp.Diff(got, want); diff != "" {
|
||||
t.Errorf("mismatch (-want +got):\n%s", diff)
|
||||
|
@ -230,7 +229,7 @@ func testHelperGetShellsAndCompletionScripts() ([]shellTestDataItem, error) {
|
|||
shellsAndValues,
|
||||
shellTestDataItem{
|
||||
shellName: shellName,
|
||||
shellPath: fmt.Sprintf("/bin/%s", shellName),
|
||||
shellPath: "/bin/" + shellName,
|
||||
completionScriptTemplate: t,
|
||||
},
|
||||
)
|
||||
|
|
|
@ -66,7 +66,7 @@ func FmtFile(args FmtArgs) error {
|
|||
if args.OutputFile == "" {
|
||||
fmt.Print(beautified)
|
||||
} else {
|
||||
if err := os.WriteFile(args.OutputFile, []byte(beautified), 0744); err != nil {
|
||||
if err := os.WriteFile(args.OutputFile, []byte(beautified), 0o744); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(os.Stderr, "File %s successfully written\n", args.OutputFile)
|
||||
|
|
|
@ -2,6 +2,7 @@ package commands
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"regexp"
|
||||
|
@ -129,10 +130,10 @@ func GetCerts(args GetCertsArgs) error {
|
|||
fmt.Println(args.JSFile)
|
||||
// check agree flag
|
||||
if !args.AgreeTOS {
|
||||
return fmt.Errorf("you must agree to the Let's Encrypt Terms of Service by using -agreeTOS")
|
||||
return errors.New("you must agree to the Let's Encrypt Terms of Service by using -agreeTOS")
|
||||
}
|
||||
if args.Email == "" {
|
||||
return fmt.Errorf("must provide email to use for Let's Encrypt registration")
|
||||
return errors.New("must provide email to use for Let's Encrypt registration")
|
||||
}
|
||||
|
||||
// load dns config
|
||||
|
@ -142,7 +143,7 @@ func GetCerts(args GetCertsArgs) error {
|
|||
}
|
||||
errs := normalize.ValidateAndNormalizeConfig(cfg)
|
||||
if PrintValidationErrors(errs) {
|
||||
return fmt.Errorf("exiting due to validation errors")
|
||||
return errors.New("exiting due to validation errors")
|
||||
}
|
||||
providerConfigs, err := credsfile.LoadProviderConfigs(args.CredsFile)
|
||||
if err != nil {
|
||||
|
@ -170,7 +171,7 @@ func GetCerts(args GetCertsArgs) error {
|
|||
return err
|
||||
}
|
||||
if len(certList) == 0 {
|
||||
return fmt.Errorf("must provide at least one certificate to issue in cert configuration")
|
||||
return errors.New("must provide at least one certificate to issue in cert configuration")
|
||||
}
|
||||
if err = validateCertificateList(certList, cfg); err != nil {
|
||||
return err
|
||||
|
@ -207,7 +208,7 @@ func GetCerts(args GetCertsArgs) error {
|
|||
if manyerr == nil {
|
||||
manyerr = err
|
||||
} else {
|
||||
manyerr = fmt.Errorf("%w; %v", manyerr, err)
|
||||
manyerr = fmt.Errorf("%w; %w", manyerr, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,7 +26,7 @@ var _ = cmd(catUtils, func() *cli.Command {
|
|||
args.CredName = ctx.Args().Get(0)
|
||||
arg1 := ctx.Args().Get(1)
|
||||
args.ProviderName = arg1
|
||||
// In v4.0, skip the first args.ZoneNames if it it equals "-".
|
||||
// In v4.0, skip the first args.ZoneNames if it equals "-".
|
||||
args.ZoneNames = ctx.Args().Slice()[2:]
|
||||
|
||||
if arg1 != "" && arg1 != "-" {
|
||||
|
@ -212,7 +212,6 @@ func GetZone(args GetZoneArgs) error {
|
|||
dspVariableName := "DSP_" + strings.ToUpper(args.CredName)
|
||||
|
||||
if args.OutputFormat == "js" || args.OutputFormat == "djs" {
|
||||
|
||||
if args.ProviderName == "-" {
|
||||
fmt.Fprintf(w, `var %s = NewDnsProvider("%s");`+"\n",
|
||||
dspVariableName, args.CredName)
|
||||
|
@ -229,10 +228,11 @@ func GetZone(args GetZoneArgs) error {
|
|||
|
||||
z := prettyzone.PrettySort(recs, zoneName, 0, nil)
|
||||
switch args.OutputFormat {
|
||||
|
||||
case "zone":
|
||||
fmt.Fprintf(w, "$ORIGIN %s.\n", zoneName)
|
||||
prettyzone.WriteZoneFileRC(w, z.Records, zoneName, uint32(args.DefaultTTL), nil)
|
||||
if err := prettyzone.WriteZoneFileRC(w, z.Records, zoneName, uint32(args.DefaultTTL), nil); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintln(w)
|
||||
|
||||
case "js", "djs":
|
||||
|
@ -281,7 +281,6 @@ func GetZone(args GetZoneArgs) error {
|
|||
|
||||
case "tsv":
|
||||
for _, rec := range recs {
|
||||
|
||||
cfproxy := ""
|
||||
if cp, ok := rec.Metadata["cloudflare_proxy"]; ok {
|
||||
if cp == "true" {
|
||||
|
@ -315,7 +314,6 @@ func jsonQuoted(i string) string {
|
|||
}
|
||||
|
||||
func formatDsl(rec *models.RecordConfig, defaultTTL uint32) string {
|
||||
|
||||
target := rec.GetTargetCombined()
|
||||
|
||||
ttl := uint32(0)
|
||||
|
|
|
@ -32,7 +32,7 @@ func testFormat(t *testing.T, domain, format string) {
|
|||
expectedFilename := fmt.Sprintf("test_data/%s.zone.%s", domain, format)
|
||||
outputFiletmpl := fmt.Sprintf("%s.zone.%s.*.txt", domain, format)
|
||||
|
||||
outfile, err := os.CreateTemp("", outputFiletmpl)
|
||||
outfile, err := os.CreateTemp(t.TempDir(), outputFiletmpl)
|
||||
if err != nil {
|
||||
log.Fatal(fmt.Errorf("gz can't TempFile %q: %w", outputFiletmpl, err))
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func testFormat(t *testing.T, domain, format string) {
|
|||
|
||||
if w, g := string(want), string(got); w != g {
|
||||
// If the test fails, output a file showing "got"
|
||||
err = os.WriteFile(expectedFilename+".ACTUAL", got, 0644)
|
||||
err = os.WriteFile(expectedFilename+".ACTUAL", got, 0o644)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package commands
|
|||
import (
|
||||
"cmp"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
@ -88,7 +89,7 @@ type PPreviewArgs struct {
|
|||
}
|
||||
|
||||
// ReportItem is a record of corrections for a particular domain/provider/registrar.
|
||||
//type ReportItem struct {
|
||||
// type ReportItem struct {
|
||||
// Domain string `json:"domain"`
|
||||
// Corrections int `json:"corrections"`
|
||||
// Provider string `json:"provider,omitempty"`
|
||||
|
@ -140,8 +141,8 @@ func (args *PPreviewArgs) flags() []cli.Flag {
|
|||
Name: "reportmax",
|
||||
Hidden: true,
|
||||
Usage: `Limit the IGNORE/NO_PURGE report to this many lines (Expermental. Will change in the future.)`,
|
||||
Action: func(ctx *cli.Context, max int) error {
|
||||
printer.MaxReport = max
|
||||
Action: func(ctx *cli.Context, maxreport int) error {
|
||||
printer.MaxReport = maxreport
|
||||
return nil
|
||||
},
|
||||
})
|
||||
|
@ -220,7 +221,6 @@ var pobsoleteDiff2FlagUsed = false
|
|||
|
||||
// run is the main routine common to preview/push
|
||||
func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, report string) error {
|
||||
|
||||
// This is a hack until we have the new printer replacement.
|
||||
printer.SkinnyReport = !args.Full
|
||||
fullMode := args.Full
|
||||
|
@ -250,7 +250,7 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor
|
|||
out.PrintfIf(fullMode, "Normalizing and validating 'desired'..\n")
|
||||
errs := normalize.ValidateAndNormalizeConfig(cfg)
|
||||
if PrintValidationErrors(errs) {
|
||||
return fmt.Errorf("exiting due to validation errors")
|
||||
return errors.New("exiting due to validation errors")
|
||||
}
|
||||
|
||||
zcache := NewZoneCache()
|
||||
|
@ -312,7 +312,6 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor
|
|||
reportItems = append(reportItems, genReportItem(zone.Name, corrections, zone.RegistrarName))
|
||||
anyErrors = cmp.Or(anyErrors, pprintOrRunCorrections(zone.Name, zone.RegistrarInstance.Name, corrections, out, push, interactive, notifier, report))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if os.Getenv("TEAMCITY_VERSION") != "" {
|
||||
|
@ -323,18 +322,18 @@ func prun(args PPreviewArgs, push bool, interactive bool, out printer.CLI, repor
|
|||
out.Printf("Done. %d corrections.\n", totalCorrections)
|
||||
err = writeReport(report, reportItems)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not write report")
|
||||
return errors.New("could not write report")
|
||||
}
|
||||
if anyErrors {
|
||||
return fmt.Errorf("completed with errors")
|
||||
return errors.New("completed with errors")
|
||||
}
|
||||
if totalCorrections != 0 && args.WarnChanges {
|
||||
return fmt.Errorf("there are pending changes")
|
||||
return errors.New("there are pending changes")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
//func countActions(corrections []*models.Correction) int {
|
||||
// func countActions(corrections []*models.Correction) int {
|
||||
// r := 0
|
||||
// for _, c := range corrections {
|
||||
// if c.F != nil {
|
||||
|
@ -382,12 +381,12 @@ func splitConcurrent(domains []*models.DomainConfig, filter string) (serial []*m
|
|||
// concurrency. Otherwise false is returned.
|
||||
func allConcur(dc *models.DomainConfig) bool {
|
||||
if !providers.ProviderHasCapability(dc.RegistrarInstance.ProviderType, providers.CanConcur) {
|
||||
//fmt.Printf("WHY? %q: %+v\n", dc.Name, dc.RegistrarInstance)
|
||||
// fmt.Printf("WHY? %q: %+v\n", dc.Name, dc.RegistrarInstance)
|
||||
return false
|
||||
}
|
||||
for _, p := range dc.DNSProviderInstances {
|
||||
if !providers.ProviderHasCapability(p.ProviderType, providers.CanConcur) {
|
||||
//fmt.Printf("WHY? %q: %+v\n", dc.Name, p)
|
||||
// fmt.Printf("WHY? %q: %+v\n", dc.Name, p)
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
@ -421,7 +420,6 @@ func oneZone(zone *models.DomainConfig, args PPreviewArgs, zc *zoneCache) {
|
|||
// Loop over the (selected) providers configured for that zone:
|
||||
providersToProcess := whichProvidersToProcess(zone.DNSProviderInstances, args.Providers)
|
||||
for _, provider := range providersToProcess {
|
||||
|
||||
// Populate the zones at the provider (if desired/needed/able):
|
||||
if !args.NoPopulate {
|
||||
populateCorrections := generatePopulateCorrections(provider, zone.Name, zc)
|
||||
|
@ -441,7 +439,6 @@ func oneZone(zone *models.DomainConfig, args PPreviewArgs, zc *zoneCache) {
|
|||
}
|
||||
|
||||
func whichProvidersToProcess(providers []*models.DNSProviderInstance, filter string) []*models.DNSProviderInstance {
|
||||
|
||||
if filter == "all" { // all
|
||||
return providers
|
||||
}
|
||||
|
@ -477,7 +474,6 @@ func skipProvider(name string, providers []*models.DNSProviderInstance) bool {
|
|||
}
|
||||
|
||||
func genReportItem(zname string, corrections []*models.Correction, pname string) *ReportItem {
|
||||
|
||||
// Only count the actions, not the messages.
|
||||
cnt := 0
|
||||
for _, cor := range corrections {
|
||||
|
@ -502,7 +498,6 @@ func pprintOrRunCorrections(zoneName string, providerName string, corrections []
|
|||
cc := 0
|
||||
cn := 0
|
||||
for _, correction := range corrections {
|
||||
|
||||
// Print what we're about to do.
|
||||
if correction.F == nil {
|
||||
out.PrintReport(cn, correction)
|
||||
|
@ -514,7 +509,6 @@ func pprintOrRunCorrections(zoneName string, providerName string, corrections []
|
|||
|
||||
var err error
|
||||
if push {
|
||||
|
||||
// If interactive, ask "are you sure?" and skip if not.
|
||||
if interactive && !out.PromptToRun() {
|
||||
continue
|
||||
|
@ -542,7 +536,7 @@ func writeReport(report string, reportItems []*ReportItem) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(report, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
f, err := os.OpenFile(report, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -558,7 +552,6 @@ func writeReport(report string, reportItems []*ReportItem) error {
|
|||
}
|
||||
|
||||
func generatePopulateCorrections(provider *models.DNSProviderInstance, zoneName string, zcache *zoneCache) []*models.Correction {
|
||||
|
||||
lister, ok := provider.Driver.(providers.ZoneLister)
|
||||
if !ok {
|
||||
return nil // We can't generate a list. No corrections are possible.
|
||||
|
@ -595,7 +588,7 @@ func generateZoneCorrections(zone *models.DomainConfig, provider *models.DNSProv
|
|||
}
|
||||
|
||||
func generateDelegationCorrections(zone *models.DomainConfig, providers []*models.DNSProviderInstance, _ *models.RegistrarInstance) ([]*models.Correction, int) {
|
||||
//fmt.Printf("DEBUG: generateDelegationCorrections start zone=%q nsList = %v\n", zone.Name, zone.Nameservers)
|
||||
// fmt.Printf("DEBUG: generateDelegationCorrections start zone=%q nsList = %v\n", zone.Name, zone.Nameservers)
|
||||
nsList, err := nameservers.DetermineNameserversForProviders(zone, providers, true)
|
||||
if err != nil {
|
||||
return msg(fmt.Sprintf("DetermineNS: zone %q; Error: %s", zone.Name, err)), 0
|
||||
|
@ -645,7 +638,7 @@ func PInitializeProviders(cfg *models.DNSConfig, providerConfigs map[string]map[
|
|||
fmt.Fprintln(os.Stderr, strings.Join(msgs, "\n"))
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
return notify, err
|
||||
}
|
||||
|
||||
registrars := map[string]providers.Registrar{}
|
||||
|
@ -674,7 +667,7 @@ func PInitializeProviders(cfg *models.DNSConfig, providerConfigs map[string]map[
|
|||
pInst.IsDefault = !isNonDefault[pInst.Name]
|
||||
}
|
||||
}
|
||||
return
|
||||
return notify, err
|
||||
}
|
||||
|
||||
// pproviderTypeFieldName is the name of the field in creds.json that specifies the provider type id.
|
||||
|
@ -765,7 +758,6 @@ func puniqueStrings(stringSlice []string) []string {
|
|||
}
|
||||
|
||||
func prefineProviderType(credEntryName string, t string, credFields map[string]string, source string) (replacementType string, warnMsg string, err error) {
|
||||
|
||||
// t="" and t="-" are processed the same. Standardize on "-" to reduce the number of cases to check.
|
||||
if t == "" {
|
||||
t = "-"
|
||||
|
@ -778,7 +770,7 @@ func prefineProviderType(credEntryName string, t string, credFields map[string]s
|
|||
// - or "" GANDI lookup worked. Nothing to say.
|
||||
// - or "" - or "" ERROR "creds.json has invalid or missing data"
|
||||
// GANDI "" WARNING "Working but.... Please fix as follows..."
|
||||
// GANDI GANDI INFO "working but unneeded: clean up as follows..."
|
||||
// GANDI INFO "working but unneeded: clean up as follows..."
|
||||
// GANDI NAMEDOT ERROR "error mismatched: please fix as follows..."
|
||||
|
||||
// ERROR: Invalid.
|
||||
|
@ -869,5 +861,4 @@ func prefineProviderType(credEntryName string, t string, credFields map[string]s
|
|||
// use the value in creds.json (this should be the normal case)
|
||||
return ct, "", nil
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,13 +2,12 @@ package commands
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"golang.org/x/net/idna"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/credsfile"
|
||||
"github.com/StackExchange/dnscontrol/v4/pkg/nameservers"
|
||||
|
@ -19,6 +18,7 @@ import (
|
|||
"github.com/StackExchange/dnscontrol/v4/pkg/zonerecs"
|
||||
"github.com/StackExchange/dnscontrol/v4/providers"
|
||||
"golang.org/x/exp/slices"
|
||||
"golang.org/x/net/idna"
|
||||
)
|
||||
|
||||
// ReportItem is a record of corrections for a particular domain/provider/registrar.
|
||||
|
@ -67,7 +67,7 @@ func run(args PPreviewArgs, push bool, interactive bool, out printer.CLI, report
|
|||
|
||||
errs := normalize.ValidateAndNormalizeConfig(cfg)
|
||||
if PrintValidationErrors(errs) {
|
||||
return fmt.Errorf("exiting due to validation errors")
|
||||
return errors.New("exiting due to validation errors")
|
||||
}
|
||||
anyErrors := false
|
||||
totalCorrections := 0
|
||||
|
@ -112,8 +112,8 @@ func run(args PPreviewArgs, push bool, interactive bool, out printer.CLI, report
|
|||
aceZoneName, _ := idna.ToASCII(domain.Name)
|
||||
|
||||
if !slices.Contains(zones, aceZoneName) {
|
||||
//out.Warnf("DEBUG: zones: %v\n", zones)
|
||||
//out.Warnf("DEBUG: Name: %v\n", domain.Name)
|
||||
// out.Warnf("DEBUG: zones: %v\n", zones)
|
||||
// out.Warnf("DEBUG: Name: %v\n", domain.Name)
|
||||
|
||||
out.Warnf("Zone '%s' does not exist in the '%s' profile and will be added automatically.\n", domain.Name, provider.Name)
|
||||
continue // continue with next provider, as we can not determine corrections without an existing zone
|
||||
|
@ -141,7 +141,6 @@ func run(args PPreviewArgs, push bool, interactive bool, out printer.CLI, report
|
|||
nameservers.AddNSRecords(domain)
|
||||
|
||||
for _, provider := range providersWithExistingZone {
|
||||
|
||||
shouldrun := args.shouldRunProvider(provider.Name, domain)
|
||||
out.StartDNSProvider(provider.Name, !shouldrun)
|
||||
if !shouldrun {
|
||||
|
@ -199,13 +198,13 @@ func run(args PPreviewArgs, push bool, interactive bool, out printer.CLI, report
|
|||
notifier.Done()
|
||||
out.Printf("Done. %d corrections.\n", totalCorrections)
|
||||
if anyErrors {
|
||||
return fmt.Errorf("completed with errors")
|
||||
return errors.New("completed with errors")
|
||||
}
|
||||
if totalCorrections != 0 && args.WarnChanges {
|
||||
return fmt.Errorf("there are pending changes")
|
||||
return errors.New("there are pending changes")
|
||||
}
|
||||
if report != nil && *report != "" {
|
||||
f, err := os.OpenFile(*report, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0644)
|
||||
f, err := os.OpenFile(*report, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0o644)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -245,7 +244,7 @@ func InitializeProviders(cfg *models.DNSConfig, providerConfigs map[string]map[s
|
|||
fmt.Fprintln(os.Stderr, strings.Join(msgs, "\n"))
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
return notify, err
|
||||
}
|
||||
|
||||
registrars := map[string]providers.Registrar{}
|
||||
|
@ -274,7 +273,7 @@ func InitializeProviders(cfg *models.DNSConfig, providerConfigs map[string]map[s
|
|||
pInst.IsDefault = !isNonDefault[pInst.Name]
|
||||
}
|
||||
}
|
||||
return
|
||||
return notify, err
|
||||
}
|
||||
|
||||
// providerTypeFieldName is the name of the field in creds.json that specifies the provider type id.
|
||||
|
@ -364,7 +363,6 @@ func uniqueStrings(stringSlice []string) []string {
|
|||
}
|
||||
|
||||
func refineProviderType(credEntryName string, t string, credFields map[string]string, source string) (replacementType string, warnMsg string, err error) {
|
||||
|
||||
// t="" and t="-" are processed the same. Standardize on "-" to reduce the number of cases to check.
|
||||
if t == "" {
|
||||
t = "-"
|
||||
|
@ -377,7 +375,7 @@ func refineProviderType(credEntryName string, t string, credFields map[string]st
|
|||
// - or "" GANDI lookup worked. Nothing to say.
|
||||
// - or "" - or "" ERROR "creds.json has invalid or missing data"
|
||||
// GANDI "" WARNING "Working but.... Please fix as follows..."
|
||||
// GANDI GANDI INFO "working but unneeded: clean up as follows..."
|
||||
// GANDI INFO "working but unneeded: clean up as follows..."
|
||||
// GANDI NAMEDOT ERROR "error mismatched: please fix as follows..."
|
||||
|
||||
// ERROR: Invalid.
|
||||
|
@ -468,7 +466,6 @@ func refineProviderType(credEntryName string, t string, credFields map[string]st
|
|||
// use the value in creds.json (this should be the normal case)
|
||||
return ct, "", nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func printOrRunCorrections(domain string, provider string, corrections []*models.Correction, out printer.CLI, push bool, interactive bool, notifier notifications.Notifier) (anyErrors bool) {
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
)
|
||||
|
||||
func Test_refineProviderType(t *testing.T) {
|
||||
|
||||
var mapEmpty map[string]string
|
||||
mapTypeMissing := map[string]string{"otherfield": "othervalue"}
|
||||
mapTypeFoo := map[string]string{"TYPE": "FOO"}
|
||||
|
|
|
@ -2,6 +2,7 @@ package commands
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
@ -42,7 +43,6 @@ var _ = cmd(catDebug, func() *cli.Command {
|
|||
Name: "check",
|
||||
Usage: "Check and validate dnsconfig.js. Output to stdout. Do not access providers.",
|
||||
Action: func(c *cli.Context) error {
|
||||
|
||||
// Create a PrintIRArgs struct and copy our args to the
|
||||
// appropriate fields.
|
||||
var pargs PrintIRArgs
|
||||
|
@ -96,7 +96,7 @@ func PrintIR(args PrintIRArgs) error {
|
|||
if !args.Raw {
|
||||
errs := normalize.ValidateAndNormalizeConfig(cfg)
|
||||
if PrintValidationErrors(errs) {
|
||||
return fmt.Errorf("exiting due to validation errors")
|
||||
return errors.New("exiting due to validation errors")
|
||||
}
|
||||
}
|
||||
return PrintJSON(args.PrintJSONArgs, cfg)
|
||||
|
@ -122,7 +122,7 @@ func PrintValidationErrors(errs []error) (fatal bool) {
|
|||
// ExecuteDSL executes the dnsconfig.js contents.
|
||||
func ExecuteDSL(args ExecuteDSLArgs) (*models.DNSConfig, error) {
|
||||
if args.JSFile == "" {
|
||||
return nil, fmt.Errorf("no config specified")
|
||||
return nil, errors.New("no config specified")
|
||||
}
|
||||
|
||||
dnsConfig, err := js.ExecuteJavaScript(args.JSFile, args.DevMode, stringSliceToMap(args.Variable))
|
||||
|
|
|
@ -13,7 +13,7 @@ func TestR53Test_1(t *testing.T) {
|
|||
Name: "foo",
|
||||
NameFQDN: "foo.domain.tld",
|
||||
}
|
||||
rec.SetTarget("bar")
|
||||
rec.MustSetTarget("bar")
|
||||
rec.R53Alias = make(map[string]string)
|
||||
rec.R53Alias["type"] = "A"
|
||||
w := `R53_ALIAS("foo", "A", "bar")`
|
||||
|
@ -28,7 +28,7 @@ func TestR53Test_1ttl(t *testing.T) {
|
|||
Name: "foo",
|
||||
NameFQDN: "foo.domain.tld",
|
||||
}
|
||||
rec.SetTarget("bar")
|
||||
rec.MustSetTarget("bar")
|
||||
rec.R53Alias = make(map[string]string)
|
||||
rec.R53Alias["type"] = "A"
|
||||
w := `R53_ALIAS("foo", "A", "bar", TTL(321))`
|
||||
|
@ -43,7 +43,7 @@ func TestR53Test_2(t *testing.T) {
|
|||
Name: "foo",
|
||||
NameFQDN: "foo.domain.tld",
|
||||
}
|
||||
rec.SetTarget("bar")
|
||||
rec.MustSetTarget("bar")
|
||||
rec.R53Alias = make(map[string]string)
|
||||
rec.R53Alias["type"] = "A"
|
||||
rec.R53Alias["zone_id"] = "blarg"
|
||||
|
@ -59,7 +59,7 @@ func TestR53Test_2ttl(t *testing.T) {
|
|||
Name: "foo",
|
||||
NameFQDN: "foo.domain.tld",
|
||||
}
|
||||
rec.SetTarget("bar")
|
||||
rec.MustSetTarget("bar")
|
||||
rec.R53Alias = make(map[string]string)
|
||||
rec.R53Alias["type"] = "A"
|
||||
rec.R53Alias["zone_id"] = "blarg"
|
||||
|
@ -75,7 +75,7 @@ func TestR53Test_3(t *testing.T) {
|
|||
Name: "foo",
|
||||
NameFQDN: "foo.domain.tld",
|
||||
}
|
||||
rec.SetTarget("bar")
|
||||
rec.MustSetTarget("bar")
|
||||
rec.R53Alias = make(map[string]string)
|
||||
rec.R53Alias["type"] = "A"
|
||||
rec.R53Alias["evaluate_target_health"] = "true"
|
||||
|
@ -91,7 +91,7 @@ func TestR53Test_3ttl(t *testing.T) {
|
|||
Name: "foo",
|
||||
NameFQDN: "foo.domain.tld",
|
||||
}
|
||||
rec.SetTarget("bar")
|
||||
rec.MustSetTarget("bar")
|
||||
rec.R53Alias = make(map[string]string)
|
||||
rec.R53Alias["type"] = "A"
|
||||
rec.R53Alias["evaluate_target_health"] = "true"
|
||||
|
@ -107,7 +107,7 @@ func TestR53Test_4(t *testing.T) {
|
|||
Name: "foo",
|
||||
NameFQDN: "foo.domain.tld",
|
||||
}
|
||||
rec.SetTarget("bar")
|
||||
rec.MustSetTarget("bar")
|
||||
rec.R53Alias = make(map[string]string)
|
||||
rec.R53Alias["type"] = "A"
|
||||
rec.R53Alias["zone_id"] = "blarg"
|
||||
|
@ -124,7 +124,7 @@ func TestR53Test_4ttl(t *testing.T) {
|
|||
Name: "foo",
|
||||
NameFQDN: "foo.domain.tld",
|
||||
}
|
||||
rec.SetTarget("bar")
|
||||
rec.MustSetTarget("bar")
|
||||
rec.R53Alias = make(map[string]string)
|
||||
rec.R53Alias["type"] = "A"
|
||||
rec.R53Alias["zone_id"] = "blarg"
|
||||
|
|
|
@ -52,10 +52,18 @@ func WriteTypes(args TypesArgs) error {
|
|||
}
|
||||
defer file.Close()
|
||||
|
||||
file.WriteString("// This file was automatically generated by DNSControl. Do not edit it directly.\n")
|
||||
file.WriteString("// To update it, run `dnscontrol write-types`.\n\n")
|
||||
file.WriteString("// " + version + "\n")
|
||||
file.WriteString(dtsContent)
|
||||
if _, err := file.WriteString("// This file was automatically generated by DNSControl. Do not edit it directly.\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := file.WriteString("// To update it, run `dnscontrol write-types`.\n\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := file.WriteString("// " + version + "\n"); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := file.WriteString(dtsContent); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
print("Successfully wrote " + args.DTSFile + "\n")
|
||||
return nil
|
||||
|
|
|
@ -2,6 +2,7 @@ package main
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
|
@ -20,14 +21,16 @@ import (
|
|||
"github.com/miekg/dns/dnsutil"
|
||||
)
|
||||
|
||||
var providerFlag = flag.String("provider", "", "Provider to run (if empty, deduced from -profile)")
|
||||
var profileFlag = flag.String("profile", "", "Entry in profiles.json to use (if empty, copied from -provider)")
|
||||
var startIdx = flag.Int("start", -1, "Test number to begin with")
|
||||
var endIdx = flag.Int("end", -1, "Test index to stop after")
|
||||
var verbose = flag.Bool("verbose", false, "Print corrections as you run them")
|
||||
var printElapsed = flag.Bool("elapsed", false, "Print elapsed time for each testgroup")
|
||||
var enableCFWorkers = flag.Bool("cfworkers", true, "Set false to disable CF worker tests")
|
||||
var enableCFRedirectMode = flag.String("cfredirect", "", "cloudflare pagerule tests: default=page_rules, c=convert old to enw, n=new-style, o=none")
|
||||
var (
|
||||
providerFlag = flag.String("provider", "", "Provider to run (if empty, deduced from -profile)")
|
||||
profileFlag = flag.String("profile", "", "Entry in profiles.json to use (if empty, copied from -provider)")
|
||||
startIdx = flag.Int("start", -1, "Test number to begin with")
|
||||
endIdx = flag.Int("end", -1, "Test index to stop after")
|
||||
verbose = flag.Bool("verbose", false, "Print corrections as you run them")
|
||||
printElapsed = flag.Bool("elapsed", false, "Print elapsed time for each testgroup")
|
||||
enableCFWorkers = flag.Bool("cfworkers", true, "Set false to disable CF worker tests")
|
||||
enableCFRedirectMode = flag.String("cfredirect", "", "cloudflare pagerule tests: default=page_rules, c=convert old to enw, n=new-style, o=none")
|
||||
)
|
||||
|
||||
func init() {
|
||||
testing.Init()
|
||||
|
@ -47,6 +50,12 @@ func CfCProxyFull() *TestCase { return tc("cproxyf", cfProxyCNAME("cproxy", "exa
|
|||
|
||||
// ---
|
||||
|
||||
func panicOnErr(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func getProvider(t *testing.T) (providers.DNSServiceProvider, string, map[string]string) {
|
||||
if *providerFlag == "" && *profileFlag == "" {
|
||||
t.Log("No -provider or -profile specified")
|
||||
|
@ -97,7 +106,7 @@ func getProvider(t *testing.T) (providers.DNSServiceProvider, string, map[string
|
|||
*providerFlag = profileType
|
||||
}
|
||||
|
||||
//fmt.Printf("DEBUG flag=%q Profile=%q TYPE=%q\n", *providerFlag, profileName, profileType)
|
||||
// fmt.Printf("DEBUG flag=%q Profile=%q TYPE=%q\n", *providerFlag, profileName, profileType)
|
||||
fmt.Printf("Testing Profile=%q TYPE=%q\n", profileName, profileType)
|
||||
|
||||
var metadata json.RawMessage
|
||||
|
@ -152,7 +161,6 @@ func TestDNSProviders(t *testing.T) {
|
|||
t.Run(domain, func(t *testing.T) {
|
||||
runTests(t, provider, domain, cfg)
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func getDomainConfigWithNameservers(t *testing.T, prv providers.DNSServiceProvider, domainName string) *models.DomainConfig {
|
||||
|
@ -174,10 +182,9 @@ func getDomainConfigWithNameservers(t *testing.T, prv providers.DNSServiceProvid
|
|||
// testPermitted returns nil if the test is permitted, otherwise an
|
||||
// error explaining why it is not.
|
||||
func testPermitted(p string, f TestGroup) error {
|
||||
|
||||
// not() and only() can't be mixed.
|
||||
if len(f.only) != 0 && len(f.not) != 0 {
|
||||
return fmt.Errorf("invalid filter: can't mix not() and only()")
|
||||
return errors.New("invalid filter: can't mix not() and only()")
|
||||
}
|
||||
// TODO(tlim): Have a separate validation pass so that such mistakes
|
||||
// are more visible?
|
||||
|
@ -205,7 +212,7 @@ func testPermitted(p string, f TestGroup) error {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
return fmt.Errorf("disabled by only")
|
||||
return errors.New("disabled by only")
|
||||
}
|
||||
|
||||
// If there are any "not" items, you must NOT be one of them.
|
||||
|
@ -238,7 +245,7 @@ func makeChanges(t *testing.T, prv providers.DNSServiceProvider, dc *models.Doma
|
|||
if strings.Contains(rc.GetLabelFQDN(), "**current-domain**") {
|
||||
rc.SetLabelFromFQDN(strings.Replace(rc.GetLabelFQDN(), "**current-domain**", domainName, 1), domainName)
|
||||
}
|
||||
//if providers.ProviderHasCapability(*providerToRun, providers.CanUseAzureAlias) {
|
||||
// if providers.ProviderHasCapability(*providerToRun, providers.CanUseAzureAlias) {
|
||||
if strings.Contains(rc.GetTargetField(), "**subscription-id**") {
|
||||
_ = rc.SetTarget(strings.Replace(rc.GetTargetField(), "**subscription-id**", origConfig["SubscriptionID"], 1))
|
||||
}
|
||||
|
@ -315,7 +322,6 @@ func makeChanges(t *testing.T, prv providers.DNSServiceProvider, dc *models.Doma
|
|||
}
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -334,7 +340,6 @@ func runTests(t *testing.T, prv providers.DNSServiceProvider, domainName string,
|
|||
|
||||
curGroup := -1
|
||||
for gIdx, group := range testGroups {
|
||||
|
||||
// Abide by -start -end flags
|
||||
curGroup++
|
||||
if curGroup < firstGroup || curGroup > lastGroup {
|
||||
|
@ -342,9 +347,9 @@ func runTests(t *testing.T, prv providers.DNSServiceProvider, domainName string,
|
|||
}
|
||||
|
||||
// Abide by filter
|
||||
//fmt.Printf("DEBUG testPermitted: prov=%q profile=%q\n", *providerFlag, *profileFlag)
|
||||
// fmt.Printf("DEBUG testPermitted: prov=%q profile=%q\n", *providerFlag, *profileFlag)
|
||||
if err := testPermitted(*profileFlag, *group); err != nil {
|
||||
//t.Logf("%s: ***SKIPPED(%v)***", group.Desc, err)
|
||||
// t.Logf("%s: ***SKIPPED(%v)***", group.Desc, err)
|
||||
makeChanges(t, prv, dc, tc("Empty"), fmt.Sprintf("%02d:%s ***SKIPPED(%v)***", gIdx, group.Desc, err), false, origConfig)
|
||||
continue
|
||||
}
|
||||
|
@ -356,7 +361,6 @@ func runTests(t *testing.T, prv providers.DNSServiceProvider, domainName string,
|
|||
start := time.Now()
|
||||
|
||||
for _, tst := range group.tests {
|
||||
|
||||
// TODO(tlim): This is the old version. It skipped the remaining tc() statements if one failed.
|
||||
// The new code continues to test the remaining tc() statements. Keeping this as a comment
|
||||
// in case we ever want to do something similar.
|
||||
|
@ -368,16 +372,13 @@ func runTests(t *testing.T, prv providers.DNSServiceProvider, domainName string,
|
|||
if ok := makeChanges(t, prv, dc, tst, fmt.Sprintf("%02d:%s", gIdx, group.Desc), true, origConfig); !ok {
|
||||
break
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
elapsed := time.Since(start)
|
||||
if *printElapsed {
|
||||
fmt.Printf("ELAPSED %02d %7.2f %q\n", gIdx, elapsed.Seconds(), group.Desc)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestDualProviders(t *testing.T) {
|
||||
|
@ -474,7 +475,7 @@ func TestNameserverDots(t *testing.T) {
|
|||
|
||||
t.Run("No trailing dot in nameserver", func(t *testing.T) {
|
||||
for _, nameserver := range dc.Nameservers {
|
||||
//fmt.Printf("DEBUG: nameserver.Name = %q\n", nameserver.Name)
|
||||
// fmt.Printf("DEBUG: nameserver.Name = %q\n", nameserver.Name)
|
||||
if strings.HasSuffix(nameserver.Name, ".") {
|
||||
t.Errorf("Provider returned nameserver with trailing dot: %q", nameserver)
|
||||
}
|
||||
|
@ -543,7 +544,7 @@ func azureAlias(name, aliasType, target string) *models.RecordConfig {
|
|||
|
||||
func caa(name string, tag string, flag uint8, target string) *models.RecordConfig {
|
||||
r := makeRec(name, target, "CAA")
|
||||
r.SetTargetCAA(flag, tag, target)
|
||||
panicOnErr(r.SetTargetCAA(flag, tag, target))
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -567,10 +568,7 @@ func cfSingleRedirectEnabled() bool {
|
|||
|
||||
func cfSingleRedirect(name string, code any, when, then string) *models.RecordConfig {
|
||||
r := makeRec("@", name, cfsingleredirect.SINGLEREDIRECT)
|
||||
err := cfsingleredirect.FromRaw(r, []any{name, code, when, then})
|
||||
if err != nil {
|
||||
panic("Should not happen... cfSingleRedirect")
|
||||
}
|
||||
panicOnErr(cfsingleredirect.FromRaw(r, []any{name, code, when, then})) // Should not happen
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -606,13 +604,13 @@ func dname(name, target string) *models.RecordConfig {
|
|||
|
||||
func ds(name string, keyTag uint16, algorithm, digestType uint8, digest string) *models.RecordConfig {
|
||||
r := makeRec(name, "", "DS")
|
||||
r.SetTargetDS(keyTag, algorithm, digestType, digest)
|
||||
panicOnErr(r.SetTargetDS(keyTag, algorithm, digestType, digest))
|
||||
return r
|
||||
}
|
||||
|
||||
func dnskey(name string, flags uint16, protocol, algorithm uint8, publicKey string) *models.RecordConfig {
|
||||
r := makeRec(name, "", "DNSKEY")
|
||||
r.SetTargetDNSKEY(flags, protocol, algorithm, publicKey)
|
||||
panicOnErr(r.SetTargetDNSKEY(flags, protocol, algorithm, publicKey))
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -644,9 +642,10 @@ func ignore(labelSpec string, typeSpec string, targetSpec string) *models.Record
|
|||
}
|
||||
|
||||
func loc(name string, d1 uint8, m1 uint8, s1 float32, ns string,
|
||||
d2 uint8, m2 uint8, s2 float32, ew string, al float32, sz float32, hp float32, vp float32) *models.RecordConfig {
|
||||
d2 uint8, m2 uint8, s2 float32, ew string, al float32, sz float32, hp float32, vp float32,
|
||||
) *models.RecordConfig {
|
||||
r := makeRec(name, "", "LOC")
|
||||
r.SetLOCParams(d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
|
||||
panicOnErr(r.SetLOCParams(d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp))
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -656,13 +655,13 @@ func makeRec(name, target, typ string) *models.RecordConfig {
|
|||
TTL: 300,
|
||||
}
|
||||
SetLabel(r, name, "**current-domain**")
|
||||
r.SetTarget(target)
|
||||
r.MustSetTarget(target)
|
||||
return r
|
||||
}
|
||||
|
||||
func manyA(namePattern, target string, n int) []*models.RecordConfig {
|
||||
recs := []*models.RecordConfig{}
|
||||
for i := 0; i < n; i++ {
|
||||
for i := range n {
|
||||
recs = append(recs, makeRec(fmt.Sprintf(namePattern, i), target, "A"))
|
||||
}
|
||||
return recs
|
||||
|
@ -680,7 +679,7 @@ func ns(name, target string) *models.RecordConfig {
|
|||
|
||||
func naptr(name string, order uint16, preference uint16, flags string, service string, regexp string, target string) *models.RecordConfig {
|
||||
r := makeRec(name, target, "NAPTR")
|
||||
r.SetTargetNAPTR(order, preference, flags, service, regexp, target)
|
||||
panicOnErr(r.SetTargetNAPTR(order, preference, flags, service, regexp, target))
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -699,19 +698,19 @@ func r53alias(name, aliasType, target, evalTargetHealth string) *models.RecordCo
|
|||
|
||||
func soa(name string, ns, mbox string, serial, refresh, retry, expire, minttl uint32) *models.RecordConfig {
|
||||
r := makeRec(name, "", "SOA")
|
||||
r.SetTargetSOA(ns, mbox, serial, refresh, retry, expire, minttl)
|
||||
panicOnErr(r.SetTargetSOA(ns, mbox, serial, refresh, retry, expire, minttl))
|
||||
return r
|
||||
}
|
||||
|
||||
func srv(name string, priority, weight, port uint16, target string) *models.RecordConfig {
|
||||
r := makeRec(name, target, "SRV")
|
||||
r.SetTargetSRV(priority, weight, port, target)
|
||||
panicOnErr(r.SetTargetSRV(priority, weight, port, target))
|
||||
return r
|
||||
}
|
||||
|
||||
func sshfp(name string, algorithm uint8, fingerprint uint8, target string) *models.RecordConfig {
|
||||
r := makeRec(name, target, "SSHFP")
|
||||
r.SetTargetSSHFP(algorithm, fingerprint, target)
|
||||
panicOnErr(r.SetTargetSSHFP(algorithm, fingerprint, target))
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -738,7 +737,7 @@ func makeOvhNativeRecord(name, target, rType string) *models.RecordConfig {
|
|||
r := makeRec(name, "", "TXT")
|
||||
r.Metadata = make(map[string]string)
|
||||
r.Metadata["create_ovh_native_record"] = rType
|
||||
r.SetTarget(target)
|
||||
r.MustSetTarget(target)
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -807,7 +806,7 @@ func tc(desc string, recs ...*models.RecordConfig) *TestCase {
|
|||
|
||||
func txt(name, target string) *models.RecordConfig {
|
||||
r := makeRec(name, "", "TXT")
|
||||
r.SetTargetTXT(target)
|
||||
panicOnErr(r.SetTargetTXT(target))
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -819,7 +818,7 @@ func ttl(r *models.RecordConfig, t uint32) *models.RecordConfig {
|
|||
|
||||
func tlsa(name string, usage, selector, matchingtype uint8, target string) *models.RecordConfig {
|
||||
r := makeRec(name, target, "TLSA")
|
||||
r.SetTargetTLSA(usage, selector, matchingtype, target)
|
||||
panicOnErr(r.SetTargetTLSA(usage, selector, matchingtype, target))
|
||||
return r
|
||||
}
|
||||
|
||||
|
@ -832,7 +831,7 @@ func porkbunUrlfwd(name, target, t, includePath, wildcard string) *models.Record
|
|||
return r
|
||||
}
|
||||
|
||||
func clear() *TestCase {
|
||||
func tcEmptyZone() *TestCase {
|
||||
return tc("Empty")
|
||||
}
|
||||
|
||||
|
@ -871,7 +870,6 @@ func alltrue(f ...bool) alltrueFilter {
|
|||
//
|
||||
|
||||
func makeTests() []*TestGroup {
|
||||
|
||||
sha256hash := strings.Repeat("0123456789abcdef", 4)
|
||||
sha512hash := strings.Repeat("0123456789abcdef", 8)
|
||||
reversedSha512 := strings.Repeat("fedcba9876543210", 8)
|
||||
|
@ -906,12 +904,11 @@ func makeTests() []*TestGroup {
|
|||
// whether or not a certain kind of record can be created and
|
||||
// deleted.
|
||||
|
||||
// clear() is the same as tc("Empty"). It removes all records.
|
||||
// Each testgroup() begins with clear() automagically. You do not
|
||||
// have to include the clear() in each testgroup().
|
||||
// emptyzone() is the same as tc("Empty"). It removes all records.
|
||||
// Each testgroup() begins with tcEmptyZone() automagically. You do not
|
||||
// have to include the tcEmptyZone() in each testgroup().
|
||||
|
||||
tests := []*TestGroup{
|
||||
|
||||
// START HERE
|
||||
|
||||
// Narrative: Hello friend! Are you adding a new DNS provider to
|
||||
|
@ -1040,7 +1037,7 @@ func makeTests() []*TestGroup {
|
|||
|
||||
testgroup("ManyAtOnce",
|
||||
tc("CreateManyAtLabel", a("www", "1.1.1.1"), a("www", "2.2.2.2"), a("www", "3.3.3.3")),
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("Create an A record", a("www", "1.1.1.1")),
|
||||
tc("Add at label1", a("www", "1.1.1.1"), a("www", "2.2.2.2")),
|
||||
tc("Add at label2", a("www", "1.1.1.1"), a("www", "2.2.2.2"), a("www", "3.3.3.3")),
|
||||
|
@ -1048,7 +1045,7 @@ func makeTests() []*TestGroup {
|
|||
|
||||
testgroup("manyTypesAtOnce",
|
||||
tc("CreateManyTypesAtLabel", a("www", "1.1.1.1"), mx("testmx", 5, "foo.com."), mx("testmx", 100, "bar.com.")),
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("Create an A record", a("www", "1.1.1.1")),
|
||||
tc("Add Type At Label", a("www", "1.1.1.1"), mx("testmx", 5, "foo.com.")),
|
||||
tc("Add Type At Label", a("www", "1.1.1.1"), mx("testmx", 5, "foo.com."), mx("testmx", 100, "bar.com.")),
|
||||
|
@ -1286,7 +1283,7 @@ func makeTests() []*TestGroup {
|
|||
tc("a 764-byte TXT", txt("foo764", strings.Repeat("G", 764))), // 255*3-1
|
||||
tc("a 765-byte TXT", txt("foo765", strings.Repeat("H", 765))), // 255*3
|
||||
tc("a 766-byte TXT", txt("foo766", strings.Repeat("J", 766))), // 255*3+1
|
||||
//clear(),
|
||||
// tcEmptyZone(),
|
||||
|
||||
tc("TXT with 1 single-quote", txt("foosq", "quo'te")),
|
||||
tc("TXT with 1 backtick", txt("foobt", "blah`blah")),
|
||||
|
@ -1301,14 +1298,14 @@ func makeTests() []*TestGroup {
|
|||
tc("TXT with semicolon ws", txt("foosc2", `wssemi ; colon`)),
|
||||
|
||||
tc("TXT interior ws", txt("foosp", "with spaces")),
|
||||
//tc("TXT leading ws", txt("foowsb", " leadingspace")),
|
||||
// tc("TXT leading ws", txt("foowsb", " leadingspace")),
|
||||
tc("TXT trailing ws", txt("foows1", "trailingws ")),
|
||||
|
||||
// Vultr syntax-checks TXT records with SPF contents.
|
||||
tc("Create a TXT/SPF", txt("foo", "v=spf1 ip4:99.99.99.99 -all")),
|
||||
|
||||
// Nobody needs this and many APIs don't allow it.
|
||||
//tc("Create TXT with frequently difficult characters", txt("fooex", `!^.*$@#%^&()([][{}{<></:;-_=+\`)),
|
||||
// tc("Create TXT with frequently difficult characters", txt("fooex", `!^.*$@#%^&()([][{}{<></:;-_=+\`)),
|
||||
),
|
||||
|
||||
testgroup("TXT backslashes",
|
||||
|
@ -1352,7 +1349,7 @@ func makeTests() []*TestGroup {
|
|||
),
|
||||
tc("deleteOne",
|
||||
a("foo", "1.2.3.4"),
|
||||
//a("foo", "3.4.5.6"), // Delete
|
||||
// a("foo", "3.4.5.6"), // Delete
|
||||
),
|
||||
tc("addOne",
|
||||
a("foo", "1.2.3.4"),
|
||||
|
@ -1380,7 +1377,7 @@ func makeTests() []*TestGroup {
|
|||
tc("deleteOne",
|
||||
a("bar", "1.2.3.4"),
|
||||
a("foo", "2.3.4.5"),
|
||||
//a("foo", "8.8.8.8"), // Delete
|
||||
// a("foo", "8.8.8.8"), // Delete
|
||||
mx("foo", 10, "foo.**current-domain**"),
|
||||
mx("foo", 20, "bar.**current-domain**"),
|
||||
),
|
||||
|
@ -1444,7 +1441,7 @@ func makeTests() []*TestGroup {
|
|||
"CLOUDFLAREAPI", // Infinite pagesize but due to slow speed, skipping.
|
||||
"DIGITALOCEAN", // No paging. Why bother?
|
||||
"DESEC", // Skip due to daily update limits.
|
||||
//"CSCGLOBAL", // Doesn't page. Works fine. Due to the slow API we skip.
|
||||
// "CSCGLOBAL", // Doesn't page. Works fine. Due to the slow API we skip.
|
||||
"GANDI_V5", // Their API is so damn slow. We'll add it back as needed.
|
||||
"HEDNS", // Doesn't page. Works fine. Due to the slow API we skip.
|
||||
"HEXONET", // Doesn't page. Works fine. Due to the slow API we skip.
|
||||
|
@ -1452,7 +1449,7 @@ func makeTests() []*TestGroup {
|
|||
"MSDNS", // No paging done. No need to test.
|
||||
"NAMEDOTCOM", // Their API is so damn slow. We'll add it back as needed.
|
||||
"NS1", // Free acct only allows 50 records, therefore we skip
|
||||
//"ROUTE53", // Batches up changes in pages.
|
||||
// "ROUTE53", // Batches up changes in pages.
|
||||
"TRANSIP", // Doesn't page. Works fine. Due to the slow API we skip.
|
||||
"CNR", // Test beaks limits.
|
||||
),
|
||||
|
@ -1463,7 +1460,7 @@ func makeTests() []*TestGroup {
|
|||
|
||||
testgroup("pager601",
|
||||
only(
|
||||
//"AZURE_DNS", // Removed because it is too slow
|
||||
// "AZURE_DNS", // Removed because it is too slow
|
||||
//"CLOUDFLAREAPI", // Infinite pagesize but due to slow speed, skipping.
|
||||
//"CSCGLOBAL", // Doesn't page. Works fine. Due to the slow API we skip.
|
||||
//"DESEC", // Skip due to daily update limits.
|
||||
|
@ -1479,7 +1476,7 @@ func makeTests() []*TestGroup {
|
|||
|
||||
testgroup("pager1201",
|
||||
only(
|
||||
//"AKAMAIEDGEDNS", // No paging done. No need to test.
|
||||
// "AKAMAIEDGEDNS", // No paging done. No need to test.
|
||||
//"AZURE_DNS", // Currently failing. See https://github.com/StackExchange/dnscontrol/issues/770
|
||||
//"CLOUDFLAREAPI", // Fails with >1000 corrections. See https://github.com/StackExchange/dnscontrol/issues/1440
|
||||
//"CSCGLOBAL", // Doesn't page. Works fine. Due to the slow API we skip.
|
||||
|
@ -1537,20 +1534,20 @@ func makeTests() []*TestGroup {
|
|||
// LOCation records. // No.47
|
||||
testgroup("LOC",
|
||||
requires(providers.CanUseLOC),
|
||||
//42 21 54 N 71 06 18 W -24m 30m
|
||||
// 42 21 54 N 71 06 18 W -24m 30m
|
||||
tc("Single LOC record", loc("@", 42, 21, 54, "N", 71, 6, 18, "W", -24.05, 30, 0, 0)),
|
||||
//42 21 54 N 71 06 18 W -24m 30m
|
||||
// 42 21 54 N 71 06 18 W -24m 30m
|
||||
tc("Update single LOC record", loc("@", 42, 21, 54, "N", 71, 6, 18, "W", -24.06, 30, 10, 0)),
|
||||
tc("Multiple LOC records-create a-d modify apex", //create a-d, modify @
|
||||
//42 21 54 N 71 06 18 W -24m 30m
|
||||
tc("Multiple LOC records-create a-d modify apex", // create a-d, modify @
|
||||
// 42 21 54 N 71 06 18 W -24m 30m
|
||||
loc("@", 42, 21, 54, "N", 71, 6, 18, "W", -24, 30, 0, 0),
|
||||
//42 21 43.952 N 71 5 6.344 W -24m 1m 200m
|
||||
// 42 21 43.952 N 71 5 6.344 W -24m 1m 200m
|
||||
loc("a", 42, 21, 43.952, "N", 71, 5, 6.344, "W", -24.33, 1, 200, 10),
|
||||
//52 14 05 N 00 08 50 E 10m
|
||||
// 52 14 05 N 00 08 50 E 10m
|
||||
loc("b", 52, 14, 5, "N", 0, 8, 50, "E", 10.22, 0, 0, 0),
|
||||
//32 7 19 S 116 2 25 E 10m
|
||||
// 32 7 19 S 116 2 25 E 10m
|
||||
loc("c", 32, 7, 19, "S", 116, 2, 25, "E", 10, 0, 0, 0),
|
||||
//42 21 28.764 N 71 00 51.617 W -44m 2000m
|
||||
// 42 21 28.764 N 71 00 51.617 W -44m 2000m
|
||||
loc("d", 42, 21, 28.764, "N", 71, 0, 51.617, "W", -44, 2000, 0, 0),
|
||||
),
|
||||
),
|
||||
|
@ -1590,7 +1587,7 @@ func makeTests() []*TestGroup {
|
|||
// SOA
|
||||
testgroup("SOA",
|
||||
requires(providers.CanUseSOA),
|
||||
clear(), // Extra clear required or only the first run passes.
|
||||
tcEmptyZone(), // Required or only the first run passes.
|
||||
tc("Create SOA record", soa("@", "kim.ns.cloudflare.com.", "dns.cloudflare.com.", 2037190000, 10000, 2400, 604800, 3600)),
|
||||
tc("Modify SOA ns ", soa("@", "mmm.ns.cloudflare.com.", "dns.cloudflare.com.", 2037190000, 10000, 2400, 604800, 3600)),
|
||||
tc("Modify SOA mbox ", soa("@", "mmm.ns.cloudflare.com.", "eee.cloudflare.com.", 2037190000, 10000, 2400, 604800, 3600)),
|
||||
|
@ -1610,7 +1607,7 @@ func makeTests() []*TestGroup {
|
|||
tc("Change Priority", srv("_sip._tcp", 52, 6, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")),
|
||||
tc("Change Weight", srv("_sip._tcp", 52, 62, 7, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")),
|
||||
tc("Change Port", srv("_sip._tcp", 52, 62, 72, "foo.com."), srv("_sip._tcp", 15, 65, 75, "foo4.com.")),
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("Null Target", srv("_sip._tcp", 15, 65, 75, ".")),
|
||||
),
|
||||
|
||||
|
@ -1713,7 +1710,7 @@ func makeTests() []*TestGroup {
|
|||
ds("child", 63909, 3, 4, "EEC7FA02E6788DA889B2CE41D43D92F948AB126EDCF83B7037E73CE9531C8E7E45653ABBAA76C2D6E42F98316EDE599B"),
|
||||
ns("child", "ns101.cloudns.net."),
|
||||
),
|
||||
//tc("modify field 2", ds("child", 65535, 254, 4, "0123456789ABCDEF")),
|
||||
// tc("modify field 2", ds("child", 65535, 254, 4, "0123456789ABCDEF")),
|
||||
tc("delete 1, create 1",
|
||||
ds("another-child", 35632, 13, 4, "F5F32ABCA6B01AA7A9963012F90B7C8523A1D946185A3AD70B67F3C9F18E7312FA9DD6AB2F7D8382F789213DB173D429"),
|
||||
ns("another-child", "ns101.cloudns.net."),
|
||||
|
@ -1726,7 +1723,7 @@ func makeTests() []*TestGroup {
|
|||
),
|
||||
// in CLouDNS we must delete DS Record before deleting NS record
|
||||
// should no longer be necessary, provider should handle order correctly
|
||||
//tc("delete all DS",
|
||||
// tc("delete all DS",
|
||||
// ns("another-child", "ns101.cloudns.net."),
|
||||
//),
|
||||
),
|
||||
|
@ -1938,12 +1935,12 @@ func makeTests() []*TestGroup {
|
|||
|
||||
// Removed these for speed. They tested if order matters,
|
||||
// which it doesn't seem to. Re-add if needed.
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("multipleA",
|
||||
cfRedir("cnn.**current-domain-no-trailing**/*", "https://www.cnn.com/$1"),
|
||||
cfRedir("msnbc.**current-domain-no-trailing**/*", "https://msnbc.cnn.com/$1"),
|
||||
),
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("multipleB",
|
||||
cfRedir("msnbc.**current-domain-no-trailing**/*", "https://msnbc.cnn.com/$1"),
|
||||
cfRedir("cnn.**current-domain-no-trailing**/*", "https://www.cnn.com/$1"),
|
||||
|
@ -1958,7 +1955,7 @@ func makeTests() []*TestGroup {
|
|||
),
|
||||
|
||||
// NB(tlim): This test case used to fail but mysteriously started working.
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("multiple3",
|
||||
cfRedir("msnbc.**current-domain-no-trailing**/*", "https://msnbc.cnn.com/$1"),
|
||||
cfRedir("cnn.**current-domain-no-trailing**/*", "https://www.cnn.com/$1"),
|
||||
|
@ -1966,16 +1963,16 @@ func makeTests() []*TestGroup {
|
|||
),
|
||||
|
||||
// Repeat the above tests using CF_TEMP_REDIR instead
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("tempredir", cfRedirTemp("cnn.**current-domain-no-trailing**/*", "https://www.cnn.com/$1")),
|
||||
tc("tempchange", cfRedirTemp("cnn.**current-domain-no-trailing**/*", "https://change.cnn.com/$1")),
|
||||
tc("tempchangelabel", cfRedirTemp("cable.**current-domain-no-trailing**/*", "https://change.cnn.com/$1")),
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("tempmultipleA",
|
||||
cfRedirTemp("cnn.**current-domain-no-trailing**/*", "https://www.cnn.com/$1"),
|
||||
cfRedirTemp("msnbc.**current-domain-no-trailing**/*", "https://msnbc.cnn.com/$1"),
|
||||
),
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("tempmultipleB",
|
||||
cfRedirTemp("msnbc.**current-domain-no-trailing**/*", "https://msnbc.cnn.com/$1"),
|
||||
cfRedirTemp("cnn.**current-domain-no-trailing**/*", "https://www.cnn.com/$1"),
|
||||
|
@ -2018,10 +2015,10 @@ func makeTests() []*TestGroup {
|
|||
|
||||
testgroup("CF_PROXY A create",
|
||||
only("CLOUDFLAREAPI"),
|
||||
CfProxyOff(), clear(),
|
||||
CfProxyOn(), clear(),
|
||||
CfProxyFull1(), clear(),
|
||||
CfProxyFull2(), clear(),
|
||||
CfProxyOff(), tcEmptyZone(),
|
||||
CfProxyOn(), tcEmptyZone(),
|
||||
CfProxyFull1(), tcEmptyZone(),
|
||||
CfProxyFull2(), tcEmptyZone(),
|
||||
),
|
||||
|
||||
// These next testgroups attempt every possible transition between off, on, full1 and full2.
|
||||
|
@ -2030,62 +2027,62 @@ func makeTests() []*TestGroup {
|
|||
|
||||
testgroup("CF_PROXY A off to X",
|
||||
only("CLOUDFLAREAPI"),
|
||||
//CF_PROXY_OFF(), CF_PROXY_OFF(), clear(), // redundant
|
||||
CfProxyOff(), CfProxyOn(), clear(),
|
||||
CfProxyOff(), CfProxyFull1(), clear(),
|
||||
CfProxyOff(), CfProxyFull2(), clear(),
|
||||
// CF_PROXY_OFF(), CF_PROXY_OFF(), tcEmptyZone(), // redundant
|
||||
CfProxyOff(), CfProxyOn(), tcEmptyZone(),
|
||||
CfProxyOff(), CfProxyFull1(), tcEmptyZone(),
|
||||
CfProxyOff(), CfProxyFull2(), tcEmptyZone(),
|
||||
),
|
||||
|
||||
testgroup("CF_PROXY A on to X",
|
||||
only("CLOUDFLAREAPI"),
|
||||
CfProxyOn(), CfProxyOff(), clear(),
|
||||
//CF_PROXY_ON(), CF_PROXY_ON(), clear(), // redundant
|
||||
//CF_PROXY_ON(), CF_PROXY_FULL1().ExpectNoChanges(), clear(), // Removed for speed
|
||||
CfProxyOn(), CfProxyFull2(), clear(),
|
||||
CfProxyOn(), CfProxyOff(), tcEmptyZone(),
|
||||
// CF_PROXY_ON(), CF_PROXY_ON(), tcEmptyZone(), // redundant
|
||||
// CF_PROXY_ON(), CF_PROXY_FULL1().ExpectNoChanges(), tcEmptyZone(), // Removed for speed
|
||||
CfProxyOn(), CfProxyFull2(), tcEmptyZone(),
|
||||
),
|
||||
|
||||
testgroup("CF_PROXY A full1 to X",
|
||||
only("CLOUDFLAREAPI"),
|
||||
CfProxyFull1(), CfProxyOff(), clear(),
|
||||
//CF_PROXY_FULL1(), CF_PROXY_ON().ExpectNoChanges(), clear(), // Removed for speed
|
||||
//CF_PROXY_FULL1(), CF_PROXY_FULL1(), clear(), // redundant
|
||||
CfProxyFull1(), CfProxyFull2(), clear(),
|
||||
CfProxyFull1(), CfProxyOff(), tcEmptyZone(),
|
||||
// CF_PROXY_FULL1(), CF_PROXY_ON().ExpectNoChanges(), tcEmptyZone(), // Removed for speed
|
||||
// CF_PROXY_FULL1(), tcEmptyZone(), // redundant
|
||||
CfProxyFull1(), CfProxyFull2(), tcEmptyZone(),
|
||||
),
|
||||
|
||||
testgroup("CF_PROXY A full2 to X",
|
||||
only("CLOUDFLAREAPI"),
|
||||
CfProxyFull2(), CfProxyOff(), clear(),
|
||||
CfProxyFull2(), CfProxyOn(), clear(),
|
||||
CfProxyFull2(), CfProxyFull1(), clear(),
|
||||
//CF_PROXY_FULL2(), CF_PROXY_FULL2(), clear(), // redundant
|
||||
CfProxyFull2(), CfProxyOff(), tcEmptyZone(),
|
||||
CfProxyFull2(), CfProxyOn(), tcEmptyZone(),
|
||||
CfProxyFull2(), CfProxyFull1(), tcEmptyZone(),
|
||||
// CF_PROXY_FULL2(), CF_PROXY_FULL2(), tcEmptyZone(), // redundant
|
||||
),
|
||||
|
||||
testgroup("CF_PROXY CNAME create",
|
||||
only("CLOUDFLAREAPI"),
|
||||
CfCProxyOff(), clear(),
|
||||
CfCProxyOn(), clear(),
|
||||
CfCProxyFull(), clear(),
|
||||
CfCProxyOff(), tcEmptyZone(),
|
||||
CfCProxyOn(), tcEmptyZone(),
|
||||
CfCProxyFull(), tcEmptyZone(),
|
||||
),
|
||||
|
||||
testgroup("CF_PROXY CNAME off to X",
|
||||
only("CLOUDFLAREAPI"),
|
||||
//CF_CPROXY_OFF(), CF_CPROXY_OFF(), clear(), // redundant
|
||||
CfCProxyOff(), CfCProxyOn(), clear(),
|
||||
CfCProxyOff(), CfCProxyFull(), clear(),
|
||||
// CF_CPROXY_OFF(), CF_CPROXY_OFF(), tcEmptyZone(), // redundant
|
||||
CfCProxyOff(), CfCProxyOn(), tcEmptyZone(),
|
||||
CfCProxyOff(), CfCProxyFull(), tcEmptyZone(),
|
||||
),
|
||||
|
||||
testgroup("CF_PROXY CNAME on to X",
|
||||
only("CLOUDFLAREAPI"),
|
||||
CfCProxyOn(), CfCProxyOff(), clear(),
|
||||
//CF_CPROXY_ON(), CF_CPROXY_ON(), clear(), // redundant
|
||||
//CF_CPROXY_ON(), CF_CPROXY_FULL().ExpectNoChanges(), clear(), // Removed for speed
|
||||
CfCProxyOn(), CfCProxyOff(), tcEmptyZone(),
|
||||
// CF_CPROXY_ON(), CF_CPROXY_ON(), tcEmptyZone(), // redundant
|
||||
// CF_CPROXY_ON(), CF_CPROXY_FULL().ExpectNoChanges(), tcEmptyZone(), // Removed for speed
|
||||
),
|
||||
|
||||
testgroup("CF_PROXY CNAME full to X",
|
||||
only("CLOUDFLAREAPI"),
|
||||
CfCProxyFull(), CfCProxyOff(), clear(),
|
||||
//CF_CPROXY_FULL(), CF_CPROXY_ON().ExpectNoChanges(), clear(), // Removed for speed
|
||||
//CF_CPROXY_FULL(), CF_CPROXY_FULL(), clear(), // redundant
|
||||
CfCProxyFull(), CfCProxyOff(), tcEmptyZone(),
|
||||
// CF_CPROXY_FULL(), CF_CPROXY_ON().ExpectNoChanges(), tcEmptyZone(), // Removed for speed
|
||||
// CF_CPROXY_FULL(), tcEmptyZone(), // redundant
|
||||
),
|
||||
|
||||
testgroup("CF_WORKER_ROUTE",
|
||||
|
@ -2095,7 +2092,7 @@ func makeTests() []*TestGroup {
|
|||
tc("simple", cfWorkerRoute("cnn.**current-domain-no-trailing**/*", "dnscontrol_integrationtest_cnn")),
|
||||
tc("changeScript", cfWorkerRoute("cnn.**current-domain-no-trailing**/*", "dnscontrol_integrationtest_msnbc")),
|
||||
tc("changePattern", cfWorkerRoute("cable.**current-domain-no-trailing**/*", "dnscontrol_integrationtest_msnbc")),
|
||||
clear(),
|
||||
tcEmptyZone(),
|
||||
tc("createMultiple",
|
||||
cfWorkerRoute("cnn.**current-domain-no-trailing**/*", "dnscontrol_integrationtest_cnn"),
|
||||
cfWorkerRoute("msnbc.**current-domain-no-trailing**/*", "dnscontrol_integrationtest_msnbc"),
|
||||
|
@ -2137,9 +2134,9 @@ func makeTests() []*TestGroup {
|
|||
// NB(tlim): This ignores 1 record of a recordSet. This should
|
||||
// fail for diff2.ByRecordSet() providers if diff2 is not
|
||||
// implemented correctly.
|
||||
//a("foo", "1.2.3.4"),
|
||||
//a("foo", "2.3.4.5"),
|
||||
//txt("foo", "simple"),
|
||||
// a("foo", "1.2.3.4"),
|
||||
// a("foo", "2.3.4.5"),
|
||||
// txt("foo", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
ignore("foo", "", ""),
|
||||
|
@ -2153,8 +2150,8 @@ func makeTests() []*TestGroup {
|
|||
).ExpectNoChanges(),
|
||||
|
||||
tc("ignore label,type",
|
||||
//a("foo", "1.2.3.4"),
|
||||
//a("foo", "2.3.4.5"),
|
||||
// a("foo", "1.2.3.4"),
|
||||
// a("foo", "2.3.4.5"),
|
||||
txt("foo", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
|
@ -2169,7 +2166,7 @@ func makeTests() []*TestGroup {
|
|||
).ExpectNoChanges(),
|
||||
|
||||
tc("ignore label,type,target",
|
||||
//a("foo", "1.2.3.4"),
|
||||
// a("foo", "1.2.3.4"),
|
||||
a("foo", "2.3.4.5"),
|
||||
txt("foo", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
|
@ -2185,10 +2182,10 @@ func makeTests() []*TestGroup {
|
|||
).ExpectNoChanges(),
|
||||
|
||||
tc("ignore type",
|
||||
//a("foo", "1.2.3.4"),
|
||||
//a("foo", "2.3.4.5"),
|
||||
// a("foo", "1.2.3.4"),
|
||||
// a("foo", "2.3.4.5"),
|
||||
txt("foo", "simple"),
|
||||
//a("bar", "5.5.5.5"),
|
||||
// a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
ignore("", "A", ""),
|
||||
).ExpectNoChanges(),
|
||||
|
@ -2202,7 +2199,7 @@ func makeTests() []*TestGroup {
|
|||
|
||||
tc("ignore type,target",
|
||||
a("foo", "1.2.3.4"),
|
||||
//a("foo", "2.3.4.5"),
|
||||
// a("foo", "2.3.4.5"),
|
||||
txt("foo", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
|
@ -2218,7 +2215,7 @@ func makeTests() []*TestGroup {
|
|||
|
||||
tc("ignore target",
|
||||
a("foo", "1.2.3.4"),
|
||||
//a("foo", "2.3.4.5"),
|
||||
// a("foo", "2.3.4.5"),
|
||||
txt("foo", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
|
@ -2234,10 +2231,10 @@ func makeTests() []*TestGroup {
|
|||
|
||||
// Many types:
|
||||
tc("ignore manytypes",
|
||||
//a("foo", "1.2.3.4"),
|
||||
//a("foo", "2.3.4.5"),
|
||||
//txt("foo", "simple"),
|
||||
//a("bar", "5.5.5.5"),
|
||||
// a("foo", "1.2.3.4"),
|
||||
// a("foo", "2.3.4.5"),
|
||||
// txt("foo", "simple"),
|
||||
// a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
ignore("", "A,TXT", ""),
|
||||
).ExpectNoChanges(),
|
||||
|
@ -2255,7 +2252,7 @@ func makeTests() []*TestGroup {
|
|||
a("foo", "2.3.4.5"),
|
||||
txt("foo", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
//cname("mail", "ghs.googlehosted.com."),
|
||||
// cname("mail", "ghs.googlehosted.com."),
|
||||
ignore("", "CNAME", "*.googlehosted.com."),
|
||||
).ExpectNoChanges(),
|
||||
tc("VERIFY PREVIOUS",
|
||||
|
@ -2281,13 +2278,13 @@ func makeTests() []*TestGroup {
|
|||
// NB(tlim): This ignores 1 record of a recordSet. This should
|
||||
// fail for diff2.ByRecordSet() providers if diff2 is not
|
||||
// implemented correctly.
|
||||
//a("@", "1.2.3.4"),
|
||||
//a("@", "2.3.4.5"),
|
||||
//txt("@", "simple"),
|
||||
// a("@", "1.2.3.4"),
|
||||
// a("@", "2.3.4.5"),
|
||||
// txt("@", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
ignore("@", "", ""),
|
||||
//ignore("", "NS", ""),
|
||||
// ignore("", "NS", ""),
|
||||
// NB(tlim): .UnsafeIgnore is needed because the NS records
|
||||
// that providers injects into zones are treated like input
|
||||
// from dnsconfig.js.
|
||||
|
@ -2301,8 +2298,8 @@ func makeTests() []*TestGroup {
|
|||
).ExpectNoChanges(),
|
||||
|
||||
tc("apex label,type",
|
||||
//a("@", "1.2.3.4"),
|
||||
//a("@", "2.3.4.5"),
|
||||
// a("@", "1.2.3.4"),
|
||||
// a("@", "2.3.4.5"),
|
||||
txt("@", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
|
@ -2317,7 +2314,7 @@ func makeTests() []*TestGroup {
|
|||
).ExpectNoChanges(),
|
||||
|
||||
tc("apex label,type,target",
|
||||
//a("@", "1.2.3.4"),
|
||||
// a("@", "1.2.3.4"),
|
||||
a("@", "2.3.4.5"),
|
||||
txt("@", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
|
@ -2336,10 +2333,10 @@ func makeTests() []*TestGroup {
|
|||
).ExpectNoChanges(),
|
||||
|
||||
tc("apex type",
|
||||
//a("@", "1.2.3.4"),
|
||||
//a("@", "2.3.4.5"),
|
||||
// a("@", "1.2.3.4"),
|
||||
// a("@", "2.3.4.5"),
|
||||
txt("@", "simple"),
|
||||
//a("bar", "5.5.5.5"),
|
||||
// a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
ignore("", "A", ""),
|
||||
).ExpectNoChanges(),
|
||||
|
@ -2353,7 +2350,7 @@ func makeTests() []*TestGroup {
|
|||
|
||||
tc("apex type,target",
|
||||
a("@", "1.2.3.4"),
|
||||
//a("@", "2.3.4.5"),
|
||||
// a("@", "2.3.4.5"),
|
||||
txt("@", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
|
@ -2369,7 +2366,7 @@ func makeTests() []*TestGroup {
|
|||
|
||||
tc("apex target",
|
||||
a("@", "1.2.3.4"),
|
||||
//a("@", "2.3.4.5"),
|
||||
// a("@", "2.3.4.5"),
|
||||
txt("@", "simple"),
|
||||
a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
|
@ -2385,10 +2382,10 @@ func makeTests() []*TestGroup {
|
|||
|
||||
// Many types:
|
||||
tc("apex manytypes",
|
||||
//a("@", "1.2.3.4"),
|
||||
//a("@", "2.3.4.5"),
|
||||
//txt("@", "simple"),
|
||||
//a("bar", "5.5.5.5"),
|
||||
// a("@", "1.2.3.4"),
|
||||
// a("@", "2.3.4.5"),
|
||||
// txt("@", "simple"),
|
||||
// a("bar", "5.5.5.5"),
|
||||
cname("mail", "ghs.googlehosted.com."),
|
||||
ignore("", "A,TXT", ""),
|
||||
).ExpectNoChanges(),
|
||||
|
@ -2452,9 +2449,9 @@ func makeTests() []*TestGroup {
|
|||
),
|
||||
|
||||
tc("ignore label=foo.*",
|
||||
//a("foo.bat", "1.2.3.4"),
|
||||
//a("foo.bat", "2.3.4.5"),
|
||||
//txt("foo.bat", "simple"),
|
||||
// a("foo.bat", "1.2.3.4"),
|
||||
// a("foo.bat", "2.3.4.5"),
|
||||
// txt("foo.bat", "simple"),
|
||||
a("bar.bat", "5.5.5.5"),
|
||||
cname("mail.bat", "ghs.googlehosted.com."),
|
||||
ignore("foo.*", "", ""),
|
||||
|
@ -2468,10 +2465,10 @@ func makeTests() []*TestGroup {
|
|||
).ExpectNoChanges(),
|
||||
|
||||
tc("ignore label=foo.bat,type",
|
||||
//a("foo.bat", "1.2.3.4"),
|
||||
//a("foo.bat", "2.3.4.5"),
|
||||
// a("foo.bat", "1.2.3.4"),
|
||||
// a("foo.bat", "2.3.4.5"),
|
||||
txt("foo.bat", "simple"),
|
||||
//a("bar.bat", "5.5.5.5"),
|
||||
// a("bar.bat", "5.5.5.5"),
|
||||
cname("mail.bat", "ghs.googlehosted.com."),
|
||||
ignore("*.bat", "A", ""),
|
||||
).ExpectNoChanges(),
|
||||
|
@ -2488,7 +2485,7 @@ func makeTests() []*TestGroup {
|
|||
a("foo.bat", "2.3.4.5"),
|
||||
txt("foo.bat", "simple"),
|
||||
a("bar.bat", "5.5.5.5"),
|
||||
//cname("mail.bat", "ghs.googlehosted.com."),
|
||||
// cname("mail.bat", "ghs.googlehosted.com."),
|
||||
ignore("", "", "*.googlehosted.com."),
|
||||
).ExpectNoChanges(),
|
||||
tc("VERIFY PREVIOUS",
|
||||
|
@ -2521,8 +2518,8 @@ func makeTests() []*TestGroup {
|
|||
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
|
||||
mx("foo", 10, "aspmx.l.google.com."),
|
||||
mx("foo", 20, "alt1.aspmx.l.google.com."),
|
||||
//a("zzz", "3.3.3.3"),
|
||||
//a("zzz", "4.4.4.4"),
|
||||
// a("zzz", "3.3.3.3"),
|
||||
// a("zzz", "4.4.4.4"),
|
||||
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
|
||||
),
|
||||
tc("VERIFY PREVIOUS",
|
||||
|
@ -2542,8 +2539,8 @@ func makeTests() []*TestGroup {
|
|||
a("foo", "1.1.1.1"),
|
||||
a("foo", "12.12.12.12"), // CHANGE
|
||||
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
|
||||
//mx("foo", 10, "aspmx.l.google.com."),
|
||||
//mx("foo", 20, "alt1.aspmx.l.google.com"),
|
||||
// mx("foo", 10, "aspmx.l.google.com."),
|
||||
// mx("foo", 20, "alt1.aspmx.l.google.com"),
|
||||
a("zzz", "3.3.3.3"),
|
||||
a("zzz", "4.4.4.4"),
|
||||
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
|
||||
|
@ -2564,9 +2561,9 @@ func makeTests() []*TestGroup {
|
|||
ignore("foo", "MX,AAAA", ""),
|
||||
a("foo", "1.1.1.1"),
|
||||
a("foo", "13.13.13.13"), // CHANGE
|
||||
//aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
|
||||
//mx("foo", 10, "aspmx.l.google.com."),
|
||||
//mx("foo", 20, "alt1.aspmx.l.google.com"),
|
||||
// aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
|
||||
// mx("foo", 10, "aspmx.l.google.com."),
|
||||
// mx("foo", 20, "alt1.aspmx.l.google.com"),
|
||||
a("zzz", "3.3.3.3"),
|
||||
a("zzz", "4.4.4.4"),
|
||||
aaaa("zzz", "2003:dd:d7ff::fe71:cccc"),
|
||||
|
@ -2585,7 +2582,7 @@ func makeTests() []*TestGroup {
|
|||
// Change within a (name+type+data) ("ByRecord")
|
||||
tc("IGNORE change ByRecord",
|
||||
ignore("foo", "A", "1.1.1.1"),
|
||||
//a("foo", "1.1.1.1"),
|
||||
// a("foo", "1.1.1.1"),
|
||||
a("foo", "14.14.14.14"),
|
||||
aaaa("foo", "2003:dd:d7ff::fe71:aaaa"),
|
||||
mx("foo", 10, "aspmx.l.google.com."),
|
||||
|
@ -2658,7 +2655,7 @@ func makeTests() []*TestGroup {
|
|||
a("testdefined", "9.9.9.9"),
|
||||
),
|
||||
tc("ignore",
|
||||
//a("testignore", "8.8.8.8"),
|
||||
// a("testignore", "8.8.8.8"),
|
||||
a("testdefined", "9.9.9.9"),
|
||||
ignore("testignore", "", ""),
|
||||
).ExpectNoChanges(),
|
||||
|
@ -2677,7 +2674,7 @@ func makeTests() []*TestGroup {
|
|||
).ExpectNoChanges(),
|
||||
|
||||
tc("ignore with change",
|
||||
//a("testignore", "8.8.8.8"),
|
||||
// a("testignore", "8.8.8.8"),
|
||||
a("testdefined", "2.2.2.2"),
|
||||
ignore("testignore", "", ""),
|
||||
),
|
||||
|
|
|
@ -2,6 +2,7 @@ package models
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
@ -67,7 +68,7 @@ func ToNameservers(nss []string) ([]*Nameserver, error) {
|
|||
nservers := []*Nameserver{}
|
||||
for _, ns := range nss {
|
||||
if strings.HasSuffix(ns, ".") {
|
||||
return nil, fmt.Errorf("provider code leaves trailing dot on nameserver")
|
||||
return nil, errors.New("provider code leaves trailing dot on nameserver")
|
||||
// If you see this error, maybe the provider should call
|
||||
// ToNameserversStripTD instead.
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ type DomainConfig struct {
|
|||
UnmanagedUnsafe bool `json:"unmanaged_disable_safety_check,omitempty"` // DISABLE_IGNORE_SAFETY_CHECK
|
||||
|
||||
AutoDNSSEC string `json:"auto_dnssec,omitempty"` // "", "on", "off"
|
||||
//DNSSEC bool `json:"dnssec,omitempty"`
|
||||
// DNSSEC bool `json:"dnssec,omitempty"`
|
||||
|
||||
// These fields contain instantiated provider instances once everything is linked up.
|
||||
// This linking is in two phases:
|
||||
|
@ -130,9 +130,13 @@ func (dc *DomainConfig) Punycode() error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rec.SetTarget(t)
|
||||
if err := rec.SetTarget(t); err != nil {
|
||||
return err
|
||||
}
|
||||
case "CLOUDFLAREAPI_SINGLE_REDIRECT", "CF_REDIRECT", "CF_TEMP_REDIRECT", "CF_WORKER_ROUTE":
|
||||
rec.SetTarget(rec.GetTargetField())
|
||||
if err := rec.SetTarget(rec.GetTargetField()); err != nil {
|
||||
return err
|
||||
}
|
||||
case "A", "AAAA", "CAA", "DHCID", "DNSKEY", "DS", "HTTPS", "LOC", "NAPTR", "SOA", "SSHFP", "SVCB", "TXT", "TLSA", "AZURE_ALIAS":
|
||||
// Nothing to do.
|
||||
default:
|
||||
|
|
|
@ -65,23 +65,37 @@ func TestParseQuotedTxt(t *testing.T) {
|
|||
{`"aaa" "bbb"`, []string{`aaa`, `bbb`}},
|
||||
{`"a"a" "bbb"`, []string{`a"a`, `bbb`}},
|
||||
// Seen in live traffic:
|
||||
{"\"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\"",
|
||||
[]string{r("B", 254)}},
|
||||
{"\"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\"",
|
||||
[]string{r("C", 255)}},
|
||||
{"\"DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\" \"D\"",
|
||||
[]string{r("D", 255), "D"}},
|
||||
{"\"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\" \"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\"",
|
||||
[]string{r("E", 255), r("E", 255)}},
|
||||
{"\"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\" \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\" \"F\"",
|
||||
[]string{r("F", 255), r("F", 255), "F"}},
|
||||
{"\"GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\" \"GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\" \"GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\"",
|
||||
[]string{r("G", 255), r("G", 255), r("G", 255)}},
|
||||
{"\"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\" \"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\" \"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\" \"H\"",
|
||||
[]string{r("H", 255), r("H", 255), r("H", 255), "H"}},
|
||||
{
|
||||
"\"BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB\"",
|
||||
[]string{r("B", 254)},
|
||||
},
|
||||
{
|
||||
"\"CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC\"",
|
||||
[]string{r("C", 255)},
|
||||
},
|
||||
{
|
||||
"\"DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD\" \"D\"",
|
||||
[]string{r("D", 255), "D"},
|
||||
},
|
||||
{
|
||||
"\"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\" \"EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE\"",
|
||||
[]string{r("E", 255), r("E", 255)},
|
||||
},
|
||||
{
|
||||
"\"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\" \"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF\" \"F\"",
|
||||
[]string{r("F", 255), r("F", 255), "F"},
|
||||
},
|
||||
{
|
||||
"\"GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\" \"GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\" \"GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG\"",
|
||||
[]string{r("G", 255), r("G", 255), r("G", 255)},
|
||||
},
|
||||
{
|
||||
"\"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\" \"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\" \"HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH\" \"H\"",
|
||||
[]string{r("H", 255), r("H", 255), r("H", 255), "H"},
|
||||
},
|
||||
{"\"quo'te\"", []string{`quo'te`}},
|
||||
{"\"blah`blah\"", []string{"blah`blah"}},
|
||||
//{"\"quo\\\"te\"", []string{`quo"te`}},
|
||||
// {"\"quo\\\"te\"", []string{`quo"te`}},
|
||||
//{"\"q\\\"uo\\\"te\"", []string{`q"uo"te`}},
|
||||
//{"\"backs\\\\lash\"", []string{`back\slash`}},
|
||||
}
|
||||
|
@ -111,7 +125,7 @@ func TestParseQuotedFields(t *testing.T) {
|
|||
}
|
||||
for i, test := range tests {
|
||||
ls, _ := ParseQuotedFields(test.d1)
|
||||
//fmt.Printf("%v: expected TxtStrings:\nWANT: %v\n GOT: %v\n", i, test.e1, ls)
|
||||
// fmt.Printf("%v: expected TxtStrings:\nWANT: %v\n GOT: %v\n", i, test.e1, ls)
|
||||
if len(ls) != len(test.e1) {
|
||||
t.Errorf("%v: expected TxtStrings=(%v) got (%v)", i, test.e1, ls)
|
||||
}
|
||||
|
|
|
@ -253,9 +253,13 @@ func (rc *RecordConfig) UnmarshalJSON(b []byte) error {
|
|||
}
|
||||
|
||||
// Copy the exported fields.
|
||||
copier.CopyWithOption(&rc, &recj, copier.Option{IgnoreEmpty: true, DeepCopy: true})
|
||||
if err := copier.CopyWithOption(&rc, &recj, copier.Option{IgnoreEmpty: true, DeepCopy: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
// Set each unexported field.
|
||||
rc.SetTarget(recj.Target)
|
||||
if err := rc.SetTarget(recj.Target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Some sanity checks:
|
||||
if recj.Type != rc.Type {
|
||||
|
@ -288,7 +292,6 @@ func (rc *RecordConfig) Copy() (*RecordConfig, error) {
|
|||
// short must not have a training dot: That would mean you have a FQDN, and
|
||||
// shouldn't be using SetLabel(). Maybe SetLabelFromFQDN()?
|
||||
func (rc *RecordConfig) SetLabel(short, origin string) {
|
||||
|
||||
// Assertions that make sure the function is being used correctly:
|
||||
if strings.HasSuffix(origin, ".") {
|
||||
panic(fmt.Errorf("origin (%s) is not supposed to end with a dot", origin))
|
||||
|
@ -317,7 +320,6 @@ func (rc *RecordConfig) SetLabel(short, origin string) {
|
|||
// fqdn may have a trailing "." but it is not required.
|
||||
// origin may not have a trailing dot.
|
||||
func (rc *RecordConfig) SetLabelFromFQDN(fqdn, origin string) {
|
||||
|
||||
// Assertions that make sure the function is being used correctly:
|
||||
if strings.HasSuffix(origin, ".") {
|
||||
panic(fmt.Errorf("origin (%s) is not supposed to end with a dot", origin))
|
||||
|
@ -360,9 +362,9 @@ func (rc *RecordConfig) ToComparableNoTTL() string {
|
|||
return fmt.Sprintf("%s %v %d %d %d %d", rc.target, rc.SoaMbox, rc.SoaRefresh, rc.SoaRetry, rc.SoaExpire, rc.SoaMinttl)
|
||||
// SoaSerial is not included because it isn't used in comparisons.
|
||||
case "TXT":
|
||||
//fmt.Fprintf(os.Stdout, "DEBUG: ToComNoTTL raw txts=%s q=%q\n", rc.target, rc.target)
|
||||
// fmt.Fprintf(os.Stdout, "DEBUG: ToComNoTTL raw txts=%s q=%q\n", rc.target, rc.target)
|
||||
r := txtutil.EncodeQuoted(rc.target)
|
||||
//fmt.Fprintf(os.Stdout, "DEBUG: ToComNoTTL cmp txts=%s q=%q\n", r, r)
|
||||
// fmt.Fprintf(os.Stdout, "DEBUG: ToComNoTTL cmp txts=%s q=%q\n", r, r)
|
||||
return r
|
||||
case "UNKNOWN":
|
||||
return fmt.Sprintf("rtype=%s rdata=%s", rc.UnknownTypeName, rc.target)
|
||||
|
@ -372,7 +374,6 @@ func (rc *RecordConfig) ToComparableNoTTL() string {
|
|||
|
||||
// ToRR converts a RecordConfig to a dns.RR.
|
||||
func (rc *RecordConfig) ToRR() dns.RR {
|
||||
|
||||
// Don't call this on fake types.
|
||||
rdtype, ok := dns.StringToType[rc.Type]
|
||||
if !ok {
|
||||
|
@ -486,7 +487,6 @@ func (rc *RecordConfig) ToRR() dns.RR {
|
|||
|
||||
// GetDependencies returns the FQDNs on which this record dependents
|
||||
func (rc *RecordConfig) GetDependencies() []string {
|
||||
|
||||
switch rc.Type {
|
||||
// #rtype_variations
|
||||
case "NS", "SRV", "CNAME", "DNAME", "MX", "ALIAS", "AZURE_ALIAS", "R53_ALIAS":
|
||||
|
|
|
@ -24,7 +24,7 @@ func TestHasRecordTypeName(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestKey(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
rc RecordConfig
|
||||
expected RecordKey
|
||||
}{
|
||||
|
@ -136,7 +136,7 @@ func TestRecordConfig_Copy(t *testing.T) {
|
|||
TlsaMatchingType: 3,
|
||||
R53Alias: map[string]string{"a": "eh", "b": "bee"},
|
||||
AzureAlias: map[string]string{"az": "az", "ure": "your"},
|
||||
//Original interface{},
|
||||
// Original interface{},
|
||||
},
|
||||
want: &RecordConfig{
|
||||
Type: "type",
|
||||
|
@ -174,7 +174,7 @@ func TestRecordConfig_Copy(t *testing.T) {
|
|||
TlsaMatchingType: 3,
|
||||
R53Alias: map[string]string{"a": "eh", "b": "bee"},
|
||||
AzureAlias: map[string]string{"az": "az", "ure": "your"},
|
||||
//Original interface{},
|
||||
// Original interface{},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ func NewRecordDBFromRecords(recs Records, zone string) *RecordDB {
|
|||
for _, rec := range recs {
|
||||
result.labelAndTypeMap[rec.Key()] = struct{}{}
|
||||
}
|
||||
//fmt.Printf("DEBUG: BUILDING RecordDB: DONE!\n")
|
||||
// fmt.Printf("DEBUG: BUILDING RecordDB: DONE!\n")
|
||||
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -9,7 +9,9 @@ import (
|
|||
func (rc *RecordConfig) SetTargetCAA(flag uint8, tag string, target string) error {
|
||||
rc.CaaTag = tag
|
||||
rc.CaaFlag = flag
|
||||
rc.SetTarget(target)
|
||||
if err := rc.SetTarget(target); err != nil {
|
||||
return err
|
||||
}
|
||||
if rc.Type == "" {
|
||||
rc.Type = "CAA"
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ func (rc *RecordConfig) SetTargetLOC(ver uint8, lat uint32, lon uint32, alt uint
|
|||
// for further processing to the LOC native 7 input binary format:
|
||||
// LocVersion (0), LocLatitude, LocLongitude, LocAltitude, LocSize, LocVertPre, LocHorizPre
|
||||
func (rc *RecordConfig) SetLOCParams(d1 uint8, m1 uint8, s1 float32, ns string,
|
||||
d2 uint8, m2 uint8, s2 float32, ew string, al float32, sz float32, hp float32, vp float32) error {
|
||||
|
||||
d2 uint8, m2 uint8, s2 float32, ew string, al float32, sz float32, hp float32, vp float32,
|
||||
) error {
|
||||
err := rc.calculateLOCFields(d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
|
||||
|
||||
return err
|
||||
|
@ -90,14 +90,13 @@ func (rc *RecordConfig) extractLOCFieldsFromStringInput(input string) error {
|
|||
}
|
||||
// fmt.Printf("\ngot: %d %d %g %s %d %d %g %s %0.2fm %0.2fm %0.2fm %0.2fm \n", d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
|
||||
|
||||
rc.calculateLOCFields(d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
|
||||
|
||||
return nil
|
||||
return rc.calculateLOCFields(d1, m1, s1, ns, d2, m2, s2, ew, al, sz, hp, vp)
|
||||
}
|
||||
|
||||
// calculateLOCFields converts from 12 user inputs to the LOC 7 binary fields
|
||||
func (rc *RecordConfig) calculateLOCFields(d1 uint8, m1 uint8, s1 float32, ns string,
|
||||
d2 uint8, m2 uint8, s2 float32, ew string, al float32, sz float32, hp float32, vp float32) error {
|
||||
d2 uint8, m2 uint8, s2 float32, ew string, al float32, sz float32, hp float32, vp float32,
|
||||
) error {
|
||||
// Crazy hairy shit happens here.
|
||||
// We already got the useful "string" version earlier. ¯\_(ツ)_/¯ code golf...
|
||||
const LOCEquator uint64 = 0x80000000 // 1 << 31 // RFC 1876, Section 2.
|
||||
|
|
|
@ -9,7 +9,9 @@ import (
|
|||
// SetTargetMX sets the MX fields.
|
||||
func (rc *RecordConfig) SetTargetMX(pref uint16, target string) error {
|
||||
rc.MxPreference = pref
|
||||
rc.SetTarget(target)
|
||||
if err := rc.SetTarget(target); err != nil {
|
||||
return err
|
||||
}
|
||||
if rc.Type == "" {
|
||||
rc.Type = "MX"
|
||||
}
|
||||
|
|
|
@ -16,7 +16,9 @@ func (rc *RecordConfig) SetTargetNAPTR(order uint16, preference uint16, flags st
|
|||
rc.NaptrFlags = flags
|
||||
rc.NaptrService = service
|
||||
rc.NaptrRegexp = regexp
|
||||
rc.SetTarget(target)
|
||||
if err := rc.SetTarget(target); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if rc.Type == "" {
|
||||
rc.Type = "NAPTR"
|
||||
|
|
|
@ -110,7 +110,7 @@ func (rc *RecordConfig) PopulateFromStringFunc(rtype, contents, origin string, t
|
|||
case "TLSA":
|
||||
return rc.SetTargetTLSAString(contents)
|
||||
default:
|
||||
//return fmt.Errorf("unknown rtype (%s) when parsing (%s) domain=(%s)", rtype, contents, origin)
|
||||
// return fmt.Errorf("unknown rtype (%s) when parsing (%s) domain=(%s)", rtype, contents, origin)
|
||||
return MakeUnknown(rc, rtype, contents, origin)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,10 @@ work that providers do.
|
|||
|
||||
// SetTargetSOA sets the SOA fields.
|
||||
func (rc *RecordConfig) SetTargetSOA(ns, mbox string, serial, refresh, retry, expire, minttl uint32) error {
|
||||
rc.SetTarget(ns) // The NS field is stored as the .Target
|
||||
// The NS field is stored as the .Target
|
||||
if err := rc.SetTarget(ns); err != nil {
|
||||
return err
|
||||
}
|
||||
rc.SoaMbox = mbox
|
||||
rc.SoaSerial = serial
|
||||
rc.SoaRefresh = refresh
|
||||
|
@ -39,7 +42,6 @@ func (rc *RecordConfig) SetTargetSOA(ns, mbox string, serial, refresh, retry, ex
|
|||
|
||||
// SetTargetSOAStrings is like SetTargetSOA but accepts strings.
|
||||
func (rc *RecordConfig) SetTargetSOAStrings(ns, mbox, serial, refresh, retry, expire, minttl string) error {
|
||||
|
||||
u32serial, err := strconv.ParseUint(serial, 10, 32)
|
||||
if err != nil {
|
||||
return fmt.Errorf("SOA serial '%v' is invalid: %w", serial, err)
|
||||
|
|
|
@ -11,7 +11,9 @@ func (rc *RecordConfig) SetTargetSRV(priority, weight, port uint16, target strin
|
|||
rc.SrvPriority = priority
|
||||
rc.SrvWeight = weight
|
||||
rc.SrvPort = port
|
||||
rc.SetTarget(target)
|
||||
if err := rc.SetTarget(target); err != nil {
|
||||
return err
|
||||
}
|
||||
if rc.Type == "" {
|
||||
rc.Type = "SRV"
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ import (
|
|||
func (rc *RecordConfig) SetTargetSSHFP(algorithm uint8, fingerprint uint8, target string) error {
|
||||
rc.SshfpAlgorithm = algorithm
|
||||
rc.SshfpFingerprint = fingerprint
|
||||
rc.SetTarget(target)
|
||||
if err := rc.SetTarget(target); err != nil {
|
||||
return err
|
||||
}
|
||||
if rc.Type == "" {
|
||||
rc.Type = "SSHFP"
|
||||
}
|
||||
|
|
|
@ -10,7 +10,9 @@ import (
|
|||
// SetTargetSVCB sets the SVCB fields.
|
||||
func (rc *RecordConfig) SetTargetSVCB(priority uint16, target string, params []dns.SVCBKeyValue) error {
|
||||
rc.SvcPriority = priority
|
||||
rc.SetTarget(target)
|
||||
if err := rc.SetTarget(target); err != nil {
|
||||
return err
|
||||
}
|
||||
paramsStr := []string{}
|
||||
for _, kv := range params {
|
||||
paramsStr = append(paramsStr, fmt.Sprintf("%s=%s", kv.Key(), kv.String()))
|
||||
|
@ -32,7 +34,7 @@ func (rc *RecordConfig) SetTargetSVCBString(origin, contents string) error {
|
|||
}
|
||||
record, err := dns.NewRR(fmt.Sprintf("%s. %s %s", origin, rc.Type, contents))
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not parse SVCB record: %s", err)
|
||||
return fmt.Errorf("could not parse SVCB record: %w", err)
|
||||
}
|
||||
switch r := record.(type) {
|
||||
case *dns.HTTPS:
|
||||
|
|
|
@ -11,7 +11,9 @@ func (rc *RecordConfig) SetTargetTLSA(usage, selector, matchingtype uint8, targe
|
|||
rc.TlsaUsage = usage
|
||||
rc.TlsaSelector = selector
|
||||
rc.TlsaMatchingType = matchingtype
|
||||
rc.SetTarget(target)
|
||||
if err := rc.SetTarget(target); err != nil {
|
||||
return err
|
||||
}
|
||||
if rc.Type == "" {
|
||||
rc.Type = "TLSA"
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@ represented by the provider, which could be a single string, a series
|
|||
of smaller strings, or a single string that is quoted/escaped. This
|
||||
created tons of edge-cases and other distractions.
|
||||
|
||||
If a provider doesn't support certain charactors in a TXT record, use
|
||||
If a provider doesn't support certain characters in a TXT record, use
|
||||
the providers/$PROVIDER/auditrecords.go file to indicate this.
|
||||
DNSControl uses this information to warn users of unsupporrted input,
|
||||
and to skip related integration tests.
|
||||
|
@ -87,7 +87,7 @@ func splitChunks(buf string, lim int) []string {
|
|||
chunks = append(chunks, chunk)
|
||||
}
|
||||
if len(buf) > 0 {
|
||||
chunks = append(chunks, buf[:])
|
||||
chunks = append(chunks, buf)
|
||||
}
|
||||
return chunks
|
||||
}
|
||||
|
|
|
@ -45,7 +45,6 @@ func (rc *RecordConfig) GetTargetCombinedFunc(encodeFn func(s string) string) st
|
|||
// WARNING: How TXT records are handled is buggy but we can't change it because
|
||||
// code depends on the bugs. Use Get GetTargetCombinedFunc() instead.
|
||||
func (rc *RecordConfig) GetTargetCombined() string {
|
||||
|
||||
// Pseudo records:
|
||||
if _, ok := dns.StringToType[rc.Type]; !ok {
|
||||
switch rc.Type { // #rtype_variations
|
||||
|
@ -82,7 +81,7 @@ func (rc *RecordConfig) zoneFileQuoted() string {
|
|||
// TODO(tlim): Request the dns project add a function that returns
|
||||
// the string without the header.
|
||||
if rc.Type == "NAPTR" && rc.GetTargetField() == "" {
|
||||
rc.SetTarget(".")
|
||||
rc.MustSetTarget(".")
|
||||
}
|
||||
rr := rc.ToRR()
|
||||
header := rr.Header().String()
|
||||
|
@ -112,7 +111,7 @@ func (rc *RecordConfig) GetTargetDebug() string {
|
|||
case "A", "AAAA", "AKAMAICDN", "CNAME", "DHCID", "NS", "PTR", "TXT":
|
||||
// Nothing special.
|
||||
case "AZURE_ALIAS":
|
||||
content += fmt.Sprintf(" type=%s", rc.AzureAlias["type"])
|
||||
content += " type=" + rc.AzureAlias["type"]
|
||||
case "CAA":
|
||||
content += fmt.Sprintf(" caatag=%s caaflag=%d", rc.CaaTag, rc.CaaFlag)
|
||||
case "DS":
|
||||
|
@ -153,9 +152,16 @@ func (rc *RecordConfig) SetTarget(target string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// MustSetTarget is like SetTarget, but panics if an error occurs.
|
||||
// It should only be used in _test.go files and in the init() function.
|
||||
func (rc *RecordConfig) MustSetTarget(target string) {
|
||||
if err := rc.SetTarget(target); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
// SetTargetIP sets the target to an IP, verifying this is an appropriate rtype.
|
||||
func (rc *RecordConfig) SetTargetIP(ip net.IP) error {
|
||||
// TODO(tlim): Verify the rtype is appropriate for an IP.
|
||||
rc.SetTarget(ip.String())
|
||||
return nil
|
||||
return rc.SetTarget(ip.String())
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ package acme
|
|||
import (
|
||||
"crypto/x509"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
|
@ -104,7 +105,7 @@ func (c *certManager) IssueOrRenewCert(cfg *CertConfig, renewUnder int, verbose
|
|||
if !verbose {
|
||||
acmelog.Logger = log.New(io.Discard, "", 0)
|
||||
}
|
||||
defer c.finalCleanUp()
|
||||
defer c.finalCleanUp() //nolint:errcheck
|
||||
|
||||
log.Printf("Checking certificate [%s]", cfg.CertName)
|
||||
existing, err := c.storage.GetCertificate(cfg.CertName)
|
||||
|
@ -114,7 +115,7 @@ func (c *certManager) IssueOrRenewCert(cfg *CertConfig, renewUnder int, verbose
|
|||
|
||||
var client *lego.Client
|
||||
|
||||
var action = func() (*certificate.Resource, error) {
|
||||
action := func() (*certificate.Resource, error) {
|
||||
return client.Certificate.Obtain(certificate.ObtainRequest{
|
||||
Bundle: true,
|
||||
Domains: cfg.Names,
|
||||
|
@ -133,7 +134,7 @@ func (c *certManager) IssueOrRenewCert(cfg *CertConfig, renewUnder int, verbose
|
|||
namesOK := dnsNamesEqual(cfg.Names, names)
|
||||
if daysLeft >= float64(renewUnder) && namesOK {
|
||||
log.Println("Nothing to do")
|
||||
//nothing to do
|
||||
// nothing to do
|
||||
return false, nil
|
||||
}
|
||||
if !namesOK {
|
||||
|
@ -159,7 +160,7 @@ func (c *certManager) IssueOrRenewCert(cfg *CertConfig, renewUnder int, verbose
|
|||
}
|
||||
client.Challenge.Remove(challenge.HTTP01)
|
||||
client.Challenge.Remove(challenge.TLSALPN01)
|
||||
client.Challenge.SetDNS01Provider(c, dns01.WrapPreCheck(c.preCheckDNS))
|
||||
client.Challenge.SetDNS01Provider(c, dns01.WrapPreCheck(c.preCheckDNS)) //nolint:errcheck
|
||||
|
||||
certResource, err := action()
|
||||
if err != nil {
|
||||
|
@ -176,7 +177,7 @@ func (c *certManager) IssueOrRenewCert(cfg *CertConfig, renewUnder int, verbose
|
|||
func getCertInfo(pemBytes []byte) (names []string, remaining float64, err error) {
|
||||
block, _ := pem.Decode(pemBytes)
|
||||
if block == nil {
|
||||
return nil, 0, fmt.Errorf("invalid certificate PEM data")
|
||||
return nil, 0, errors.New("invalid certificate PEM data")
|
||||
}
|
||||
cert, err := x509.ParseCertificate(block.Bytes)
|
||||
if err != nil {
|
||||
|
@ -187,7 +188,7 @@ func getCertInfo(pemBytes []byte) (names []string, remaining float64, err error)
|
|||
// may be decommed eventually, and since there are no unit tests,
|
||||
// I'm not excited about making this change.
|
||||
// var daysLeft = float64(time.Until(cert.NotAfter)) / float64(time.Hour*24)
|
||||
var daysLeft = float64(cert.NotAfter.Sub(time.Now())) / float64(time.Hour*24)
|
||||
daysLeft := float64(time.Until(cert.NotAfter)) / float64(time.Hour*24)
|
||||
return cert.DNSNames, daysLeft, nil
|
||||
}
|
||||
|
||||
|
@ -225,24 +226,26 @@ func (c *certManager) Present(domain, token, keyAuth string) (e error) {
|
|||
nameservers.AddNSRecords(d)
|
||||
|
||||
// make sure we have the latest config before we change anything.
|
||||
// alternately, we could avoid a lot of this trouble if we really really trusted no-purge in all cases
|
||||
// alternately, we could avoid a lot of this trouble if we really trusted no-purge in all cases
|
||||
if err := c.ensureNoPendingCorrections(d); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy domain and work from copy from now on. That way original config can be used to "restore" when we are all done.
|
||||
copy, err := d.Copy()
|
||||
// Copy domain and work from cpy from now on. That way original config can be used to "restore" when we are all done.
|
||||
cpy, err := d.Copy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.originalDomains = append(c.originalDomains, d)
|
||||
c.domains[name] = copy
|
||||
d = copy
|
||||
c.domains[name] = cpy
|
||||
d = cpy
|
||||
}
|
||||
|
||||
fqdn, val := dns01.GetRecord(domain, keyAuth)
|
||||
txt := &models.RecordConfig{Type: "TXT"}
|
||||
txt.SetTargetTXT(val)
|
||||
if err := txt.SetTargetTXT(val); err != nil {
|
||||
return err
|
||||
}
|
||||
txt.SetLabelFromFQDN(fqdn, d.Name)
|
||||
d.Records = append(d.Records, txt)
|
||||
return c.getAndRunCorrections(d)
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"errors"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
|
@ -18,6 +18,7 @@ type directoryStorage string
|
|||
func (d directoryStorage) certFile(name, ext string) string {
|
||||
return filepath.Join(d.certDir(name), name+"."+ext)
|
||||
}
|
||||
|
||||
func (d directoryStorage) certDir(name string) string {
|
||||
return filepath.Join(string(d), "certificates", name)
|
||||
}
|
||||
|
@ -29,12 +30,15 @@ func (d directoryStorage) accountDirectory(acmeHost string) string {
|
|||
func (d directoryStorage) accountFile(acmeHost string) string {
|
||||
return filepath.Join(d.accountDirectory(acmeHost), "account.json")
|
||||
}
|
||||
|
||||
func (d directoryStorage) accountKeyFile(acmeHost string) string {
|
||||
return filepath.Join(d.accountDirectory(acmeHost), "account.key")
|
||||
}
|
||||
|
||||
const perms os.FileMode = 0600
|
||||
const dirPerms os.FileMode = 0700
|
||||
const (
|
||||
perms os.FileMode = 0o600
|
||||
dirPerms os.FileMode = 0o700
|
||||
)
|
||||
|
||||
func (d directoryStorage) GetCertificate(name string) (*certificate.Resource, error) {
|
||||
f, err := os.Open(d.certFile(name, "json"))
|
||||
|
@ -106,7 +110,7 @@ func (d directoryStorage) GetAccount(acmeHost string) (*Account, error) {
|
|||
}
|
||||
keyBlock, _ := pem.Decode(keyBytes)
|
||||
if keyBlock == nil {
|
||||
return nil, fmt.Errorf("error decoding account private key")
|
||||
return nil, errors.New("error decoding account private key")
|
||||
}
|
||||
acct.key, err = x509.ParseECPrivateKey(keyBlock.Bytes)
|
||||
if err != nil {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"crypto/x509"
|
||||
"encoding/json"
|
||||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -123,7 +124,7 @@ func (v *vaultStorage) GetAccount(acmeHost string) (*Account, error) {
|
|||
if dat, err = v.getString("tls.key", secret.Data, path); err != nil {
|
||||
return nil, err
|
||||
} else if block, _ = pem.Decode(dat); block == nil {
|
||||
return nil, fmt.Errorf("error decoding account private key")
|
||||
return nil, errors.New("error decoding account private key")
|
||||
} else if key, err = x509.ParseECPrivateKey(block.Bytes); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
|
||||
// LoadProviderConfigs will open or execute the specified file name, and parse its contents. It will replace environment variables it finds if any value matches $[A-Za-z_-0-9]+
|
||||
func LoadProviderConfigs(fname string) (map[string]map[string]string, error) {
|
||||
var results = map[string]map[string]string{}
|
||||
results := map[string]map[string]string{}
|
||||
|
||||
var dat []byte
|
||||
var err error
|
||||
|
@ -45,7 +45,7 @@ func LoadProviderConfigs(fname string) (map[string]map[string]string, error) {
|
|||
r := JsonConfigReader.New(strings.NewReader(s))
|
||||
err = json.NewDecoder(r).Decode(&results)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed parsing provider credentials file %v: %v", fname, err)
|
||||
return nil, fmt.Errorf("failed parsing provider credentials file %v: %w", fname, err)
|
||||
}
|
||||
if err = replaceEnvVars(results); err != nil {
|
||||
return nil, err
|
||||
|
@ -66,7 +66,7 @@ func LoadProviderConfigs(fname string) (map[string]map[string]string, error) {
|
|||
|
||||
func isExecutable(filename string) bool {
|
||||
if stat, statErr := os.Stat(filename); statErr == nil {
|
||||
if mode := stat.Mode(); mode&0111 == 0111 {
|
||||
if mode := stat.Mode(); mode&0o111 == 0o111 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ func readCredsFile(filename string) ([]byte, error) {
|
|||
fmt.Printf("INFO: Config file %q does not exist. Skipping.\n", filename)
|
||||
return []byte{}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed reading provider credentials file %v: %v", filename, err)
|
||||
return nil, fmt.Errorf("failed reading provider credentials file %v: %w", filename, err)
|
||||
}
|
||||
return dat, nil
|
||||
}
|
||||
|
|
|
@ -26,8 +26,7 @@ type Differ interface {
|
|||
ChangedGroups(existing []*models.RecordConfig) (map[models.RecordKey][]string, []string, int, error)
|
||||
}
|
||||
|
||||
type differ struct {
|
||||
}
|
||||
type differ struct{}
|
||||
|
||||
// get normalized content for record. target, ttl, mxprio, and specified metadata
|
||||
func (d *differ) content(r *models.RecordConfig) string {
|
||||
|
|
|
@ -89,7 +89,6 @@ func analyzeByLabel(cc *CompareConfig) (ChangeList, int) {
|
|||
}
|
||||
|
||||
func analyzeByRecord(cc *CompareConfig) (ChangeList, int) {
|
||||
|
||||
var instructions ChangeList
|
||||
var actualChangeCount int
|
||||
// For each label, for each type at that label, see if there are any changes.
|
||||
|
@ -136,7 +135,6 @@ func mkDelete(l string, t string, msgs []string, oldRecs models.Records) Change
|
|||
}
|
||||
|
||||
func removeCommon(existing, desired []targetConfig) ([]targetConfig, []targetConfig) {
|
||||
|
||||
// Sort by comparableFull.
|
||||
sort.Slice(existing, func(i, j int) bool { return existing[i].comparableFull < existing[j].comparableFull })
|
||||
sort.Slice(desired, func(i, j int) bool { return desired[i].comparableFull < desired[j].comparableFull })
|
||||
|
@ -159,7 +157,6 @@ func removeCommon(existing, desired []targetConfig) ([]targetConfig, []targetCon
|
|||
// findTTLChanges finds the records that ONLY change their TTL. For those, generate a Change.
|
||||
// Remove such items from the list.
|
||||
func findTTLChanges(existing, desired []targetConfig) ([]targetConfig, []targetConfig, ChangeList) {
|
||||
|
||||
if (len(existing) == 0) || (len(desired) == 0) {
|
||||
return existing, desired, nil
|
||||
}
|
||||
|
@ -251,8 +248,7 @@ func humanDiff(a, b targetConfig) string {
|
|||
}
|
||||
|
||||
func diffTargets(existing, desired []targetConfig) ChangeList {
|
||||
|
||||
//fmt.Printf("DEBUG: diffTargets(\nexisting=%v\ndesired=%v\nDEBUG.\n", existing, desired)
|
||||
// fmt.Printf("DEBUG: diffTargets(\nexisting=%v\ndesired=%v\nDEBUG.\n", existing, desired)
|
||||
|
||||
// Nothing to do?
|
||||
if len(existing) == 0 && len(desired) == 0 {
|
||||
|
@ -277,7 +273,7 @@ func diffTargets(existing, desired []targetConfig) ChangeList {
|
|||
|
||||
// the remaining chunks are changes (regardless of TTL)
|
||||
mi := min(len(existing), len(desired))
|
||||
for i := 0; i < mi; i++ {
|
||||
for i := range mi {
|
||||
er := existing[i].rec
|
||||
dr := desired[i].rec
|
||||
|
||||
|
|
|
@ -60,48 +60,55 @@ func makeRec(label, rtype, content string) *models.RecordConfig {
|
|||
origin := "f.com"
|
||||
r := models.RecordConfig{TTL: 300}
|
||||
r.SetLabel(label, origin)
|
||||
r.PopulateFromString(rtype, content, origin)
|
||||
if err := r.PopulateFromString(rtype, content, origin); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return &r
|
||||
}
|
||||
|
||||
func makeRecTTL(label, rtype, content string, ttl uint32) *models.RecordConfig {
|
||||
r := makeRec(label, rtype, content)
|
||||
r.TTL = ttl
|
||||
return r
|
||||
}
|
||||
|
||||
var testDataAA1234 = makeRec("laba", "A", "1.2.3.4") // [ 0]
|
||||
var testDataAA5678 = makeRec("laba", "A", "5.6.7.8") //
|
||||
var testDataAA1234ttl700 = makeRecTTL("laba", "A", "1.2.3.4", 700) //
|
||||
var testDataAA5678ttl700 = makeRecTTL("laba", "A", "5.6.7.8", 700) //
|
||||
var testDataAMX10a = makeRec("laba", "MX", "10 laba") // [ 1]
|
||||
var testDataCCa = makeRec("labc", "CNAME", "laba") // [ 2]
|
||||
var testDataEA15 = makeRec("labe", "A", "10.10.10.15") // [ 3]
|
||||
var e4 = makeRec("labe", "A", "10.10.10.16") // [ 4]
|
||||
var e5 = makeRec("labe", "A", "10.10.10.17") // [ 5]
|
||||
var e6 = makeRec("labe", "A", "10.10.10.18") // [ 6]
|
||||
var e7 = makeRec("labg", "NS", "laba") // [ 7]
|
||||
var e8 = makeRec("labg", "NS", "labb") // [ 8]
|
||||
var e9 = makeRec("labg", "NS", "labc") // [ 9]
|
||||
var e10 = makeRec("labg", "NS", "labe") // [10]
|
||||
var e11mx = makeRec("labh", "MX", "22 ttt") // [11]
|
||||
var e11 = makeRec("labh", "CNAME", "labd") // [11]
|
||||
var testDataApexMX1aaa = makeRec("", "MX", "1 aaa")
|
||||
var (
|
||||
testDataAA1234 = makeRec("laba", "A", "1.2.3.4") // [ 0]
|
||||
testDataAA5678 = makeRec("laba", "A", "5.6.7.8") //
|
||||
testDataAA1234ttl700 = makeRecTTL("laba", "A", "1.2.3.4", 700) //
|
||||
testDataAA5678ttl700 = makeRecTTL("laba", "A", "5.6.7.8", 700) //
|
||||
testDataAMX10a = makeRec("laba", "MX", "10 laba") // [ 1]
|
||||
testDataCCa = makeRec("labc", "CNAME", "laba") // [ 2]
|
||||
testDataEA15 = makeRec("labe", "A", "10.10.10.15") // [ 3]
|
||||
e4 = makeRec("labe", "A", "10.10.10.16") // [ 4]
|
||||
e5 = makeRec("labe", "A", "10.10.10.17") // [ 5]
|
||||
e6 = makeRec("labe", "A", "10.10.10.18") // [ 6]
|
||||
e7 = makeRec("labg", "NS", "laba") // [ 7]
|
||||
e8 = makeRec("labg", "NS", "labb") // [ 8]
|
||||
e9 = makeRec("labg", "NS", "labc") // [ 9]
|
||||
e10 = makeRec("labg", "NS", "labe") // [10]
|
||||
e11mx = makeRec("labh", "MX", "22 ttt") // [11]
|
||||
e11 = makeRec("labh", "CNAME", "labd") // [11]
|
||||
testDataApexMX1aaa = makeRec("", "MX", "1 aaa")
|
||||
)
|
||||
|
||||
var testDataAA1234clone = makeRec("laba", "A", "1.2.3.4") // [ 0']
|
||||
var testDataAA12345 = makeRec("laba", "A", "1.2.3.5") // [ 1']
|
||||
var testDataAMX20b = makeRec("laba", "MX", "20 labb") // [ 2']
|
||||
var d3 = makeRec("labe", "A", "10.10.10.95") // [ 3']
|
||||
var d4 = makeRec("labe", "A", "10.10.10.96") // [ 4']
|
||||
var d5 = makeRec("labe", "A", "10.10.10.97") // [ 5']
|
||||
var d6 = makeRec("labe", "A", "10.10.10.98") // [ 6']
|
||||
var d7 = makeRec("labf", "TXT", "foo") // [ 7']
|
||||
var d8 = makeRec("labg", "NS", "labf") // [ 8']
|
||||
var d9 = makeRec("labg", "NS", "laba") // [ 9']
|
||||
var d10 = makeRec("labg", "NS", "labe") // [10']
|
||||
var d11 = makeRec("labg", "NS", "labb") // [11']
|
||||
var d12 = makeRec("labh", "A", "1.2.3.4") // [12']
|
||||
var d13 = makeRec("labc", "CNAME", "labe") // [13']
|
||||
var testDataApexMX22bbb = makeRec("", "MX", "22 bbb")
|
||||
var (
|
||||
testDataAA1234clone = makeRec("laba", "A", "1.2.3.4") // [ 0']
|
||||
testDataAA12345 = makeRec("laba", "A", "1.2.3.5") // [ 1']
|
||||
testDataAMX20b = makeRec("laba", "MX", "20 labb") // [ 2']
|
||||
d3 = makeRec("labe", "A", "10.10.10.95") // [ 3']
|
||||
d4 = makeRec("labe", "A", "10.10.10.96") // [ 4']
|
||||
d5 = makeRec("labe", "A", "10.10.10.97") // [ 5']
|
||||
d6 = makeRec("labe", "A", "10.10.10.98") // [ 6']
|
||||
d7 = makeRec("labf", "TXT", "foo") // [ 7']
|
||||
d8 = makeRec("labg", "NS", "labf") // [ 8']
|
||||
d9 = makeRec("labg", "NS", "laba") // [ 9']
|
||||
d10 = makeRec("labg", "NS", "labe") // [10']
|
||||
d11 = makeRec("labg", "NS", "labb") // [11']
|
||||
d12 = makeRec("labh", "A", "1.2.3.4") // [12']
|
||||
d13 = makeRec("labc", "CNAME", "labe") // [13']
|
||||
testDataApexMX22bbb = makeRec("", "MX", "22 bbb")
|
||||
)
|
||||
|
||||
func justMsgString(cl ChangeList) string {
|
||||
msgs := justMsgs(cl)
|
||||
|
@ -158,7 +165,6 @@ func Test_analyzeByRecordSet(t *testing.T) {
|
|||
wantChangeZone string
|
||||
wantChangeCount int
|
||||
}{
|
||||
|
||||
{
|
||||
name: "oneequal",
|
||||
args: args{
|
||||
|
@ -559,7 +565,6 @@ ChangeList: len=11
|
|||
})
|
||||
|
||||
// NB(tlim): There is no analyzeByZone(). diff2.ByZone() uses analyzeByRecord().
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -586,15 +591,15 @@ func mkTargetConfig(x ...*models.RecordConfig) []targetConfig {
|
|||
}
|
||||
|
||||
func mkTargetConfigMap(x ...*models.RecordConfig) map[string]*targetConfig {
|
||||
var m = map[string]*targetConfig{}
|
||||
m := map[string]*targetConfig{}
|
||||
for _, v := range mkTargetConfig(x...) {
|
||||
v := v
|
||||
m[v.comparableFull] = &v
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func Test_diffTargets(t *testing.T) {
|
||||
|
||||
type args struct {
|
||||
existing []targetConfig
|
||||
desired []targetConfig
|
||||
|
@ -604,7 +609,6 @@ func Test_diffTargets(t *testing.T) {
|
|||
args args
|
||||
want ChangeList
|
||||
}{
|
||||
|
||||
{
|
||||
name: "add1changettl",
|
||||
args: args{
|
||||
|
@ -612,9 +616,10 @@ func Test_diffTargets(t *testing.T) {
|
|||
desired: mkTargetConfig(testDataAA5678ttl700, testDataAA1234ttl700),
|
||||
},
|
||||
want: ChangeList{
|
||||
Change{Type: CHANGE,
|
||||
Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "A"},
|
||||
New: models.Records{testDataAA5678ttl700, testDataAA1234ttl700},
|
||||
Change{
|
||||
Type: CHANGE,
|
||||
Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "A"},
|
||||
New: models.Records{testDataAA5678ttl700, testDataAA1234ttl700},
|
||||
Msgs: []string{
|
||||
"± MODIFY-TTL laba.f.com A 5.6.7.8 ttl=(300->700)",
|
||||
"+ CREATE laba.f.com A 1.2.3.4 ttl=700",
|
||||
|
@ -629,7 +634,7 @@ func Test_diffTargets(t *testing.T) {
|
|||
existing: mkTargetConfig(testDataAA1234),
|
||||
desired: mkTargetConfig(testDataAA1234),
|
||||
},
|
||||
//want: ,
|
||||
// want: ,
|
||||
},
|
||||
|
||||
{
|
||||
|
@ -639,7 +644,8 @@ func Test_diffTargets(t *testing.T) {
|
|||
desired: mkTargetConfig(testDataAA1234, testDataAMX10a),
|
||||
},
|
||||
want: ChangeList{
|
||||
Change{Type: CREATE,
|
||||
Change{
|
||||
Type: CREATE,
|
||||
Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "MX"},
|
||||
New: models.Records{makeRec("laba", "MX", "10 laba.f.com.")},
|
||||
Msgs: []string{"+ CREATE laba.f.com MX 10 laba.f.com. ttl=300"},
|
||||
|
@ -654,7 +660,8 @@ func Test_diffTargets(t *testing.T) {
|
|||
desired: mkTargetConfig(testDataAA1234),
|
||||
},
|
||||
want: ChangeList{
|
||||
Change{Type: DELETE,
|
||||
Change{
|
||||
Type: DELETE,
|
||||
Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "MX"},
|
||||
Old: models.Records{makeRec("laba", "MX", "10 laba.f.com.")},
|
||||
Msgs: []string{"- DELETE laba.f.com MX 10 laba.f.com. ttl=300"},
|
||||
|
@ -669,7 +676,8 @@ func Test_diffTargets(t *testing.T) {
|
|||
desired: mkTargetConfig(testDataAA1234, testDataAMX20b),
|
||||
},
|
||||
want: ChangeList{
|
||||
Change{Type: CHANGE,
|
||||
Change{
|
||||
Type: CHANGE,
|
||||
Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "MX"},
|
||||
Old: models.Records{testDataAMX10a},
|
||||
New: models.Records{testDataAMX20b},
|
||||
|
@ -685,7 +693,8 @@ func Test_diffTargets(t *testing.T) {
|
|||
desired: mkTargetConfig(testDataAA1234),
|
||||
},
|
||||
want: ChangeList{
|
||||
Change{Type: CHANGE,
|
||||
Change{
|
||||
Type: CHANGE,
|
||||
Key: models.RecordKey{NameFQDN: "laba.f.com", Type: "A"},
|
||||
Old: models.Records{testDataAA1234, testDataAA5678},
|
||||
New: models.Records{testDataAA1234},
|
||||
|
@ -696,13 +705,13 @@ func Test_diffTargets(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
//fmt.Printf("DEBUG: Test %02d\n", i)
|
||||
// fmt.Printf("DEBUG: Test %02d\n", i)
|
||||
got := diffTargets(tt.args.existing, tt.args.desired)
|
||||
g := strings.TrimSpace(justMsgString(got))
|
||||
w := strings.TrimSpace(justMsgString(tt.want))
|
||||
d := diff.Diff(g, w)
|
||||
if d != "" {
|
||||
//fmt.Printf("DEBUG: fail %q %q\n", g, w)
|
||||
// fmt.Printf("DEBUG: fail %q %q\n", g, w)
|
||||
t.Errorf("diffTargets()\n diff=%s", d)
|
||||
}
|
||||
})
|
||||
|
@ -720,7 +729,6 @@ func Test_removeCommon(t *testing.T) {
|
|||
want []targetConfig
|
||||
want1 []targetConfig
|
||||
}{
|
||||
|
||||
{
|
||||
name: "same",
|
||||
args: args{
|
||||
|
@ -772,7 +780,6 @@ func Test_filterBy(t *testing.T) {
|
|||
args args
|
||||
want []targetConfig
|
||||
}{
|
||||
|
||||
{
|
||||
name: "removeall",
|
||||
args: args{
|
||||
|
@ -821,7 +828,6 @@ func Test_splitTTLOnly(t *testing.T) {
|
|||
wantDesireDiff []targetConfig
|
||||
wantChanges string
|
||||
}{
|
||||
|
||||
{
|
||||
name: "simple",
|
||||
args: args{
|
||||
|
|
|
@ -113,7 +113,6 @@ func NewCompareConfig(origin string, existing, desired models.Records, compFn Co
|
|||
|
||||
// verifyCNAMEAssertions verifies assertions about CNAME updates ordering.
|
||||
func (cc *CompareConfig) verifyCNAMEAssertions() {
|
||||
|
||||
// According to the RFCs if a label has a CNAME, it can not have any other
|
||||
// records at that label... even other CNAMEs. Therefore, we need to be
|
||||
// careful with changes at a label that involve a CNAME.
|
||||
|
@ -121,7 +120,7 @@ func (cc *CompareConfig) verifyCNAMEAssertions() {
|
|||
// OLD: a.example.com CNAME b
|
||||
// NEW: a.example.com A 1.2.3.4
|
||||
// We must delete the CNAME record THEN create the A record. If we
|
||||
// blindly create the the A first, most APIs will reply with an error
|
||||
// blindly create the A first, most APIs will reply with an error
|
||||
// because there is already a CNAME at that label.
|
||||
// Example 2:
|
||||
// OLD: a.example.com A 1.2.3.4
|
||||
|
@ -141,9 +140,7 @@ func (cc *CompareConfig) verifyCNAMEAssertions() {
|
|||
|
||||
for _, ld := range cc.ldata {
|
||||
for j, td := range ld.tdata {
|
||||
|
||||
if td.rType == "CNAME" {
|
||||
|
||||
// This assertion doesn't hold for a site that permits a
|
||||
// recordset with both CNAMEs and other records, such as
|
||||
// Cloudflare.
|
||||
|
@ -167,13 +164,11 @@ func (cc *CompareConfig) verifyCNAMEAssertions() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Generate a string that can be used to compare this record to others
|
||||
// for equality.
|
||||
func mkCompareBlobs(rc *models.RecordConfig, f func(*models.RecordConfig) string) (string, string) {
|
||||
|
||||
// Start with the comparable string
|
||||
comp := rc.ToComparableNoTTL()
|
||||
|
||||
|
@ -204,7 +199,6 @@ func (cc *CompareConfig) addRecords(recs models.Records, storeInExisting bool) {
|
|||
z := prettyzone.PrettySort(recs, cc.origin, 0, nil)
|
||||
|
||||
for _, rec := range z.Records {
|
||||
|
||||
key := rec.Key()
|
||||
label := key.NameFQDN
|
||||
rtype := key.Type
|
||||
|
|
|
@ -51,7 +51,6 @@ func TestNewCompareConfig(t *testing.T) {
|
|||
args args
|
||||
want string
|
||||
}{
|
||||
|
||||
{
|
||||
name: "one",
|
||||
args: args{
|
||||
|
@ -227,7 +226,6 @@ compFn: <nil>
|
|||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
models.CanonicalizeTargets(tt.args.desired, "f.com")
|
||||
models.CanonicalizeTargets(tt.args.existing, "f.com")
|
||||
|
||||
|
@ -264,7 +262,6 @@ func Test_mkCompareBlobs(t *testing.T) {
|
|||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
got, got1 := mkCompareBlobs(tt.args.rc, tt.args.f)
|
||||
if got != tt.want {
|
||||
t.Errorf("mkCompareBlobs() got = %q, want %q", got, tt.want)
|
||||
|
|
|
@ -5,6 +5,7 @@ package diff2
|
|||
// NO_PURGE, ENSURE_ABSENT and IGNORE*() features.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -56,7 +57,7 @@ As a result, the diff2 algorithm won't delete them because they are desired!
|
|||
(Of course "desired" can't have duplicate records. Check before you add.)
|
||||
|
||||
This is different than in the old implementation (pkg/diff) which would generate the
|
||||
diff but but then do a bunch of checking to see if the record was one that
|
||||
diff but then do a bunch of checking to see if the record was one that
|
||||
shouldn't be deleted. Or, in the case of NO_PURGE, would simply not do the
|
||||
deletions. This was complex because there were many edge cases to deal with.
|
||||
It was often also wrong. For example, if a provider updates all records in a
|
||||
|
@ -114,13 +115,16 @@ func handsoff(
|
|||
return nil, nil, err
|
||||
}
|
||||
|
||||
var punct = ":"
|
||||
punct := ":"
|
||||
if printer.MaxReport == 0 {
|
||||
punct = "."
|
||||
}
|
||||
|
||||
// Process IGNORE*() and NO_PURGE features:
|
||||
ignorable, foreign := processIgnoreAndNoPurge(domain, existing, desired, absences, unmanagedConfigs, noPurge)
|
||||
ignorable, foreign, err := processIgnoreAndNoPurge(domain, existing, desired, absences, unmanagedConfigs, noPurge)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if len(foreign) != 0 {
|
||||
msgs = append(msgs, fmt.Sprintf("%d records not being deleted because of NO_PURGE%s", len(foreign), punct))
|
||||
msgs = append(msgs, reportSkips(foreign, !printer.SkinnyReport)...)
|
||||
|
@ -138,7 +142,7 @@ func handsoff(
|
|||
msgs = append(msgs, fmt.Sprintf(" %s %s %s", r.GetLabelFQDN(), r.Type, r.GetTargetCombined()))
|
||||
}
|
||||
if !unmanagedSafely {
|
||||
return nil, nil, fmt.Errorf(strings.Join(msgs, "\n") +
|
||||
return nil, nil, errors.New(strings.Join(msgs, "\n") +
|
||||
"\nERROR: Unsafe to continue. Add DISABLE_IGNORE_SAFETY_CHECK to D() to override")
|
||||
}
|
||||
}
|
||||
|
@ -172,14 +176,16 @@ func reportSkips(recs models.Records, full bool) []string {
|
|||
}
|
||||
|
||||
// processIgnoreAndNoPurge processes the IGNORE_*() and NO_PURGE/ENSURE_ABSENT() features.
|
||||
func processIgnoreAndNoPurge(domain string, existing, desired, absences models.Records, unmanagedConfigs []*models.UnmanagedConfig, noPurge bool) (models.Records, models.Records) {
|
||||
func processIgnoreAndNoPurge(domain string, existing, desired, absences models.Records, unmanagedConfigs []*models.UnmanagedConfig, noPurge bool) (models.Records, models.Records, error) {
|
||||
var ignorable, foreign models.Records
|
||||
desiredDB := models.NewRecordDBFromRecords(desired, domain)
|
||||
absentDB := models.NewRecordDBFromRecords(absences, domain)
|
||||
compileUnmanagedConfigs(unmanagedConfigs)
|
||||
if err := compileUnmanagedConfigs(unmanagedConfigs); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
for _, rec := range existing {
|
||||
isMatch := matchAny(unmanagedConfigs, rec)
|
||||
//fmt.Printf("DEBUG: matchAny returned: %v\n", isMatch)
|
||||
// fmt.Printf("DEBUG: matchAny returned: %v\n", isMatch)
|
||||
if isMatch {
|
||||
ignorable = append(ignorable, rec)
|
||||
} else {
|
||||
|
@ -194,7 +200,7 @@ func processIgnoreAndNoPurge(domain string, existing, desired, absences models.R
|
|||
}
|
||||
}
|
||||
}
|
||||
return ignorable, foreign
|
||||
return ignorable, foreign, nil
|
||||
}
|
||||
|
||||
// findConflicts takes a list of recs and a list of (compiled) UnmanagedConfigs
|
||||
|
@ -247,7 +253,7 @@ func compileUnmanagedConfigs(configs []*models.UnmanagedConfig) error {
|
|||
|
||||
// matchAny returns true if rec matches any of the uconfigs.
|
||||
func matchAny(uconfigs []*models.UnmanagedConfig, rec *models.RecordConfig) bool {
|
||||
//fmt.Printf("DEBUG: matchAny(%s, %q, %q, %q)\n", models.DebugUnmanagedConfig(uconfigs), rec.NameFQDN, rec.Type, rec.GetTargetField())
|
||||
// fmt.Printf("DEBUG: matchAny(%s, %q, %q, %q)\n", models.DebugUnmanagedConfig(uconfigs), rec.NameFQDN, rec.Type, rec.GetTargetField())
|
||||
for _, uc := range uconfigs {
|
||||
if matchLabel(uc.LabelGlob, rec.GetLabel()) &&
|
||||
matchType(uc.RTypeMap, rec.Type) &&
|
||||
|
@ -257,12 +263,14 @@ func matchAny(uconfigs []*models.UnmanagedConfig, rec *models.RecordConfig) bool
|
|||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func matchLabel(labelGlob glob.Glob, labelName string) bool {
|
||||
if labelGlob == nil {
|
||||
return true
|
||||
}
|
||||
return labelGlob.Match(labelName)
|
||||
}
|
||||
|
||||
func matchType(typeMap map[string]struct{}, typeName string) bool {
|
||||
if len(typeMap) == 0 {
|
||||
return true
|
||||
|
@ -270,6 +278,7 @@ func matchType(typeMap map[string]struct{}, typeName string) bool {
|
|||
_, ok := typeMap[typeName]
|
||||
return ok
|
||||
}
|
||||
|
||||
func matchTarget(targetGlob glob.Glob, targetName string) bool {
|
||||
if targetGlob == nil {
|
||||
return true
|
||||
|
|
|
@ -11,7 +11,7 @@ import (
|
|||
testifyrequire "github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// parseZoneContents is copied verbatium from providers/bind/bindProvider.go
|
||||
// parseZoneContents is copied verbatim from providers/bind/bindProvider.go
|
||||
// because import cycles and... tests shouldn't depend on huge modules.
|
||||
func parseZoneContents(content string, zoneName string, zonefileName string) (models.Records, error) {
|
||||
zp := dns.NewZoneParser(strings.NewReader(content), zoneName, zonefileName)
|
||||
|
@ -47,7 +47,7 @@ func handsoffHelper(t *testing.T, existingZone, desiredJs string, noPurge bool,
|
|||
|
||||
existing, err := parseZoneContents(existingZone, "f.com", "no_file_name")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dnsconfig, err := js.ExecuteJavascriptString([]byte(desiredJs), false, nil)
|
||||
|
@ -68,13 +68,16 @@ func handsoffHelper(t *testing.T, existingZone, desiredJs string, noPurge bool,
|
|||
absences[i].SetLabel(j.GetLabel(), "f.com")
|
||||
}
|
||||
|
||||
ignored, purged := processIgnoreAndNoPurge(
|
||||
ignored, purged, err := processIgnoreAndNoPurge(
|
||||
"f.com",
|
||||
existing, desired,
|
||||
absences,
|
||||
unmanagedConfigs,
|
||||
noPurge,
|
||||
)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ignoredRecs := showRecs(ignored)
|
||||
purgedRecs := showRecs(purged)
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
package diff2
|
||||
|
||||
import "golang.org/x/exp/constraints"
|
||||
|
||||
func min[T constraints.Ordered](a, b T) T {
|
||||
if a < b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
|
@ -145,7 +145,6 @@ func (edges Edges[T]) RemoveNode(toRemove *Node[T]) Edges[T] {
|
|||
|
||||
// Contains returns true if a node is in the graph AND is in that direction.
|
||||
func (edges Edges[T]) Contains(toFind *Node[T], direction edgeDirection) bool {
|
||||
|
||||
for _, edge := range edges {
|
||||
if edge.Node == toFind && edge.Direction == direction {
|
||||
return true
|
||||
|
|
|
@ -58,7 +58,7 @@ func Test_RemoveNode(t *testing.T) {
|
|||
|
||||
// example.com change has been removed
|
||||
nodes := graph.Tree.Get("example.com")
|
||||
assert.Len(t, nodes, 0)
|
||||
assert.Empty(t, nodes)
|
||||
|
||||
nodes = graph.Tree.Get("a.hq.example.com")
|
||||
assert.Len(t, nodes, 1)
|
||||
|
|
|
@ -22,7 +22,6 @@ func SortUsingGraph[T dnsgraph.Graphable](records []T) SortResult[T] {
|
|||
sortState := createDirectedSortState(records)
|
||||
|
||||
for sortState.hasWork() {
|
||||
|
||||
for _, node := range sortState.graph.All {
|
||||
sortState.hasResolvedLastRound = false
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
)
|
||||
|
||||
func Test_graphsort(t *testing.T) {
|
||||
|
||||
t.Run("Direct dependency",
|
||||
executeGraphSort(
|
||||
[]testutils.StubRecord{
|
||||
|
|
|
@ -7,7 +7,6 @@ import (
|
|||
)
|
||||
|
||||
func Test_domaintree(t *testing.T) {
|
||||
|
||||
t.Run("Single FQDN",
|
||||
executeTreeTest(
|
||||
[]string{
|
||||
|
|
|
@ -18,7 +18,7 @@ func hashFunc(call otto.FunctionCall) otto.Value {
|
|||
algorithm := call.Argument(0).String() // The algorithm to use for hashing
|
||||
value := call.Argument(1).String() // The value to hash
|
||||
//lint:ignore SA4006 work around bug in staticcheck. This value is needed if the switch statement follows the default path.
|
||||
result := otto.Value{}
|
||||
result := otto.Value{} //nolint:staticcheck
|
||||
fmt.Printf("%s\n", value)
|
||||
|
||||
switch algorithm {
|
||||
|
|
36
pkg/js/js.go
36
pkg/js/js.go
|
@ -51,7 +51,6 @@ func ExecuteJavaScript(file string, devMode bool, variables map[string]string) (
|
|||
|
||||
// ExecuteJavascriptString accepts a string containing javascript and runs it, returning the resulting dnsConfig.
|
||||
func ExecuteJavascriptString(script []byte, devMode bool, variables map[string]string) (*models.DNSConfig, error) {
|
||||
|
||||
vm := otto.New()
|
||||
l := loop.New(vm)
|
||||
|
||||
|
@ -69,16 +68,26 @@ func ExecuteJavascriptString(script []byte, devMode bool, variables map[string]s
|
|||
}
|
||||
}
|
||||
|
||||
vm.Set("require", require)
|
||||
vm.Set("REV", reverse)
|
||||
vm.Set("REVCOMPAT", reverseCompat)
|
||||
vm.Set("glob", listFiles) // used for require_glob()
|
||||
vm.Set("PANIC", jsPanic)
|
||||
vm.Set("HASH", hashFunc)
|
||||
// add functions to otto
|
||||
functions := map[string]interface{}{
|
||||
"require": require,
|
||||
"REV": reverse,
|
||||
"REVCOMPAT": reverseCompat,
|
||||
"glob": listFiles, // used for require_glob()
|
||||
"PANIC": jsPanic,
|
||||
"HASH": hashFunc,
|
||||
}
|
||||
for name, fn := range functions {
|
||||
if err := vm.Set(name, fn); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// add cli variables to otto
|
||||
for key, value := range variables {
|
||||
vm.Set(key, value)
|
||||
if err := vm.Set(key, value); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
helperJs := GetHelpers(devMode)
|
||||
|
@ -150,15 +159,14 @@ func require(call otto.FunctionCall) otto.Value {
|
|||
printer.Debugf("requiring: %s (%s)\n", file, relFile)
|
||||
// quick fix, by replacing to linux slashes, to make it work with windows paths too.
|
||||
data, err := os.ReadFile(filepath.ToSlash(relFile))
|
||||
|
||||
if err != nil {
|
||||
throw(call.Otto, err.Error())
|
||||
}
|
||||
|
||||
var value = otto.TrueValue()
|
||||
value := otto.TrueValue()
|
||||
|
||||
// If its a json file return the json value, else default to true
|
||||
var ext = strings.ToLower(filepath.Ext(relFile))
|
||||
ext := strings.ToLower(filepath.Ext(relFile))
|
||||
if strings.HasSuffix(ext, "json") || strings.HasSuffix(ext, "json5") {
|
||||
cmd := fmt.Sprintf(`JSON.parse(JSON.stringify(%s))`, string(data))
|
||||
value, err = call.Otto.Run(cmd)
|
||||
|
@ -201,7 +209,7 @@ func listFiles(call otto.FunctionCall) otto.Value {
|
|||
}
|
||||
|
||||
// Second: Recursive?
|
||||
var recursive = true
|
||||
recursive := true
|
||||
if call.Argument(1).IsDefined() && !call.Argument(1).IsNull() {
|
||||
if call.Argument(1).IsBoolean() {
|
||||
recursive, _ = call.Argument(1).ToBoolean() // If it should be recursive
|
||||
|
@ -211,7 +219,7 @@ func listFiles(call otto.FunctionCall) otto.Value {
|
|||
}
|
||||
|
||||
// Third: File extension filter.
|
||||
var fileExtension = ".js"
|
||||
fileExtension := ".js"
|
||||
if call.Argument(2).IsDefined() && !call.Argument(2).IsNull() {
|
||||
if call.Argument(2).IsString() {
|
||||
fileExtension = call.Argument(2).String() // Which file extension to filter for.
|
||||
|
@ -247,7 +255,7 @@ func listFiles(call otto.FunctionCall) otto.Value {
|
|||
// ONLY skip, when the file extension is NOT matching, or when filter is NOT disabled.
|
||||
return nil
|
||||
}
|
||||
//dirPath := filepath.ToSlash(filepath.Dir(path)) + "/"
|
||||
// dirPath := filepath.ToSlash(filepath.Dir(path)) + "/"
|
||||
files = append(files, path)
|
||||
return err
|
||||
})
|
||||
|
|
|
@ -23,7 +23,10 @@ const (
|
|||
)
|
||||
|
||||
func init() {
|
||||
os.Chdir("../..") // go up a directory so we helpers.js is in a consistent place.
|
||||
// go up a directory so we helpers.js is in a consistent place.
|
||||
if err := os.Chdir("../.."); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestParsedFiles(t *testing.T) {
|
||||
|
@ -56,8 +59,8 @@ func TestParsedFiles(t *testing.T) {
|
|||
}
|
||||
|
||||
for _, dc := range conf.Domains {
|
||||
//fmt.Printf("DEBUG: PrettySort: domain=%q #rec=%d\n", dc.Name, len(dc.Records))
|
||||
//fmt.Printf("DEBUG: records = %d %v\n", len(dc.Records), dc.Records)
|
||||
// fmt.Printf("DEBUG: PrettySort: domain=%q #rec=%d\n", dc.Name, len(dc.Records))
|
||||
// fmt.Printf("DEBUG: records = %d %v\n", len(dc.Records), dc.Records)
|
||||
ps := prettyzone.PrettySort(dc.Records, dc.Name, 0, nil)
|
||||
dc.Records = ps.Records
|
||||
if len(dc.Records) == 0 {
|
||||
|
@ -67,7 +70,7 @@ func TestParsedFiles(t *testing.T) {
|
|||
|
||||
// Initialize any DNS providers mentioned.
|
||||
for _, dProv := range conf.DNSProviders {
|
||||
var pcfg = map[string]string{}
|
||||
pcfg := map[string]string{}
|
||||
|
||||
if dProv.Type == "-" {
|
||||
// Pretend any "look up provider type in creds.json" results
|
||||
|
@ -101,8 +104,10 @@ func TestParsedFiles(t *testing.T) {
|
|||
es := string(expectedJSON)
|
||||
as := string(actualJSON)
|
||||
_, _ = es, as
|
||||
// When debugging, leave behind the actual result:
|
||||
os.WriteFile(expectedFile+".ACTUAL", []byte(as), 0644) // Leave behind the actual result:
|
||||
// Leave behind the actual result:
|
||||
if err := os.WriteFile(expectedFile+".ACTUAL", []byte(as), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
testifyrequire.JSONEqf(t, es, as, "EXPECTING %q = \n```\n%s\n```", expectedFile, as)
|
||||
|
||||
// For each domain, if there is a zone file, test against it:
|
||||
|
@ -128,16 +133,16 @@ func TestParsedFiles(t *testing.T) {
|
|||
as := actualZone
|
||||
if es != as {
|
||||
// On failure, leave behind the .ACTUAL file.
|
||||
os.WriteFile(zoneFile+".ACTUAL", []byte(actualZone), 0644)
|
||||
if err := os.WriteFile(zoneFile+".ACTUAL", []byte(actualZone), 0o644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
testifyrequire.Equal(t, es, as, "EXPECTING %q =\n```\n%s```", zoneFile, as)
|
||||
}
|
||||
if dCount > 0 && (len(conf.Domains) != dCount) {
|
||||
t.Fatal(fmt.Errorf("only %d of %d domains in %q have zonefiles", dCount, len(conf.Domains), name))
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -160,6 +165,5 @@ func TestErrors(t *testing.T) {
|
|||
t.Fatal("Expected error but found none")
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ func DetermineNameserversForProviders(dc *models.DomainConfig, providers []*mode
|
|||
if n > 0 && n < take {
|
||||
take = n
|
||||
}
|
||||
for i := 0; i < take; i++ {
|
||||
for i := range take {
|
||||
ns = append(ns, nss[i])
|
||||
}
|
||||
}
|
||||
|
@ -78,7 +78,9 @@ func AddNSRecords(dc *models.DomainConfig) {
|
|||
if !strings.HasSuffix(t, ".") {
|
||||
t += "."
|
||||
}
|
||||
rc.SetTarget(t)
|
||||
if err := rc.SetTarget(t); err != nil {
|
||||
fmt.Printf("failed AddNSRecords rc.SetTarget(%q): %s\n", t, err)
|
||||
}
|
||||
|
||||
dc.Records = append(dc.Records, rc)
|
||||
}
|
||||
|
|
|
@ -9,14 +9,16 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
const providersImportDir = "../../providers"
|
||||
const providersPackageName = "providers"
|
||||
const (
|
||||
providersImportDir = "../../providers"
|
||||
providersPackageName = "providers"
|
||||
)
|
||||
|
||||
func TestCapabilitiesAreFiltered(t *testing.T) {
|
||||
// Any capabilities which we wish to whitelist because it's not directly
|
||||
// something we can test against.
|
||||
skipCheckCapabilities := make(map[string]struct{})
|
||||
//skipCheckCapabilities["CanUseBlahBlahBlah"] = struct{}{}
|
||||
// skipCheckCapabilities["CanUseBlahBlahBlah"] = struct{}{}
|
||||
|
||||
fset := token.NewFileSet()
|
||||
pkgs, err := parser.ParseDir(fset, providersImportDir, nil, 0)
|
||||
|
@ -70,5 +72,4 @@ func TestCapabilitiesAreFiltered(t *testing.T) {
|
|||
t.Errorf("MISSING: providers.%s (%d) is not checked by checkProviderCapabilities", capName, capInt)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,6 @@ func flattenSPFs(cfg *models.DNSConfig) []error {
|
|||
}
|
||||
// now split if needed
|
||||
if split, ok := txt.Metadata["split"]; ok {
|
||||
|
||||
overhead1 := 0
|
||||
// overhead1: The first segment of the SPF record
|
||||
// needs to be shorter than the others due to the overhead of
|
||||
|
@ -91,10 +90,14 @@ func flattenSPFs(cfg *models.DNSConfig) []error {
|
|||
for _, k := range sortedKeys(recs) {
|
||||
v := recs[k]
|
||||
if k == "@" {
|
||||
txt.SetTargetTXTs(v)
|
||||
if err := txt.SetTargetTXTs(v); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
} else {
|
||||
cp, _ := txt.Copy()
|
||||
cp.SetTargetTXTs(v)
|
||||
if err := cp.SetTargetTXTs(v); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
cp.SetLabelFromFQDN(k, domain.Name)
|
||||
domain.Records = append(domain.Records, cp)
|
||||
}
|
||||
|
@ -107,7 +110,7 @@ func flattenSPFs(cfg *models.DNSConfig) []error {
|
|||
}
|
||||
// check if cache is stale
|
||||
for _, e := range cache.ResolveErrors() {
|
||||
errs = append(errs, Warning{fmt.Errorf("problem resolving SPF record: %s", e)})
|
||||
errs = append(errs, Warning{fmt.Errorf("problem resolving SPF record: %w", e)})
|
||||
}
|
||||
if len(cache.ResolveErrors()) == 0 {
|
||||
changed := cache.ChangedRecords()
|
||||
|
|
|
@ -8,12 +8,11 @@ import (
|
|||
|
||||
func makeRC(label, domain, target string, rc models.RecordConfig) *models.RecordConfig {
|
||||
rc.SetLabel(label, domain)
|
||||
rc.SetTarget(target)
|
||||
rc.MustSetTarget(target)
|
||||
return &rc
|
||||
}
|
||||
|
||||
func TestImportTransform(t *testing.T) {
|
||||
|
||||
const transformDouble = "0.0.0.0~1.1.1.1~~9.0.0.0,10.0.0.0"
|
||||
const transformSingle = "0.0.0.0~1.1.1.1~~8.0.0.0"
|
||||
src := &models.DomainConfig{
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
"net"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
|
@ -35,7 +36,7 @@ func checkTarget(target string) error {
|
|||
return nil
|
||||
}
|
||||
if target == "" {
|
||||
return fmt.Errorf("empty target")
|
||||
return errors.New("empty target")
|
||||
}
|
||||
if strings.ContainsAny(target, `'" +,|!£$%&()=?^*ç°§;:<>[]()@`) {
|
||||
return fmt.Errorf("target (%v) includes invalid char", target)
|
||||
|
@ -53,7 +54,7 @@ func checkTarget(target string) error {
|
|||
// validateRecordTypes list of valid rec.Type values. Returns true if this is a real DNS record type, false means it is a pseudo-type used internally.
|
||||
func validateRecordTypes(rec *models.RecordConfig, domain string, pTypes []string) error {
|
||||
// #rtype_variations
|
||||
var validTypes = map[string]bool{
|
||||
validTypes := map[string]bool{
|
||||
"A": true,
|
||||
"AAAA": true,
|
||||
"ALIAS": false,
|
||||
|
@ -230,12 +231,12 @@ func checkTargets(rec *models.RecordConfig, domain string) (errs []error) {
|
|||
default:
|
||||
if rec.Metadata["orig_custom_type"] != "" {
|
||||
// it is a valid custom type. We perform no validation on target
|
||||
return
|
||||
return errs
|
||||
}
|
||||
errs = append(errs, fmt.Errorf("checkTargets: Unimplemented record type (%v) domain=%v name=%v",
|
||||
rec.Type, domain, rec.GetLabel()))
|
||||
}
|
||||
return
|
||||
return errs
|
||||
}
|
||||
|
||||
func transformCNAME(target, oldDomain, newDomain, suffixstrip string) string {
|
||||
|
@ -270,7 +271,8 @@ func transformLabel(label, suffixstrip string) (string, error) {
|
|||
|
||||
// import_transform imports the records of one zone into another, modifying records along the way.
|
||||
func importTransform(srcDomain, dstDomain *models.DomainConfig,
|
||||
transforms []transform.IPConversion, ttl uint32, suffixstrip string) error {
|
||||
transforms []transform.IPConversion, ttl uint32, suffixstrip string,
|
||||
) error {
|
||||
// Read srcDomain.Records, transform, and append to dstDomain.Records:
|
||||
// 1. Skip any that aren't A or CNAMEs.
|
||||
// 2. Append destDomainname to the end of the label.
|
||||
|
@ -290,7 +292,7 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig,
|
|||
case "A":
|
||||
trs, err := transform.IPToList(net.ParseIP(rec.GetTargetField()), transforms)
|
||||
if err != nil {
|
||||
return fmt.Errorf("import_transform: TransformIP(%v, %v) returned err=%s", rec.GetTargetField(), transforms, err)
|
||||
return fmt.Errorf("import_transform: TransformIP(%v, %v) returned err=%w", rec.GetTargetField(), transforms, err)
|
||||
}
|
||||
for _, tr := range trs {
|
||||
r := newRec(rec, ttl)
|
||||
|
@ -299,7 +301,9 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig,
|
|||
return err
|
||||
}
|
||||
r.SetLabel(l, dstDomain.Name)
|
||||
r.SetTarget(tr.String())
|
||||
if err := r.SetTarget(tr.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
dstDomain.Records = append(dstDomain.Records, r)
|
||||
}
|
||||
case "CNAME":
|
||||
|
@ -309,7 +313,9 @@ func importTransform(srcDomain, dstDomain *models.DomainConfig,
|
|||
return err
|
||||
}
|
||||
r.SetLabel(l, dstDomain.Name)
|
||||
r.SetTarget(transformCNAME(r.GetTargetField(), srcDomain.Name, dstDomain.Name, suffixstrip))
|
||||
if err := r.SetTarget(transformCNAME(r.GetTargetField(), srcDomain.Name, dstDomain.Name, suffixstrip)); err != nil {
|
||||
return err
|
||||
}
|
||||
dstDomain.Records = append(dstDomain.Records, r)
|
||||
default:
|
||||
// Anything else is ignored.
|
||||
|
@ -376,7 +382,6 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) {
|
|||
// Normalize Records.
|
||||
models.PostProcessRecords(domain.Records)
|
||||
for _, rec := range domain.Records {
|
||||
|
||||
if rec.TTL == 0 {
|
||||
rec.TTL = models.DefaultTTL
|
||||
}
|
||||
|
@ -425,9 +430,13 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) {
|
|||
if rec.SubDomain != "" {
|
||||
origin = rec.SubDomain + "." + origin
|
||||
}
|
||||
rec.SetTarget(dnsutil.AddOrigin(rec.GetTargetField(), origin))
|
||||
if err := rec.SetTarget(dnsutil.AddOrigin(rec.GetTargetField(), origin)); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
} else if rec.Type == "A" || rec.Type == "AAAA" {
|
||||
rec.SetTarget(net.ParseIP(rec.GetTargetField()).String())
|
||||
if err := rec.SetTarget(net.ParseIP(rec.GetTargetField()).String()); err != nil {
|
||||
errs = append(errs, err)
|
||||
}
|
||||
} else if rec.Type == "PTR" {
|
||||
var err error
|
||||
var name string
|
||||
|
@ -460,7 +469,6 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) {
|
|||
if _, ok := rec.Metadata["ignore_name_disable_safety_check"]; ok {
|
||||
errs = append(errs, errors.New("IGNORE_NAME_DISABLE_SAFETY_CHECK no longer supported. Please use DISABLE_IGNORE_SAFETY_CHECK for the entire domain"))
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -481,7 +489,7 @@ func ValidateAndNormalizeConfig(config *models.DNSConfig) (errs []error) {
|
|||
}
|
||||
c := config.FindDomain(rec.GetTargetField())
|
||||
if c == nil {
|
||||
err = fmt.Errorf("IMPORT_TRANSFORM mentions non-existant domain %q", rec.GetTargetField())
|
||||
err = fmt.Errorf("IMPORT_TRANSFORM mentions non-existent domain %q", rec.GetTargetField())
|
||||
errs = append(errs, err)
|
||||
}
|
||||
err = importTransform(c, domain, table, rec.TTL, suffixstrip)
|
||||
|
@ -677,7 +685,6 @@ func checkRecordSetHasMultipleTTLs(records []*models.RecordConfig) (errs []error
|
|||
func formatInconsistency(r map[string]map[uint32]bool) string {
|
||||
var rtypeResult []string
|
||||
for rtype, ttlsMap := range r {
|
||||
|
||||
ttlList := make([]int, len(ttlsMap))
|
||||
i := 0
|
||||
for k := range ttlsMap {
|
||||
|
@ -696,7 +703,7 @@ func formatInconsistency(r map[string]map[uint32]bool) string {
|
|||
func commaSepInts(list []int) string {
|
||||
slist := make([]string, len(list))
|
||||
for i, v := range list {
|
||||
slist[i] = fmt.Sprintf("%d", v)
|
||||
slist[i] = strconv.Itoa(v)
|
||||
}
|
||||
return strings.Join(slist, ",")
|
||||
}
|
||||
|
@ -707,7 +714,7 @@ func commaSepInts(list []int) string {
|
|||
var providerCapabilityChecks = []pairTypeCapability{
|
||||
// #rtype_variations
|
||||
// If a zone uses rType X, the provider must support capability Y.
|
||||
//{"X", providers.Y},
|
||||
// {"X", providers.Y},
|
||||
capabilityCheck("AKAMAICDN", providers.CanUseAKAMAICDN),
|
||||
capabilityCheck("ALIAS", providers.CanUseAlias),
|
||||
capabilityCheck("AUTODNSSEC", providers.CanAutoDNSSEC),
|
||||
|
@ -803,7 +810,6 @@ func checkProviderCapabilities(dc *models.DomainConfig) error {
|
|||
break
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if !hasAny {
|
||||
continue
|
||||
|
@ -854,15 +860,20 @@ func applyRecordTransforms(domain *models.DomainConfig) error {
|
|||
}
|
||||
for i, newIP := range newIPs {
|
||||
if i == 0 && !newIP.Equal(ip) {
|
||||
rec.SetTarget(newIP.String()) // replace target of first record if different
|
||||
// replace target of first record if different
|
||||
if err := rec.SetTarget(newIP.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
} else if i > 0 {
|
||||
// any additional ips need identical records with the alternate ip added to the domain
|
||||
copy, err := rec.Copy()
|
||||
cpy, err := rec.Copy()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
copy.SetTarget(newIP.String())
|
||||
domain.Records = append(domain.Records, copy)
|
||||
if err := cpy.SetTarget(newIP.String()); err != nil {
|
||||
return err
|
||||
}
|
||||
domain.Records = append(domain.Records, cpy)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import (
|
|||
)
|
||||
|
||||
func TestSoaLabelAndTarget(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
isError bool
|
||||
label string
|
||||
target string
|
||||
|
@ -22,8 +22,10 @@ func TestSoaLabelAndTarget(t *testing.T) {
|
|||
}
|
||||
for _, test := range tests {
|
||||
experiment := fmt.Sprintf("%s %s", test.label, test.target)
|
||||
rc := makeRC(test.label, "foo.com", test.target, models.RecordConfig{Type: "SOA",
|
||||
SoaExpire: 1, SoaMinttl: 1, SoaRefresh: 1, SoaRetry: 1, SoaSerial: 1, SoaMbox: "bar.foo.com"})
|
||||
rc := makeRC(test.label, "foo.com", test.target, models.RecordConfig{
|
||||
Type: "SOA",
|
||||
SoaExpire: 1, SoaMinttl: 1, SoaRefresh: 1, SoaRetry: 1, SoaSerial: 1, SoaMbox: "bar.foo.com",
|
||||
})
|
||||
err := checkTargets(rc, "foo.com")
|
||||
if err != nil && !test.isError {
|
||||
t.Errorf("%v: Error (%v)\n", experiment, err)
|
||||
|
@ -35,7 +37,7 @@ func TestSoaLabelAndTarget(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCheckSoa(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
isError bool
|
||||
expire uint32
|
||||
minttl uint32
|
||||
|
@ -75,7 +77,7 @@ func TestCheckSoa(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCheckLabel(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
label string
|
||||
rType string
|
||||
target string
|
||||
|
@ -109,7 +111,6 @@ func TestCheckLabel(t *testing.T) {
|
|||
t.Errorf("%02d: Expected error but got none", i)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -123,7 +124,7 @@ func checkError(t *testing.T, err error, shouldError bool, experiment string) {
|
|||
}
|
||||
|
||||
func Test_assert_valid_ipv4(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
experiment string
|
||||
isError bool
|
||||
}{
|
||||
|
@ -140,7 +141,7 @@ func Test_assert_valid_ipv4(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_assert_valid_target(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
experiment string
|
||||
isError bool
|
||||
}{
|
||||
|
@ -162,7 +163,7 @@ func Test_assert_valid_target(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_transform_cname(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
experiment string
|
||||
expected string
|
||||
}{
|
||||
|
@ -182,41 +183,71 @@ func Test_transform_cname(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_transform_cname_strip(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
p []string
|
||||
expected string
|
||||
}{
|
||||
{[]string{"ai.meta.stackexchange.com.", "stackexchange.com", "com.internal", "com"},
|
||||
"ai.meta.stackexchange.com.internal."},
|
||||
{[]string{"askubuntu.com.", "askubuntu.com", "com.internal", "com"},
|
||||
"askubuntu.com.internal."},
|
||||
{[]string{"blogoverflow.com.", "stackoverflow.com", "com.internal", "com"},
|
||||
"blogoverflow.com.internal."},
|
||||
{[]string{"careers.stackoverflow.com.", "stackoverflow.com", "com.internal", "com"},
|
||||
"careers.stackoverflow.com.internal."},
|
||||
{[]string{"chat.stackexchange.com.", "askubuntu.com", "com.internal", "com"},
|
||||
"chat.stackexchange.com.internal."},
|
||||
{[]string{"chat.stackexchange.com.", "stackoverflow.com", "com.internal", "com"},
|
||||
"chat.stackexchange.com.internal."},
|
||||
{[]string{"chat.stackexchange.com.", "superuser.com", "com.internal", "com"},
|
||||
"chat.stackexchange.com.internal."},
|
||||
{[]string{"sstatic.net.", "sstatic.net", "net.internal", "net"},
|
||||
"sstatic.net.internal."},
|
||||
{[]string{"stackapps.com.", "stackapps.com", "com.internal", "com"},
|
||||
"stackapps.com.internal."},
|
||||
{[]string{"stackexchange.com.", "stackexchange.com", "com.internal", "com"},
|
||||
"stackexchange.com.internal."},
|
||||
{[]string{"stackoverflow.com.", "stackoverflow.com", "com.internal", "com"},
|
||||
"stackoverflow.com.internal."},
|
||||
{[]string{"superuser.com.", "superuser.com", "com.internal", "com"},
|
||||
"superuser.com.internal."},
|
||||
{[]string{"teststackoverflow.com.", "teststackoverflow.com", "com.internal", "com"},
|
||||
"teststackoverflow.com.internal."},
|
||||
{[]string{"webapps.stackexchange.com.", "stackexchange.com", "com.internal", "com"},
|
||||
"webapps.stackexchange.com.internal."},
|
||||
{
|
||||
[]string{"ai.meta.stackexchange.com.", "stackexchange.com", "com.internal", "com"},
|
||||
"ai.meta.stackexchange.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"askubuntu.com.", "askubuntu.com", "com.internal", "com"},
|
||||
"askubuntu.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"blogoverflow.com.", "stackoverflow.com", "com.internal", "com"},
|
||||
"blogoverflow.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"careers.stackoverflow.com.", "stackoverflow.com", "com.internal", "com"},
|
||||
"careers.stackoverflow.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"chat.stackexchange.com.", "askubuntu.com", "com.internal", "com"},
|
||||
"chat.stackexchange.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"chat.stackexchange.com.", "stackoverflow.com", "com.internal", "com"},
|
||||
"chat.stackexchange.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"chat.stackexchange.com.", "superuser.com", "com.internal", "com"},
|
||||
"chat.stackexchange.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"sstatic.net.", "sstatic.net", "net.internal", "net"},
|
||||
"sstatic.net.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"stackapps.com.", "stackapps.com", "com.internal", "com"},
|
||||
"stackapps.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"stackexchange.com.", "stackexchange.com", "com.internal", "com"},
|
||||
"stackexchange.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"stackoverflow.com.", "stackoverflow.com", "com.internal", "com"},
|
||||
"stackoverflow.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"superuser.com.", "superuser.com", "com.internal", "com"},
|
||||
"superuser.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"teststackoverflow.com.", "teststackoverflow.com", "com.internal", "com"},
|
||||
"teststackoverflow.com.internal.",
|
||||
},
|
||||
{
|
||||
[]string{"webapps.stackexchange.com.", "stackexchange.com", "com.internal", "com"},
|
||||
"webapps.stackexchange.com.internal.",
|
||||
},
|
||||
//
|
||||
{[]string{"sstatic.net.", "sstatic.net", "com.internal", "com"},
|
||||
"sstatic.net.internal."},
|
||||
{
|
||||
[]string{"sstatic.net.", "sstatic.net", "com.internal", "com"},
|
||||
"sstatic.net.internal.",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@ -231,7 +262,7 @@ func TestNSAtRoot(t *testing.T) {
|
|||
// do not allow ns records for @
|
||||
rec := &models.RecordConfig{Type: "NS"}
|
||||
rec.SetLabel("test", "foo.com")
|
||||
rec.SetTarget("ns1.name.com.")
|
||||
rec.MustSetTarget("ns1.name.com.")
|
||||
errs := checkTargets(rec, "foo.com")
|
||||
if len(errs) > 0 {
|
||||
t.Error("Expect no error with ns record on subdomain")
|
||||
|
@ -246,7 +277,7 @@ func TestNSAtRoot(t *testing.T) {
|
|||
func TestNS1URLFWDValid(t *testing.T) {
|
||||
rec := &models.RecordConfig{Type: "NS1_URLFWD"}
|
||||
rec.SetLabel("test1", "foo.com")
|
||||
rec.SetTarget("/ http://example.com 302 2 0")
|
||||
rec.MustSetTarget("/ http://example.com 302 2 0")
|
||||
|
||||
errs := checkTargets(rec, "foo.com")
|
||||
if len(errs) > 0 {
|
||||
|
@ -257,7 +288,7 @@ func TestNS1URLFWDValid(t *testing.T) {
|
|||
func TestNS1URLFWDInvalid(t *testing.T) {
|
||||
rec := &models.RecordConfig{Type: "NS1_URLFWD"}
|
||||
rec.SetLabel("test2", "foo.com")
|
||||
rec.SetTarget("/ http://example.com 302 2")
|
||||
rec.MustSetTarget("/ http://example.com 302 2")
|
||||
|
||||
errs := checkTargets(rec, "foo.com")
|
||||
if len(errs) == 0 {
|
||||
|
@ -266,7 +297,7 @@ func TestNS1URLFWDInvalid(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestTransforms(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
givenIP string
|
||||
expectedRecords []string
|
||||
}{
|
||||
|
@ -300,9 +331,9 @@ func TestTransforms(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestCNAMEMutex(t *testing.T) {
|
||||
var recA = &models.RecordConfig{Type: "CNAME"}
|
||||
recA := &models.RecordConfig{Type: "CNAME"}
|
||||
recA.SetLabel("foo", "foo.example.com")
|
||||
recA.SetTarget("example.com.")
|
||||
recA.MustSetTarget("example.com.")
|
||||
tests := []struct {
|
||||
rType string
|
||||
name string
|
||||
|
@ -315,9 +346,9 @@ func TestCNAMEMutex(t *testing.T) {
|
|||
}
|
||||
for _, tst := range tests {
|
||||
t.Run(fmt.Sprintf("%s %s", tst.rType, tst.name), func(t *testing.T) {
|
||||
var recB = &models.RecordConfig{Type: tst.rType}
|
||||
recB := &models.RecordConfig{Type: tst.rType}
|
||||
recB.SetLabel(tst.name, "example.com")
|
||||
recB.SetTarget("example2.com.")
|
||||
recB.MustSetTarget("example2.com.")
|
||||
dc := &models.DomainConfig{
|
||||
Name: "example.com",
|
||||
Records: []*models.RecordConfig{recA, recB},
|
||||
|
@ -479,7 +510,8 @@ func TestTLSAValidation(t *testing.T) {
|
|||
RegistrarName: "BIND",
|
||||
Records: []*models.RecordConfig{
|
||||
makeRC("_443._tcp", "_443._tcp.example.com", "abcdef0", models.RecordConfig{
|
||||
Type: "TLSA", TlsaUsage: 4, TlsaSelector: 1, TlsaMatchingType: 1}),
|
||||
Type: "TLSA", TlsaUsage: 4, TlsaSelector: 1, TlsaMatchingType: 1,
|
||||
}),
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
@ -30,7 +30,7 @@ func (b bonfireNotifier) Notify(domain, provider, msg string, err error, preview
|
|||
// chat doesn't markdownify multiline messages. Split in two so the first line can have markdown
|
||||
parts := strings.SplitN(payload, "\n", 2)
|
||||
for _, p := range parts {
|
||||
http.Post(string(b), "text/markdown", strings.NewReader(p))
|
||||
_, _ = http.Post(string(b), "text/markdown", strings.NewReader(p))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,6 @@ func stripAnsiColors(colored string) string {
|
|||
}
|
||||
|
||||
func (m multiNotifier) Notify(domain, provider string, message string, err error, preview bool) {
|
||||
|
||||
// force-remove ansi colors that might come with the message from dnscontrol.
|
||||
// These usually don't render well in notifiers, outputting escape codes.
|
||||
// If a notifier wants to output colors, they should probably implement
|
||||
|
@ -50,6 +49,7 @@ func (m multiNotifier) Notify(domain, provider string, message string, err error
|
|||
n.Notify(domain, provider, nMsg, err, preview)
|
||||
}
|
||||
}
|
||||
|
||||
func (m multiNotifier) Done() {
|
||||
for _, n := range m {
|
||||
n.Done()
|
||||
|
|
|
@ -3,7 +3,6 @@ package notifications
|
|||
import "testing"
|
||||
|
||||
func Test_stripAnsiColorsValid(t *testing.T) {
|
||||
|
||||
coloredStr := "\x1b[0133myellow\x1b[0m" // 33 == yellow
|
||||
nonColoredStr := "yellow"
|
||||
|
||||
|
@ -14,7 +13,6 @@ func Test_stripAnsiColorsValid(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_stripAnsiColorsInvalid(t *testing.T) {
|
||||
|
||||
coloredStr := "\x1b[01AAmyellow\x1b[0m" // AA not a real color
|
||||
nonColoredStr := "yellow"
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ func (b shoutrrrNotifier) Notify(domain, provider, msg string, err error, previe
|
|||
} else {
|
||||
payload = fmt.Sprintf("DNSControl successfully ran correction for %s[%s]:\n%s", domain, provider, msg)
|
||||
}
|
||||
shoutrrr.Send(string(b), payload)
|
||||
_ = shoutrrr.Send(string(b), payload)
|
||||
}
|
||||
|
||||
func (b shoutrrrNotifier) Done() {}
|
||||
|
|
|
@ -40,7 +40,7 @@ func (s *slackNotifier) Notify(domain, provider, msg string, err error, preview
|
|||
}
|
||||
|
||||
json, _ := json.Marshal(payload)
|
||||
http.Post(s.URL, "text/json", bytes.NewReader(json))
|
||||
_, _ = http.Post(s.URL, "text/json", bytes.NewReader(json))
|
||||
}
|
||||
|
||||
func (s *slackNotifier) Done() {}
|
||||
|
|
|
@ -46,7 +46,7 @@ func (s *teamsNotifier) Notify(domain, provider, msg string, err error, preview
|
|||
}
|
||||
|
||||
json, _ := json.Marshal(payload)
|
||||
http.Post(s.URL, "text/json", bytes.NewReader(json))
|
||||
_, _ = http.Post(s.URL, "text/json", bytes.NewReader(json))
|
||||
}
|
||||
|
||||
func (s *teamsNotifier) Done() {}
|
||||
|
|
|
@ -35,7 +35,7 @@ func (s *telegramNotifier) Notify(domain, provider, msg string, err error, previ
|
|||
Text string `json:"text"`
|
||||
}
|
||||
|
||||
var url = fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", s.BotToken)
|
||||
url := fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage", s.BotToken)
|
||||
|
||||
payload.ChatID, _ = strconv.ParseInt(s.ChatID, 10, 64)
|
||||
|
||||
|
@ -50,7 +50,6 @@ func (s *telegramNotifier) Notify(domain, provider, msg string, err error, previ
|
|||
marshaledPayload, _ := json.Marshal(payload)
|
||||
|
||||
_, _ = http.Post(url, "application/json", bytes.NewBuffer(marshaledPayload))
|
||||
|
||||
}
|
||||
|
||||
func (s *telegramNotifier) Done() {}
|
||||
|
|
|
@ -20,25 +20,25 @@ type SSH struct {
|
|||
Session sshSession
|
||||
}
|
||||
|
||||
// func (b *SSH) StartProcess(cmd string, args ...string) (Waiter, io.Writer, io.Reader, io.Reader, error) {
|
||||
// func (b *SSH) StartProcess(cmd string, args ...string) (Waiter, io.Writer, io.Reader, error)
|
||||
// stdin, err := b.Session.StdinPipe()
|
||||
// if err != nil {
|
||||
// return nil, nil, nil, nil, errors.Annotate(err, "Could not get hold of the SSH session's stdin stream")
|
||||
// return nil, errors.Annotate(err, "Could not get hold of the SSH session's stdin stream")
|
||||
// }
|
||||
|
||||
// stdout, err := b.Session.StdoutPipe()
|
||||
// if err != nil {
|
||||
// return nil, nil, nil, nil, errors.Annotate(err, "Could not get hold of the SSH session's stdout stream")
|
||||
// return nil, errors.Annotate(err, "Could not get hold of the SSH session's stdout stream")
|
||||
// }
|
||||
|
||||
// stderr, err := b.Session.StderrPipe()
|
||||
// if err != nil {
|
||||
// return nil, nil, nil, nil, errors.Annotate(err, "Could not get hold of the SSH session's stderr stream")
|
||||
// return nil, errors.Annotate(err, "Could not get hold of the SSH session's stderr stream")
|
||||
// }
|
||||
|
||||
// err = b.Session.Start(b.createCmd(cmd, args))
|
||||
// if err != nil {
|
||||
// return nil, nil, nil, nil, errors.Annotate(err, "Could not spawn process via SSH")
|
||||
// return nil, errors.Annotate(err, "Could not spawn process via SSH")
|
||||
// }
|
||||
|
||||
// return b.Session, stdin, stdout, stderr, nil
|
||||
|
|
|
@ -42,6 +42,6 @@ func (s *session) Execute(cmd string) (string, string, error) {
|
|||
}
|
||||
|
||||
func (s *session) Exit() {
|
||||
s.upstream.Execute(fmt.Sprintf("Disconnect-PSSession -Session $%s", s.name))
|
||||
_, _, _ = s.upstream.Execute("Disconnect-PSSession -Session $" + s.name)
|
||||
s.upstream.Exit()
|
||||
}
|
||||
|
|
|
@ -91,5 +91,5 @@ func (c *UserPasswordCredential) prepare(s Middleware) (interface{}, error) {
|
|||
return nil, errors.Annotate(err, "Could not create PSCredential object")
|
||||
}
|
||||
|
||||
return fmt.Sprintf("$%s", name), nil
|
||||
return "$" + name, nil
|
||||
}
|
||||
|
|
|
@ -59,8 +59,8 @@ func (s *shell) Execute(cmd string) (string, string, error) {
|
|||
waiter := &sync.WaitGroup{}
|
||||
waiter.Add(2)
|
||||
|
||||
go streamReader(s.stdout, outBoundary, &sout, waiter)
|
||||
go streamReader(s.stderr, errBoundary, &serr, waiter)
|
||||
go streamReader(s.stdout, outBoundary, &sout, waiter) //nolint:errcheck
|
||||
go streamReader(s.stdout, outBoundary, &sout, waiter) //nolint:errcheck
|
||||
|
||||
waiter.Wait()
|
||||
|
||||
|
@ -72,7 +72,7 @@ func (s *shell) Execute(cmd string) (string, string, error) {
|
|||
}
|
||||
|
||||
func (s *shell) Exit() {
|
||||
s.stdin.Write([]byte("exit" + newline))
|
||||
_, _ = s.stdin.Write([]byte("exit" + newline))
|
||||
|
||||
// if it's possible to close stdin, do so (some backends, like the local one,
|
||||
// do support it)
|
||||
|
@ -81,7 +81,7 @@ func (s *shell) Exit() {
|
|||
closer.Close()
|
||||
}
|
||||
|
||||
s.handle.Wait()
|
||||
_ = s.handle.Wait()
|
||||
|
||||
s.handle = nil
|
||||
s.stdin = nil
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"fmt"
|
||||
"io"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
|
@ -87,7 +88,6 @@ func PrettySort(records models.Records, origin string, defaultTTL uint32, commen
|
|||
|
||||
// generateZoneFileHelper creates a pretty zonefile.
|
||||
func (z *ZoneGenData) generateZoneFileHelper(w io.Writer) error {
|
||||
|
||||
nameShortPrevious := ""
|
||||
|
||||
sort.Sort(z)
|
||||
|
@ -103,7 +103,6 @@ func (z *ZoneGenData) generateZoneFileHelper(w io.Writer) error {
|
|||
}
|
||||
}
|
||||
for i, rr := range z.Records {
|
||||
|
||||
// Fake types are commented out.
|
||||
prefix := ""
|
||||
_, ok := dns.StringToType[rr.Type]
|
||||
|
@ -122,7 +121,7 @@ func (z *ZoneGenData) generateZoneFileHelper(w io.Writer) error {
|
|||
// ttl
|
||||
ttl := ""
|
||||
if rr.TTL != z.DefaultTTL && rr.TTL != 0 {
|
||||
ttl = fmt.Sprint(rr.TTL)
|
||||
ttl = strconv.FormatUint(uint64(rr.TTL), 10)
|
||||
}
|
||||
|
||||
// type
|
||||
|
|
|
@ -30,7 +30,9 @@ func parseAndRegen(t *testing.T, buf *bytes.Buffer, expected string) {
|
|||
|
||||
// Generate it back:
|
||||
buf2 := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf2, parsed, "bosun.org")
|
||||
if err := writeZoneFileRR(buf2, parsed, "bosun.org"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// Compare:
|
||||
if buf2.String() != expected {
|
||||
|
@ -61,6 +63,7 @@ func writeZoneFileRR(w io.Writer, records []dns.RR, origin string) error {
|
|||
|
||||
return WriteZoneFileRC(w, rcs, origin, 0, nil)
|
||||
}
|
||||
|
||||
func TestMostCommonTtl(t *testing.T) {
|
||||
var records []dns.RR
|
||||
var g, e uint32
|
||||
|
@ -117,7 +120,6 @@ func TestMostCommonTtl(t *testing.T) {
|
|||
if e != g {
|
||||
t.Fatalf("expected %d; got %d\n", e, g)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// func WriteZoneFile
|
||||
|
@ -127,7 +129,9 @@ func TestWriteZoneFileSimple(t *testing.T) {
|
|||
r2, _ := dns.NewRR("bosun.org. 300 IN A 192.30.252.154")
|
||||
r3, _ := dns.NewRR("www.bosun.org. 300 IN CNAME bosun.org.")
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, []dns.RR{r1, r2, r3}, "bosun.org")
|
||||
if err := writeZoneFileRR(buf, []dns.RR{r1, r2, r3}, "bosun.org"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := `$TTL 300
|
||||
@ IN A 192.30.252.153
|
||||
IN A 192.30.252.154
|
||||
|
@ -148,7 +152,9 @@ func TestWriteZoneFileSimpleTtl(t *testing.T) {
|
|||
r3, _ := dns.NewRR("bosun.org. 100 IN A 192.30.252.155")
|
||||
r4, _ := dns.NewRR("www.bosun.org. 300 IN CNAME bosun.org.")
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, []dns.RR{r1, r2, r3, r4}, "bosun.org")
|
||||
if err := writeZoneFileRR(buf, []dns.RR{r1, r2, r3, r4}, "bosun.org"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := `$TTL 100
|
||||
@ IN A 192.30.252.153
|
||||
IN A 192.30.252.154
|
||||
|
@ -178,7 +184,9 @@ func TestWriteZoneFileMx(t *testing.T) {
|
|||
r8, _ := dns.NewRR("ccc.bosun.org. IN MX 40 aaa.example.com.")
|
||||
r9, _ := dns.NewRR("ccc.bosun.org. IN MX 1 ttt.example.com.")
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, []dns.RR{r1, r2, r3, r4, r5, r6, r7, r8, r9}, "bosun.org")
|
||||
if err := writeZoneFileRR(buf, []dns.RR{r1, r2, r3, r4, r5, r6, r7, r8, r9}, "bosun.org"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if buf.String() != testdataZFMX {
|
||||
t.Log(buf.String())
|
||||
t.Log(testdataZFMX)
|
||||
|
@ -207,7 +215,9 @@ func TestWriteZoneFileSrv(t *testing.T) {
|
|||
r4, _ := dns.NewRR(`bosun.org. 300 IN SRV 20 10 5050 foo.com.`)
|
||||
r5, _ := dns.NewRR(`bosun.org. 300 IN SRV 10 10 5050 foo.com.`)
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, []dns.RR{r1, r2, r3, r4, r5}, "bosun.org")
|
||||
if err := writeZoneFileRR(buf, []dns.RR{r1, r2, r3, r4, r5}, "bosun.org"); err != nil { // 5
|
||||
t.Fatal(err)
|
||||
}
|
||||
if buf.String() != testdataZFSRV {
|
||||
t.Log(buf.String())
|
||||
t.Log(testdataZFSRV)
|
||||
|
@ -230,7 +240,9 @@ func TestWriteZoneFilePtr(t *testing.T) {
|
|||
r2, _ := dns.NewRR(`bosun.org. 300 IN PTR barney.bosun.org.`)
|
||||
r3, _ := dns.NewRR(`bosun.org. 300 IN PTR alex.bosun.org.`)
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, []dns.RR{r1, r2, r3}, "bosun.org")
|
||||
if err := writeZoneFileRR(buf, []dns.RR{r1, r2, r3}, "bosun.org"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if buf.String() != testdataZFPTR {
|
||||
t.Log(buf.String())
|
||||
t.Log(testdataZFPTR)
|
||||
|
@ -254,7 +266,9 @@ func TestWriteZoneFileCaa(t *testing.T) {
|
|||
r5, _ := dns.NewRR(`bosun.org. 300 IN CAA 0 iodef "https://example.net"`)
|
||||
r6, _ := dns.NewRR(`bosun.org. 300 IN CAA 1 iodef "mailto:example.com"`)
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, []dns.RR{r1, r2, r3, r4, r5, r6}, "bosun.org")
|
||||
if err := writeZoneFileRR(buf, []dns.RR{r1, r2, r3, r4, r5, r6}, "bosun.org"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if buf.String() != testdataZFCAA {
|
||||
t.Log(buf.String())
|
||||
t.Log(testdataZFCAA)
|
||||
|
@ -298,7 +312,9 @@ func TestWriteZoneFileTxt(t *testing.T) {
|
|||
|
||||
// Generate the zonefile:
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, []dns.RR{rr}, "bosun.org")
|
||||
if err := writeZoneFileRR(buf, []dns.RR{rr}, "bosun.org"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
gz := buf.String()
|
||||
if gz != ez {
|
||||
t.Log("got: " + gz)
|
||||
|
@ -309,7 +325,6 @@ func TestWriteZoneFileTxt(t *testing.T) {
|
|||
// Reverse the process. Turn the zonefile into a list of records
|
||||
parseAndRegen(t, buf, ez)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Test 1 of each record type
|
||||
|
@ -344,7 +359,9 @@ func TestWriteZoneFileEach(t *testing.T) {
|
|||
d = append(d, mustNewRR(`bosun.org. 300 IN HTTPS 1 . alpn="h3,h2"`))
|
||||
d = append(d, mustNewRR(`bosun.org. 300 IN SVCB 1 . alpn="h3,h2"`))
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, d, "bosun.org")
|
||||
if err := writeZoneFileRR(buf, d, "bosun.org"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if buf.String() != testdataZFEach {
|
||||
t.Log(buf.String())
|
||||
t.Log(testdataZFEach)
|
||||
|
@ -390,7 +407,9 @@ func TestWriteZoneFileSynth(t *testing.T) {
|
|||
recs = append(recs, rsynz)
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
WriteZoneFileRC(buf, recs, "bosun.org", 0, []string{"c1", "c2", "c3\nc4"})
|
||||
if err := WriteZoneFileRC(buf, recs, "bosun.org", 0, []string{"c1", "c2", "c3\nc4"}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
expected := `$TTL 300
|
||||
; c1
|
||||
; c2
|
||||
|
@ -438,7 +457,9 @@ func TestWriteZoneFileOrder(t *testing.T) {
|
|||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, records, "stackoverflow.com")
|
||||
if err := writeZoneFileRR(buf, records, "stackoverflow.com"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Compare
|
||||
if buf.String() != testdataOrder {
|
||||
t.Log("Found:")
|
||||
|
@ -458,7 +479,9 @@ func TestWriteZoneFileOrder(t *testing.T) {
|
|||
}
|
||||
// Generate
|
||||
buf := &bytes.Buffer{}
|
||||
writeZoneFileRR(buf, records, "stackoverflow.com")
|
||||
if err := writeZoneFileRR(buf, records, "stackoverflow.com"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// Compare
|
||||
if buf.String() != testdataOrder {
|
||||
t.Log(buf.String())
|
||||
|
@ -532,7 +555,7 @@ func TestZoneLabelLess(t *testing.T) {
|
|||
zap
|
||||
*/
|
||||
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
e1, e2 string
|
||||
expected bool
|
||||
}{
|
||||
|
@ -584,7 +607,7 @@ func TestZoneRrtypeLess(t *testing.T) {
|
|||
In zonefiles we want to list SOAs, then NSs, then all others.
|
||||
*/
|
||||
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
e1, e2 string
|
||||
expected bool
|
||||
}{
|
||||
|
|
|
@ -29,7 +29,7 @@ func (z *ZoneGenData) Less(i, j int) bool {
|
|||
|
||||
//fmt.Printf("DEBUG: LabelLess(%q, %q) = %v %q %q\n", compA, compB, LabelLess(compA, compB), a.Name, b.Name)
|
||||
compA, compB := a.NameFQDN, b.NameFQDN
|
||||
// If we are at the apex, pass "@" to the Less function.
|
||||
// Unify FQDNs to "@". LabelLess needs FQDNs to be "@" to work properly.
|
||||
if a.Name == "@" {
|
||||
compA = "@"
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ func (z *ZoneGenData) Less(i, j int) bool {
|
|||
}
|
||||
return a.MxPreference < b.MxPreference
|
||||
case "SRV":
|
||||
//ta2, tb2 := a.(*dns.SRV), b.(*dns.SRV)
|
||||
// ta2, tb2 := a.(*dns.SRV), b.(*dns.SRV)
|
||||
pa, pb := a.SrvPort, b.SrvPort
|
||||
if pa != pb {
|
||||
return pa < pb
|
||||
|
@ -88,13 +88,13 @@ func (z *ZoneGenData) Less(i, j int) bool {
|
|||
}
|
||||
return a.SvcPriority < b.SvcPriority
|
||||
case "PTR":
|
||||
//ta2, tb2 := a.(*dns.PTR), b.(*dns.PTR)
|
||||
// ta2, tb2 := a.(*dns.PTR), b.(*dns.PTR)
|
||||
pa, pb := a.GetTargetField(), b.GetTargetField()
|
||||
if pa != pb {
|
||||
return pa < pb
|
||||
}
|
||||
case "CAA":
|
||||
//ta2, tb2 := a.(*dns.CAA), b.(*dns.CAA)
|
||||
// ta2, tb2 := a.(*dns.CAA), b.(*dns.CAA)
|
||||
// sort by tag
|
||||
pa, pb := a.CaaTag, b.CaaTag
|
||||
if pa != pb {
|
||||
|
@ -123,7 +123,7 @@ func (z *ZoneGenData) Less(i, j int) bool {
|
|||
default:
|
||||
// pass through. String comparison is sufficient.
|
||||
}
|
||||
//fmt.Printf("DEBUG: Less %q < %q == %v\n", a.String(), b.String(), a.String() < b.String())
|
||||
// fmt.Printf("DEBUG: Less %q < %q == %v\n", a.String(), b.String(), a.String() < b.String())
|
||||
return a.String() < b.String()
|
||||
}
|
||||
|
||||
|
@ -138,7 +138,7 @@ func LabelLess(a, b string) bool {
|
|||
}
|
||||
|
||||
// Sort @ at the top, then *, then everything else lexigraphically.
|
||||
// i.e. @ always is less. * is is less than everything but @.
|
||||
// i.e. @ always is less. * is less than everything but @.
|
||||
if a == "@" {
|
||||
return true
|
||||
}
|
||||
|
@ -171,11 +171,10 @@ func LabelLess(a, b string) bool {
|
|||
for i, j := ia, ib; minIdx >= 0; i, j, minIdx = i-1, j-1, minIdx-1 {
|
||||
// Compare as[i] < bs[j]
|
||||
// Sort @ at the top, then *, then everything else.
|
||||
// i.e. @ always is less. * is is less than everything but @.
|
||||
// i.e. @ always is less. * is less than everything but @.
|
||||
// If both are numeric, compare as integers, otherwise as strings.
|
||||
|
||||
if as[i] != bs[j] {
|
||||
|
||||
// If the first element is *, it is always less.
|
||||
if i == 0 && as[i] == "*" {
|
||||
return true
|
||||
|
@ -207,7 +206,8 @@ func zoneRrtypeLess(a, b string) bool {
|
|||
|
||||
// List SOAs, NSs, etc. then all others alphabetically.
|
||||
|
||||
for _, t := range []string{"SOA", "NS", "CNAME",
|
||||
for _, t := range []string{
|
||||
"SOA", "NS", "CNAME",
|
||||
"A", "AAAA", "MX", "SRV", "TXT",
|
||||
} {
|
||||
if a == t {
|
||||
|
|
|
@ -32,7 +32,7 @@ type Printer interface {
|
|||
Println(lines ...string)
|
||||
Warnf(fmt string, args ...interface{})
|
||||
Errorf(fmt string, args ...interface{})
|
||||
PrintfIf(print bool, fmt string, args ...interface{})
|
||||
PrintfIf(prnt bool, fmt string, args ...interface{})
|
||||
}
|
||||
|
||||
// Debugf is called to print/format debug information.
|
||||
|
@ -61,20 +61,18 @@ func Warnf(fmt string, args ...interface{}) {
|
|||
// }
|
||||
|
||||
// PrintfIf is called to optionally print something.
|
||||
func PrintfIf(print bool, fmt string, args ...interface{}) {
|
||||
DefaultPrinter.PrintfIf(print, fmt, args...)
|
||||
func PrintfIf(prnt bool, fmt string, args ...interface{}) {
|
||||
DefaultPrinter.PrintfIf(prnt, fmt, args...)
|
||||
}
|
||||
|
||||
var (
|
||||
// DefaultPrinter is the default Printer, used by Debugf, Printf, and Warnf.
|
||||
DefaultPrinter = &ConsolePrinter{
|
||||
Reader: bufio.NewReader(os.Stdin),
|
||||
Writer: os.Stdout,
|
||||
Verbose: false,
|
||||
}
|
||||
)
|
||||
// DefaultPrinter is the default Printer, used by Debugf, Printf, and Warnf.
|
||||
var DefaultPrinter = &ConsolePrinter{
|
||||
Reader: bufio.NewReader(os.Stdin),
|
||||
Writer: os.Stdout,
|
||||
Verbose: false,
|
||||
}
|
||||
|
||||
// SkinnyReport is true to to disable certain print statements.
|
||||
// SkinnyReport is true to disable certain print statements.
|
||||
// This is a hack until we have the new printer replacement. The long
|
||||
// variable name is easy to grep for when we make the conversion.
|
||||
var SkinnyReport = true
|
||||
|
@ -211,8 +209,8 @@ func (c ConsolePrinter) Errorf(format string, args ...interface{}) {
|
|||
}
|
||||
|
||||
// PrintfIf is called to optionally print/format a message.
|
||||
func (c ConsolePrinter) PrintfIf(print bool, format string, args ...interface{}) {
|
||||
if print {
|
||||
func (c ConsolePrinter) PrintfIf(prnt bool, format string, args ...interface{}) {
|
||||
if prnt {
|
||||
fmt.Fprintf(c.Writer, format, args...)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ func NewFromRecords(recs models.Records) *RecordDB {
|
|||
|
||||
// ContainsLT returns true if recdb contains rec. Matching is done
|
||||
// on the record's label and type (i.e. the RecordKey)
|
||||
//func (recdb RecordDB) ContainsLT(rec *models.RecordConfig) bool {
|
||||
// func (recdb RecordDB) ContainsLT(rec *models.RecordConfig) bool {
|
||||
// _, ok := recdb.labelAndTypeMap[rec.Key()]
|
||||
// return ok
|
||||
//}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package rejectif
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
|
@ -12,7 +12,7 @@ import (
|
|||
// CaaFlagIsNonZero identifies CAA records where tag is no zero.
|
||||
func CaaFlagIsNonZero(rc *models.RecordConfig) error {
|
||||
if rc.CaaFlag != 0 {
|
||||
return fmt.Errorf("caa flag is non-zero")
|
||||
return errors.New("caa flag is non-zero")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ func CaaFlagIsNonZero(rc *models.RecordConfig) error {
|
|||
// See https://github.com/StackExchange/dnscontrol/issues/1374
|
||||
func CaaTargetContainsWhitespace(rc *models.RecordConfig) error {
|
||||
if strings.ContainsAny(rc.GetTargetField(), " \t\r\n") {
|
||||
return fmt.Errorf("caa target contains whitespace")
|
||||
return errors.New("caa target contains whitespace")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package rejectif
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ import (
|
|||
// is only permitted at the apex.
|
||||
func LabelNotApex(rc *models.RecordConfig) error {
|
||||
if rc.GetLabel() != "@" {
|
||||
return fmt.Errorf("use not at apex")
|
||||
return errors.New("use not at apex")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package rejectif
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
)
|
||||
|
@ -12,7 +12,7 @@ import (
|
|||
// This is needed by providers that don't support RFC 7505.
|
||||
func MxNull(rc *models.RecordConfig) error {
|
||||
if rc.GetTargetField() == "." {
|
||||
return fmt.Errorf("mx has null target")
|
||||
return errors.New("mx has null target")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
package rejectif
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
|
||||
"github.com/StackExchange/dnscontrol/v4/models"
|
||||
)
|
||||
|
@ -11,7 +11,7 @@ import (
|
|||
// SrvHasNullTarget detects SRV records that has a null target.
|
||||
func SrvHasNullTarget(rc *models.RecordConfig) error {
|
||||
if rc.GetTargetField() == "." {
|
||||
return fmt.Errorf("srv has null target")
|
||||
return errors.New("srv has null target")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package rejectif
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
|
@ -12,7 +13,7 @@ import (
|
|||
// TxtHasBackslash audits TXT records for strings that contains one or more backslashes.
|
||||
func TxtHasBackslash(rc *models.RecordConfig) error {
|
||||
if strings.Contains(rc.GetTargetTXTJoined(), `\`) {
|
||||
return fmt.Errorf("txtstring contains backslashes")
|
||||
return errors.New("txtstring contains backslashes")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -20,7 +21,7 @@ func TxtHasBackslash(rc *models.RecordConfig) error {
|
|||
// TxtHasBackticks audits TXT records for strings that contain backticks.
|
||||
func TxtHasBackticks(rc *models.RecordConfig) error {
|
||||
if strings.Contains(rc.GetTargetTXTJoined(), "`") {
|
||||
return fmt.Errorf("txtstring contains backtick")
|
||||
return errors.New("txtstring contains backtick")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -28,7 +29,7 @@ func TxtHasBackticks(rc *models.RecordConfig) error {
|
|||
// TxtHasDoubleQuotes audits TXT records for strings that contain doublequotes.
|
||||
func TxtHasDoubleQuotes(rc *models.RecordConfig) error {
|
||||
if strings.Contains(rc.GetTargetTXTJoined(), `"`) {
|
||||
return fmt.Errorf("txtstring contains doublequotes")
|
||||
return errors.New("txtstring contains doublequotes")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -36,7 +37,7 @@ func TxtHasDoubleQuotes(rc *models.RecordConfig) error {
|
|||
// TxtHasSemicolon audits TXT records for strings that contain backticks.
|
||||
func TxtHasSemicolon(rc *models.RecordConfig) error {
|
||||
if strings.Contains(rc.GetTargetTXTJoined(), ";") {
|
||||
return fmt.Errorf("txtstring contains semicolon")
|
||||
return errors.New("txtstring contains semicolon")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -44,7 +45,7 @@ func TxtHasSemicolon(rc *models.RecordConfig) error {
|
|||
// TxtHasSingleQuotes audits TXT records for strings that contain single-quotes.
|
||||
func TxtHasSingleQuotes(rc *models.RecordConfig) error {
|
||||
if strings.Contains(rc.GetTargetTXTJoined(), "'") {
|
||||
return fmt.Errorf("txtstring contains single-quotes")
|
||||
return errors.New("txtstring contains single-quotes")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -53,7 +54,7 @@ func TxtHasSingleQuotes(rc *models.RecordConfig) error {
|
|||
func TxtHasTrailingSpace(rc *models.RecordConfig) error {
|
||||
txt := rc.GetTargetTXTJoined()
|
||||
if txt != "" && txt[ultimate(txt)] == ' ' {
|
||||
return fmt.Errorf("txtstring ends with space")
|
||||
return errors.New("txtstring ends with space")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -61,7 +62,7 @@ func TxtHasTrailingSpace(rc *models.RecordConfig) error {
|
|||
// TxtHasUnpairedDoubleQuotes audits TXT records for strings that contain unpaired doublequotes.
|
||||
func TxtHasUnpairedDoubleQuotes(rc *models.RecordConfig) error {
|
||||
if strings.Count(rc.GetTargetTXTJoined(), `"`)%2 == 1 {
|
||||
return fmt.Errorf("txtstring contains unpaired doublequotes")
|
||||
return errors.New("txtstring contains unpaired doublequotes")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -69,7 +70,7 @@ func TxtHasUnpairedDoubleQuotes(rc *models.RecordConfig) error {
|
|||
// TxtIsEmpty audits TXT records for empty strings.
|
||||
func TxtIsEmpty(rc *models.RecordConfig) error {
|
||||
if len(rc.GetTargetTXTJoined()) == 0 {
|
||||
return fmt.Errorf("txtstring is empty")
|
||||
return errors.New("txtstring is empty")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -90,7 +91,7 @@ func TxtLongerThan(maxLength int) func(rc *models.RecordConfig) error {
|
|||
func TxtStartsOrEndsWithSpaces(rc *models.RecordConfig) error {
|
||||
txt := rc.GetTargetTXTJoined()
|
||||
if len(txt) > 0 && (txt[0] == ' ' || txt[len(txt)-1] == ' ') {
|
||||
return fmt.Errorf("txtstring starts or ends with spaces")
|
||||
return errors.New("txtstring starts or ends with spaces")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
package rfc4183
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
import "errors"
|
||||
|
||||
// reverseIPv6 returns the ipv6.arpa string suitable for reverse DNS lookups.
|
||||
func reverseIPv6(ip []byte, maskbits int) (arpa string, err error) {
|
||||
// Must be IPv6
|
||||
if len(ip) != 16 {
|
||||
return "", fmt.Errorf("not IPv6")
|
||||
return "", errors.New("not IPv6")
|
||||
}
|
||||
|
||||
buf := []byte("x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.ip6.arpa")
|
||||
|
|
|
@ -1,17 +1,20 @@
|
|||
package rfc4183
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var newmode bool
|
||||
var modeset bool
|
||||
var (
|
||||
newmode bool
|
||||
modeset bool
|
||||
)
|
||||
|
||||
// SetCompatibilityMode sets REV() compatibility mode.
|
||||
func SetCompatibilityMode(m string) error {
|
||||
if modeset {
|
||||
return fmt.Errorf("ERROR: REVCOMPAT() already set")
|
||||
return errors.New("ERROR: REVCOMPAT() already set")
|
||||
}
|
||||
modeset = true
|
||||
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
// a in-addr name. IP addresses are assumed to be /32 or /128 CIDR blocks.
|
||||
// CIDR host bits are changed to 0s.
|
||||
func ReverseDomainName(cidr string) (string, error) {
|
||||
|
||||
// Mask missing? Add it.
|
||||
if !strings.Contains(cidr, "/") {
|
||||
a, err := netip.ParseAddr(cidr)
|
||||
|
@ -75,5 +74,4 @@ func ReverseDomainName(cidr string) (string, error) {
|
|||
return fmt.Sprintf("%d-%d.%d.in-addr.arpa", y, m, x), nil
|
||||
}
|
||||
return "", fmt.Errorf("fewer than 8 mask bits is not reasonable: %v", cidr)
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
)
|
||||
|
||||
func TestReverse(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
in string
|
||||
out string
|
||||
}{
|
||||
|
@ -106,7 +106,7 @@ func TestReverse(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestReverseErrors(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
in string
|
||||
}{
|
||||
{"0.0.0.0/0"},
|
||||
|
|
|
@ -10,7 +10,6 @@ import (
|
|||
// 'i': uinet16 (will convert strings, truncate floats, etc)
|
||||
// 's': Valid only if string.
|
||||
func PaveArgs(args []any, argTypes string) error {
|
||||
|
||||
if len(args) != len(argTypes) {
|
||||
return fmt.Errorf("wrong number of arguments. Expected %v, got %v", len(argTypes), len(args))
|
||||
}
|
||||
|
@ -18,7 +17,6 @@ func PaveArgs(args []any, argTypes string) error {
|
|||
for i, at := range argTypes {
|
||||
arg := args[i]
|
||||
switch at {
|
||||
|
||||
case 'i': // uint16
|
||||
if s, ok := arg.(string); ok { // Is this a string-encoded int?
|
||||
ni, err := strconv.Atoi(s)
|
||||
|
@ -42,7 +40,6 @@ func PaveArgs(args []any, argTypes string) error {
|
|||
} else {
|
||||
args[i] = fmt.Sprintf("%v", arg)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,11 +8,9 @@ import (
|
|||
)
|
||||
|
||||
func PostProcess(domains []*models.DomainConfig) error {
|
||||
|
||||
var err error
|
||||
|
||||
for _, dc := range domains {
|
||||
|
||||
for _, rawRec := range dc.RawRecords {
|
||||
rec := &models.RecordConfig{
|
||||
Type: rawRec.Type,
|
||||
|
@ -33,9 +31,8 @@ func PostProcess(domains []*models.DomainConfig) error {
|
|||
}
|
||||
|
||||
// Call the proper initialize function.
|
||||
// TODO(tlim): Good candiate for an interface or a lookup table.
|
||||
// TODO(tlim): Good candidate for an interface or a lookup table.
|
||||
switch rawRec.Type {
|
||||
|
||||
case "CLOUDFLAREAPI_SINGLE_REDIRECT":
|
||||
err = cfsingleredirect.FromRaw(rec, rawRec.Args)
|
||||
rec.SetLabel("@", dc.Name)
|
||||
|
|
|
@ -9,23 +9,24 @@ import (
|
|||
// use this to split TXT records into 255 sized chunks for RFC 4408
|
||||
// https://tools.ietf.org/html/rfc4408#section-3.1.3
|
||||
// Borrowed from https://stackoverflow.com/a/61469854/11477663
|
||||
// TODO(tlim): Consider replacing with https://pkg.go.dev/slices#Chunk
|
||||
func Chunks(s string, chunkSize int) []string {
|
||||
if chunkSize >= len(s) {
|
||||
return []string{s}
|
||||
}
|
||||
var chunks []string
|
||||
chunk := make([]rune, chunkSize)
|
||||
len := 0
|
||||
lngth := 0
|
||||
for _, r := range s {
|
||||
chunk[len] = r
|
||||
len++
|
||||
if len == chunkSize {
|
||||
chunk[lngth] = r
|
||||
lngth++
|
||||
if lngth == chunkSize {
|
||||
chunks = append(chunks, string(chunk))
|
||||
len = 0
|
||||
lngth = 0
|
||||
}
|
||||
}
|
||||
if len > 0 {
|
||||
chunks = append(chunks, string(chunk[:len]))
|
||||
if lngth > 0 {
|
||||
chunks = append(chunks, string(chunk[:lngth]))
|
||||
}
|
||||
return chunks
|
||||
}
|
||||
|
@ -58,7 +59,6 @@ func (s *SPFRecord) TXTSplit(pattern string, overhead int, txtMaxSize int) map[s
|
|||
m := map[string][]string{}
|
||||
s.split("@", pattern, 1, m, overhead, txtMaxSize)
|
||||
return m
|
||||
|
||||
}
|
||||
|
||||
func (s *SPFRecord) split(thisfqdn string, pattern string, nextIdx int, m map[string][]string, overhead int, txtMaxSize int) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package spflib
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
@ -28,7 +29,7 @@ var qualifiers = map[byte]bool{
|
|||
// Parse parses a raw SPF record.
|
||||
func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
||||
if !strings.HasPrefix(text, "v=spf1 ") {
|
||||
return nil, fmt.Errorf("not an SPF record")
|
||||
return nil, errors.New("not an SPF record")
|
||||
}
|
||||
parts := strings.Split(text, " ")
|
||||
rec := &SPFRecord{}
|
||||
|
@ -73,7 +74,7 @@ func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
|||
}
|
||||
p.IncludeRecord, err = Parse(subRecord, dnsres)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("in included SPF: %s", err)
|
||||
return nil, fmt.Errorf("in included SPF: %w", err)
|
||||
}
|
||||
}
|
||||
} else if strings.HasPrefix(part, "exists:") || strings.HasPrefix(part, "ptr:") {
|
||||
|
@ -81,7 +82,6 @@ func Parse(text string, dnsres Resolver) (*SPFRecord, error) {
|
|||
} else {
|
||||
return nil, fmt.Errorf("unsupported SPF part %s", part)
|
||||
}
|
||||
|
||||
}
|
||||
return rec, nil
|
||||
}
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
)
|
||||
|
||||
func dump(rec *SPFRecord, indent string, w io.Writer) {
|
||||
|
||||
fmt.Fprintf(w, "%sTotal Lookups: %d\n", indent, rec.Lookups())
|
||||
fmt.Fprint(w, indent+"v=spf1")
|
||||
for _, p := range rec.Parts {
|
||||
|
@ -53,19 +52,21 @@ func TestParse(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rec, err := Parse(strings.Join([]string{"v=spf1",
|
||||
rec, err := Parse(strings.Join([]string{
|
||||
"v=spf1",
|
||||
"ip4:198.252.206.0/24",
|
||||
"ip4:192.111.0.0/24",
|
||||
"include:_spf.google.com",
|
||||
"include:mailgun.org",
|
||||
//"include:spf-basic.fogcreek.com",
|
||||
// "include:spf-basic.fogcreek.com",
|
||||
"include:mail.zendesk.com",
|
||||
"include:servers.mcsv.net",
|
||||
"include:sendgrid.net",
|
||||
"include:spf.mtasv.net",
|
||||
"exists:%{i}._spf.sparkpostmail.com",
|
||||
"ptr:sparkpostmail.com",
|
||||
"~all"}, " "), dnsres)
|
||||
"~all",
|
||||
}, " "), dnsres)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -90,9 +91,11 @@ func TestParseRedirectNotLast(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = Parse(strings.Join([]string{"v=spf1",
|
||||
_, err = Parse(strings.Join([]string{
|
||||
"v=spf1",
|
||||
"redirect=servers.mcsv.net",
|
||||
"~all"}, " "), dnsres)
|
||||
"~all",
|
||||
}, " "), dnsres)
|
||||
if err == nil {
|
||||
t.Fatal("should fail")
|
||||
}
|
||||
|
@ -104,7 +107,8 @@ func TestParseRedirectColon(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = Parse(strings.Join([]string{"v=spf1",
|
||||
_, err = Parse(strings.Join([]string{
|
||||
"v=spf1",
|
||||
"redirect:servers.mcsv.net",
|
||||
}, " "), dnsres)
|
||||
if err == nil {
|
||||
|
@ -117,8 +121,10 @@ func TestParseRedirectOnly(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rec, err := Parse(strings.Join([]string{"v=spf1",
|
||||
"redirect=servers.mcsv.net"}, " "), dnsres)
|
||||
rec, err := Parse(strings.Join([]string{
|
||||
"v=spf1",
|
||||
"redirect=servers.mcsv.net",
|
||||
}, " "), dnsres)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
@ -130,9 +136,11 @@ func TestParseRedirectLast(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
rec, err := Parse(strings.Join([]string{"v=spf1",
|
||||
rec, err := Parse(strings.Join([]string{
|
||||
"v=spf1",
|
||||
"ip4:198.252.206.0/24",
|
||||
"redirect=servers.mcsv.net"}, " "), dnsres)
|
||||
"redirect=servers.mcsv.net",
|
||||
}, " "), dnsres)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
|
|
@ -125,6 +125,7 @@ func (c *cache) ResolveErrors() (errs []error) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *cache) Save(filename string) error {
|
||||
outRecs := make(map[string]*cacheEntry, len(c.records))
|
||||
for k, entry := range c.records {
|
||||
|
@ -136,5 +137,5 @@ func (c *cache) Save(filename string) error {
|
|||
}
|
||||
}
|
||||
dat, _ := json.MarshalIndent(outRecs, "", " ")
|
||||
return os.WriteFile(filename, dat, 0644)
|
||||
return os.WriteFile(filename, dat, 0o644)
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
// For cases not covered by RFC2317, implement RFC4183
|
||||
// The host bits must all be zeros.
|
||||
func ReverseDomainName(cidr string) (string, error) {
|
||||
|
||||
if rfc4183.IsRFC4183Mode() {
|
||||
return rfc4183.ReverseDomainName(cidr)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
)
|
||||
|
||||
func TestReverse(t *testing.T) {
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
in string
|
||||
isError bool
|
||||
out string
|
||||
|
|
|
@ -63,7 +63,6 @@ var isRfc2317Format1 = regexp.MustCompile(`(\d{1,3})/(\d{1,3})\.(\d{1,3})\.(\d{1
|
|||
// ipMatchesClasslessDomain returns true if ip is appropriate for domain.
|
||||
// domain is a reverse DNS lookup zone (in-addr.arpa) as described in RFC2317.
|
||||
func ipMatchesClasslessDomain(ip net.IP, domain string) bool {
|
||||
|
||||
// The unofficial but preferred format in RFC2317:
|
||||
m := isRfc2317Format1.FindStringSubmatch(domain)
|
||||
if m != nil {
|
||||
|
|
|
@ -56,8 +56,10 @@ func TestPtrMagic(t *testing.T) {
|
|||
|
||||
// User manually reversed addresses:
|
||||
{"1.1.1.1.in-addr.arpa.", "1.1.in-addr.arpa", "1.1", false},
|
||||
{"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.",
|
||||
"0.2.ip6.arpa", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0", false},
|
||||
{
|
||||
"1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa.",
|
||||
"0.2.ip6.arpa", "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0", false,
|
||||
},
|
||||
|
||||
// Error cases:
|
||||
{"1.1.1.1.in-addr.arpa.", "2.2.in-addr.arpa", "", true},
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package transform
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
@ -22,7 +23,7 @@ func ipToUint(i net.IP) (uint32, error) {
|
|||
return r, nil
|
||||
}
|
||||
|
||||
// UintToIP convert a 32-bit into into a net.IP.
|
||||
// UintToIP convert a 32-bit into a net.IP.
|
||||
func UintToIP(u uint32) net.IP {
|
||||
return net.IPv4(
|
||||
byte((u>>24)&255),
|
||||
|
@ -51,7 +52,6 @@ func DecodeTransformTable(transforms string) ([]IPConversion, error) {
|
|||
parseList := func(s string) ([]net.IP, error) {
|
||||
ips := []net.IP{}
|
||||
for _, ip := range strings.Split(s, ",") {
|
||||
|
||||
if ip == "" {
|
||||
continue
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ func DecodeTransformTable(transforms string) ([]IPConversion, error) {
|
|||
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 {
|
||||
return nil, fmt.Errorf("transform_table_rows should only specify one of NewBases or NewIPs, Not both")
|
||||
return nil, errors.New("transform_table_rows should only specify one of NewBases or NewIPs, Not both")
|
||||
}
|
||||
result = append(result, con)
|
||||
}
|
||||
|
@ -104,15 +104,15 @@ func IPToList(address net.IP, transforms []IPConversion) ([]net.IP, error) {
|
|||
return nil, err
|
||||
}
|
||||
for _, conv := range transforms {
|
||||
min, err := ipToUint(conv.Low)
|
||||
min_, err := ipToUint(conv.Low)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
max, err := ipToUint(conv.High)
|
||||
max_, err := ipToUint(conv.High)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if (thisIP >= min) && (thisIP <= max) {
|
||||
if (thisIP >= min_) && (thisIP <= max_) {
|
||||
if len(conv.NewIPs) > 0 {
|
||||
return conv.NewIPs, nil
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ func IPToList(address net.IP, transforms []IPConversion) ([]net.IP, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
list = append(list, UintToIP(newbase+(thisIP-min)))
|
||||
list = append(list, UintToIP(newbase+(thisIP-min_)))
|
||||
}
|
||||
return list, nil
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@ func Test_DecodeTransformTable_1(t *testing.T) {
|
|||
testIP(t, "NewBase[1]", "7.6.5.4", result[1].NewBases[0])
|
||||
// test_ip(t, "newIP[1]", "", result[0].NewIP)
|
||||
}
|
||||
|
||||
func Test_DecodeTransformTable_NewIP(t *testing.T) {
|
||||
result, err := DecodeTransformTable("1.2.3.4 ~ 2.3.4.5 ~ ~ 3.4.5.6 ")
|
||||
if err != nil {
|
||||
|
@ -104,8 +105,7 @@ func Test_DecodeTransformTable_Base_and_IP(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_IP(t *testing.T) {
|
||||
|
||||
var transforms1 = []IPConversion{{
|
||||
transforms1 := []IPConversion{{
|
||||
Low: net.ParseIP("11.11.11.0"),
|
||||
High: net.ParseIP("11.11.11.20"),
|
||||
NewBases: []net.IP{net.ParseIP("99.99.99.0")},
|
||||
|
@ -128,7 +128,7 @@ func Test_IP(t *testing.T) {
|
|||
}}
|
||||
// NO TRANSFORMS ON 99.x.x.x PLZ
|
||||
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
experiment string
|
||||
expected string
|
||||
}{
|
||||
|
@ -172,23 +172,23 @@ func Test_IP(t *testing.T) {
|
|||
}
|
||||
|
||||
func Test_IP_NewIP(t *testing.T) {
|
||||
|
||||
var transforms1 = []IPConversion{{
|
||||
Low: net.ParseIP("11.11.11.0"),
|
||||
High: net.ParseIP("11.11.11.20"),
|
||||
NewIPs: []net.IP{net.ParseIP("1.1.1.1")},
|
||||
}, {
|
||||
Low: net.ParseIP("22.22.22.0"),
|
||||
High: net.ParseIP("22.22.22.40"),
|
||||
NewIPs: []net.IP{net.ParseIP("2.2.2.2")},
|
||||
}, {
|
||||
Low: net.ParseIP("33.33.33.20"),
|
||||
High: net.ParseIP("33.33.35.40"),
|
||||
NewIPs: []net.IP{net.ParseIP("3.3.3.3")},
|
||||
},
|
||||
transforms1 := []IPConversion{
|
||||
{
|
||||
Low: net.ParseIP("11.11.11.0"),
|
||||
High: net.ParseIP("11.11.11.20"),
|
||||
NewIPs: []net.IP{net.ParseIP("1.1.1.1")},
|
||||
}, {
|
||||
Low: net.ParseIP("22.22.22.0"),
|
||||
High: net.ParseIP("22.22.22.40"),
|
||||
NewIPs: []net.IP{net.ParseIP("2.2.2.2")},
|
||||
}, {
|
||||
Low: net.ParseIP("33.33.33.20"),
|
||||
High: net.ParseIP("33.33.35.40"),
|
||||
NewIPs: []net.IP{net.ParseIP("3.3.3.3")},
|
||||
},
|
||||
}
|
||||
|
||||
var tests = []struct {
|
||||
tests := []struct {
|
||||
experiment string
|
||||
expected string
|
||||
}{
|
||||
|
|
|
@ -70,10 +70,10 @@ func txtDecode(s string) (string, error) {
|
|||
/*
|
||||
|
||||
BNF:
|
||||
txttarget := `""`` | item | item ` ` item*
|
||||
txttarget := `""`` | item | item ` item*
|
||||
item := quoteditem | unquoteditem
|
||||
quoteditem := quote innertxt quote
|
||||
quote := `"`
|
||||
:= `"`
|
||||
innertxt := (escaped | printable )*
|
||||
escaped := `\\` | `\"`
|
||||
printable := (printable ASCII chars)
|
||||
|
@ -81,16 +81,14 @@ func txtDecode(s string) (string, error) {
|
|||
|
||||
*/
|
||||
|
||||
//printer.Printf("DEBUG: txtDecode txt inboundv=%v\n", s)
|
||||
// printer.Printf("DEBUG: txtDecode txt inboundv=%v\n", s)
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
state := StateStart
|
||||
for i, c := range s {
|
||||
|
||||
//printer.Printf("DEBUG: state=%v rune=%v\n", state, string(c))
|
||||
// printer.Printf("DEBUG: state=%v rune=%v\n", state, string(c))
|
||||
|
||||
switch state {
|
||||
|
||||
case StateStart:
|
||||
if c == ' ' {
|
||||
// skip whitespace
|
||||
|
@ -133,18 +131,17 @@ func txtDecode(s string) (string, error) {
|
|||
} else {
|
||||
return "", fmt.Errorf("txtDecode expected whitespace after close quote q(%q)", s)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
r := b.String()
|
||||
//printer.Printf("DEBUG: txtDecode txt decodedv=%v\n", r)
|
||||
// printer.Printf("DEBUG: txtDecode txt decodedv=%v\n", r)
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// txtEncode encodes TXT strings in RFC1035 format as interpreted by Tom.
|
||||
func txtEncode(ts []string) string {
|
||||
//printer.Printf("DEBUG: txtEncode txt outboundv=%v\n", ts)
|
||||
// printer.Printf("DEBUG: txtEncode txt outboundv=%v\n", ts)
|
||||
if (len(ts) == 0) || (strings.Join(ts, "") == "") {
|
||||
return `""`
|
||||
}
|
||||
|
@ -160,6 +157,6 @@ func txtEncode(ts []string) string {
|
|||
}
|
||||
t := strings.Join(r, ` `)
|
||||
|
||||
//printer.Printf("DEBUG: txtEncode txt encodedv=%v\n", t)
|
||||
// printer.Printf("DEBUG: txtEncode txt encodedv=%v\n", t)
|
||||
return t
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue