mirror of https://github.com/k3s-io/k3s
Move protection common func to protectionutil
parent
f5574bf62a
commit
e9c13409a8
|
@ -136,6 +136,7 @@ filegroup(
|
|||
"//pkg/controller/volume/events:all-srcs",
|
||||
"//pkg/controller/volume/expand:all-srcs",
|
||||
"//pkg/controller/volume/persistentvolume:all-srcs",
|
||||
"//pkg/controller/volume/protectionutil:all-srcs",
|
||||
"//pkg/controller/volume/pvcprotection:all-srcs",
|
||||
"//pkg/controller/volume/pvprotection:all-srcs",
|
||||
],
|
||||
|
|
|
@ -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"],
|
||||
)
|
|
@ -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)
|
||||
}
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -7,6 +7,7 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/volume/protectionutil:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/slice:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/protectionutil"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
|
@ -157,7 +158,7 @@ func (c *Controller) processPVC(pvcNamespace, pvcName string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if isDeletionCandidate(pvc) {
|
||||
if protectionutil.IsDeletionCandidate(pvc, volumeutil.PVCProtectionFinalizer) {
|
||||
// PVC should be deleted. Check if it's used and remove finalizer if
|
||||
// it's not.
|
||||
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
|
||||
// finalizer should be added by admission plugin, this is just to add
|
||||
// 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)
|
||||
|
||||
if needToAddFinalizer(pvc) || isDeletionCandidate(pvc) {
|
||||
if protectionutil.NeedToAddFinalizer(pvc, volumeutil.PVCProtectionFinalizer) || protectionutil.IsDeletionCandidate(pvc, volumeutil.PVCProtectionFinalizer) {
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
@ -34,6 +33,7 @@ import (
|
|||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
|
|
@ -7,6 +7,7 @@ go_library(
|
|||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/controller/volume/protectionutil:go_default_library",
|
||||
"//pkg/util/metrics:go_default_library",
|
||||
"//pkg/util/slice:go_default_library",
|
||||
"//pkg/volume/util:go_default_library",
|
||||
|
|
|
@ -31,6 +31,7 @@ import (
|
|||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/controller/volume/protectionutil"
|
||||
"k8s.io/kubernetes/pkg/util/metrics"
|
||||
"k8s.io/kubernetes/pkg/util/slice"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
|
@ -135,7 +136,7 @@ func (c *Controller) processPV(pvName string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
if isDeletionCandidate(pv) {
|
||||
if protectionutil.IsDeletionCandidate(pv, volumeutil.PVProtectionFinalizer) {
|
||||
// PV should be deleted. Check if it's used and remove finalizer if
|
||||
// it's not.
|
||||
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
|
||||
// finalizer should be added by admission plugin, this is just to add
|
||||
// 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)
|
||||
|
||||
if needToAddFinalizer(pv) || isDeletionCandidate(pv) {
|
||||
if protectionutil.NeedToAddFinalizer(pv, volumeutil.PVProtectionFinalizer) || protectionutil.IsDeletionCandidate(pv, volumeutil.PVProtectionFinalizer) {
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"k8s.io/klog"
|
||||
|
||||
"k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
@ -34,6 +33,7 @@ import (
|
|||
"k8s.io/client-go/informers"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
clienttesting "k8s.io/client-go/testing"
|
||||
"k8s.io/klog"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue