From 6bd2b4b51ab04d2bc69fdcd7c5366e7380659cb8 Mon Sep 17 00:00:00 2001 From: Kenjiro Nakayama Date: Wed, 17 Nov 2021 17:31:33 +0900 Subject: [PATCH] Add retry checker for DNS failure from Ingress --- test/spoof/error_checks.go | 6 ++++++ test/spoof/spoof.go | 10 +++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/test/spoof/error_checks.go b/test/spoof/error_checks.go index 378bf58240..b0638ad341 100644 --- a/test/spoof/error_checks.go +++ b/test/spoof/error_checks.go @@ -21,6 +21,7 @@ package spoof import ( "errors" "net" + "net/http" "strings" ) @@ -62,3 +63,8 @@ func isConnectionReset(err error) bool { func isNoRouteToHostError(err error) bool { return err != nil && strings.Contains(err.Error(), "connect: no route to host") } + +func isResponseDNSError(resp *Response) bool { + // no such host with 502 is sent back from istio-ingressgateway when it fails to resolve domain. + return resp.StatusCode == http.StatusBadGateway && strings.Contains(string(resp.Body), "no such host") +} diff --git a/test/spoof/spoof.go b/test/spoof/spoof.go index f2baa4edf1..147a64adc7 100644 --- a/test/spoof/spoof.go +++ b/test/spoof/spoof.go @@ -164,7 +164,7 @@ func (sc *SpoofingClient) Do(req *http.Request, errorRetryCheckers ...interface{ // If no retry checkers are specified `DefaultErrorRetryChecker` will be used. func (sc *SpoofingClient) Poll(req *http.Request, inState ResponseChecker, checkers ...interface{}) (*Response, error) { if len(checkers) == 0 { - checkers = []interface{}{ErrorRetryChecker(DefaultErrorRetryChecker)} + checkers = []interface{}{ErrorRetryChecker(DefaultErrorRetryChecker), ResponseRetryChecker(DefaultResponseRetryChecker)} } var resp *Response @@ -255,6 +255,14 @@ func DefaultErrorRetryChecker(err error) (bool, error) { return false, err } +// DefaultResponseRetryChecker implements the defaults for retrying on response. +func DefaultResponseRetryChecker(resp *Response) (bool, error) { + if isResponseDNSError(resp) { + return true, fmt.Errorf("retrying for DNS related failure response: %v", resp) + } + return false, nil +} + // logZipkinTrace provides support to log Zipkin Trace for param: spoofResponse // We only log Zipkin trace for HTTP server errors i.e for HTTP status codes between 500 to 600 func (sc *SpoofingClient) logZipkinTrace(spoofResp *Response) {