diff --git a/.clusterfuzzlite/Dockerfile b/.clusterfuzzlite/Dockerfile index fc9dbb3c18..910590469d 100644 --- a/.clusterfuzzlite/Dockerfile +++ b/.clusterfuzzlite/Dockerfile @@ -1,4 +1,4 @@ -FROM gcr.io/oss-fuzz-base/base-builder-go@sha256:9e293085f163de4a9d9c02f0c17663b3d1e082db3355c142144bc2483d69b5ef +FROM gcr.io/oss-fuzz-base/base-builder-go@sha256:9e76082f0d5e86f349c9f87f4e9bc994f905ba865160886ed121fe661e59d4aa COPY . $SRC/skipper COPY ./.clusterfuzzlite/build.sh $SRC/ diff --git a/.github/labeler.yml b/.github/labeler.yml new file mode 100644 index 0000000000..4d99ccff6b --- /dev/null +++ b/.github/labeler.yml @@ -0,0 +1,7 @@ +# Add 'enhancement' label to any PR where the head branch name starts with `feature/` in the name +enhancement: + - head-branch: ['^feature/'] + +# Add 'codefreeze' label to any PR that is opened against the `cw2025` branch +codefreeze: + - base-branch: 'cw2025' diff --git a/.github/workflows/gh-packages.yaml b/.github/workflows/gh-packages.yaml index 65e0771b91..7e077a1ee3 100644 --- a/.github/workflows/gh-packages.yaml +++ b/.github/workflows/gh-packages.yaml @@ -47,7 +47,7 @@ jobs: make build.linux - name: Set up QEMU - uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 + uses: docker/setup-qemu-action@c7c53464625b32c7a7e944ae62b3e17d2b600130 - name: Set up Docker Buildx uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 @@ -61,7 +61,7 @@ jobs: password: ${{ secrets.GITHUB_TOKEN }} - name: Docker meta - uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f + uses: docker/metadata-action@318604b99e75e41977312d83839a89be02ca4893 id: meta with: images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} diff --git a/config/config.go b/config/config.go index 3a002faecd..dbc256f26e 100644 --- a/config/config.go +++ b/config/config.go @@ -195,6 +195,7 @@ type Config struct { KubernetesBackendTrafficAlgorithm kubernetes.BackendTrafficAlgorithm `yaml:"-"` KubernetesDefaultLoadBalancerAlgorithm string `yaml:"kubernetes-default-lb-algorithm"` KubernetesForceService bool `yaml:"kubernetes-force-service"` + KubernetesNoPoll bool `yaml:"kubernetes-no-poll"` // Default filters DefaultFiltersDir string `yaml:"default-filters-dir"` @@ -519,6 +520,7 @@ func NewConfig() *Config { flag.StringVar(&cfg.KubernetesBackendTrafficAlgorithmString, "kubernetes-backend-traffic-algorithm", kubernetes.TrafficPredicateAlgorithm.String(), "sets the algorithm to be used for traffic splitting between backends: traffic-predicate or traffic-segment-predicate") flag.StringVar(&cfg.KubernetesDefaultLoadBalancerAlgorithm, "kubernetes-default-lb-algorithm", kubernetes.DefaultLoadBalancerAlgorithm, "sets the default algorithm to be used for load balancing between backend endpoints, available options: roundRobin, consistentHash, random, powerOfRandomNChoices") flag.BoolVar(&cfg.KubernetesForceService, "kubernetes-force-service", false, "overrides default Skipper functionality and routes traffic using Kubernetes Services instead of Endpoints") + flag.BoolVar(&cfg.KubernetesNoPoll, "kubernetes-no-poll", false, "force kubernetes dataclient to not to create/update routing table") // Auth: flag.BoolVar(&cfg.EnableOAuth2GrantFlow, "enable-oauth2-grant-flow", false, "enables OAuth2 Grant Flow filter") @@ -935,6 +937,7 @@ func (c *Config) ToOptions() skipper.Options { KubernetesBackendTrafficAlgorithm: c.KubernetesBackendTrafficAlgorithm, KubernetesDefaultLoadBalancerAlgorithm: c.KubernetesDefaultLoadBalancerAlgorithm, KubernetesForceService: c.KubernetesForceService, + KubernetesNoPoll: c.KubernetesNoPoll, // API Monitoring: ApiUsageMonitoringEnable: c.ApiUsageMonitoringEnable, diff --git a/config/config_test.go b/config/config_test.go index 48a27745d9..3f7fdc99b7 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -114,6 +114,7 @@ func defaultConfig(with func(*Config)) *Config { KubernetesRedisServicePort: 6379, KubernetesBackendTrafficAlgorithmString: "traffic-predicate", KubernetesDefaultLoadBalancerAlgorithm: "roundRobin", + KubernetesNoPoll: false, Oauth2TokeninfoTimeout: 2 * time.Second, Oauth2TokenintrospectionTimeout: 2 * time.Second, Oauth2TokeninfoSubjectKey: "uid", diff --git a/dataclients/kubernetes/kube.go b/dataclients/kubernetes/kube.go index 6a1ccecbf8..78ab9a15a9 100644 --- a/dataclients/kubernetes/kube.go +++ b/dataclients/kubernetes/kube.go @@ -257,6 +257,9 @@ type Options struct { // ForwardBackendURL allows to use backend via kubernetes, for example routgroup backend `type: forward`. ForwardBackendURL string + + // KubernetesNoPoll force kubernetes dataclient to not create routing table + KubernetesNoPoll bool } // Client is a Skipper DataClient implementation used to create routes based on Kubernetes Ingress settings. @@ -276,6 +279,7 @@ type Client struct { state *clusterState loggingInterval time.Duration loggingLastEnabled time.Time + noPoll bool } // New creates and initializes a Kubernetes DataClient. @@ -355,6 +359,7 @@ func New(o Options) (*Client, error) { defaultFiltersDir: o.DefaultFiltersDir, forwardBackendURL: o.ForwardBackendURL, loggingInterval: 1 * time.Minute, + noPoll: o.KubernetesNoPoll, }, nil } @@ -420,6 +425,11 @@ func mapRoutes(routes []*eskip.Route) (map[string]*eskip.Route, []*eskip.Route) } func (c *Client) loadAndConvert() ([]*eskip.Route, error) { + if c.noPoll { + log.Debug("kubernetes dataclient is set to not poll") + return []*eskip.Route{}, nil + } + c.mu.Lock() state, err := c.ClusterClient.fetchClusterState() if err != nil { @@ -503,7 +513,7 @@ func healthcheckRoutes(reverseSourcePredicate bool) []*eskip.Route { if i > 0 { cidrs.WriteString(", ") } - cidrs.WriteString(fmt.Sprintf("%q", ip)) + fmt.Fprintf(cidrs, "%q", ip) } params.SourceCIDRs = cidrs.String() @@ -533,7 +543,7 @@ func (c *Client) LoadAll() ([]*eskip.Route, error) { // // TODO: implement a force reset after some time. func (c *Client) LoadUpdate() ([]*eskip.Route, []string, error) { - log.Debugf("polling for updates") + log.Debug("polling for updates") r, err := c.loadAndConvert() if err != nil { log.Errorf("polling for updates failed: %v", err) @@ -549,8 +559,7 @@ func (c *Client) LoadUpdate() ([]*eskip.Route, []string, error) { ) for id := range c.current { - // TODO: use eskip.Eq() - if r, ok := next[id]; ok && r.String() != c.current[id].String() { + if r, ok := next[id]; ok && eskip.Eq(r, c.current[id]) { updatedRoutes = append(updatedRoutes, r) } else if !ok { deletedIDs = append(deletedIDs, id) diff --git a/dataclients/kubernetes/kube_test.go b/dataclients/kubernetes/kube_test.go index a5e958e167..9f6e34e9c5 100644 --- a/dataclients/kubernetes/kube_test.go +++ b/dataclients/kubernetes/kube_test.go @@ -2969,3 +2969,16 @@ func (mockSecretProvider) Add(string) error { } func (mockSecretProvider) Close() {} + +func TestNoPoll(t *testing.T) { + api := newTestAPI(t, nil, &definitions.IngressV1List{}) + defer api.Close() + + dc, err := New(Options{KubernetesURL: api.server.URL, KubernetesNoPoll: true}) + require.NoError(t, err) + + routes, err := dc.LoadAll() + require.NoError(t, err) + + assert.Len(t, routes, 0) +} diff --git a/filters/builtin/builtin.go b/filters/builtin/builtin.go index 9746418d48..1653e7aa98 100644 --- a/filters/builtin/builtin.go +++ b/filters/builtin/builtin.go @@ -8,6 +8,7 @@ import ( "github.com/zalando/skipper/filters/accesslog" "github.com/zalando/skipper/filters/annotate" "github.com/zalando/skipper/filters/auth" + "github.com/zalando/skipper/filters/awssigner/awssigv4" "github.com/zalando/skipper/filters/circuit" "github.com/zalando/skipper/filters/consistenthash" "github.com/zalando/skipper/filters/cookie" @@ -170,6 +171,7 @@ func Filters() []filters.Spec { NewSetDynamicBackendScheme(), NewSetDynamicBackendUrl(), NewOriginMarkerSpec(), + awssigv4.New(), diag.NewRandom(), diag.NewRepeat(), diag.NewRepeatHex(), @@ -202,6 +204,7 @@ func Filters() []filters.Spec { sed.NewDelimitedRequest(), auth.NewBasicAuth(), cookie.NewDropRequestCookie(), + cookie.NewDropResponseCookie(), cookie.NewRequestCookie(), cookie.NewResponseCookie(), cookie.NewJSCookie(), diff --git a/filters/shedder/admission.go b/filters/shedder/admission.go index 95fd0bffd6..903ef63407 100644 --- a/filters/shedder/admission.go +++ b/filters/shedder/admission.go @@ -3,7 +3,7 @@ package shedder import ( "context" "math" - "math/rand" + "math/rand/v2" "net/http" "sync" "sync/atomic" @@ -94,7 +94,8 @@ const ( ) type Options struct { - Tracer opentracing.Tracer + Tracer opentracing.Tracer + testRand bool } type admissionControlPre struct{} @@ -164,7 +165,8 @@ func (spec *admissionControlPost) Do(routes []*routing.Route) []*routing.Route { } type AdmissionControlSpec struct { - tracer opentracing.Tracer + tracer opentracing.Tracer + testRand bool } type admissionControl struct { @@ -190,6 +192,13 @@ type admissionControl struct { success []int64 counter *atomic.Int64 successCounter *atomic.Int64 + + muRand sync.Mutex + rand func() float64 +} + +func randWithSeed() func() float64 { + return rand.New(rand.NewPCG(2, 3)).Float64 } func NewAdmissionControl(o Options) filters.Spec { @@ -198,7 +207,8 @@ func NewAdmissionControl(o Options) filters.Spec { tracer = &opentracing.NoopTracer{} } return &AdmissionControlSpec{ - tracer: tracer, + tracer: tracer, + testRand: o.testRand, } } @@ -298,6 +308,11 @@ func (spec *AdmissionControlSpec) CreateFilter(args []interface{}) (filters.Filt averageRpsFactor := float64(time.Second) / (float64(d) * float64(windowSize)) + r := rand.Float64 + if spec.testRand { + r = randWithSeed() + } + ac := &admissionControl{ once: sync.Once{}, @@ -319,6 +334,7 @@ func (spec *AdmissionControlSpec) CreateFilter(args []interface{}) (filters.Filt success: make([]int64, windowSize), counter: new(atomic.Int64), successCounter: new(atomic.Int64), + rand: r, } go ac.tickWindows(d) return ac, nil @@ -406,8 +422,11 @@ func (ac *admissionControl) pReject() float64 { func (ac *admissionControl) shouldReject() bool { p := ac.pReject() // [0, ac.maxRejectProbability] and -1 to disable + var r float64 + ac.muRand.Lock() /* #nosec */ - r := rand.Float64() // [0,1) + r = ac.rand() // [0,1) + ac.muRand.Unlock() if ac.mode == logInactive { log.Infof("%s: p: %0.2f, r: %0.2f", filters.AdmissionControlName, p, r) diff --git a/filters/shedder/admission_test.go b/filters/shedder/admission_test.go index 6563319ba5..e57e07a4b6 100644 --- a/filters/shedder/admission_test.go +++ b/filters/shedder/admission_test.go @@ -3,7 +3,6 @@ package shedder import ( "fmt" "io" - "math/rand" "net/http" "net/http/httptest" "net/url" @@ -151,12 +150,9 @@ func TestAdmissionControl(t *testing.T) { pExpectedAdmissionShedding: 0.0, }} { t.Run(ti.msg, func(t *testing.T) { - var mu sync.Mutex + randFunc := randWithSeed() backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - mu.Lock() - p := rand.Float64() - mu.Unlock() - if p < ti.pBackendErr { + if randFunc() < ti.pBackendErr { w.WriteHeader(http.StatusInternalServerError) } else { w.WriteHeader(http.StatusOK) @@ -164,7 +160,9 @@ func TestAdmissionControl(t *testing.T) { })) defer backend.Close() - spec := NewAdmissionControl(Options{}).(*AdmissionControlSpec) + spec := NewAdmissionControl(Options{ + testRand: true, + }).(*AdmissionControlSpec) args := make([]interface{}, 0, 6) args = append(args, "testmetric", ti.mode, ti.d.String(), ti.windowsize, ti.minRequests, ti.successThreshold, ti.maxrejectprobability, ti.exponent) @@ -262,7 +260,9 @@ func TestAdmissionControlChainOnlyBackendErrorPass(t *testing.T) { })) defer backend.Close() - spec := NewAdmissionControl(Options{}).(*AdmissionControlSpec) + spec := NewAdmissionControl(Options{ + testRand: true, + }).(*AdmissionControlSpec) argsLeaf := make([]interface{}, 0, 6) argsLeaf = append(argsLeaf, "testmetric-leaf", "active", "5ms", 5, 5, 0.9, 0.95, 1.0) @@ -393,7 +393,9 @@ func TestAdmissionControlCleanupModes(t *testing.T) { })) defer backend2.Close() - fspec := NewAdmissionControl(Options{}) + fspec := NewAdmissionControl(Options{ + testRand: true, + }) spec, ok := fspec.(*AdmissionControlSpec) if !ok { t.Fatal("FilterSpec is not a AdmissionControlSpec") @@ -564,7 +566,9 @@ func TestAdmissionControlCleanupMultipleFilters(t *testing.T) { })) defer backend.Close() - fspec := NewAdmissionControl(Options{}) + fspec := NewAdmissionControl(Options{ + testRand: true, + }) spec, ok := fspec.(*AdmissionControlSpec) if !ok { t.Fatal("FilterSpec is not a AdmissionControlSpec") @@ -605,7 +609,7 @@ func TestAdmissionControlSetsSpansTags(t *testing.T) { })) defer backend.Close() - fspec := NewAdmissionControl(Options{Tracer: tracer}) + fspec := NewAdmissionControl(Options{Tracer: tracer, testRand: true}) spec, ok := fspec.(*AdmissionControlSpec) if !ok { t.Fatal("FilterSpec is not a AdmissionControlSpec") diff --git a/filters/tee/teeloopback_test.go b/filters/tee/teeloopback_test.go index b134237161..9941ef74db 100644 --- a/filters/tee/teeloopback_test.go +++ b/filters/tee/teeloopback_test.go @@ -7,6 +7,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/zalando/skipper/eskip" "github.com/zalando/skipper/filters" "github.com/zalando/skipper/predicates/source" @@ -59,10 +60,12 @@ func TestLoopbackAndMatchPredicate(t *testing.T) { if err != nil { t.Error("teeloopback: failed to execute the request.", err) } + assert.Eventually(t, func() bool { + return matchRequestsCount(split, 1) && matchRequestsCount(shadow, 1) + }, 100*time.Millisecond, 10*time.Millisecond, + "teeloopback: expected to receive 1 requests in split and shadow backend but got Split: %d, Shadow: %d", + len(split.GetRequests()), len(shadow.GetRequests())) waitForAll(split, original, shadow) - if !matchRequestsCount(shadow, 1) || !matchRequestsCount(split, 1) { - t.Errorf("teeloopback: expected to receive 1 requests in split and shadow backend but got Split: %d, Shadow: %d", len(split.GetRequests()), len(shadow.GetRequests())) - } if !matchRequestsCount(original, 0) { t.Errorf("teeloopback: backend of original route should not receive requests but got %d", len(original.GetRequests())) } diff --git a/fuzz/Dockerfile b/fuzz/Dockerfile index 04ea35f6b5..a948b8f4e1 100644 --- a/fuzz/Dockerfile +++ b/fuzz/Dockerfile @@ -1,4 +1,4 @@ -FROM amazonlinux:2023@sha256:8c22ec81612b78284b5db864e0fad3c8df7688a8fd5baa861d69fe3baf2c7377 +FROM amazonlinux:2023@sha256:5ea333708360add6cc16ecec2569b8b75b6ee862528217bac65ad80752f4129b WORKDIR /workspace diff --git a/go.mod b/go.mod index 89a0839b50..f9459beb32 100644 --- a/go.mod +++ b/go.mod @@ -18,13 +18,13 @@ require ( github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 github.com/docker/go-connections v0.6.0 - github.com/envoyproxy/go-control-plane/envoy v1.35.0 + github.com/envoyproxy/go-control-plane/envoy v1.36.0 github.com/ghodss/yaml v1.0.0 github.com/golang-jwt/jwt/v4 v4.5.2 github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 github.com/hashicorp/memberlist v0.5.3 - github.com/instana/go-sensor v1.71.1 + github.com/instana/go-sensor v1.71.2 github.com/lightstep/lightstep-tracer-go v0.26.0 github.com/miekg/dns v1.1.68 github.com/oklog/ulid v1.3.1 @@ -41,7 +41,7 @@ require ( github.com/sony/gobreaker v1.0.0 github.com/stretchr/testify v1.11.1 github.com/szuecs/rate-limit-buffer v0.9.0 - github.com/testcontainers/testcontainers-go v0.39.0 + github.com/testcontainers/testcontainers-go v0.40.0 github.com/tidwall/gjson v1.18.0 github.com/tsenart/vegeta v12.7.0+incompatible github.com/uber/jaeger-client-go v2.30.0+incompatible @@ -61,8 +61,8 @@ require ( golang.org/x/crypto v0.43.0 golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 golang.org/x/net v0.46.0 - golang.org/x/oauth2 v0.32.0 - golang.org/x/sync v0.17.0 + golang.org/x/oauth2 v0.33.0 + golang.org/x/sync v0.18.0 golang.org/x/term v0.36.0 golang.org/x/time v0.14.0 google.golang.org/protobuf v1.36.10 @@ -97,7 +97,7 @@ require ( github.com/dgraph-io/ristretto/v2 v2.2.0 // indirect github.com/dgryski/go-gk v0.0.0-20200319235926-a69029f61654 // indirect github.com/distribution/reference v0.6.0 // indirect - github.com/docker/docker v28.3.3+incompatible // indirect + github.com/docker/docker v28.5.1+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/ebitengine/purego v0.8.4 // indirect @@ -201,7 +201,7 @@ require ( golang.org/x/tools/godoc v0.1.0-deprecated // indirect google.golang.org/genproto/googleapis/api v0.0.0-20250908214217-97024824d090 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090 // indirect - google.golang.org/grpc v1.75.0 // indirect + google.golang.org/grpc v1.75.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect oras.land/oras-go/v2 v2.6.0 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/go.sum b/go.sum index a1dea1eed9..5a20ac38d3 100644 --- a/go.sum +++ b/go.sum @@ -117,8 +117,8 @@ github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598 h1:MGKhKyiYrvMDZs github.com/dimfeld/httppath v0.0.0-20170720192232-ee938bf73598/go.mod h1:0FpDmbrt36utu8jEmeU05dPC9AB5tsLYVVi+ZHfyuwI= github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk= github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= -github.com/docker/docker v28.3.3+incompatible h1:Dypm25kh4rmk49v1eiVbsAtpAsYURjYkaKubwuBdxEI= -github.com/docker/docker v28.3.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v28.5.1+incompatible h1:Bm8DchhSD2J6PsFzxC35TZo4TLGR2PdW/E69rU45NhM= +github.com/docker/docker v28.5.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94= github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE= github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4= @@ -127,8 +127,8 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw= github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/envoyproxy/go-control-plane/envoy v1.35.0 h1:ixjkELDE+ru6idPxcHLj8LBVc2bFP7iBytj353BoHUo= -github.com/envoyproxy/go-control-plane/envoy v1.35.0/go.mod h1:09qwbGVuSWWAyN5t/b3iyVfz5+z8QWGrzkoqm/8SbEs= +github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= +github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= @@ -240,8 +240,8 @@ github.com/hashicorp/memberlist v0.5.3/go.mod h1:h60o12SZn/ua/j0B6iKAZezA4eDaGsI github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/influxdata/tdigest v0.0.1 h1:XpFptwYmnEKUqmkcDjrzffswZ3nvNeevbUSLPP/ZzIY= github.com/influxdata/tdigest v0.0.1/go.mod h1:Z0kXnxzbTC2qrx4NaIzYkE1k66+6oEDQTvL95hQFh5Y= -github.com/instana/go-sensor v1.71.1 h1:EqRQS/gi7C2FeYseRlgUB+u1qvD9aLGJCJ0PBXrtshM= -github.com/instana/go-sensor v1.71.1/go.mod h1:wWLB5TQn5zd+XxZPLkaScMzRr74ymtptaDTPhrueDyM= +github.com/instana/go-sensor v1.71.2 h1:xjAJiE2RrhRi0vMoK7I8jnL9TYabgyfKgTHUkqCsWwk= +github.com/instana/go-sensor v1.71.2/go.mod h1:wWLB5TQn5zd+XxZPLkaScMzRr74ymtptaDTPhrueDyM= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -442,8 +442,8 @@ github.com/szuecs/rate-limit-buffer v0.9.0 h1:65fBCVsaJFh0E1G5C6/sInEPlYR6dXtF9J github.com/szuecs/rate-limit-buffer v0.9.0/go.mod h1:BxqrsmnHsCnWcvbtdcaDLEBmjNEvRFU5LQ8edoZ9B0M= github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhgwZDDc= github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k= -github.com/testcontainers/testcontainers-go v0.39.0 h1:uCUJ5tA+fcxbFAB0uP3pIK3EJ2IjjDUHFSZ1H1UxAts= -github.com/testcontainers/testcontainers-go v0.39.0/go.mod h1:qmHpkG7H5uPf/EvOORKvS6EuDkBUPE3zpVGaH9NL7f8= +github.com/testcontainers/testcontainers-go v0.40.0 h1:pSdJYLOVgLE8YdUY2FHQ1Fxu+aMnb6JfVz1mxk7OeMU= +github.com/testcontainers/testcontainers-go v0.40.0/go.mod h1:FSXV5KQtX2HAMlm7U3APNyLkkap35zNLxukw9oBi/MY= github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= @@ -603,8 +603,8 @@ golang.org/x/net v0.46.0 h1:giFlY12I07fugqwPuWJi68oOnpfqFnJIJzaIIm2JVV4= golang.org/x/net v0.46.0/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= -golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.33.0 h1:4Q+qn+E5z8gPRJfmRy7C2gGG3T4jIprK6aSYgTXGRpo= +golang.org/x/oauth2 v0.33.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -614,8 +614,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -699,8 +699,8 @@ google.golang.org/genproto/googleapis/rpc v0.0.0-20250908214217-97024824d090/go. google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.75.0 h1:+TW+dqTd2Biwe6KKfhE5JpiYIBWq865PhKGSXiivqt4= -google.golang.org/grpc v1.75.0/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= +google.golang.org/grpc v1.75.1 h1:/ODCNEuf9VghjgO3rqLcfg8fiOP0nSluljWFlDxELLI= +google.golang.org/grpc v1.75.1/go.mod h1:JtPAzKiq4v1xcAB2hydNlWI2RnF85XXcV0mhKXr2ecQ= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/proxy/healthy_endpoints_test.go b/proxy/healthy_endpoints_test.go index 620f3a4580..6f55fd8f9c 100644 --- a/proxy/healthy_endpoints_test.go +++ b/proxy/healthy_endpoints_test.go @@ -275,7 +275,7 @@ func TestPHCNoHealthyEndpoints(t *testing.T) { ) servicesString := setupServices(t, healthy, unhealthy) - mockMetrics, ps := setupProxy(t, fmt.Sprintf(`* -> backendTimeout("20ms") -> `, + mockMetrics, ps := setupProxy(t, fmt.Sprintf(`* -> backendTimeout("20ms") -> `, servicesString)) va := fireVegeta(t, ps, 5000, 1*time.Second, 5*time.Second) diff --git a/skipper.go b/skipper.go index e43d336eb2..db6ca44efd 100644 --- a/skipper.go +++ b/skipper.go @@ -310,6 +310,9 @@ type Options struct { // instead using Kubernetes Services. KubernetesForceService bool + // KubernetesNoPoll force kubernetes dataclient to not create routing table + KubernetesNoPoll bool + // KubernetesBackendTrafficAlgorithm specifies the algorithm to calculate the backend traffic KubernetesBackendTrafficAlgorithm kubernetes.BackendTrafficAlgorithm @@ -1054,6 +1057,7 @@ func (o *Options) KubernetesDataClientOptions() kubernetes.Options { BackendTrafficAlgorithm: o.KubernetesBackendTrafficAlgorithm, DefaultLoadBalancerAlgorithm: o.KubernetesDefaultLoadBalancerAlgorithm, ForwardBackendURL: o.ForwardBackendURL, + KubernetesNoPoll: o.KubernetesNoPoll, } }