diff --git a/cmd/dns-preload/main.go b/cmd/dns-preload/main.go index 0b3758e..4ec3ff1 100644 --- a/cmd/dns-preload/main.go +++ b/cmd/dns-preload/main.go @@ -31,6 +31,7 @@ const ( ) var ( + //nolint:govet // fieldalignment is not required here. cli struct { All Preload `cmd:"" help:"preload all of the following types from the configuration file"` Cname Preload `cmd:"" help:"preload only the cname entries from the configuration file"` @@ -48,27 +49,27 @@ var ( ) type Preload struct { - ConfigFile string `required:"" help:"The configuration file to read the domain list to query from"` - Server string `default:"localhost" help:"The server to query to seed the domain list into"` - Port string `default:"53" help:"The port the DNS server listens for requests on"` + resolver dns.CustomResolver + ConfigFile string `required:"" help:"The configuration file to read the domain list to query from"` + Server string `default:"localhost" help:"The server to query to seed the domain list into"` + Port string `default:"53" help:"The port the DNS server listens for requests on"` + nameserver string + Timeout time.Duration `default:"30s" help:"The timeout for each DNS query to succeed (not implemented)"` Workers uint8 `default:"2" help:"The number of concurrent goroutines used to query the DNS server"` Mute bool `default:"false" help:"Suppress the preload task output to the console"` Quiet bool `default:"false" help:"Suppress the preload response output to the console"` Full bool `default:"true" help:"For record types that return a Hostname ensure that these are resolved"` Debug bool `default:"false" help:"Debug mode"` - Timeout time.Duration `default:"30s" help:"The timeout for each DNS query to succeed (not implemented)"` - resolver dns.CustomResolver - nameserver string } type Config struct { + Validate struct { + ConfigFile string `required:"" help:"The configuration file to load"` + } `cmd:"" help:"Validate a configuration file"` Quiet bool `default:"false" help:"Suppress the info output to the console"` Generate struct { Generate bool `default:"true" help:"Generate an empty configuration and output it to stdout"` } `cmd:"" help:"Generate a configuration file"` - Validate struct { - ConfigFile string `required:"" help:"The configuration file to load"` - } `cmd:"" help:"Validate a configuration file"` } // Config Run() prints an empty YAML configuration to stdout. @@ -394,10 +395,11 @@ func (p *Preload) IntroPrinter(queryType string, hosts []string) { } // CompletedPrinter prints out a completion message and a timer to stdout. -func completedPrinter(quiet bool, t time.Time) { +func completedPrinter(quiet bool, t time.Time) string { if !quiet { - fmt.Printf(completedMessage+"\n", time.Since(t)) + return fmt.Sprintf(completedMessage+"\n", time.Since(t)) } + return "" } // createErrGroup handles the logic to setup an errgroup for concurrency. diff --git a/cmd/dns-preload/main_test.go b/cmd/dns-preload/main_test.go index 8abedea..01e17e8 100644 --- a/cmd/dns-preload/main_test.go +++ b/cmd/dns-preload/main_test.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "net" + "strings" "testing" "time" @@ -956,7 +957,7 @@ func TestPreloadRun(t *testing.T) { } } -func Test_completedPrinter(t *testing.T) { +func TestCompletedPrinter(t *testing.T) { start := time.Now() type args struct { quiet bool @@ -981,12 +982,22 @@ func Test_completedPrinter(t *testing.T) { quiet: false, t: start, }, - want: "", + want: completedMessage, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - completedPrinter(tt.args.quiet, tt.args.t) + s := completedPrinter(tt.args.quiet, tt.args.t) + if tt.args.quiet { + if s != tt.want { + t.Errorf("expected nil, got %s", tt.want) + } + } + if !tt.args.quiet { + if strings.Index(strings.Split(s, "0")[0], strings.Split(tt.want, " ")[0]) != 0 { + t.Errorf("expected return to start with %s, got %s", tt.want, s) + } + } }) } } diff --git a/pkg/confighandlers/config.go b/pkg/confighandlers/config.go index 5eaae2e..e67845f 100644 --- a/pkg/confighandlers/config.go +++ b/pkg/confighandlers/config.go @@ -7,12 +7,13 @@ import ( ) const ( - Mx string = "mx" - Ns string = "ns" - Txt string = "txt" - Cname string = "cname" - Hosts string = "hosts" - Ptr string = "ptr" + Mx string = "mx" + Ns string = "ns" + Txt string = "txt" + Cname string = "cname" + Hosts string = "hosts" + Ptr string = "ptr" + nilRecords uint16 = 0 ) var ( @@ -27,23 +28,24 @@ type Configuration struct { // QueryType lsits out the structure for the different domains and their query type type QueryType struct { // Cnames for doing a cname lookup - Cname []string `yaml:"cname" json:"cname" validate:"dive,fqdn"` - CnameCount uint16 `yaml:",omitempty"` + Cname []string `yaml:"cname" json:"cname" validate:"dive,fqdn"` // Hosts for doing a query for type A and AAAA - Hosts []string `yaml:"hosts" json:"hosts" validate:"dive,fqdn"` - HostsCount uint16 `yaml:",omitempty"` + Hosts []string `yaml:"hosts" json:"hosts" validate:"dive,fqdn"` // ns for doing a query for type NS - NS []string `yaml:"ns" json:"ns" validate:"dive,fqdn"` - NSCount uint16 `yaml:",omitempty"` + NS []string `yaml:"ns" json:"ns" validate:"dive,fqdn"` // MX for doing a query for type MX - MX []string `yaml:"mx" json:"mx" validate:"dive,fqdn"` - MXCount uint16 `yaml:",omitempty"` + MX []string `yaml:"mx" json:"mx" validate:"dive,fqdn"` // TXT for doing a query for type TXT - TXT []string `yaml:"txt" json:"txt" validate:"dive,fqdn"` - TXTCount uint16 `yaml:",omitempty"` + TXT []string `yaml:"txt" json:"txt" validate:"dive,fqdn"` // PTR for doing a query for type PTR - PTR []string `yaml:"ptr" json:"ptr" validate:"dive,ip_addr"` - PTRCount uint16 `yaml:",omitempty"` + PTR []string `yaml:"ptr" json:"ptr" validate:"dive,ip_addr"` + // Metrics values below this point. + CnameCount uint16 `yaml:",omitempty"` + HostsCount uint16 `yaml:",omitempty"` + NSCount uint16 `yaml:",omitempty"` + MXCount uint16 `yaml:",omitempty"` + TXTCount uint16 `yaml:",omitempty"` + PTRCount uint16 `yaml:",omitempty"` } // PopulateCounts for how many domains are in each query_type. diff --git a/pkg/confighandlers/file.go b/pkg/confighandlers/file.go index 839528c..1329109 100644 --- a/pkg/confighandlers/file.go +++ b/pkg/confighandlers/file.go @@ -50,7 +50,7 @@ func LoadConfigFromFile(cfgfile *string) (*Configuration, error) { if err != nil { return &Configuration{}, err } - if (cfg.QueryType.CnameCount == 0) && (cfg.QueryType.HostsCount == 0) && (cfg.QueryType.MXCount == 0) && (cfg.QueryType.PTRCount == 00) && (cfg.QueryType.TXTCount == 0) { + if (cfg.QueryType.CnameCount == nilRecords) && (cfg.QueryType.HostsCount == nilRecords) && (cfg.QueryType.MXCount == nilRecords) && (cfg.QueryType.PTRCount == nilRecords) && (cfg.QueryType.TXTCount == nilRecords) { return &Configuration{}, fmt.Errorf("empty configuration or invalid keys") } diff --git a/pkg/dns/resolver.go b/pkg/dns/resolver.go index 441357e..e6c5616 100644 --- a/pkg/dns/resolver.go +++ b/pkg/dns/resolver.go @@ -20,7 +20,9 @@ type Resolver struct { client *net.Resolver } +// NewResolver creates a custom resolver where the DNS servers are pinned. func NewResolver(nameserver string, timeout time.Duration) *Resolver { + //nolint:revive // address is a returned function, it gets set by the caller. return &Resolver{ client: &net.Resolver{ PreferGo: true,