diff --git a/staging/src/k8s.io/legacy-cloud-providers/gce/gce_annotations.go b/staging/src/k8s.io/legacy-cloud-providers/gce/gce_annotations.go index 2dd59e8da09..f1b4a921ffa 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/gce/gce_annotations.go +++ b/staging/src/k8s.io/legacy-cloud-providers/gce/gce_annotations.go @@ -74,6 +74,13 @@ const ( // NetworkTierAnnotationPremium is an annotation to indicate the Service is on the Premium network tier NetworkTierAnnotationPremium = cloud.NetworkTierPremium + + // RBSAnnotationKey is annotated on a Service object to indicate + // opt-in mode for RBS NetLB + RBSAnnotationKey = "cloud.google.com/l4-rbs" + + // RBSEnabled is an annotation to indicate the Service is opt-in for RBS + RBSEnabled = "enabled" ) // GetLoadBalancerAnnotationType returns the type of GCP load balancer which should be assembled. diff --git a/staging/src/k8s.io/legacy-cloud-providers/gce/gce_loadbalancer_external.go b/staging/src/k8s.io/legacy-cloud-providers/gce/gce_loadbalancer_external.go index 86d43789126..5b9f2344b8d 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/gce/gce_loadbalancer_external.go +++ b/staging/src/k8s.io/legacy-cloud-providers/gce/gce_loadbalancer_external.go @@ -31,6 +31,7 @@ import ( "k8s.io/apimachinery/pkg/types" utilerrors "k8s.io/apimachinery/pkg/util/errors" "k8s.io/apimachinery/pkg/util/sets" + cloudprovider "k8s.io/cloud-provider" servicehelpers "k8s.io/cloud-provider/service/helpers" utilnet "k8s.io/utils/net" @@ -51,6 +52,11 @@ const ( // new load balancers and updating existing load balancers, recognizing when // each is needed. func (g *Cloud) ensureExternalLoadBalancer(clusterName string, clusterID string, apiService *v1.Service, existingFwdRule *compute.ForwardingRule, nodes []*v1.Node) (*v1.LoadBalancerStatus, error) { + // Skip service handling if managed by ingress-gce using Regional Backend Services + if val, ok := apiService.Annotations[RBSAnnotationKey]; ok && val == RBSEnabled { + return nil, cloudprovider.ImplementedElsewhere + } + if len(nodes) == 0 { return nil, fmt.Errorf(errStrLbNoHosts) } diff --git a/staging/src/k8s.io/legacy-cloud-providers/gce/gce_loadbalancer_external_test.go b/staging/src/k8s.io/legacy-cloud-providers/gce/gce_loadbalancer_external_test.go index bd493b51e8b..fe39187637a 100644 --- a/staging/src/k8s.io/legacy-cloud-providers/gce/gce_loadbalancer_external_test.go +++ b/staging/src/k8s.io/legacy-cloud-providers/gce/gce_loadbalancer_external_test.go @@ -22,7 +22,6 @@ package gce import ( "context" "fmt" - "reflect" "strings" "testing" @@ -30,6 +29,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" compute "google.golang.org/api/compute/v1" + cloudprovider "k8s.io/cloud-provider" "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud" "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta" @@ -580,6 +580,48 @@ func TestEnsureExternalLoadBalancerFailsWithNoNodes(t *testing.T) { assert.EqualError(t, err, errStrLbNoHosts) } +func TestEnsureExternalLoadBalancerRBSAnnotation(t *testing.T) { + t.Parallel() + + vals := DefaultTestClusterValues() + gce, err := fakeGCECloud(DefaultTestClusterValues()) + require.NoError(t, err) + nodeNames := []string{"test-node-1"} + + nodes, err := createAndInsertNodes(gce, nodeNames, vals.ZoneName) + require.NoError(t, err) + + svc := fakeLoadbalancerService("") + + for desc, tc := range map[string]struct { + annotations map[string]string + expectError *error + }{ + "When RBS enabled": { + annotations: map[string]string{RBSAnnotationKey: RBSEnabled}, + expectError: &cloudprovider.ImplementedElsewhere, + }, + "When RBS not enabled": { + annotations: map[string]string{}, + expectError: nil, + }, + "When RBS annotation has wrong value": { + annotations: map[string]string{RBSAnnotationKey: "WrongValue"}, + expectError: nil, + }, + } { + t.Run(desc, func(t *testing.T) { + svc.Annotations = tc.annotations + _, err = gce.ensureExternalLoadBalancer(vals.ClusterName, vals.ClusterID, svc, nil, nodes) + if tc.expectError != nil { + assert.EqualError(t, err, (*tc.expectError).Error()) + } else { + assert.NoError(t, err, "Should not return an error "+desc) + } + }) + } +} + func TestForwardingRuleNeedsUpdate(t *testing.T) { t.Parallel()