Skip to content

Commit

Permalink
Create forwarding rules controller
Browse files Browse the repository at this point in the history
This removes copy pasted code between l4 ilb and l4 elb
  • Loading branch information
panslava committed Jul 27, 2022
1 parent 2292c69 commit ef431d0
Show file tree
Hide file tree
Showing 29 changed files with 1,806 additions and 84 deletions.
62 changes: 62 additions & 0 deletions pkg/forwardingrules/forwarding_rules.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package forwardingrules

import (
"fmt"

"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
"k8s.io/ingress-gce/pkg/composite"
"k8s.io/ingress-gce/pkg/utils"
"k8s.io/klog"
"k8s.io/legacy-cloud-providers/gce"
)

type ForwardingRulesController struct {
cloud *gce.Cloud
version meta.Version
scope meta.KeyType
}

func NewForwardingRulesController(cloud *gce.Cloud, version meta.Version, scope meta.KeyType) *ForwardingRulesController {
return &ForwardingRulesController{
cloud: cloud,
version: version,
scope: scope,
}
}

func (frc *ForwardingRulesController) createKey(name string) (*meta.Key, error) {
return composite.CreateKey(frc.cloud, name, frc.scope)
}

func (frc *ForwardingRulesController) CreateForwardingRule(forwardingRule *composite.ForwardingRule) error {
key, err := frc.createKey(forwardingRule.Name)
if err != nil {
klog.Errorf("Failed to create key for creating forwarding rule %s, err: %v", forwardingRule.Name, err)
return nil
}
return composite.CreateForwardingRule(frc.cloud, key, forwardingRule)
}

func (frc *ForwardingRulesController) GetForwardingRule(name string) (*composite.ForwardingRule, error) {
key, err := frc.createKey(name)
if err != nil {
return nil, fmt.Errorf("Failed to create key for fetching forwarding rule %s, err: %w", name, err)
}
fr, err := composite.GetForwardingRule(frc.cloud, key, frc.version)
if utils.IgnoreHTTPNotFound(err) != nil {
return nil, fmt.Errorf("Failed to get existing forwarding rule %s, err: %w", name, err)
}
return fr, nil
}

func (frc *ForwardingRulesController) DeleteForwardingRule(name string) error {
key, err := frc.createKey(name)
if err != nil {
return fmt.Errorf("Failed to create key for deleting forwarding rule %s, err: %w", name, err)
}
err = composite.DeleteForwardingRule(frc.cloud, key, frc.version)
if utils.IgnoreHTTPNotFound(err) != nil {
return fmt.Errorf("Failed to delete forwarding rule %s, err: %w", name, err)
}
return nil
}
217 changes: 217 additions & 0 deletions pkg/forwardingrules/forwarding_rules_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
package forwardingrules

import (
"testing"

"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud"
"github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"k8s.io/ingress-gce/pkg/composite"
"k8s.io/ingress-gce/pkg/utils"
"k8s.io/legacy-cloud-providers/gce"
)

func TestCreateForwardingRule(t *testing.T) {
testCases := []struct {
frRule *composite.ForwardingRule
desc string
}{
{
frRule: &composite.ForwardingRule{
Name: "elb",
Description: "elb description",
LoadBalancingScheme: string(cloud.SchemeExternal),
},
desc: "Test creating external forwarding rule",
},
{
frRule: &composite.ForwardingRule{
Name: "ilb",
Description: "ilb description",
LoadBalancingScheme: string(cloud.SchemeInternal),
},
desc: "Test creating internal forwarding rule",
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues())
frc := NewForwardingRulesController(fakeGCE, meta.VersionGA, meta.Regional)

err := frc.CreateForwardingRule(tc.frRule)
if err != nil {
t.Fatalf("frc.CreateForwardingRule(%v), returned error %v, want nil", tc.frRule, err)
}

verifyForwardingRuleExists(t, fakeGCE, tc.frRule.Name)
})
}
}

func TestGetForwardingRule(t *testing.T) {
elbForwardingRule := &composite.ForwardingRule{
Name: "elb",
Version: meta.VersionGA,
Scope: meta.Regional,
LoadBalancingScheme: string(cloud.SchemeExternal),
}
ilbForwardingRule := &composite.ForwardingRule{
Name: "ilb",
Version: meta.VersionGA,
Scope: meta.Regional,
LoadBalancingScheme: string(cloud.SchemeInternal),
}

testCases := []struct {
existingFwdRules []*composite.ForwardingRule
getFwdRuleName string
expectedFwdRule *composite.ForwardingRule
desc string
}{
{
existingFwdRules: []*composite.ForwardingRule{elbForwardingRule, ilbForwardingRule},
getFwdRuleName: elbForwardingRule.Name,
expectedFwdRule: elbForwardingRule,
desc: "Test getting external forwarding rule",
},
{
existingFwdRules: []*composite.ForwardingRule{elbForwardingRule, ilbForwardingRule},
getFwdRuleName: ilbForwardingRule.Name,
expectedFwdRule: ilbForwardingRule,
desc: "Test getting internal forwarding rule",
},
{
existingFwdRules: []*composite.ForwardingRule{elbForwardingRule, ilbForwardingRule},
getFwdRuleName: "non-existent-rule",
expectedFwdRule: nil,
desc: "Test getting non existent forwarding rule",
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues())
for _, fr := range tc.existingFwdRules {
mustCreateForwardingRule(t, fakeGCE, fr)
}
frc := NewForwardingRulesController(fakeGCE, meta.VersionGA, meta.Regional)

fr, err := frc.GetForwardingRule(tc.getFwdRuleName)
if err != nil {
t.Fatalf("frc.GetForwardingRule(%v), returned error %v, want nil", tc.getFwdRuleName, err)
}

if !cmp.Equal(fr, tc.expectedFwdRule, cmpopts.IgnoreFields(composite.ForwardingRule{}, "SelfLink", "Region")) {
diff := cmp.Diff(fr, tc.expectedFwdRule, cmpopts.IgnoreFields(composite.ForwardingRule{}, "SelfLink", "Region"))
t.Errorf("frc.GetForwardingRule(s) returned %v, not equal to expectedFwdRule %v, diff: %v", fr, tc.expectedFwdRule, diff)
}
})
}
}

func TestDeleteForwardingRule(t *testing.T) {
elbForwardingRule := &composite.ForwardingRule{
Name: "elb",
LoadBalancingScheme: string(cloud.SchemeExternal),
}
ilbForwardingRule := &composite.ForwardingRule{
Name: "ilb",
LoadBalancingScheme: string(cloud.SchemeInternal),
}

testCases := []struct {
existingFwdRules []*composite.ForwardingRule
deleteFwdRuleName string
shouldExistFwdRules []*composite.ForwardingRule
desc string
}{
{
existingFwdRules: []*composite.ForwardingRule{elbForwardingRule, ilbForwardingRule},
deleteFwdRuleName: elbForwardingRule.Name,
shouldExistFwdRules: []*composite.ForwardingRule{},
desc: "Delete elb forwarding rule",
},
{
existingFwdRules: []*composite.ForwardingRule{elbForwardingRule, ilbForwardingRule},
deleteFwdRuleName: ilbForwardingRule.Name,
shouldExistFwdRules: []*composite.ForwardingRule{elbForwardingRule},
desc: "Delete ilb forwarding rule",
},
{
existingFwdRules: []*composite.ForwardingRule{elbForwardingRule},
deleteFwdRuleName: elbForwardingRule.Name,
shouldExistFwdRules: []*composite.ForwardingRule{},
desc: "Delete single elb forwarding rule",
},
{
existingFwdRules: []*composite.ForwardingRule{elbForwardingRule, ilbForwardingRule},
deleteFwdRuleName: "non-existent",
shouldExistFwdRules: []*composite.ForwardingRule{elbForwardingRule, ilbForwardingRule},
desc: "Delete non existent forwarding rule",
},
}

for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues())
for _, fr := range tc.existingFwdRules {
mustCreateForwardingRule(t, fakeGCE, fr)
}
frc := NewForwardingRulesController(fakeGCE, meta.VersionGA, meta.Regional)

err := frc.DeleteForwardingRule(tc.deleteFwdRuleName)
if err != nil {
t.Fatalf("frc.DeleteForwardingRule(%v), returned error %v, want nil", tc.deleteFwdRuleName, err)
}

verifyForwardingRuleNotExists(t, fakeGCE, tc.deleteFwdRuleName)
for _, fw := range tc.shouldExistFwdRules {
verifyForwardingRuleExists(t, fakeGCE, fw.Name)
}
})
}
}

func verifyForwardingRuleExists(t *testing.T, cloud *gce.Cloud, name string) {
t.Helper()
verifyForwardingRuleShouldExists(t, cloud, name, true)
}

func verifyForwardingRuleNotExists(t *testing.T, cloud *gce.Cloud, name string) {
t.Helper()
verifyForwardingRuleShouldExists(t, cloud, name, false)
}

func verifyForwardingRuleShouldExists(t *testing.T, cloud *gce.Cloud, name string, shouldExist bool) {
t.Helper()

key, err := composite.CreateKey(cloud, name, meta.Regional)
if err != nil {
t.Fatalf("Failed to create key for fetching forwarding rule %s, err: %v", name, err)
}
_, err = composite.GetForwardingRule(cloud, key, meta.VersionGA)
if err != nil {
if utils.IsNotFoundError(err) {
if shouldExist {
t.Errorf("Forwarding rule %s was not found", name)
}
return
}
t.Fatalf("composite.GetForwardingRule(_, %v, %v) returned error %v, want nil", key, meta.VersionGA, err)
}
if !shouldExist {
t.Errorf("Forwarding rule %s exists, expected to be not found", name)
}
}

func mustCreateForwardingRule(t *testing.T, cloud *gce.Cloud, fr *composite.ForwardingRule) {
t.Helper()

key := meta.RegionalKey(fr.Name, cloud.Region())
err := composite.CreateForwardingRule(cloud, key, fr)
if err != nil {
t.Fatalf("composite.CreateForwardingRule(_, %s, %v) returned error %v, want nil", key, fr, err)
}
}
11 changes: 11 additions & 0 deletions pkg/forwardingrules/interfaces.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package forwardingrules

import (
"k8s.io/ingress-gce/pkg/composite"
)

type ForwardingRules interface {
GetForwardingRule(name string) (*composite.ForwardingRule, error)
CreateForwardingRule(forwardingRule *composite.ForwardingRule) error
DeleteForwardingRule(name string) error
}
2 changes: 1 addition & 1 deletion pkg/l4lb/l4controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ func (l4c *L4Controller) shouldProcessService(service *v1.Service, l4 *loadbalan
frName := utils.LegacyForwardingRuleName(service)
// Processing should continue if an external forwarding rule exists. This can happen if the service is transitioning from External to Internal.
// The external forwarding rule might not be deleted by the time this controller starts processing the service.
if fr := l4.GetForwardingRule(frName, meta.VersionGA); fr != nil && fr.LoadBalancingScheme == string(cloud.SchemeInternal) {
if fr := l4.GetForwardingRule(frName); fr != nil && fr.LoadBalancingScheme == string(cloud.SchemeInternal) {
klog.Warningf("Ignoring update for service %s:%s as it contains legacy forwarding rule %q", service.Namespace, service.Name, frName)
return false
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/l4lb/l4netlbcontroller.go
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ func (lc *L4NetLBController) hasTargetPoolForwardingRule(service *v1.Service) bo
return false
}

existingFR := l4netlb.GetForwardingRule(frName, meta.VersionGA)
existingFR := l4netlb.GetForwardingRule(frName)
if existingFR != nil && existingFR.Target != "" {
return true
}
Expand Down Expand Up @@ -323,7 +323,7 @@ func (lc *L4NetLBController) hasRBSForwardingRule(svc *v1.Service) bool {
if lc.hasForwardingRuleAnnotation(svc, frName) {
return true
}
existingFR := l4netlb.GetForwardingRule(frName, meta.VersionGA)
existingFR := l4netlb.GetForwardingRule(frName)
return existingFR != nil && existingFR.LoadBalancingScheme == string(cloud.SchemeExternal) && existingFR.BackendService != ""
}

Expand Down
Loading

0 comments on commit ef431d0

Please sign in to comment.