mirror of
https://github.com/kubernetes/client-go.git
synced 2026-01-05 07:34:23 +00:00
Merge pull request #134505 from p0lyn0mial/upstream-watchlist-unsupported-wl-semantics-reflector-listwatch
client-go/tools/cache/listwatch: intro ToListWatcherWithWatchListSemantics Kubernetes-commit: 3828756d90cf28e0ab5e0ccd550041b70c642b91
This commit is contained in:
2
go.mod
2
go.mod
@@ -25,7 +25,7 @@ require (
|
|||||||
google.golang.org/protobuf v1.36.8
|
google.golang.org/protobuf v1.36.8
|
||||||
gopkg.in/evanphx/json-patch.v4 v4.13.0
|
gopkg.in/evanphx/json-patch.v4 v4.13.0
|
||||||
k8s.io/api v0.0.0-20251014034829-180fdecad17a
|
k8s.io/api v0.0.0-20251014034829-180fdecad17a
|
||||||
k8s.io/apimachinery v0.0.0-20251013232933-de3ea85ba46a
|
k8s.io/apimachinery v0.0.0-20251015043641-db7bb2323050
|
||||||
k8s.io/klog/v2 v2.130.1
|
k8s.io/klog/v2 v2.130.1
|
||||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912
|
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912
|
||||||
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
|
k8s.io/utils v0.0.0-20250604170112-4c0f3b243397
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -119,8 +119,8 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
|||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
k8s.io/api v0.0.0-20251014034829-180fdecad17a h1:xQZUr3sFO3VRP4paNCKSwDBL//XW7MfgEIc6F16S7tc=
|
k8s.io/api v0.0.0-20251014034829-180fdecad17a h1:xQZUr3sFO3VRP4paNCKSwDBL//XW7MfgEIc6F16S7tc=
|
||||||
k8s.io/api v0.0.0-20251014034829-180fdecad17a/go.mod h1:G9i/7w0plhqKf252B96rN9Ng5YQFUYQcEjRg17gOBdc=
|
k8s.io/api v0.0.0-20251014034829-180fdecad17a/go.mod h1:G9i/7w0plhqKf252B96rN9Ng5YQFUYQcEjRg17gOBdc=
|
||||||
k8s.io/apimachinery v0.0.0-20251013232933-de3ea85ba46a h1:6rysSFhh7j8BX8v+cqAFLo+62x5NMeJHZ5OiFZZYcDE=
|
k8s.io/apimachinery v0.0.0-20251015043641-db7bb2323050 h1:m5nhDhLbK0Gg1QHh7n9ekBWQ4oU7lr6Mmgi3TbW3JZ8=
|
||||||
k8s.io/apimachinery v0.0.0-20251013232933-de3ea85ba46a/go.mod h1:wE5nOmI8k5gdg4Nuo6Csst6CE+WgeB7ZNhh7K5lLUbs=
|
k8s.io/apimachinery v0.0.0-20251015043641-db7bb2323050/go.mod h1:wE5nOmI8k5gdg4Nuo6Csst6CE+WgeB7ZNhh7K5lLUbs=
|
||||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=
|
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=
|
||||||
|
|||||||
30
tools/cache/listwatch.go
vendored
30
tools/cache/listwatch.go
vendored
@@ -24,6 +24,7 @@ import (
|
|||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
"k8s.io/apimachinery/pkg/watch"
|
"k8s.io/apimachinery/pkg/watch"
|
||||||
restclient "k8s.io/client-go/rest"
|
restclient "k8s.io/client-go/rest"
|
||||||
|
"k8s.io/client-go/util/watchlist"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Lister is any object that knows how to perform an initial list.
|
// Lister is any object that knows how to perform an initial list.
|
||||||
@@ -130,6 +131,35 @@ type listerWatcherWrapper struct {
|
|||||||
ListerWithContext
|
ListerWithContext
|
||||||
WatcherWithContext
|
WatcherWithContext
|
||||||
}
|
}
|
||||||
|
type listWatcherWithWatchListSemanticsWrapper struct {
|
||||||
|
*ListWatch
|
||||||
|
|
||||||
|
// unsupportedWatchListSemantics indicates whether a client explicitly does NOT support
|
||||||
|
// WatchList semantics.
|
||||||
|
//
|
||||||
|
// Over the years, unit tests in kube have been written in many different ways.
|
||||||
|
// After enabling the WatchListClient feature by default, existing tests started failing.
|
||||||
|
// To avoid breaking lots of existing client-go users after upgrade,
|
||||||
|
// we introduced this field as an opt-in.
|
||||||
|
//
|
||||||
|
// When true, the reflector disables WatchList even if the feature gate is enabled.
|
||||||
|
unsupportedWatchListSemantics bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (lw *listWatcherWithWatchListSemanticsWrapper) IsWatchListSemanticsUnSupported() bool {
|
||||||
|
return lw.unsupportedWatchListSemantics
|
||||||
|
}
|
||||||
|
|
||||||
|
// ToListWatcherWithWatchListSemantics returns a ListerWatcher
|
||||||
|
// that knows whether the provided client explicitly
|
||||||
|
// does NOT support the WatchList semantics. This allows Reflectors
|
||||||
|
// to adapt their behavior based on client capabilities.
|
||||||
|
func ToListWatcherWithWatchListSemantics(lw *ListWatch, client any) ListerWatcher {
|
||||||
|
return &listWatcherWithWatchListSemanticsWrapper{
|
||||||
|
lw,
|
||||||
|
watchlist.DoesClientNotSupportWatchListSemantics(client),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ListFunc knows how to list resources
|
// ListFunc knows how to list resources
|
||||||
//
|
//
|
||||||
|
|||||||
65
tools/cache/listwatch_test.go
vendored
Normal file
65
tools/cache/listwatch_test.go
vendored
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2025 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package cache
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/client-go/util/watchlist"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fakeWatchListClient struct {
|
||||||
|
unSupportedWatchListSemantics bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f fakeWatchListClient) IsWatchListSemanticsUnSupported() bool {
|
||||||
|
return f.unSupportedWatchListSemantics
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestToListWatcherWithWatchListSemantics(t *testing.T) {
|
||||||
|
scenarios := []struct {
|
||||||
|
name string
|
||||||
|
client any
|
||||||
|
expectUnSupportedWatchListSemantics bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "client which doesn't implement the interface supports WatchList semantics",
|
||||||
|
client: nil,
|
||||||
|
expectUnSupportedWatchListSemantics: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "client does not support WatchList semantics",
|
||||||
|
client: fakeWatchListClient{unSupportedWatchListSemantics: true},
|
||||||
|
expectUnSupportedWatchListSemantics: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "client supports WatchList semantics",
|
||||||
|
client: fakeWatchListClient{unSupportedWatchListSemantics: false},
|
||||||
|
expectUnSupportedWatchListSemantics: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, scenario := range scenarios {
|
||||||
|
t.Run(scenario.name, func(t *testing.T) {
|
||||||
|
target := ToListWatcherWithWatchListSemantics(&ListWatch{}, scenario.client)
|
||||||
|
|
||||||
|
if got := watchlist.DoesClientNotSupportWatchListSemantics(target); got != scenario.expectUnSupportedWatchListSemantics {
|
||||||
|
t.Fatalf("DoesClientNotSupportWatchListSemantics returned: %v, want: %v", got, scenario.expectUnSupportedWatchListSemantics)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user