From b5e1de165b235cb154fcf127ba5cfa709c443105 Mon Sep 17 00:00:00 2001 From: Evan Broder Date: Sat, 10 Jan 2015 13:11:32 +0100 Subject: [PATCH] Add "only_passing" option to DNS config This excludes nodes from DNS results if their healthchecks are in any non-passing state, not just if they're critical. --- command/agent/config.go | 8 ++++++++ command/agent/config_test.go | 11 +++++++++++ command/agent/dns.go | 3 ++- website/source/docs/agent/options.html.markdown | 4 ++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/command/agent/config.go b/command/agent/config.go index ae53ba05d..3e1413492 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -74,6 +74,11 @@ type DNSConfig struct { // stale read is performed. MaxStale time.Duration `mapstructure:"-"` MaxStaleRaw string `mapstructure:"max_stale" json:"-"` + + // OnlyPassing is used to determine whether to filter nodes + // whose health checks are in any non-passing state. By + // default, only nodes in a critical state are excluded. + OnlyPassing bool `mapstructure:"only_passing"` } // Config is the configuration that can be set for an Agent. @@ -835,6 +840,9 @@ func MergeConfig(a, b *Config) *Config { if b.DNSConfig.MaxStale != 0 { result.DNSConfig.MaxStale = b.DNSConfig.MaxStale } + if b.DNSConfig.OnlyPassing { + result.DNSConfig.OnlyPassing = true + } if b.CheckUpdateIntervalRaw != "" || b.CheckUpdateInterval != 0 { result.CheckUpdateInterval = b.CheckUpdateInterval } diff --git a/command/agent/config_test.go b/command/agent/config_test.go index 051d01869..292e1b272 100644 --- a/command/agent/config_test.go +++ b/command/agent/config_test.go @@ -472,6 +472,17 @@ func TestDecodeConfig(t *testing.T) { t.Fatalf("bad: %#v", config) } + // DNS only passing + input = `{"dns_config": {"only_passing": true}}` + config, err = DecodeConfig(bytes.NewReader([]byte(input))) + if err != nil { + t.Fatalf("err: %s", err) + } + + if !config.DNSConfig.OnlyPassing { + t.Fatalf("bad: %#v", config) + } + // CheckUpdateInterval input = `{"check_update_interval": "10m"}` config, err = DecodeConfig(bytes.NewReader([]byte(input))) diff --git a/command/agent/dns.go b/command/agent/dns.go index 1b270bae7..d4b250641 100644 --- a/command/agent/dns.go +++ b/command/agent/dns.go @@ -554,7 +554,8 @@ OUTER: for i := 0; i < n; i++ { node := nodes[i] for _, check := range node.Checks { - if check.Status == structs.HealthCritical { + if check.Status == structs.HealthCritical || + (d.config.OnlyPassing && check.Status != structs.HealthPassing) { d.logger.Printf("[WARN] dns: node '%s' failing health check '%s: %s', dropping from service '%s'", node.Node.Node, check.CheckID, check.Name, node.Service.Service) nodes[i], nodes[n-1] = nodes[n-1], structs.CheckServiceNode{} diff --git a/website/source/docs/agent/options.html.markdown b/website/source/docs/agent/options.html.markdown index b9d7bef28..5144342a0 100644 --- a/website/source/docs/agent/options.html.markdown +++ b/website/source/docs/agent/options.html.markdown @@ -312,6 +312,10 @@ definitions support being updated during a reload. will set the truncated flag, indicating to clients that they should re-query using TCP to get the full set of records. + * `only_passing` - If set to true, any nodes whose healthchecks are not passing will be + excluded from DNS results. By default (or if set to false), only nodes whose healthchecks + are failing as critical will be excluded. + * `domain` - By default, Consul responds to DNS queries in the "consul." domain. This flag can be used to change that domain. All queries in this domain are assumed to be handled by Consul, and will not be recursively resolved.