Unverified Commit bc323073 authored by Kubernetes Prow Robot's avatar Kubernetes Prow Robot Committed by GitHub

Merge pull request #78262 from MrHohn/svc-finalizer-cleanup2

Add Service Load Balancer finalizer support
parents bb7898ba 64198a43
...@@ -19,6 +19,7 @@ go_library( ...@@ -19,6 +19,7 @@ go_library(
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/features:go_default_library", "//pkg/features:go_default_library",
"//pkg/util/metrics:go_default_library", "//pkg/util/metrics:go_default_library",
"//pkg/util/slice:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
...@@ -36,6 +37,7 @@ go_library( ...@@ -36,6 +37,7 @@ go_library(
"//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/client-go/util/workqueue:go_default_library", "//staging/src/k8s.io/client-go/util/workqueue:go_default_library",
"//staging/src/k8s.io/cloud-provider:go_default_library", "//staging/src/k8s.io/cloud-provider:go_default_library",
"//staging/src/k8s.io/cloud-provider/service/helpers:go_default_library",
"//vendor/k8s.io/klog:go_default_library", "//vendor/k8s.io/klog:go_default_library",
], ],
) )
...@@ -50,16 +52,20 @@ go_test( ...@@ -50,16 +52,20 @@ go_test(
deps = [ deps = [
"//pkg/api/testapi:go_default_library", "//pkg/api/testapi:go_default_library",
"//pkg/controller:go_default_library", "//pkg/controller:go_default_library",
"//pkg/features:go_default_library",
"//staging/src/k8s.io/api/core/v1:go_default_library", "//staging/src/k8s.io/api/core/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/types:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/types:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/client-go/informers:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library",
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library", "//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
"//staging/src/k8s.io/client-go/testing:go_default_library", "//staging/src/k8s.io/client-go/testing:go_default_library",
"//staging/src/k8s.io/client-go/tools/record:go_default_library", "//staging/src/k8s.io/client-go/tools/record:go_default_library",
"//staging/src/k8s.io/cloud-provider/fake:go_default_library", "//staging/src/k8s.io/cloud-provider/fake:go_default_library",
"//staging/src/k8s.io/cloud-provider/service/helpers:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
], ],
) )
......
...@@ -454,6 +454,12 @@ const ( ...@@ -454,6 +454,12 @@ const (
// Enables the regional PD feature on GCE. // Enables the regional PD feature on GCE.
deprecatedGCERegionalPersistentDisk featuregate.Feature = "GCERegionalPersistentDisk" deprecatedGCERegionalPersistentDisk featuregate.Feature = "GCERegionalPersistentDisk"
// owner: @MrHohn
// alpha: v1.15
//
// Enables Finalizer Protection for Service LoadBalancers.
ServiceLoadBalancerFinalizer featuregate.Feature = "ServiceLoadBalancerFinalizer"
// owner: @RobertKrawitz // owner: @RobertKrawitz
// alpha: v1.15 // alpha: v1.15
// //
...@@ -548,6 +554,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS ...@@ -548,6 +554,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
TTLAfterFinished: {Default: false, PreRelease: featuregate.Alpha}, TTLAfterFinished: {Default: false, PreRelease: featuregate.Alpha},
KubeletPodResources: {Default: true, PreRelease: featuregate.Beta}, KubeletPodResources: {Default: true, PreRelease: featuregate.Beta},
WindowsGMSA: {Default: false, PreRelease: featuregate.Alpha}, WindowsGMSA: {Default: false, PreRelease: featuregate.Alpha},
ServiceLoadBalancerFinalizer: {Default: false, PreRelease: featuregate.Alpha},
LocalStorageCapacityIsolationFSQuotaMonitoring: {Default: false, PreRelease: featuregate.Alpha}, LocalStorageCapacityIsolationFSQuotaMonitoring: {Default: false, PreRelease: featuregate.Alpha},
NonPreemptingPriority: {Default: false, PreRelease: featuregate.Alpha}, NonPreemptingPriority: {Default: false, PreRelease: featuregate.Alpha},
VolumePVCDataSource: {Default: false, PreRelease: featuregate.Alpha}, VolumePVCDataSource: {Default: false, PreRelease: featuregate.Alpha},
......
...@@ -32,6 +32,7 @@ go_test( ...@@ -32,6 +32,7 @@ go_test(
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//staging/src/k8s.io/api/core/v1: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",
"//vendor/k8s.io/utils/net:go_default_library", "//vendor/k8s.io/utils/net:go_default_library",
], ],
) )
...@@ -20,7 +20,7 @@ import ( ...@@ -20,7 +20,7 @@ import (
"fmt" "fmt"
"strings" "strings"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
utilnet "k8s.io/utils/net" utilnet "k8s.io/utils/net"
) )
...@@ -31,6 +31,11 @@ in order for in-tree cloud providers to not depend on internal packages. ...@@ -31,6 +31,11 @@ in order for in-tree cloud providers to not depend on internal packages.
const ( const (
defaultLoadBalancerSourceRanges = "0.0.0.0/0" defaultLoadBalancerSourceRanges = "0.0.0.0/0"
// LoadBalancerCleanupFinalizer is the finalizer added to load balancer
// services to ensure the Service resource is not fully deleted until
// the correlating load balancer resources are deleted.
LoadBalancerCleanupFinalizer = "service.kubernetes.io/load-balancer-cleanup"
) )
// IsAllowAll checks whether the utilnet.IPNet allows traffic from 0.0.0.0/0 // IsAllowAll checks whether the utilnet.IPNet allows traffic from 0.0.0.0/0
...@@ -100,3 +105,13 @@ func NeedsHealthCheck(service *v1.Service) bool { ...@@ -100,3 +105,13 @@ func NeedsHealthCheck(service *v1.Service) bool {
} }
return RequestsOnlyLocalTraffic(service) return RequestsOnlyLocalTraffic(service)
} }
// HasLBFinalizer checks if service contains LoadBalancerCleanupFinalizer.
func HasLBFinalizer(service *v1.Service) bool {
for _, finalizer := range service.ObjectMeta.Finalizers {
if finalizer == LoadBalancerCleanupFinalizer {
return true
}
}
return false
}
...@@ -20,7 +20,8 @@ import ( ...@@ -20,7 +20,8 @@ import (
"strings" "strings"
"testing" "testing"
"k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilnet "k8s.io/utils/net" utilnet "k8s.io/utils/net"
) )
...@@ -219,3 +220,52 @@ func TestNeedsHealthCheck(t *testing.T) { ...@@ -219,3 +220,52 @@ func TestNeedsHealthCheck(t *testing.T) {
}, },
}) })
} }
func TestHasLBFinalizer(t *testing.T) {
testCases := []struct {
desc string
svc *v1.Service
hasFinalizer bool
}{
{
desc: "service without finalizer",
svc: &v1.Service{},
hasFinalizer: false,
},
{
desc: "service with unrelated finalizer",
svc: &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Finalizers: []string{"unrelated"},
},
},
hasFinalizer: false,
},
{
desc: "service with one finalizer",
svc: &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Finalizers: []string{LoadBalancerCleanupFinalizer},
},
},
hasFinalizer: true,
},
{
desc: "service with multiple finalizers",
svc: &v1.Service{
ObjectMeta: metav1.ObjectMeta{
Finalizers: []string{LoadBalancerCleanupFinalizer, "unrelated"},
},
},
hasFinalizer: true,
},
}
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
if hasFinalizer := HasLBFinalizer(tc.svc); hasFinalizer != tc.hasFinalizer {
t.Errorf("HasLBFinalizer() = %t, want %t", hasFinalizer, tc.hasFinalizer)
}
})
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment