From 04940e2c78496639e535460cb76adad784e09d7f Mon Sep 17 00:00:00 2001 From: John Murret Date: Tue, 14 May 2024 15:33:34 -0600 Subject: [PATCH] additional changes to ensure sameness groups without DefaultForFailover can be used for DNS (#21107) --- agent/dns.go | 7 +-- agent/dns/discovery_results_fetcher.go | 3 ++ agent/health_endpoint_test.go | 6 +-- agent/structs/errors.go | 68 +++++++++++++------------- 4 files changed, 44 insertions(+), 40 deletions(-) diff --git a/agent/dns.go b/agent/dns.go index 92dcd273e0..5e0f54a1b7 100644 --- a/agent/dns.go +++ b/agent/dns.go @@ -1096,9 +1096,10 @@ func rCodeFromError(err error) int { return dns.RcodeSuccess case errors.Is(err, errECSNotGlobal): return rCodeFromError(errors.Unwrap(err)) - case errors.Is(err, errNameNotFound): - return dns.RcodeNameError - case structs.IsErrNoDCPath(err) || structs.IsErrQueryNotFound(err): + case errors.Is(err, errNameNotFound), + structs.IsErrNoDCPath(err), + structs.IsErrQueryNotFound(err), + structs.IsErrSamenessGroupMustBeDefaultForFailover(err): return dns.RcodeNameError default: return dns.RcodeServerFailure diff --git a/agent/dns/discovery_results_fetcher.go b/agent/dns/discovery_results_fetcher.go index 0a3b70a4bd..f0012b9f77 100644 --- a/agent/dns/discovery_results_fetcher.go +++ b/agent/dns/discovery_results_fetcher.go @@ -69,6 +69,9 @@ func (d discoveryResultsFetcher) getQueryResults(opts *getQueryOptions) ([]*disc if getErrorFromECSNotGlobalError(err) != nil { opts.logger.Error("error processing discovery query", "error", err) + if structs.IsErrSamenessGroupMustBeDefaultForFailover(err) { + return nil, query, errNameNotFound + } return nil, query, err } return results, query, err diff --git a/agent/health_endpoint_test.go b/agent/health_endpoint_test.go index 4d7654bae3..98f4eaa714 100644 --- a/agent/health_endpoint_test.go +++ b/agent/health_endpoint_test.go @@ -834,9 +834,6 @@ func testHealthServiceNodes(t *testing.T, backendCfg *queryBackendConfiguration) _, err = strconv.ParseUint(header, 10, 64) require.NoError(r, err) - // Should be a cache hit! The data should've updated in the cache - // in the background so this should've been fetched directly from - // the cache. if backendCfg.cached { // Should be a cache hit! The data should've updated in the cache // in the background so this should've been fetched directly from @@ -1763,6 +1760,8 @@ func testHealthConnectServiceNodes(t *testing.T, backendCfg *queryBackendConfigu nodes := obj.(structs.CheckServiceNodes) assert.Len(t, nodes, 1) assert.Len(t, nodes[0].Checks, 0) + + require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) } func TestHealthIngressServiceNodes(t *testing.T) { @@ -2021,7 +2020,6 @@ func testHealthConnectServiceNodes_PassingFilter(t *testing.T, backendCfg *query // Should be 1 nodes := obj.(structs.CheckServiceNodes) assert.Len(t, nodes, 1) - require.Equal(t, backendCfg.queryBackend, resp.Header().Get("X-Consul-Query-Backend")) }) diff --git a/agent/structs/errors.go b/agent/structs/errors.go index 31a818bd62..b92731770c 100644 --- a/agent/structs/errors.go +++ b/agent/structs/errors.go @@ -9,38 +9,40 @@ import ( ) const ( - errNoLeader = "No cluster leader" - errNoDCPath = "No path to datacenter" - errDCNotAvailable = "Remote DC has no server currently reachable" - errNoServers = "No known Consul servers" - errNotReadyForConsistentReads = "Not ready to serve consistent reads" - errSegmentsNotSupported = "Network segments are not supported in this version of Consul" - errRPCRateExceeded = "RPC rate limit exceeded" - errServiceNotFound = "Service not found: " - errQueryNotFound = "Query not found" - errLeaderNotTracked = "Raft leader not found in server lookup mapping" - errConnectNotEnabled = "Connect must be enabled in order to use this endpoint" - errRateLimited = "Rate limit reached, try again later" // Note: we depend on this error message in the gRPC ConnectCA.Sign endpoint (see: isRateLimitError). - errNotPrimaryDatacenter = "not the primary datacenter" - errStateReadOnly = "CA Provider State is read-only" - errUsingV2CatalogExperiment = "V1 catalog is disabled when V2 is enabled" + errNoLeader = "No cluster leader" + errNoDCPath = "No path to datacenter" + errDCNotAvailable = "Remote DC has no server currently reachable" + errNoServers = "No known Consul servers" + errNotReadyForConsistentReads = "Not ready to serve consistent reads" + errSegmentsNotSupported = "Network segments are not supported in this version of Consul" + errRPCRateExceeded = "RPC rate limit exceeded" + errServiceNotFound = "Service not found: " + errQueryNotFound = "Query not found" + errLeaderNotTracked = "Raft leader not found in server lookup mapping" + errConnectNotEnabled = "Connect must be enabled in order to use this endpoint" + errRateLimited = "Rate limit reached, try again later" // Note: we depend on this error message in the gRPC ConnectCA.Sign endpoint (see: isRateLimitError). + errNotPrimaryDatacenter = "not the primary datacenter" + errStateReadOnly = "CA Provider State is read-only" + errUsingV2CatalogExperiment = "V1 catalog is disabled when V2 is enabled" + errSamenessGroupMustBeDefaultForFailover = "Sameness Group must have DefaultForFailover set to true in order to use this endpoint" ) var ( - ErrNoLeader = errors.New(errNoLeader) - ErrNoDCPath = errors.New(errNoDCPath) - ErrNoServers = errors.New(errNoServers) - ErrNotReadyForConsistentReads = errors.New(errNotReadyForConsistentReads) - ErrSegmentsNotSupported = errors.New(errSegmentsNotSupported) - ErrRPCRateExceeded = errors.New(errRPCRateExceeded) - ErrDCNotAvailable = errors.New(errDCNotAvailable) - ErrQueryNotFound = errors.New(errQueryNotFound) - ErrLeaderNotTracked = errors.New(errLeaderNotTracked) - ErrConnectNotEnabled = errors.New(errConnectNotEnabled) - ErrRateLimited = errors.New(errRateLimited) // Note: we depend on this error message in the gRPC ConnectCA.Sign endpoint (see: isRateLimitError). - ErrNotPrimaryDatacenter = errors.New(errNotPrimaryDatacenter) - ErrStateReadOnly = errors.New(errStateReadOnly) - ErrUsingV2CatalogExperiment = errors.New(errUsingV2CatalogExperiment) + ErrNoLeader = errors.New(errNoLeader) + ErrNoDCPath = errors.New(errNoDCPath) + ErrNoServers = errors.New(errNoServers) + ErrNotReadyForConsistentReads = errors.New(errNotReadyForConsistentReads) + ErrSegmentsNotSupported = errors.New(errSegmentsNotSupported) + ErrRPCRateExceeded = errors.New(errRPCRateExceeded) + ErrDCNotAvailable = errors.New(errDCNotAvailable) + ErrQueryNotFound = errors.New(errQueryNotFound) + ErrLeaderNotTracked = errors.New(errLeaderNotTracked) + ErrConnectNotEnabled = errors.New(errConnectNotEnabled) + ErrRateLimited = errors.New(errRateLimited) // Note: we depend on this error message in the gRPC ConnectCA.Sign endpoint (see: isRateLimitError). + ErrNotPrimaryDatacenter = errors.New(errNotPrimaryDatacenter) + ErrStateReadOnly = errors.New(errStateReadOnly) + ErrUsingV2CatalogExperiment = errors.New(errUsingV2CatalogExperiment) + ErrSamenessGroupMustBeDefaultForFailover = errors.New(errSamenessGroupMustBeDefaultForFailover) ) func IsErrNoDCPath(err error) bool { @@ -59,10 +61,10 @@ func IsErrRPCRateExceeded(err error) bool { return err != nil && strings.Contains(err.Error(), errRPCRateExceeded) } -func IsErrServiceNotFound(err error) bool { - return err != nil && strings.Contains(err.Error(), errServiceNotFound) -} - func IsErrUsingV2CatalogExperiment(err error) bool { return err != nil && strings.Contains(err.Error(), errUsingV2CatalogExperiment) } + +func IsErrSamenessGroupMustBeDefaultForFailover(err error) bool { + return err != nil && strings.Contains(err.Error(), errSamenessGroupMustBeDefaultForFailover) +}