Move protection common func to protectionutil

k3s-v1.15.3
caiweidong 2019-03-06 15:03:05 +08:00
parent f5574bf62a
commit e9c13409a8
10 changed files with 351 additions and 24 deletions

View File

@ -136,6 +136,7 @@ filegroup(
"//pkg/controller/volume/events:all-srcs", "//pkg/controller/volume/events:all-srcs",
"//pkg/controller/volume/expand:all-srcs", "//pkg/controller/volume/expand:all-srcs",
"//pkg/controller/volume/persistentvolume:all-srcs", "//pkg/controller/volume/persistentvolume:all-srcs",
"//pkg/controller/volume/protectionutil:all-srcs",
"//pkg/controller/volume/pvcprotection:all-srcs", "//pkg/controller/volume/pvcprotection:all-srcs",
"//pkg/controller/volume/pvprotection:all-srcs", "//pkg/controller/volume/pvprotection:all-srcs",
], ],

View File

@ -0,0 +1,37 @@
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
go_library(
name = "go_default_library",
srcs = ["utils.go"],
importpath = "k8s.io/kubernetes/pkg/controller/volume/protectionutil",
visibility = ["//visibility:public"],
deps = [
"//pkg/util/slice:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
],
)
go_test(
name = "go_default_test",
srcs = ["utils_test.go"],
embed = [":go_default_library"],
deps = [
"//pkg/volume/util:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@ -0,0 +1,34 @@
/*
Copyright 2019 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 protectionutil
import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/util/slice"
)
// IsDeletionCandidate checks if object is candidate to be deleted
func IsDeletionCandidate(obj metav1.Object, finalizer string) bool {
return obj.GetDeletionTimestamp() != nil && slice.ContainsString(obj.GetFinalizers(),
finalizer, nil)
}
// NeedToAddFinalizer checks if need to add finalizer to object
func NeedToAddFinalizer(obj metav1.Object, finalizer string) bool {
return obj.GetDeletionTimestamp() == nil && !slice.ContainsString(obj.GetFinalizers(),
finalizer, nil)
}

View File

@ -0,0 +1,267 @@
/*
Copyright 2019 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 protectionutil
import (
"testing"
"k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/kubernetes/pkg/volume/util"
)
const (
defaultNS = "default"
defaultPVCName = "pvc1"
defaultPVName = "pv1"
)
type TestCase struct {
name string
obj metav1.Object
finalizer string
result bool
}
func pvc() *v1.PersistentVolumeClaim {
return &v1.PersistentVolumeClaim{
ObjectMeta: metav1.ObjectMeta{
Name: defaultPVCName,
Namespace: defaultNS,
},
}
}
func pv() *v1.PersistentVolume {
return &v1.PersistentVolume{
ObjectMeta: metav1.ObjectMeta{
Name: defaultPVName,
},
}
}
func TestIsDeletionCandidateLackDeleteTimeAndFinalizer(t *testing.T) {
tests := []TestCase{
{
name: "pv lacks delete time and finalizer",
obj: pv(),
finalizer: util.PVProtectionFinalizer,
result: false,
},
{
name: "pvc lacks delete time and finalizer",
obj: pvc(),
finalizer: util.PVCProtectionFinalizer,
result: false,
},
}
for _, test := range tests {
if test.result != IsDeletionCandidate(test.obj, test.finalizer) {
t.Error(test.name)
}
}
}
func TestIsDeletionCandidateLackDeleteTime(t *testing.T) {
pv := pv()
pv.SetFinalizers([]string{util.PVProtectionFinalizer})
pvc := pvc()
pvc.SetFinalizers([]string{util.PVCProtectionFinalizer})
tests := []TestCase{
{
name: "pv lacks delete time",
obj: pv,
finalizer: util.PVProtectionFinalizer,
result: false,
},
{
name: "pvc lacks delete time",
obj: pvc,
finalizer: util.PVCProtectionFinalizer,
result: false,
},
}
for _, test := range tests {
if test.result != IsDeletionCandidate(test.obj, test.finalizer) {
t.Error(test.name)
}
}
}
func TestIsDeletionCandidateLackFinalizer(t *testing.T) {
pv := pv()
pv.SetDeletionTimestamp(&metav1.Time{})
pvc := pvc()
pvc.SetDeletionTimestamp(&metav1.Time{})
tests := []TestCase{
{
name: "pv lacks finalizer",
obj: pv,
finalizer: util.PVProtectionFinalizer,
result: false,
},
{
name: "pvc lacks finalizer",
obj: pvc,
finalizer: util.PVCProtectionFinalizer,
result: false,
},
}
for _, test := range tests {
if test.result != IsDeletionCandidate(test.obj, test.finalizer) {
t.Error(test.name)
}
}
}
func TestIsDeletionCandidateSuccess(t *testing.T) {
pv := pv()
pv.SetDeletionTimestamp(&metav1.Time{})
pv.SetFinalizers([]string{util.PVProtectionFinalizer})
pvc := pvc()
pvc.SetDeletionTimestamp(&metav1.Time{})
pvc.SetFinalizers([]string{util.PVCProtectionFinalizer})
tests := []TestCase{
{
name: "pv is to delete",
obj: pv,
finalizer: util.PVProtectionFinalizer,
result: true,
},
{
name: "pvc is to delete",
obj: pvc,
finalizer: util.PVCProtectionFinalizer,
result: true,
},
}
for _, test := range tests {
if test.result != IsDeletionCandidate(test.obj, test.finalizer) {
t.Error(test.name)
}
}
}
func TestNeedToAddFinalizerHasDeleteTimeAndFinalizer(t *testing.T) {
pv := pv()
pv.SetDeletionTimestamp(&metav1.Time{})
pv.SetFinalizers([]string{util.PVProtectionFinalizer})
pvc := pvc()
pvc.SetDeletionTimestamp(&metav1.Time{})
pvc.SetFinalizers([]string{util.PVCProtectionFinalizer})
tests := []TestCase{
{
name: "pv has delete time and finalizer",
obj: pv,
finalizer: util.PVProtectionFinalizer,
result: false,
},
{
name: "pvc has delete time and finalizer",
obj: pvc,
finalizer: util.PVCProtectionFinalizer,
result: false,
},
}
for _, test := range tests {
if test.result != NeedToAddFinalizer(test.obj, test.finalizer) {
t.Error(test.name)
}
}
}
func TestNeedToAddFinalizerHasDeleteTime(t *testing.T) {
pv := pv()
pv.SetDeletionTimestamp(&metav1.Time{})
pvc := pvc()
pvc.SetDeletionTimestamp(&metav1.Time{})
tests := []TestCase{
{
name: "pv has delete",
obj: pv,
finalizer: util.PVProtectionFinalizer,
result: false,
},
{
name: "pvc has delete",
obj: pvc,
finalizer: util.PVCProtectionFinalizer,
result: false,
},
}
for _, test := range tests {
if test.result != NeedToAddFinalizer(test.obj, test.finalizer) {
t.Error(test.name)
}
}
}
func TestNeedToAddFinalizerHasFinalizer(t *testing.T) {
pv := pv()
pv.SetFinalizers([]string{util.PVProtectionFinalizer})
pvc := pvc()
pvc.SetFinalizers([]string{util.PVCProtectionFinalizer})
tests := []TestCase{
{
name: "pv has finalizer",
obj: pv,
finalizer: util.PVProtectionFinalizer,
result: false,
},
{
name: "pvc has finalizer",
obj: pvc,
finalizer: util.PVCProtectionFinalizer,
result: false,
},
}
for _, test := range tests {
if test.result != NeedToAddFinalizer(test.obj, test.finalizer) {
t.Error(test.name)
}
}
}
func TestNeedToAddFinalizerSuccess(t *testing.T) {
tests := []TestCase{
{
name: "pv needs add finalizer",
obj: pv(),
finalizer: util.PVProtectionFinalizer,
result: true,
},
{
name: "pvc needs add finalizer",
obj: pvc(),
finalizer: util.PVCProtectionFinalizer,
result: true,
},
}
for _, test := range tests {
if test.result != NeedToAddFinalizer(test.obj, test.finalizer) {
t.Error(test.name)
}
}
}

View File

@ -7,6 +7,7 @@ go_library(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/controller/volume/protectionutil:go_default_library",
"//pkg/util/metrics:go_default_library", "//pkg/util/metrics:go_default_library",
"//pkg/util/slice:go_default_library", "//pkg/util/slice:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",

View File

@ -32,6 +32,7 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/controller/volume/protectionutil"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
"k8s.io/kubernetes/pkg/util/slice" "k8s.io/kubernetes/pkg/util/slice"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
@ -157,7 +158,7 @@ func (c *Controller) processPVC(pvcNamespace, pvcName string) error {
return err return err
} }
if isDeletionCandidate(pvc) { if protectionutil.IsDeletionCandidate(pvc, volumeutil.PVCProtectionFinalizer) {
// PVC should be deleted. Check if it's used and remove finalizer if // PVC should be deleted. Check if it's used and remove finalizer if
// it's not. // it's not.
isUsed, err := c.isBeingUsed(pvc) isUsed, err := c.isBeingUsed(pvc)
@ -169,7 +170,7 @@ func (c *Controller) processPVC(pvcNamespace, pvcName string) error {
} }
} }
if needToAddFinalizer(pvc) { if protectionutil.NeedToAddFinalizer(pvc, volumeutil.PVCProtectionFinalizer) {
// PVC is not being deleted -> it should have the finalizer. The // PVC is not being deleted -> it should have the finalizer. The
// finalizer should be added by admission plugin, this is just to add // finalizer should be added by admission plugin, this is just to add
// the finalizer to old PVCs that were created before the admission // the finalizer to old PVCs that were created before the admission
@ -250,7 +251,7 @@ func (c *Controller) pvcAddedUpdated(obj interface{}) {
} }
klog.V(4).Infof("Got event on PVC %s", key) klog.V(4).Infof("Got event on PVC %s", key)
if needToAddFinalizer(pvc) || isDeletionCandidate(pvc) { if protectionutil.NeedToAddFinalizer(pvc, volumeutil.PVCProtectionFinalizer) || protectionutil.IsDeletionCandidate(pvc, volumeutil.PVCProtectionFinalizer) {
c.queue.Add(key) c.queue.Add(key)
} }
} }
@ -285,11 +286,3 @@ func (c *Controller) podAddedDeletedUpdated(obj interface{}, deleted bool) {
} }
} }
} }
func isDeletionCandidate(pvc *v1.PersistentVolumeClaim) bool {
return pvc.ObjectMeta.DeletionTimestamp != nil && slice.ContainsString(pvc.ObjectMeta.Finalizers, volumeutil.PVCProtectionFinalizer, nil)
}
func needToAddFinalizer(pvc *v1.PersistentVolumeClaim) bool {
return pvc.ObjectMeta.DeletionTimestamp == nil && !slice.ContainsString(pvc.ObjectMeta.Finalizers, volumeutil.PVCProtectionFinalizer, nil)
}

View File

@ -23,7 +23,6 @@ import (
"time" "time"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"k8s.io/klog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -34,6 +33,7 @@ import (
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
clienttesting "k8s.io/client-go/testing" clienttesting "k8s.io/client-go/testing"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
) )

View File

@ -7,6 +7,7 @@ go_library(
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/controller/volume/protectionutil:go_default_library",
"//pkg/util/metrics:go_default_library", "//pkg/util/metrics:go_default_library",
"//pkg/util/slice:go_default_library", "//pkg/util/slice:go_default_library",
"//pkg/volume/util:go_default_library", "//pkg/volume/util:go_default_library",

View File

@ -31,6 +31,7 @@ import (
"k8s.io/client-go/util/workqueue" "k8s.io/client-go/util/workqueue"
"k8s.io/klog" "k8s.io/klog"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
"k8s.io/kubernetes/pkg/controller/volume/protectionutil"
"k8s.io/kubernetes/pkg/util/metrics" "k8s.io/kubernetes/pkg/util/metrics"
"k8s.io/kubernetes/pkg/util/slice" "k8s.io/kubernetes/pkg/util/slice"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
@ -135,7 +136,7 @@ func (c *Controller) processPV(pvName string) error {
return err return err
} }
if isDeletionCandidate(pv) { if protectionutil.IsDeletionCandidate(pv, volumeutil.PVProtectionFinalizer) {
// PV should be deleted. Check if it's used and remove finalizer if // PV should be deleted. Check if it's used and remove finalizer if
// it's not. // it's not.
isUsed := c.isBeingUsed(pv) isUsed := c.isBeingUsed(pv)
@ -144,7 +145,7 @@ func (c *Controller) processPV(pvName string) error {
} }
} }
if needToAddFinalizer(pv) { if protectionutil.NeedToAddFinalizer(pv, volumeutil.PVProtectionFinalizer) {
// PV is not being deleted -> it should have the finalizer. The // PV is not being deleted -> it should have the finalizer. The
// finalizer should be added by admission plugin, this is just to add // finalizer should be added by admission plugin, this is just to add
// the finalizer to old PVs that were created before the admission // the finalizer to old PVs that were created before the admission
@ -202,15 +203,7 @@ func (c *Controller) pvAddedUpdated(obj interface{}) {
} }
klog.V(4).Infof("Got event on PV %s", pv.Name) klog.V(4).Infof("Got event on PV %s", pv.Name)
if needToAddFinalizer(pv) || isDeletionCandidate(pv) { if protectionutil.NeedToAddFinalizer(pv, volumeutil.PVProtectionFinalizer) || protectionutil.IsDeletionCandidate(pv, volumeutil.PVProtectionFinalizer) {
c.queue.Add(pv.Name) c.queue.Add(pv.Name)
} }
} }
func isDeletionCandidate(pv *v1.PersistentVolume) bool {
return pv.ObjectMeta.DeletionTimestamp != nil && slice.ContainsString(pv.ObjectMeta.Finalizers, volumeutil.PVProtectionFinalizer, nil)
}
func needToAddFinalizer(pv *v1.PersistentVolume) bool {
return pv.ObjectMeta.DeletionTimestamp == nil && !slice.ContainsString(pv.ObjectMeta.Finalizers, volumeutil.PVProtectionFinalizer, nil)
}

View File

@ -23,7 +23,6 @@ import (
"time" "time"
"github.com/davecgh/go-spew/spew" "github.com/davecgh/go-spew/spew"
"k8s.io/klog"
"k8s.io/api/core/v1" "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors" apierrors "k8s.io/apimachinery/pkg/api/errors"
@ -34,6 +33,7 @@ import (
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
clienttesting "k8s.io/client-go/testing" clienttesting "k8s.io/client-go/testing"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/controller" "k8s.io/kubernetes/pkg/controller"
volumeutil "k8s.io/kubernetes/pkg/volume/util" volumeutil "k8s.io/kubernetes/pkg/volume/util"
) )