mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-27 21:47:07 +00:00
Merge pull request #56298 from pospispa/566-improvements-suggested-by-thockin-during-review-of-PR55824
Automatic merge from submit-queue (batch tested with PRs 56401, 56506, 56551, 56298, 56581). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>. Addressing Comments from Code Review **What this PR does / why we need it**: addressing comments from code review: https://github.com/kubernetes/kubernetes/pull/55824#pullrequestreview-78597250 **Which issue(s) this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close the issue(s) when PR gets merged)*: N/A **Special notes for your reviewer**: @thockin @jsafrane @msau42 PTAL **Release note**: ```release-note NONE ```
This commit is contained in:
commit
3abbd6fb1f
@ -8,6 +8,7 @@ go_library(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/controller:go_default_library",
|
"//pkg/controller:go_default_library",
|
||||||
"//pkg/util/metrics:go_default_library",
|
"//pkg/util/metrics:go_default_library",
|
||||||
|
"//pkg/util/slice:go_default_library",
|
||||||
"//pkg/volume/util:go_default_library",
|
"//pkg/volume/util:go_default_library",
|
||||||
"//pkg/volume/util/volumehelper:go_default_library",
|
"//pkg/volume/util/volumehelper:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
|
@ -33,6 +33,7 @@ import (
|
|||||||
"k8s.io/client-go/util/workqueue"
|
"k8s.io/client-go/util/workqueue"
|
||||||
"k8s.io/kubernetes/pkg/controller"
|
"k8s.io/kubernetes/pkg/controller"
|
||||||
"k8s.io/kubernetes/pkg/util/metrics"
|
"k8s.io/kubernetes/pkg/util/metrics"
|
||||||
|
"k8s.io/kubernetes/pkg/util/slice"
|
||||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||||
)
|
)
|
||||||
@ -153,7 +154,7 @@ func (c *Controller) processPVC(pvcNamespace, pvcName string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if volumeutil.IsPVCBeingDeleted(pvc) && volumeutil.IsProtectionFinalizerPresent(pvc) {
|
if isDeletionCandidate(pvc) {
|
||||||
// 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)
|
||||||
@ -165,7 +166,7 @@ func (c *Controller) processPVC(pvcNamespace, pvcName string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !volumeutil.IsPVCBeingDeleted(pvc) && !volumeutil.IsProtectionFinalizerPresent(pvc) {
|
if needToAddFinalizer(pvc) {
|
||||||
// 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
|
||||||
@ -177,7 +178,7 @@ func (c *Controller) processPVC(pvcNamespace, pvcName string) error {
|
|||||||
|
|
||||||
func (c *Controller) addFinalizer(pvc *v1.PersistentVolumeClaim) error {
|
func (c *Controller) addFinalizer(pvc *v1.PersistentVolumeClaim) error {
|
||||||
claimClone := pvc.DeepCopy()
|
claimClone := pvc.DeepCopy()
|
||||||
volumeutil.AddProtectionFinalizer(claimClone)
|
claimClone.ObjectMeta.Finalizers = append(claimClone.ObjectMeta.Finalizers, volumeutil.PVCProtectionFinalizer)
|
||||||
_, err := c.client.CoreV1().PersistentVolumeClaims(claimClone.Namespace).Update(claimClone)
|
_, err := c.client.CoreV1().PersistentVolumeClaims(claimClone.Namespace).Update(claimClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(3).Infof("Error adding protection finalizer to PVC %s/%s: %v", pvc.Namespace, pvc.Name)
|
glog.V(3).Infof("Error adding protection finalizer to PVC %s/%s: %v", pvc.Namespace, pvc.Name)
|
||||||
@ -189,7 +190,7 @@ func (c *Controller) addFinalizer(pvc *v1.PersistentVolumeClaim) error {
|
|||||||
|
|
||||||
func (c *Controller) removeFinalizer(pvc *v1.PersistentVolumeClaim) error {
|
func (c *Controller) removeFinalizer(pvc *v1.PersistentVolumeClaim) error {
|
||||||
claimClone := pvc.DeepCopy()
|
claimClone := pvc.DeepCopy()
|
||||||
volumeutil.RemoveProtectionFinalizer(claimClone)
|
claimClone.ObjectMeta.Finalizers = slice.RemoveString(claimClone.ObjectMeta.Finalizers, volumeutil.PVCProtectionFinalizer, nil)
|
||||||
_, err := c.client.CoreV1().PersistentVolumeClaims(claimClone.Namespace).Update(claimClone)
|
_, err := c.client.CoreV1().PersistentVolumeClaims(claimClone.Namespace).Update(claimClone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.V(3).Infof("Error removing protection finalizer from PVC %s/%s: %v", pvc.Namespace, pvc.Name, err)
|
glog.V(3).Infof("Error removing protection finalizer from PVC %s/%s: %v", pvc.Namespace, pvc.Name, err)
|
||||||
@ -247,7 +248,7 @@ func (c *Controller) pvcAddedUpdated(obj interface{}) {
|
|||||||
}
|
}
|
||||||
glog.V(4).Infof("Got event on PVC %s", key)
|
glog.V(4).Infof("Got event on PVC %s", key)
|
||||||
|
|
||||||
if (!volumeutil.IsPVCBeingDeleted(pvc) && !volumeutil.IsProtectionFinalizerPresent(pvc)) || (volumeutil.IsPVCBeingDeleted(pvc) && volumeutil.IsProtectionFinalizerPresent(pvc)) {
|
if needToAddFinalizer(pvc) || isDeletionCandidate(pvc) {
|
||||||
c.queue.Add(key)
|
c.queue.Add(key)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,3 +283,11 @@ 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)
|
||||||
|
}
|
||||||
|
@ -19,7 +19,6 @@ go_library(
|
|||||||
"//pkg/kubelet/util/format:go_default_library",
|
"//pkg/kubelet/util/format:go_default_library",
|
||||||
"//pkg/kubelet/volumemanager/cache:go_default_library",
|
"//pkg/kubelet/volumemanager/cache:go_default_library",
|
||||||
"//pkg/volume:go_default_library",
|
"//pkg/volume:go_default_library",
|
||||||
"//pkg/volume/util:go_default_library",
|
|
||||||
"//pkg/volume/util/types:go_default_library",
|
"//pkg/volume/util/types:go_default_library",
|
||||||
"//pkg/volume/util/volumehelper:go_default_library",
|
"//pkg/volume/util/volumehelper:go_default_library",
|
||||||
"//vendor/github.com/golang/glog:go_default_library",
|
"//vendor/github.com/golang/glog:go_default_library",
|
||||||
|
@ -41,7 +41,6 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
"k8s.io/kubernetes/pkg/kubelet/util/format"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/volumemanager/cache"
|
"k8s.io/kubernetes/pkg/kubelet/volumemanager/cache"
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
|
||||||
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
|
volumetypes "k8s.io/kubernetes/pkg/volume/util/types"
|
||||||
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
"k8s.io/kubernetes/pkg/volume/util/volumehelper"
|
||||||
)
|
)
|
||||||
@ -444,7 +443,7 @@ func (dswp *desiredStateOfWorldPopulator) getPVCExtractPV(
|
|||||||
// and users should not be that surprised.
|
// and users should not be that surprised.
|
||||||
// It should happen only in very rare case when scheduler schedules
|
// It should happen only in very rare case when scheduler schedules
|
||||||
// a pod and user deletes a PVC that's used by it at the same time.
|
// a pod and user deletes a PVC that's used by it at the same time.
|
||||||
if volumeutil.IsPVCBeingDeleted(pvc) {
|
if pvc.ObjectMeta.DeletionTimestamp != nil {
|
||||||
return "", "", fmt.Errorf(
|
return "", "", fmt.Errorf(
|
||||||
"can't start pod because PVC %s/%s is being deleted",
|
"can't start pod because PVC %s/%s is being deleted",
|
||||||
namespace,
|
namespace,
|
||||||
|
@ -68,3 +68,24 @@ func ContainsString(slice []string, s string, modifier func(s string) string) bo
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// RemoveString returns a newly created []string that contains all items from slice that
|
||||||
|
// are not equal to s and modifier(s) in case modifier func is provided.
|
||||||
|
func RemoveString(slice []string, s string, modifier func(s string) string) []string {
|
||||||
|
newSlice := make([]string, 0)
|
||||||
|
for _, item := range slice {
|
||||||
|
if item == s {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if modifier != nil && modifier(item) == s {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
newSlice = append(newSlice, item)
|
||||||
|
}
|
||||||
|
if len(newSlice) == 0 {
|
||||||
|
// Sanitize for unit tests so we don't need to distinguish empty array
|
||||||
|
// and nil.
|
||||||
|
newSlice = nil
|
||||||
|
}
|
||||||
|
return newSlice
|
||||||
|
}
|
||||||
|
@ -106,3 +106,67 @@ func TestContainsString(t *testing.T) {
|
|||||||
t.Errorf("ContainsString didn't find the string by modifier")
|
t.Errorf("ContainsString didn't find the string by modifier")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRemoveString(t *testing.T) {
|
||||||
|
modifier := func(s string) string {
|
||||||
|
if s == "ab" {
|
||||||
|
return "ee"
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
testName string
|
||||||
|
input []string
|
||||||
|
remove string
|
||||||
|
modifier func(s string) string
|
||||||
|
want []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
testName: "Nil input slice",
|
||||||
|
input: nil,
|
||||||
|
remove: "",
|
||||||
|
modifier: nil,
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "Slice doesn't contain the string",
|
||||||
|
input: []string{"a", "ab", "cdef"},
|
||||||
|
remove: "NotPresentInSlice",
|
||||||
|
modifier: nil,
|
||||||
|
want: []string{"a", "ab", "cdef"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "All strings removed, result is nil",
|
||||||
|
input: []string{"a"},
|
||||||
|
remove: "a",
|
||||||
|
modifier: nil,
|
||||||
|
want: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "No modifier func, one string removed",
|
||||||
|
input: []string{"a", "ab", "cdef"},
|
||||||
|
remove: "ab",
|
||||||
|
modifier: nil,
|
||||||
|
want: []string{"a", "cdef"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "No modifier func, all(three) strings removed",
|
||||||
|
input: []string{"ab", "a", "ab", "cdef", "ab"},
|
||||||
|
remove: "ab",
|
||||||
|
modifier: nil,
|
||||||
|
want: []string{"a", "cdef"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
testName: "Removed both the string and the modifier func result",
|
||||||
|
input: []string{"a", "cd", "ab", "ee"},
|
||||||
|
remove: "ee",
|
||||||
|
modifier: modifier,
|
||||||
|
want: []string{"a", "cd"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
if got := RemoveString(tt.input, tt.remove, tt.modifier); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("%v: RemoveString(%v, %q, %T) = %v WANT %v", tt.testName, tt.input, tt.remove, tt.modifier, got, tt.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -62,7 +62,6 @@ go_library(
|
|||||||
go_test(
|
go_test(
|
||||||
name = "go_default_test",
|
name = "go_default_test",
|
||||||
srcs = [
|
srcs = [
|
||||||
"finalizer_test.go",
|
|
||||||
"util_test.go",
|
"util_test.go",
|
||||||
] + select({
|
] + select({
|
||||||
"@io_bazel_rules_go//go/platform:linux_amd64": [
|
"@io_bazel_rules_go//go/platform:linux_amd64": [
|
||||||
@ -76,7 +75,6 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//pkg/apis/core/install:go_default_library",
|
"//pkg/apis/core/install:go_default_library",
|
||||||
"//pkg/apis/core/v1/helper:go_default_library",
|
"//pkg/apis/core/v1/helper:go_default_library",
|
||||||
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
|
|
||||||
"//vendor/k8s.io/api/core/v1:go_default_library",
|
"//vendor/k8s.io/api/core/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||||
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
"//vendor/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||||
|
@ -16,53 +16,7 @@ limitations under the License.
|
|||||||
|
|
||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
|
||||||
"k8s.io/api/core/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Name of finalizer on PVCs that have a running pod.
|
// Name of finalizer on PVCs that have a running pod.
|
||||||
PVCProtectionFinalizer = "kubernetes.io/pvc-protection"
|
PVCProtectionFinalizer = "kubernetes.io/pvc-protection"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsPVCBeingDeleted returns:
|
|
||||||
// true: in case PVC is being deleted, i.e. ObjectMeta.DeletionTimestamp is set
|
|
||||||
// false: in case PVC is not being deleted, i.e. ObjectMeta.DeletionTimestamp is nil
|
|
||||||
func IsPVCBeingDeleted(pvc *v1.PersistentVolumeClaim) bool {
|
|
||||||
return pvc.ObjectMeta.DeletionTimestamp != nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsProtectionFinalizerPresent returns true in case PVCProtectionFinalizer is
|
|
||||||
// present among the pvc.Finalizers
|
|
||||||
func IsProtectionFinalizerPresent(pvc *v1.PersistentVolumeClaim) bool {
|
|
||||||
for _, finalizer := range pvc.Finalizers {
|
|
||||||
if finalizer == PVCProtectionFinalizer {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// RemoveProtectionFinalizer returns pvc without PVCProtectionFinalizer in case
|
|
||||||
// it's present in pvc.Finalizers. It expects that pvc is writable (i.e. is not
|
|
||||||
// informer's cached copy.)
|
|
||||||
func RemoveProtectionFinalizer(pvc *v1.PersistentVolumeClaim) {
|
|
||||||
newFinalizers := make([]string, 0)
|
|
||||||
for _, finalizer := range pvc.Finalizers {
|
|
||||||
if finalizer != PVCProtectionFinalizer {
|
|
||||||
newFinalizers = append(newFinalizers, finalizer)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if len(newFinalizers) == 0 {
|
|
||||||
// Sanitize for unit tests so we don't need to distinguish empty array
|
|
||||||
// and nil.
|
|
||||||
newFinalizers = nil
|
|
||||||
}
|
|
||||||
pvc.Finalizers = newFinalizers
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddProtectionFinalizer adds PVCProtectionFinalizer to pvc. It expects that
|
|
||||||
// pvc is writable (i.e. is not informer's cached copy.)
|
|
||||||
func AddProtectionFinalizer(pvc *v1.PersistentVolumeClaim) {
|
|
||||||
pvc.Finalizers = append(pvc.Finalizers, PVCProtectionFinalizer)
|
|
||||||
}
|
|
||||||
|
@ -1,231 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2017 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 util
|
|
||||||
|
|
||||||
import (
|
|
||||||
"reflect"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/davecgh/go-spew/spew"
|
|
||||||
"k8s.io/api/core/v1"
|
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
arbitraryTime = metav1.Date(2017, 11, 1, 14, 28, 47, 0, time.FixedZone("CET", 0))
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestIsPVCBeingDeleted(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
pvc *v1.PersistentVolumeClaim
|
|
||||||
want bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
pvc: &v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
DeletionTimestamp: nil,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
pvc: &v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
DeletionTimestamp: &arbitraryTime,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
want: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
if got := IsPVCBeingDeleted(tt.pvc); got != tt.want {
|
|
||||||
t.Errorf("IsPVCBeingDeleted(%v) = %v WANT %v", tt.pvc, got, tt.want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAddProtectionFinalizer(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
pvc *v1.PersistentVolumeClaim
|
|
||||||
want *v1.PersistentVolumeClaim
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"PVC without finalizer",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"PVC with some finalizers",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{"1", "2", "3", PVCProtectionFinalizer + "suffix", "prefix" + PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{"1", "2", "3", PVCProtectionFinalizer + "suffix", "prefix" + PVCProtectionFinalizer, PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range tests {
|
|
||||||
got := test.pvc.DeepCopy()
|
|
||||||
AddProtectionFinalizer(got)
|
|
||||||
if !reflect.DeepEqual(got, test.want) {
|
|
||||||
t.Errorf("Test %q: expected:\n%s\n\ngot:\n%s", test.name, spew.Sdump(test.want), spew.Sdump(got))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRemoveProtectionFinalizer(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
pvc *v1.PersistentVolumeClaim
|
|
||||||
want *v1.PersistentVolumeClaim
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"PVC without finalizer",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"PVC with finalizer",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"PVC with many finalizers",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{"1", "2", "3", PVCProtectionFinalizer + "suffix", "prefix" + PVCProtectionFinalizer, PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{"1", "2", "3", PVCProtectionFinalizer + "suffix", "prefix" + PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range tests {
|
|
||||||
got := test.pvc.DeepCopy()
|
|
||||||
RemoveProtectionFinalizer(got)
|
|
||||||
if !reflect.DeepEqual(got, test.want) {
|
|
||||||
t.Errorf("Test %q: expected:\n%s\n\ngot:\n%s", test.name, spew.Sdump(test.want), spew.Sdump(got))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestIsProtectionFinalizerPresent(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
pvc *v1.PersistentVolumeClaim
|
|
||||||
want bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
"PVC without finalizer",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"PVC with many unrelated finalizers",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{"1", "2", "3", PVCProtectionFinalizer + "suffix", "prefix" + PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"PVC with many finalizers",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{"1", "2", "3", PVCProtectionFinalizer + "suffix", "prefix" + PVCProtectionFinalizer, PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"PVC with finalizer",
|
|
||||||
&v1.PersistentVolumeClaim{
|
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
|
||||||
Name: "pvc",
|
|
||||||
Namespace: "ns",
|
|
||||||
Finalizers: []string{PVCProtectionFinalizer},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range tests {
|
|
||||||
got := IsProtectionFinalizerPresent(test.pvc)
|
|
||||||
if got != test.want {
|
|
||||||
t.Errorf("Test %q: expected %v, got %v", test.name, test.want, got)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user