From 0a3b4550a123c20fec0f598be528f2a637180800 Mon Sep 17 00:00:00 2001 From: rashmigottipati Date: Mon, 5 Apr 2021 13:02:18 -0400 Subject: [PATCH 01/10] Initial commit for finalizer helper library Signed-off-by: rashmigottipati --- pkg/finalizer/finalizer.go | 52 ++++++++++++++++++++++++++++++++++++++ pkg/finalizer/types.go | 39 ++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 pkg/finalizer/finalizer.go create mode 100644 pkg/finalizer/types.go diff --git a/pkg/finalizer/finalizer.go b/pkg/finalizer/finalizer.go new file mode 100644 index 0000000000..5d242e9faa --- /dev/null +++ b/pkg/finalizer/finalizer.go @@ -0,0 +1,52 @@ +/* +Copyright 2021 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 finalizer + +import ( + "context" + "fmt" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +func NewFinalizers() (Finalizers, error) { + return finalizers(map[string]Finalizer{}), nil +} + +func (f finalizers) Register(key string, finalizer Finalizer) error { + if _, ok := f[key]; ok { + return fmt.Errorf("finalizer for key %q already registered", key) + } + f[key] = finalizer + return nil +} + +func (f finalizers) Finalize(ctx context.Context, obj client.Object) (bool, error) { + needsUpdate := false + for key, finalizer := range f { + if obj.GetDeletionTimestamp() == nil && !controllerutil.ContainsFinalizer(obj, key) { + controllerutil.AddFinalizer(obj, key) + needsUpdate = true + } else if obj.GetDeletionTimestamp() != nil && controllerutil.ContainsFinalizer(obj, key) { + _, err := finalizer.Finalize(ctx, obj) + if err != nil { + return true, fmt.Errorf("finalize failed for key %q: %v", key, err) + } + controllerutil.RemoveFinalizer(obj, key) + needsUpdate = true + } + } + return needsUpdate, nil +} diff --git a/pkg/finalizer/types.go b/pkg/finalizer/types.go new file mode 100644 index 0000000000..eac28d3708 --- /dev/null +++ b/pkg/finalizer/types.go @@ -0,0 +1,39 @@ +/* +Copyright 2021 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 finalizer + +import ( + "context" + + "sigs.k8s.io/controller-runtime/pkg/client" +) + +type Registerer interface { + Register(key string, f Finalizer) error +} + +type Finalizer interface { + Finalize(context.Context, client.Object) (needsUpdate bool, err error) +} + +type finalizers map[string]Finalizer + +type Finalizers interface { + // implements Registerer and Finalizer to finalize + // all registered finalizers if the provided object + // has a deletion timestamp or set all registered + // finalizers if it doesn't + Registerer + Finalizer +} From c6fecbb15597c61eed3c163e3f7f746354598617 Mon Sep 17 00:00:00 2001 From: Rashmi Gottipati Date: Tue, 20 Apr 2021 05:35:17 -0400 Subject: [PATCH 02/10] Add unit tests Signed-off-by: Rashmi Gottipati --- pkg/finalizer/finalizer.go | 11 ++-- pkg/finalizer/finalizer_test.go | 92 +++++++++++++++++++++++++++++++++ pkg/finalizer/types.go | 13 +++-- 3 files changed, 107 insertions(+), 9 deletions(-) create mode 100644 pkg/finalizer/finalizer_test.go diff --git a/pkg/finalizer/finalizer.go b/pkg/finalizer/finalizer.go index 5d242e9faa..d3a54f266c 100644 --- a/pkg/finalizer/finalizer.go +++ b/pkg/finalizer/finalizer.go @@ -21,8 +21,9 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) -func NewFinalizers() (Finalizers, error) { - return finalizers(map[string]Finalizer{}), nil +// NewFinalizers returns the Finalizers interface +func NewFinalizers() Finalizers { + return finalizers(map[string]Finalizer{}) } func (f finalizers) Register(key string, finalizer Finalizer) error { @@ -36,13 +37,13 @@ func (f finalizers) Register(key string, finalizer Finalizer) error { func (f finalizers) Finalize(ctx context.Context, obj client.Object) (bool, error) { needsUpdate := false for key, finalizer := range f { - if obj.GetDeletionTimestamp() == nil && !controllerutil.ContainsFinalizer(obj, key) { + if obj.GetDeletionTimestamp().IsZero() && !controllerutil.ContainsFinalizer(obj, key) { controllerutil.AddFinalizer(obj, key) needsUpdate = true } else if obj.GetDeletionTimestamp() != nil && controllerutil.ContainsFinalizer(obj, key) { - _, err := finalizer.Finalize(ctx, obj) + ret, err := finalizer.Finalize(ctx, obj) if err != nil { - return true, fmt.Errorf("finalize failed for key %q: %v", key, err) + return ret, fmt.Errorf("finalize failed for key %q: %v", key, err) } controllerutil.RemoveFinalizer(obj, key) needsUpdate = true diff --git a/pkg/finalizer/finalizer_test.go b/pkg/finalizer/finalizer_test.go new file mode 100644 index 0000000000..6d110db454 --- /dev/null +++ b/pkg/finalizer/finalizer_test.go @@ -0,0 +1,92 @@ +package finalizer + +import ( + "context" + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest/printer" +) + +type mockFinalizer struct{} + +func (f mockFinalizer) Finalize(context.Context, client.Object) (needsUpdate bool, err error) { + return true, nil +} +func TestFinalizer(t *testing.T) { + RegisterFailHandler(Fail) + suiteName := "Finalizer Suite" + RunSpecsWithDefaultAndCustomReporters(t, suiteName, []Reporter{printer.NewlineReporter{}, printer.NewProwReporter(suiteName)}) +} + +var _ = Describe("TestFinalizer", func() { + var err error + var pod *corev1.Pod + var finalizers Finalizers + var f mockFinalizer + BeforeEach(func() { + pod = &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Finalizers: []string{"finalizers.sigs.k8s.io/testfinalizer"}, + }, + } + Expect(pod).NotTo(BeNil()) + + finalizers = NewFinalizers() + Expect(finalizers).NotTo(BeNil()) + + f := mockFinalizer{} + Expect(f).NotTo(BeNil()) + + }) + Describe("Finalizer helper library", func() { + It("Register should successfully register a finalizer", func() { + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + }) + + It("Register should return an error when it is called twice with the same key", func() { + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + // calling Register again with the same key should return an error + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).NotTo(BeNil()) + Expect(err.Error()).To(ContainSubstring("already registered")) + + }) + + It("Finalize should return no error and indicate false for needsUpdate if a finalizer is not registered", func() { + ret, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(ret).To(BeFalse()) + }) + + It("Finalize should return no error when deletion timestamp is not nil and the finalizer exists", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + _, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + }) + + It("Finalize should return no error when deletion timestamp is nil and finalizer does not exist", func() { + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + pod.DeletionTimestamp = nil + pod.Finalizers = []string{} + + needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(needsUpdate).To(BeTrue()) + }) + }) +}) diff --git a/pkg/finalizer/types.go b/pkg/finalizer/types.go index eac28d3708..edca7f9661 100644 --- a/pkg/finalizer/types.go +++ b/pkg/finalizer/types.go @@ -19,21 +19,26 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) +// Registerer holds Register that will check if a key is already registered +// and error out and it does; and if not registered, it will add the finalizer +// to the finalizers map as the value for the provided key type Registerer interface { Register(key string, f Finalizer) error } +// Finalizer holds Finalize that will add/remove a finalizer based on the +// deletion timestamp being set and return an indication of whether the +// obj needs an update or not type Finalizer interface { Finalize(context.Context, client.Object) (needsUpdate bool, err error) } type finalizers map[string]Finalizer +// Finalizers implements Registerer and Finalizer to finalize all registered +// finalizers if the provided object has a deletion timestamp or set all +// registered finalizers if it does not type Finalizers interface { - // implements Registerer and Finalizer to finalize - // all registered finalizers if the provided object - // has a deletion timestamp or set all registered - // finalizers if it doesn't Registerer Finalizer } From 9f610897c7e4969994273b3477c2387f6eccbdea Mon Sep 17 00:00:00 2001 From: Rashmi Gottipati Date: Thu, 22 Apr 2021 12:17:09 -0400 Subject: [PATCH 03/10] Address review comments Signed-off-by: Rashmi Gottipati --- pkg/finalizer/finalizer.go | 26 +++++++++----- pkg/finalizer/finalizer_test.go | 61 +++++++++++++++++++++++++++------ pkg/finalizer/types.go | 2 -- 3 files changed, 69 insertions(+), 20 deletions(-) diff --git a/pkg/finalizer/finalizer.go b/pkg/finalizer/finalizer.go index d3a54f266c..583fdd1547 100644 --- a/pkg/finalizer/finalizer.go +++ b/pkg/finalizer/finalizer.go @@ -17,13 +17,16 @@ import ( "context" "fmt" + utilerrors "k8s.io/apimachinery/pkg/util/errors" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) +type finalizers map[string]Finalizer + // NewFinalizers returns the Finalizers interface func NewFinalizers() Finalizers { - return finalizers(map[string]Finalizer{}) + return finalizers{} } func (f finalizers) Register(key string, finalizer Finalizer) error { @@ -35,19 +38,26 @@ func (f finalizers) Register(key string, finalizer Finalizer) error { } func (f finalizers) Finalize(ctx context.Context, obj client.Object) (bool, error) { + var errList []error needsUpdate := false for key, finalizer := range f { - if obj.GetDeletionTimestamp().IsZero() && !controllerutil.ContainsFinalizer(obj, key) { + if dt := obj.GetDeletionTimestamp(); dt.IsZero() && !controllerutil.ContainsFinalizer(obj, key) { controllerutil.AddFinalizer(obj, key) needsUpdate = true - } else if obj.GetDeletionTimestamp() != nil && controllerutil.ContainsFinalizer(obj, key) { - ret, err := finalizer.Finalize(ctx, obj) + } else if !dt.IsZero() && controllerutil.ContainsFinalizer(obj, key) { + finalizerNeedsUpdate, err := finalizer.Finalize(ctx, obj) if err != nil { - return ret, fmt.Errorf("finalize failed for key %q: %v", key, err) + // Even when the finalizer fails, it may need to signal to update the primary + // object (e.g. it may set a condition and need a status update). + needsUpdate = needsUpdate || finalizerNeedsUpdate + errList = append(errList, fmt.Errorf("finalizer %q failed: %v", key, err)) + } else { + // If the finalizer succeeds, we remove the finalizer from the primary + // object's metadata, so we know it will need an update. + needsUpdate = true + controllerutil.RemoveFinalizer(obj, key) } - controllerutil.RemoveFinalizer(obj, key) - needsUpdate = true } } - return needsUpdate, nil + return needsUpdate, utilerrors.NewAggregate(errList) } diff --git a/pkg/finalizer/finalizer_test.go b/pkg/finalizer/finalizer_test.go index 6d110db454..80a197ec04 100644 --- a/pkg/finalizer/finalizer_test.go +++ b/pkg/finalizer/finalizer_test.go @@ -43,13 +43,13 @@ var _ = Describe("TestFinalizer", func() { Expect(f).NotTo(BeNil()) }) - Describe("Finalizer helper library", func() { - It("Register should successfully register a finalizer", func() { + Describe("Register", func() { + It("successfully registers a finalizer", func() { err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) Expect(err).To(BeNil()) }) - It("Register should return an error when it is called twice with the same key", func() { + It("should fail when trying to register a finalizer that was already registered", func() { err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) Expect(err).To(BeNil()) @@ -59,31 +59,72 @@ var _ = Describe("TestFinalizer", func() { Expect(err.Error()).To(ContainSubstring("already registered")) }) - - It("Finalize should return no error and indicate false for needsUpdate if a finalizer is not registered", func() { + }) + Describe("Finalize", func() { + It("should return no error and return false for needsUpdate if a finalizer is not registered", func() { ret, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) Expect(ret).To(BeFalse()) }) - It("Finalize should return no error when deletion timestamp is not nil and the finalizer exists", func() { + It("successfully finalizes and returns true for needsUpdate when deletion timestamp is nil and finalizer does not exist", func() { + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + pod.DeletionTimestamp = nil + pod.Finalizers = []string{} + + needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(needsUpdate).To(BeTrue()) + }) + + It("successfully finalizes and returns true for needsUpdate when deletion timestamp is not nil and the finalizer exists", func() { now := metav1.Now() pod.DeletionTimestamp = &now err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) Expect(err).To(BeNil()) - _, err := finalizers.Finalize(context.TODO(), pod) + pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer"} + + needsUpdate, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) + Expect(needsUpdate).To(BeTrue()) }) - It("Finalize should return no error when deletion timestamp is nil and finalizer does not exist", func() { - err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + It("should return no error and return false for needsUpdate when deletion timestamp is nil and finalizer doesn't exist", func() { + pod.DeletionTimestamp = nil + pod.Finalizers = []string{} + + needsUpdate, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) + Expect(needsUpdate).To(BeFalse()) + }) - pod.DeletionTimestamp = nil + It("should return no error and return false for needsUpdate when deletion timestamp is not nil and the finalizer doesn't exist", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now pod.Finalizers = []string{} + needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(needsUpdate).To(BeFalse()) + + }) + + It("successfully finalizes multiple finalizers and returns true for needsUpdate when deletion timestamp is not nil and the finalizer exists", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + err = finalizers.Register("finalizers.sigs.k8s.io/newtestfinalizer", f) + Expect(err).To(BeNil()) + + pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer", "finalizers.sigs.k8s.io/newtestfinalizer"} + needsUpdate, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) Expect(needsUpdate).To(BeTrue()) diff --git a/pkg/finalizer/types.go b/pkg/finalizer/types.go index edca7f9661..1020ad157c 100644 --- a/pkg/finalizer/types.go +++ b/pkg/finalizer/types.go @@ -33,8 +33,6 @@ type Finalizer interface { Finalize(context.Context, client.Object) (needsUpdate bool, err error) } -type finalizers map[string]Finalizer - // Finalizers implements Registerer and Finalizer to finalize all registered // finalizers if the provided object has a deletion timestamp or set all // registered finalizers if it does not From b2693223fb31846535f351caadaa0e55e978613e Mon Sep 17 00:00:00 2001 From: Rashmi Gottipati Date: Wed, 19 May 2021 09:53:29 -0400 Subject: [PATCH 04/10] Add needsUpdate and err fields on mockFinalizer struct for customizations Signed-off-by: Rashmi Gottipati --- pkg/finalizer/finalizer_test.go | 68 ++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/pkg/finalizer/finalizer_test.go b/pkg/finalizer/finalizer_test.go index 80a197ec04..f809f52028 100644 --- a/pkg/finalizer/finalizer_test.go +++ b/pkg/finalizer/finalizer_test.go @@ -2,6 +2,7 @@ package finalizer import ( "context" + "fmt" "testing" . "github.com/onsi/ginkgo" @@ -12,10 +13,13 @@ import ( "sigs.k8s.io/controller-runtime/pkg/envtest/printer" ) -type mockFinalizer struct{} +type mockFinalizer struct { + needsUpdate bool + err error +} func (f mockFinalizer) Finalize(context.Context, client.Object) (needsUpdate bool, err error) { - return true, nil + return f.needsUpdate, f.err } func TestFinalizer(t *testing.T) { RegisterFailHandler(Fail) @@ -129,5 +133,65 @@ var _ = Describe("TestFinalizer", func() { Expect(err).To(BeNil()) Expect(needsUpdate).To(BeTrue()) }) + + It("should return needsUpdate as false and a non-nil error", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer"} + + f.needsUpdate = false + f.err = fmt.Errorf("finalizer failed for %q", pod.Finalizers[0]) + + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) + Expect(err).To(BeNil()) + + needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("finalizer failed")) + Expect(needsUpdate).To(BeFalse()) + }) + + It("should return expected needsUpdate and error values when registering multiple finalizers", func() { + now := metav1.Now() + pod.DeletionTimestamp = &now + pod.Finalizers = []string{ + "finalizers.sigs.k8s.io/testfinalizer1", + "finalizers.sigs.k8s.io/testfinalizer2", + "finalizers.sigs.k8s.io/testfinalizer3", + } + + // registering multiple finalizers with different return values + // test for needsUpdate as true, and nil error + f.needsUpdate = true + f.err = nil + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer1", f) + Expect(err).To(BeNil()) + + result, err := finalizers.Finalize(context.TODO(), pod) + Expect(err).To(BeNil()) + Expect(result).To(BeTrue()) + + // test for needsUpdate as false, and non-nil error + f.needsUpdate = false + f.err = fmt.Errorf("finalizer failed") + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer2", f) + Expect(err).To(BeNil()) + + result, err = finalizers.Finalize(context.TODO(), pod) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("finalizer failed")) + Expect(result).To(BeFalse()) + + // test for needsUpdate as true, and non-nil error + f.needsUpdate = true + f.err = fmt.Errorf("finalizer failed") + err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer3", f) + Expect(err).To(BeNil()) + + result, err = finalizers.Finalize(context.TODO(), pod) + Expect(err).ToNot(BeNil()) + Expect(err.Error()).To(ContainSubstring("finalizer failed")) + Expect(result).To(BeTrue()) + }) }) }) From ac093b0af5c2eb6a9ece8a68331f9e9916a85240 Mon Sep 17 00:00:00 2001 From: Rashmi Gottipati Date: Thu, 20 May 2021 22:58:38 -0400 Subject: [PATCH 05/10] Address review feedback #2 Signed-off-by: Rashmi Gottipati --- pkg/finalizer/finalizer_test.go | 41 ++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/pkg/finalizer/finalizer_test.go b/pkg/finalizer/finalizer_test.go index f809f52028..d6e49453d0 100644 --- a/pkg/finalizer/finalizer_test.go +++ b/pkg/finalizer/finalizer_test.go @@ -34,18 +34,10 @@ var _ = Describe("TestFinalizer", func() { var f mockFinalizer BeforeEach(func() { pod = &corev1.Pod{ - ObjectMeta: metav1.ObjectMeta{ - Finalizers: []string{"finalizers.sigs.k8s.io/testfinalizer"}, - }, + ObjectMeta: metav1.ObjectMeta{}, } - Expect(pod).NotTo(BeNil()) - finalizers = NewFinalizers() - Expect(finalizers).NotTo(BeNil()) - - f := mockFinalizer{} - Expect(f).NotTo(BeNil()) - + f = mockFinalizer{} }) Describe("Register", func() { It("successfully registers a finalizer", func() { @@ -65,12 +57,6 @@ var _ = Describe("TestFinalizer", func() { }) }) Describe("Finalize", func() { - It("should return no error and return false for needsUpdate if a finalizer is not registered", func() { - ret, err := finalizers.Finalize(context.TODO(), pod) - Expect(err).To(BeNil()) - Expect(ret).To(BeFalse()) - }) - It("successfully finalizes and returns true for needsUpdate when deletion timestamp is nil and finalizer does not exist", func() { err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) Expect(err).To(BeNil()) @@ -81,6 +67,10 @@ var _ = Describe("TestFinalizer", func() { needsUpdate, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) Expect(needsUpdate).To(BeTrue()) + // when deletion timestamp is nil and finalizer is not present, the registered finalizer would be added to the obj + Expect(len(pod.Finalizers)).To(Equal(1)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer")) + }) It("successfully finalizes and returns true for needsUpdate when deletion timestamp is not nil and the finalizer exists", func() { @@ -95,6 +85,8 @@ var _ = Describe("TestFinalizer", func() { needsUpdate, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) Expect(needsUpdate).To(BeTrue()) + // finalizer will be removed from the obj upon successful finalization + Expect(len(pod.Finalizers)).To(Equal(0)) }) It("should return no error and return false for needsUpdate when deletion timestamp is nil and finalizer doesn't exist", func() { @@ -104,6 +96,8 @@ var _ = Describe("TestFinalizer", func() { needsUpdate, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) Expect(needsUpdate).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(0)) + }) It("should return no error and return false for needsUpdate when deletion timestamp is not nil and the finalizer doesn't exist", func() { @@ -114,6 +108,7 @@ var _ = Describe("TestFinalizer", func() { needsUpdate, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) Expect(needsUpdate).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(0)) }) @@ -132,6 +127,7 @@ var _ = Describe("TestFinalizer", func() { needsUpdate, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) Expect(needsUpdate).To(BeTrue()) + Expect(len(pod.Finalizers)).To(Equal(0)) }) It("should return needsUpdate as false and a non-nil error", func() { @@ -149,6 +145,8 @@ var _ = Describe("TestFinalizer", func() { Expect(err).ToNot(BeNil()) Expect(err.Error()).To(ContainSubstring("finalizer failed")) Expect(needsUpdate).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(1)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer")) }) It("should return expected needsUpdate and error values when registering multiple finalizers", func() { @@ -170,6 +168,11 @@ var _ = Describe("TestFinalizer", func() { result, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) Expect(result).To(BeTrue()) + // `finalizers.sigs.k8s.io/testfinalizer1` will be removed from the list + // of finalizers, so length will be 2. + Expect(len(pod.Finalizers)).To(Equal(2)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) + Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) // test for needsUpdate as false, and non-nil error f.needsUpdate = false @@ -181,6 +184,9 @@ var _ = Describe("TestFinalizer", func() { Expect(err).ToNot(BeNil()) Expect(err.Error()).To(ContainSubstring("finalizer failed")) Expect(result).To(BeFalse()) + Expect(len(pod.Finalizers)).To(Equal(2)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) + Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) // test for needsUpdate as true, and non-nil error f.needsUpdate = true @@ -192,6 +198,9 @@ var _ = Describe("TestFinalizer", func() { Expect(err).ToNot(BeNil()) Expect(err.Error()).To(ContainSubstring("finalizer failed")) Expect(result).To(BeTrue()) + Expect(len(pod.Finalizers)).To(Equal(2)) + Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) + Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) }) }) }) From 60ab6fdc8f6db577324820b7b8f29c616794b141 Mon Sep 17 00:00:00 2001 From: Rashmi Gottipati Date: Sun, 6 Jun 2021 22:30:47 -0400 Subject: [PATCH 06/10] Split needsUpdate into two separate variables and update unit tests Signed-off-by: Rashmi Gottipati --- pkg/finalizer/finalizer.go | 26 +++++++---- pkg/finalizer/finalizer_test.go | 76 +++++++++++++++++++-------------- pkg/finalizer/types.go | 2 +- 3 files changed, 62 insertions(+), 42 deletions(-) diff --git a/pkg/finalizer/finalizer.go b/pkg/finalizer/finalizer.go index 583fdd1547..bbcd46abf6 100644 --- a/pkg/finalizer/finalizer.go +++ b/pkg/finalizer/finalizer.go @@ -24,6 +24,12 @@ import ( type finalizers map[string]Finalizer +// Result struct holds Updated and StatusUpdated fields +type Result struct { + Updated bool + StatusUpdated bool +} + // NewFinalizers returns the Finalizers interface func NewFinalizers() Finalizers { return finalizers{} @@ -37,27 +43,31 @@ func (f finalizers) Register(key string, finalizer Finalizer) error { return nil } -func (f finalizers) Finalize(ctx context.Context, obj client.Object) (bool, error) { - var errList []error - needsUpdate := false +func (f finalizers) Finalize(ctx context.Context, obj client.Object) (Result, error) { + var ( + res Result + errList []error + ) + res.Updated = false for key, finalizer := range f { if dt := obj.GetDeletionTimestamp(); dt.IsZero() && !controllerutil.ContainsFinalizer(obj, key) { controllerutil.AddFinalizer(obj, key) - needsUpdate = true + res.Updated = true } else if !dt.IsZero() && controllerutil.ContainsFinalizer(obj, key) { - finalizerNeedsUpdate, err := finalizer.Finalize(ctx, obj) + finalizerRes, err := finalizer.Finalize(ctx, obj) if err != nil { // Even when the finalizer fails, it may need to signal to update the primary // object (e.g. it may set a condition and need a status update). - needsUpdate = needsUpdate || finalizerNeedsUpdate + res.Updated = res.Updated || finalizerRes.Updated + res.StatusUpdated = res.StatusUpdated || finalizerRes.StatusUpdated errList = append(errList, fmt.Errorf("finalizer %q failed: %v", key, err)) } else { // If the finalizer succeeds, we remove the finalizer from the primary // object's metadata, so we know it will need an update. - needsUpdate = true + res.Updated = true controllerutil.RemoveFinalizer(obj, key) } } } - return needsUpdate, utilerrors.NewAggregate(errList) + return res, utilerrors.NewAggregate(errList) } diff --git a/pkg/finalizer/finalizer_test.go b/pkg/finalizer/finalizer_test.go index d6e49453d0..944acd595a 100644 --- a/pkg/finalizer/finalizer_test.go +++ b/pkg/finalizer/finalizer_test.go @@ -14,12 +14,12 @@ import ( ) type mockFinalizer struct { - needsUpdate bool - err error + result Result + err error } -func (f mockFinalizer) Finalize(context.Context, client.Object) (needsUpdate bool, err error) { - return f.needsUpdate, f.err +func (f mockFinalizer) Finalize(context.Context, client.Object) (Result, error) { + return f.result, f.err } func TestFinalizer(t *testing.T) { RegisterFailHandler(Fail) @@ -56,24 +56,25 @@ var _ = Describe("TestFinalizer", func() { }) }) + Describe("Finalize", func() { - It("successfully finalizes and returns true for needsUpdate when deletion timestamp is nil and finalizer does not exist", func() { + It("successfully finalizes and returns true for Updated when deletion timestamp is nil and finalizer does not exist", func() { err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) Expect(err).To(BeNil()) pod.DeletionTimestamp = nil pod.Finalizers = []string{} - needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + result, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) - Expect(needsUpdate).To(BeTrue()) + Expect(result.Updated).To(BeTrue()) // when deletion timestamp is nil and finalizer is not present, the registered finalizer would be added to the obj Expect(len(pod.Finalizers)).To(Equal(1)) Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer")) }) - It("successfully finalizes and returns true for needsUpdate when deletion timestamp is not nil and the finalizer exists", func() { + It("successfully finalizes and returns true for Updated when deletion timestamp is not nil and the finalizer exists", func() { now := metav1.Now() pod.DeletionTimestamp = &now @@ -82,37 +83,37 @@ var _ = Describe("TestFinalizer", func() { pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer"} - needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + result, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) - Expect(needsUpdate).To(BeTrue()) + Expect(result.Updated).To(BeTrue()) // finalizer will be removed from the obj upon successful finalization Expect(len(pod.Finalizers)).To(Equal(0)) }) - It("should return no error and return false for needsUpdate when deletion timestamp is nil and finalizer doesn't exist", func() { + It("should return no error and return false for Updated when deletion timestamp is nil and finalizer doesn't exist", func() { pod.DeletionTimestamp = nil pod.Finalizers = []string{} - needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + result, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) - Expect(needsUpdate).To(BeFalse()) + Expect(result.Updated).To(BeFalse()) Expect(len(pod.Finalizers)).To(Equal(0)) }) - It("should return no error and return false for needsUpdate when deletion timestamp is not nil and the finalizer doesn't exist", func() { + It("should return no error and return false for Updated when deletion timestamp is not nil and the finalizer doesn't exist", func() { now := metav1.Now() pod.DeletionTimestamp = &now pod.Finalizers = []string{} - needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + result, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) - Expect(needsUpdate).To(BeFalse()) + Expect(result.Updated).To(BeFalse()) Expect(len(pod.Finalizers)).To(Equal(0)) }) - It("successfully finalizes multiple finalizers and returns true for needsUpdate when deletion timestamp is not nil and the finalizer exists", func() { + It("successfully finalizes multiple finalizers and returns true for Updated when deletion timestamp is not nil and the finalizer exists", func() { now := metav1.Now() pod.DeletionTimestamp = &now @@ -124,32 +125,35 @@ var _ = Describe("TestFinalizer", func() { pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer", "finalizers.sigs.k8s.io/newtestfinalizer"} - needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + result, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) - Expect(needsUpdate).To(BeTrue()) + Expect(result.Updated).To(BeTrue()) + Expect(result.StatusUpdated).To(BeFalse()) Expect(len(pod.Finalizers)).To(Equal(0)) }) - It("should return needsUpdate as false and a non-nil error", func() { + It("should return result as false and a non-nil error", func() { now := metav1.Now() pod.DeletionTimestamp = &now pod.Finalizers = []string{"finalizers.sigs.k8s.io/testfinalizer"} - f.needsUpdate = false + f.result.Updated = false + f.result.StatusUpdated = false f.err = fmt.Errorf("finalizer failed for %q", pod.Finalizers[0]) err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer", f) Expect(err).To(BeNil()) - needsUpdate, err := finalizers.Finalize(context.TODO(), pod) + result, err := finalizers.Finalize(context.TODO(), pod) Expect(err).ToNot(BeNil()) Expect(err.Error()).To(ContainSubstring("finalizer failed")) - Expect(needsUpdate).To(BeFalse()) + Expect(result.Updated).To(BeFalse()) + Expect(result.StatusUpdated).To(BeFalse()) Expect(len(pod.Finalizers)).To(Equal(1)) Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer")) }) - It("should return expected needsUpdate and error values when registering multiple finalizers", func() { + It("should return expected result values and error values when registering multiple finalizers", func() { now := metav1.Now() pod.DeletionTimestamp = &now pod.Finalizers = []string{ @@ -159,23 +163,26 @@ var _ = Describe("TestFinalizer", func() { } // registering multiple finalizers with different return values - // test for needsUpdate as true, and nil error - f.needsUpdate = true + // test for Updated as true, and nil error + f.result.Updated = true + f.result.StatusUpdated = false f.err = nil err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer1", f) Expect(err).To(BeNil()) result, err := finalizers.Finalize(context.TODO(), pod) Expect(err).To(BeNil()) - Expect(result).To(BeTrue()) + Expect(result.Updated).To(BeTrue()) + Expect(result.StatusUpdated).To(BeFalse()) // `finalizers.sigs.k8s.io/testfinalizer1` will be removed from the list // of finalizers, so length will be 2. Expect(len(pod.Finalizers)).To(Equal(2)) Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) - // test for needsUpdate as false, and non-nil error - f.needsUpdate = false + // test for Updated and StatusUpdated as false, and non-nil error + f.result.Updated = false + f.result.StatusUpdated = false f.err = fmt.Errorf("finalizer failed") err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer2", f) Expect(err).To(BeNil()) @@ -183,13 +190,15 @@ var _ = Describe("TestFinalizer", func() { result, err = finalizers.Finalize(context.TODO(), pod) Expect(err).ToNot(BeNil()) Expect(err.Error()).To(ContainSubstring("finalizer failed")) - Expect(result).To(BeFalse()) + Expect(result.Updated).To(BeFalse()) + Expect(result.StatusUpdated).To(BeFalse()) Expect(len(pod.Finalizers)).To(Equal(2)) Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) - // test for needsUpdate as true, and non-nil error - f.needsUpdate = true + // test for result as true, and non-nil error + f.result.Updated = true + f.result.StatusUpdated = true f.err = fmt.Errorf("finalizer failed") err = finalizers.Register("finalizers.sigs.k8s.io/testfinalizer3", f) Expect(err).To(BeNil()) @@ -197,7 +206,8 @@ var _ = Describe("TestFinalizer", func() { result, err = finalizers.Finalize(context.TODO(), pod) Expect(err).ToNot(BeNil()) Expect(err.Error()).To(ContainSubstring("finalizer failed")) - Expect(result).To(BeTrue()) + Expect(result.Updated).To(BeTrue()) + Expect(result.StatusUpdated).To(BeTrue()) Expect(len(pod.Finalizers)).To(Equal(2)) Expect(pod.Finalizers[0]).To(Equal("finalizers.sigs.k8s.io/testfinalizer2")) Expect(pod.Finalizers[1]).To(Equal("finalizers.sigs.k8s.io/testfinalizer3")) diff --git a/pkg/finalizer/types.go b/pkg/finalizer/types.go index 1020ad157c..29d3d1dcc9 100644 --- a/pkg/finalizer/types.go +++ b/pkg/finalizer/types.go @@ -30,7 +30,7 @@ type Registerer interface { // deletion timestamp being set and return an indication of whether the // obj needs an update or not type Finalizer interface { - Finalize(context.Context, client.Object) (needsUpdate bool, err error) + Finalize(context.Context, client.Object) (Result, error) } // Finalizers implements Registerer and Finalizer to finalize all registered From 5eb033dacaf45820517fcf9a2736a4ad3937dfd5 Mon Sep 17 00:00:00 2001 From: Rashmi Gottipati Date: Mon, 7 Jun 2021 13:21:43 -0400 Subject: [PATCH 07/10] Address review feedback #3 Signed-off-by: Rashmi Gottipati --- pkg/finalizer/finalizer.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pkg/finalizer/finalizer.go b/pkg/finalizer/finalizer.go index bbcd46abf6..1261b73994 100644 --- a/pkg/finalizer/finalizer.go +++ b/pkg/finalizer/finalizer.go @@ -24,9 +24,13 @@ import ( type finalizers map[string]Finalizer -// Result struct holds Updated and StatusUpdated fields +// Result struct holds information about what parts of an object were updated by finalizer(s). type Result struct { - Updated bool + // Updated will be true if at least one of the object's non-status field + // was updated by some registered finalizer. + Updated bool + // StatusUpdated will be true if at least one of the object's status' fields + // was updated by some registered finalizer. StatusUpdated bool } @@ -66,6 +70,8 @@ func (f finalizers) Finalize(ctx context.Context, obj client.Object) (Result, er // object's metadata, so we know it will need an update. res.Updated = true controllerutil.RemoveFinalizer(obj, key) + // The finalizer may have updated the status too. + res.StatusUpdated = res.StatusUpdated || finalizerRes.StatusUpdated } } } From fbf50b04fe17b0f091430d22557245d2aedabfd4 Mon Sep 17 00:00:00 2001 From: Will Thames Date: Wed, 9 Jun 2021 12:29:47 +1000 Subject: [PATCH 08/10] =?UTF-8?q?=E2=9C=A8=20Allow=20TLS=20minimum=20versi?= =?UTF-8?q?on=20to=20be=20configured=20(#1548)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Allow TLS minimum version to be configured Some environments have automated security scans that trigger on TLS versions or insecure cipher suites. Setting TLS to 1.3 would solve both problems (setting to 1.2 only solves the former as the default 1.2 cipher suites are insecure). Default TLS minimum version of 1.0 remains. * Add error handling to tls version conversion --- pkg/webhook/server.go | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/pkg/webhook/server.go b/pkg/webhook/server.go index cdd34c9660..dfca94e99a 100644 --- a/pkg/webhook/server.go +++ b/pkg/webhook/server.go @@ -70,6 +70,10 @@ type Server struct { // Defaults to "", which means server does not verify client's certificate. ClientCAName string + // TLSVersion is the minimum version of TLS supported. Accepts + // "", "1.0", "1.1", "1.2" and "1.3" only ("" is equivalent to "1.0" for backwards compatibility) + TLSMinVersion string + // WebhookMux is the multiplexer that handles different webhooks. WebhookMux *http.ServeMux @@ -175,6 +179,26 @@ func (s *Server) StartStandalone(ctx context.Context, scheme *runtime.Scheme) er return s.Start(ctx) } +// tlsVersion converts from human-readable TLS version (for example "1.1") +// to the values accepted by tls.Config (for example 0x301) +func tlsVersion(version string) (uint16, error) { + switch version { + // default is previous behaviour + case "": + return tls.VersionTLS10, nil + case "1.0": + return tls.VersionTLS10, nil + case "1.1": + return tls.VersionTLS11, nil + case "1.2": + return tls.VersionTLS12, nil + case "1.3": + return tls.VersionTLS13, nil + default: + return 0, fmt.Errorf("Invalid TLSMinVersion %v: expects 1.0, 1.1, 1.2, 1.3 or empty", version) + } +} + // Start runs the server. // It will install the webhook related resources depend on the server configuration. func (s *Server) Start(ctx context.Context) error { @@ -197,9 +221,15 @@ func (s *Server) Start(ctx context.Context) error { } }() + tlsMinVersion, err := tlsVersion(s.TLSMinVersion) + if err != nil { + return err + } + cfg := &tls.Config{ NextProtos: []string{"h2"}, GetCertificate: certWatcher.GetCertificate, + MinVersion: tlsMinVersion, } // load CA to verify client certificate From bf192985c5962af7d21e3f7c8ccc3a0715a460f1 Mon Sep 17 00:00:00 2001 From: Solly Ross Date: Mon, 14 Jun 2021 15:03:06 -0700 Subject: [PATCH 09/10] Move directxman12 to approvers-emeritus As per https://groups.google.com/g/kubebuilder/c/-5hOFa_adr4/m/Sp_Zb755AwAJ --- OWNERS_ALIASES | 4 ++-- SECURITY_CONTACTS | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index 243a3034d7..d93e1794fb 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -4,7 +4,6 @@ aliases: # active folks who can be contacted to perform admin-related # tasks on the repo, or otherwise approve any PRS. controller-runtime-admins: - - directxman12 - droot - mengqiy - pwittrock @@ -36,4 +35,5 @@ aliases: # folks who may have context on ancient history, # but are no longer directly involved - # controller-runtime-emeritus-maintainers: + controller-runtime-emeritus-maintainers: + - directxman12 diff --git a/SECURITY_CONTACTS b/SECURITY_CONTACTS index 6f826fe021..32e6a3b904 100644 --- a/SECURITY_CONTACTS +++ b/SECURITY_CONTACTS @@ -10,6 +10,5 @@ # DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE # INSTRUCTIONS AT https://kubernetes.io/security/ -directxman12 pwittrock droot From 0ba05d875627af40d752131a65f823e18b3a3550 Mon Sep 17 00:00:00 2001 From: Vince Prignano Date: Mon, 21 Jun 2021 11:45:37 -0700 Subject: [PATCH 10/10] :seedling: Update dependencies to Kubernetes v1.21.2 Signed-off-by: Vince Prignano --- go.mod | 12 ++++++------ go.sum | 32 ++++++++++++++++---------------- hack/check-everything.sh | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) diff --git a/go.mod b/go.mod index 2765dfd476..1423d76de0 100644 --- a/go.mod +++ b/go.mod @@ -16,14 +16,14 @@ require ( github.com/prometheus/client_model v0.2.0 go.uber.org/goleak v1.1.10 go.uber.org/zap v1.17.0 - golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba + golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 gomodules.xyz/jsonpatch/v2 v2.2.0 google.golang.org/appengine v1.6.7 // indirect - k8s.io/api v0.21.1 - k8s.io/apiextensions-apiserver v0.21.1 - k8s.io/apimachinery v0.21.1 - k8s.io/client-go v0.21.1 - k8s.io/component-base v0.21.1 + k8s.io/api v0.21.2 + k8s.io/apiextensions-apiserver v0.21.2 + k8s.io/apimachinery v0.21.2 + k8s.io/client-go v0.21.2 + k8s.io/component-base v0.21.2 k8s.io/utils v0.0.0-20210527160623-6fdb442a123b sigs.k8s.io/yaml v1.2.0 ) diff --git a/go.sum b/go.sum index f898b31ade..12cf1b35ba 100644 --- a/go.sum +++ b/go.sum @@ -164,7 +164,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -532,8 +531,8 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40 h1:JWgyZ1qgdTaF3N3oxC+MdTV7qvEEgHo3otj+HB5CM7Q= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -552,8 +551,9 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6 h1:Vv0JUPWTyeqUq42B2WJ1FeIDjjvGKoA2Ss+Ts0lAVbs= +golang.org/x/time v0.0.0-20210611083556-38a9dc6acbc6/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -699,18 +699,18 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.21.1 h1:94bbZ5NTjdINJEdzOkpS4vdPhkb1VFpTYC9zh43f75c= -k8s.io/api v0.21.1/go.mod h1:FstGROTmsSHBarKc8bylzXih8BLNYTiS3TZcsoEDg2s= -k8s.io/apiextensions-apiserver v0.21.1 h1:AA+cnsb6w7SZ1vD32Z+zdgfXdXY8X9uGX5bN6EoPEIo= -k8s.io/apiextensions-apiserver v0.21.1/go.mod h1:KESQFCGjqVcVsZ9g0xX5bacMjyX5emuWcS2arzdEouA= -k8s.io/apimachinery v0.21.1 h1:Q6XuHGlj2xc+hlMCvqyYfbv3H7SRGn2c8NycxJquDVs= -k8s.io/apimachinery v0.21.1/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= -k8s.io/apiserver v0.21.1/go.mod h1:nLLYZvMWn35glJ4/FZRhzLG/3MPxAaZTgV4FJZdr+tY= -k8s.io/client-go v0.21.1 h1:bhblWYLZKUu+pm50plvQF8WpY6TXdRRtcS/K9WauOj4= -k8s.io/client-go v0.21.1/go.mod h1:/kEw4RgW+3xnBGzvp9IWxKSNA+lXn3A7AuH3gdOAzLs= -k8s.io/code-generator v0.21.1/go.mod h1:hUlps5+9QaTrKx+jiM4rmq7YmH8wPOIko64uZCHDh6Q= -k8s.io/component-base v0.21.1 h1:iLpj2btXbR326s/xNQWmPNGu0gaYSjzn7IN/5i28nQw= -k8s.io/component-base v0.21.1/go.mod h1:NgzFZ2qu4m1juby4TnrmpR8adRk6ka62YdH5DkIIyKA= +k8s.io/api v0.21.2 h1:vz7DqmRsXTCSa6pNxXwQ1IYeAZgdIsua+DZU+o+SX3Y= +k8s.io/api v0.21.2/go.mod h1:Lv6UGJZ1rlMI1qusN8ruAp9PUBFyBwpEHAdG24vIsiU= +k8s.io/apiextensions-apiserver v0.21.2 h1:+exKMRep4pDrphEafRvpEi79wTnCFMqKf8LBtlA3yrE= +k8s.io/apiextensions-apiserver v0.21.2/go.mod h1:+Axoz5/l3AYpGLlhJDfcVQzCerVYq3K3CvDMvw6X1RA= +k8s.io/apimachinery v0.21.2 h1:vezUc/BHqWlQDnZ+XkrpXSmnANSLbpnlpwo0Lhk0gpc= +k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= +k8s.io/apiserver v0.21.2/go.mod h1:lN4yBoGyiNT7SC1dmNk0ue6a5Wi6O3SWOIw91TsucQw= +k8s.io/client-go v0.21.2 h1:Q1j4L/iMN4pTw6Y4DWppBoUxgKO8LbffEMVEV00MUp0= +k8s.io/client-go v0.21.2/go.mod h1:HdJ9iknWpbl3vMGtib6T2PyI/VYxiZfq936WNVHBRrA= +k8s.io/code-generator v0.21.2/go.mod h1:8mXJDCB7HcRo1xiEQstcguZkbxZaqeUOrO9SsicWs3U= +k8s.io/component-base v0.21.2 h1:EsnmFFoJ86cEywC0DoIkAUiEV6fjgauNugiw1lmIjs4= +k8s.io/component-base v0.21.2/go.mod h1:9lvmIThzdlrJj5Hp8Z/TOgIkdfsNARQ1pT+3PByuiuc= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/gengo v0.0.0-20201214224949-b6c5ce23f027/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= @@ -725,7 +725,7 @@ k8s.io/utils v0.0.0-20210527160623-6fdb442a123b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.19/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= diff --git a/hack/check-everything.sh b/hack/check-everything.sh index 1f02d884f4..b6d3472bcc 100755 --- a/hack/check-everything.sh +++ b/hack/check-everything.sh @@ -24,7 +24,7 @@ source ${hack_dir}/common.sh tmp_root=/tmp kb_root_dir=$tmp_root/kubebuilder -ENVTEST_K8S_VERSION=${ENVTEST_K8S_VERSION:-"1.19.2"} +ENVTEST_K8S_VERSION=${ENVTEST_K8S_VERSION:-"1.21.2"} # set up envtest tools if necessary