Skip to content

Commit bc8ec4f

Browse files
authored
Merge pull request kubernetes#125166 from p0lyn0mial/upstream-improve-check-data-consistency
client-go/util/consistencydetector: improve validation of list parameters (RV, ListOptions)
2 parents fd95f18 + 327ae98 commit bc8ec4f

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

staging/src/k8s.io/client-go/util/consistencydetector/data_consistency_detector.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ type ListFunc[T runtime.Object] func(ctx context.Context, options metav1.ListOpt
4141
// we cannot manipulate the environmental variable because
4242
// it will affect other tests in this package.
4343
func CheckDataConsistency[T runtime.Object, U any](ctx context.Context, identity string, lastSyncedResourceVersion string, listFn ListFunc[T], listOptions metav1.ListOptions, retrieveItemsFn RetrieveItemsFunc[U]) {
44+
if !canFormAdditionalListCall(lastSyncedResourceVersion, listOptions) {
45+
klog.V(4).Infof("data consistency check for %s is enabled but the parameters (RV, ListOptions) doesn't allow for creating a valid LIST request. Skipping the data consistency check.", identity)
46+
return
47+
}
4448
klog.Warningf("data consistency check for %s is enabled, this will result in an additional call to the API server.", identity)
4549
listOptions.ResourceVersion = lastSyncedResourceVersion
4650
listOptions.ResourceVersionMatch = metav1.ResourceVersionMatchExact
@@ -79,6 +83,26 @@ func CheckDataConsistency[T runtime.Object, U any](ctx context.Context, identity
7983
}
8084
}
8185

86+
// canFormAdditionalListCall ensures that we can form a valid LIST requests
87+
// for checking data consistency.
88+
func canFormAdditionalListCall(resourceVersion string, options metav1.ListOptions) bool {
89+
// since we are setting ResourceVersionMatch to metav1.ResourceVersionMatchExact
90+
// we need to make sure that the continuation hasn't been set
91+
// https://github.com/kubernetes/kubernetes/blob/be4afb9ef90b19ccb6f7e595cbdb247e088b2347/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/validation/validation.go#L38
92+
if len(options.Continue) > 0 {
93+
return false
94+
}
95+
96+
// since we are setting ResourceVersionMatch to metav1.ResourceVersionMatchExact
97+
// we need to make sure that the RV is valid because the validation code forbids RV == "0"
98+
// https://github.com/kubernetes/kubernetes/blob/be4afb9ef90b19ccb6f7e595cbdb247e088b2347/staging/src/k8s.io/apimachinery/pkg/apis/meta/internalversion/validation/validation.go#L44
99+
if resourceVersion == "0" {
100+
return false
101+
}
102+
103+
return true
104+
}
105+
82106
type byUID []metav1.Object
83107

84108
func (a byUID) Len() int { return len(a) }

staging/src/k8s.io/client-go/util/consistencydetector/data_consistency_detector_test.go

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,22 @@ func TestDataConsistencyChecker(t *testing.T) {
7676
},
7777
},
7878

79+
{
80+
name: "data consistency check won't be performed when Continuation was set",
81+
requestOptions: metav1.ListOptions{Continue: "fake continuation token"},
82+
expectedListRequests: 0,
83+
},
84+
85+
{
86+
name: "data consistency check won't be performed when ResourceVersion was set to 0",
87+
listResponse: &v1.PodList{
88+
ListMeta: metav1.ListMeta{ResourceVersion: "0"},
89+
Items: []v1.Pod{*makePod("p1", "1"), *makePod("p2", "2")},
90+
},
91+
requestOptions: metav1.ListOptions{},
92+
expectedListRequests: 0,
93+
},
94+
7995
{
8096
name: "data consistency panics when data is inconsistent",
8197
listResponse: &v1.PodList{
@@ -99,6 +115,9 @@ func TestDataConsistencyChecker(t *testing.T) {
99115
for _, scenario := range scenarios {
100116
t.Run(scenario.name, func(t *testing.T) {
101117
ctx := context.TODO()
118+
if scenario.listResponse == nil {
119+
scenario.listResponse = &v1.PodList{}
120+
}
102121
fakeLister := &listWrapper{response: scenario.listResponse}
103122
retrievedItemsFunc := func() []*v1.Pod {
104123
return scenario.retrievedItems

0 commit comments

Comments
 (0)