Skip to content

Commit 36e8780

Browse files
committed
fix(admin-token-issuer-proxy): retry DNS cold starts
1 parent d821bed commit 36e8780

2 files changed

Lines changed: 43 additions & 0 deletions

File tree

src/control-plane-services/admin-token-issuer-proxy/internal/servicecache/cache.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ func isRetryableTransportError(err error) bool {
114114
return false
115115
}
116116

117+
// Kubernetes DNS can return NXDOMAIN until a Service is created. Treat DNS
118+
// resolution failures as startup-transient so the process remains live and
119+
// unready while it waits for api-keys to become discoverable.
120+
var dnsErr *net.DNSError
121+
if errors.As(err, &dnsErr) {
122+
return true
123+
}
124+
117125
var networkErr net.Error
118126
if errors.As(err, &networkErr) && (networkErr.Timeout() || networkErr.Temporary()) {
119127
return true

src/control-plane-services/admin-token-issuer-proxy/internal/servicecache/cache_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"encoding/json"
2424
"errors"
2525
"io"
26+
"net"
2627
"net/http"
2728
"net/http/httptest"
2829
"net/url"
@@ -189,6 +190,40 @@ func TestCacheFetchWithRetryToleratesConnectionRefused(t *testing.T) {
189190
}
190191
}
191192

193+
func TestCacheFetchWithRetryToleratesDNSNotFound(t *testing.T) {
194+
var requests atomic.Int32
195+
cache := New("http://api-keys.test/v1/services")
196+
cache.httpClient.Transport = roundTripFunc(func(r *http.Request) (*http.Response, error) {
197+
if requests.Add(1) < 3 {
198+
return nil, &url.Error{
199+
Op: r.Method,
200+
URL: r.URL.String(),
201+
Err: &net.DNSError{Name: "api-keys.test", IsNotFound: true},
202+
}
203+
}
204+
return &http.Response{
205+
StatusCode: http.StatusOK,
206+
Header: make(http.Header),
207+
Body: io.NopCloser(newJSONReader(t, models.ServicesResponse{Services: []models.ServiceInfo{{
208+
ServiceID: "test-service-id",
209+
ServiceName: "test-service",
210+
}}})),
211+
}, nil
212+
})
213+
214+
err := cache.FetchWithRetry(context.Background(), RetryPolicy{
215+
InitialBackoff: time.Millisecond,
216+
MaxBackoff: 2 * time.Millisecond,
217+
})
218+
219+
if err != nil {
220+
t.Fatalf("expected DNS-not-found retries to recover, got %v", err)
221+
}
222+
if got := requests.Load(); got != 3 {
223+
t.Fatalf("expected 3 metadata requests, got %d", got)
224+
}
225+
}
226+
192227
func TestCacheFetchWithRetryStopsOnPermanentTransportConfiguration(t *testing.T) {
193228
testCases := []struct {
194229
name string

0 commit comments

Comments
 (0)