From f7f3809c513cd051c2c45bbef0655cf5a3eceea2 Mon Sep 17 00:00:00 2001 From: Lukasz Szaszkiewicz Date: Mon, 10 Jun 2024 22:52:47 +0200 Subject: [PATCH] client-go/consistencydetector: introduce CheckWatchListFromCacheDataConsistencyIfRequested --- .../list_data_consistency_detector_test.go | 6 +++ .../watch_list_data_consistency_detector.go | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 staging/src/k8s.io/client-go/util/consistencydetector/watch_list_data_consistency_detector.go diff --git a/staging/src/k8s.io/client-go/util/consistencydetector/list_data_consistency_detector_test.go b/staging/src/k8s.io/client-go/util/consistencydetector/list_data_consistency_detector_test.go index 945e0731025..e0a250166d7 100644 --- a/staging/src/k8s.io/client-go/util/consistencydetector/list_data_consistency_detector_test.go +++ b/staging/src/k8s.io/client-go/util/consistencydetector/list_data_consistency_detector_test.go @@ -36,6 +36,12 @@ var ( emptyListOptions = metav1.ListOptions{} ) +func TestDriveCheckWatchListFromCacheDataConsistencyIfRequested(t *testing.T) { + ctx := context.TODO() + + CheckWatchListFromCacheDataConsistencyIfRequested(ctx, "", emptyListFunc, emptyListOptions, &v1.PodList{}) +} + func TestDriveCheckListFromCacheDataConsistencyIfRequested(t *testing.T) { ctx := context.TODO() diff --git a/staging/src/k8s.io/client-go/util/consistencydetector/watch_list_data_consistency_detector.go b/staging/src/k8s.io/client-go/util/consistencydetector/watch_list_data_consistency_detector.go new file mode 100644 index 00000000000..cda5fc205f2 --- /dev/null +++ b/staging/src/k8s.io/client-go/util/consistencydetector/watch_list_data_consistency_detector.go @@ -0,0 +1,54 @@ +/* +Copyright 2024 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 consistencydetector + +import ( + "context" + "os" + "strconv" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +var dataConsistencyDetectionForWatchListEnabled = false + +func init() { + dataConsistencyDetectionForWatchListEnabled, _ = strconv.ParseBool(os.Getenv("KUBE_WATCHLIST_INCONSISTENCY_DETECTOR")) +} + +// IsDataConsistencyDetectionForWatchListEnabled returns true when +// the KUBE_WATCHLIST_INCONSISTENCY_DETECTOR environment variable was set during a binary startup. +func IsDataConsistencyDetectionForWatchListEnabled() bool { + return dataConsistencyDetectionForWatchListEnabled +} + +// CheckWatchListFromCacheDataConsistencyIfRequested performs a data consistency check only when +// the KUBE_WATCHLIST_INCONSISTENCY_DETECTOR environment variable was set during a binary startup. +// +// The consistency check is meant to be enforced only in the CI, not in production. +// The check ensures that data retrieved by the watch-list api call +// is exactly the same as data received by the standard list api call against etcd. +// +// Note that this function will panic when data inconsistency is detected. +// This is intentional because we want to catch it in the CI. +func CheckWatchListFromCacheDataConsistencyIfRequested[T runtime.Object](ctx context.Context, identity string, listItemsFn ListFunc[T], optionsUsedToReceiveList metav1.ListOptions, receivedList runtime.Object) { + if !IsDataConsistencyDetectionForWatchListEnabled() { + return + } + checkListFromCacheDataConsistencyIfRequestedInternal(ctx, identity, listItemsFn, optionsUsedToReceiveList, receivedList) +}