From 2ca905dda4f30c82aef5a247fe0a4732bacc2a7f Mon Sep 17 00:00:00 2001 From: Spencer Hance Date: Tue, 25 Jun 2019 12:25:07 -0700 Subject: [PATCH 1/2] Update k8s-cloud-provider to 1.6.0 --- go.mod | 4 +- go.sum | 4 + .../k8s-cloud-provider/pkg/cloud/mock/mock.go | 200 ++++++++++++------ vendor/modules.txt | 4 +- 4 files changed, 144 insertions(+), 68 deletions(-) diff --git a/go.mod b/go.mod index 5ebf07a017..8c9bd838bc 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module k8s.io/ingress-gce go 1.12 require ( - github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190612171043-2e19bb35a278 + github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190625070306-c3ad81d637ad github.com/PuerkitoBio/purell v1.1.1 // indirect github.com/beorn7/perks v1.0.0 // indirect github.com/emicklei/go-restful v2.9.3+incompatible // indirect @@ -45,7 +45,7 @@ require ( replace ( cloud.google.com/go => cloud.google.com/go v0.37.4 - github.com/GoogleCloudPlatform/k8s-cloud-provider => github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190612171043-2e19bb35a278 + github.com/GoogleCloudPlatform/k8s-cloud-provider => github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190625070306-c3ad81d637ad github.com/PuerkitoBio/purell => github.com/PuerkitoBio/purell v1.1.1 github.com/beorn7/perks => github.com/beorn7/perks v1.0.0 github.com/emicklei/go-restful => github.com/emicklei/go-restful v2.9.3+incompatible diff --git a/go.sum b/go.sum index e76cf5c23a..775afa3b11 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,8 @@ github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190604211444-77eedaf6 github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190604211444-77eedaf646f1/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190612171043-2e19bb35a278 h1:TgNrmegr5ot2LQQLFikl4VFrPvTvlOB2zCShOcpa+t8= github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190612171043-2e19bb35a278/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= +github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190625070306-c3ad81d637ad h1:dmM8d/LQF+cpMG+hl73tMYjinBkSz+wdMxzQUlysfTI= +github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190625070306-c3ad81d637ad/go.mod h1:iroGtC8B3tQiqtds1l+mgk/BBOrxbqjH+eUfFQYRc14= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -158,6 +160,8 @@ github.com/prometheus/procfs v0.0.0-20190416084830-8368d24ba045/go.mod h1:TjEm7z github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/soheilhy/cmux v0.1.3/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/spencerhance/k8s-cloud-provider v0.0.0-20190622002134-a3b35430794f h1:urtm5AHRaj52wI2J1zo8M7f5W8c7/LQqTKoPnJY2Q+k= +github.com/spencerhance/k8s-cloud-provider v0.0.0-20190622002134-a3b35430794f/go.mod h1:a2/swOxdL5eTqmC1yPqaY4Xvc0dsL6YBm5MolnXMq5g= github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock/mock.go b/vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock/mock.go index 26ca71748c..d8ebbc5e6c 100644 --- a/vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock/mock.go +++ b/vendor/github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock/mock.go @@ -333,10 +333,7 @@ func (igAttrs *InstanceGroupAttributes) List(key *meta.Key) []*ga.InstanceWithNa func AddInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroupsAddInstancesRequest, m *cloud.MockInstanceGroups) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in InstanceGroups", key.String()), - } + return err } var attrs InstanceGroupAttributes @@ -350,10 +347,7 @@ func AddInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroups func ListInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroupsListInstancesRequest, filter *filter.F, m *cloud.MockInstanceGroups) ([]*ga.InstanceWithNamedPorts, error) { _, err := m.Get(ctx, key) if err != nil { - return nil, &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in InstanceGroups", key.String()), - } + return nil, err } var attrs InstanceGroupAttributes @@ -367,10 +361,7 @@ func ListInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroup func RemoveInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGroupsRemoveInstancesRequest, m *cloud.MockInstanceGroups) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in InstanceGroups", key.String()), - } + return err } var attrs InstanceGroupAttributes @@ -385,10 +376,7 @@ func RemoveInstancesHook(ctx context.Context, key *meta.Key, req *ga.InstanceGro func UpdateFirewallHook(ctx context.Context, key *meta.Key, obj *ga.Firewall, m *cloud.MockFirewalls) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in Firewalls", key.String()), - } + return err } obj.Name = key.Name @@ -404,10 +392,7 @@ func UpdateFirewallHook(ctx context.Context, key *meta.Key, obj *ga.Firewall, m func UpdateHealthCheckHook(ctx context.Context, key *meta.Key, obj *ga.HealthCheck, m *cloud.MockHealthChecks) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in HealthChecks", key.String()), - } + return err } obj.Name = key.Name @@ -423,10 +408,7 @@ func UpdateHealthCheckHook(ctx context.Context, key *meta.Key, obj *ga.HealthChe func UpdateAlphaHealthCheckHook(ctx context.Context, key *meta.Key, obj *alpha.HealthCheck, m *cloud.MockAlphaHealthChecks) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in HealthChecks", key.String()), - } + return err } obj.Name = key.Name @@ -443,10 +425,7 @@ func UpdateAlphaHealthCheckHook(ctx context.Context, key *meta.Key, obj *alpha.H func UpdateRegionBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga.BackendService, m *cloud.MockRegionBackendServices) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in RegionBackendServices", key.String()), - } + return err } obj.Name = key.Name @@ -457,15 +436,29 @@ func UpdateRegionBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga. return nil } +// UpdateRegionBackendServiceHook defines the hook for updating a Region +// BackendsService. It replaces the object with the same key in the mock with +// the updated object. +func UpdateAlphaRegionBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga.BackendService, m *cloud.MockAlphaRegionBackendServices) error { + _, err := m.Get(ctx, key) + if err != nil { + return err + } + + obj.Name = key.Name + projectID := m.ProjectRouter.ProjectID(ctx, "ga", "backendServices") + obj.SelfLink = cloud.SelfLink(meta.VersionAlpha, projectID, "backendServices", key) + + m.Objects[*key] = &cloud.MockRegionBackendServicesObj{Obj: obj} + return nil +} + // UpdateBackendServiceHook defines the hook for updating a BackendService. // It replaces the object with the same key in the mock with the updated object. func UpdateBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga.BackendService, m *cloud.MockBackendServices) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in BackendServices", key.String()), - } + return err } obj.Name = key.Name @@ -481,10 +474,7 @@ func UpdateBackendServiceHook(ctx context.Context, key *meta.Key, obj *ga.Backen func UpdateAlphaBackendServiceHook(ctx context.Context, key *meta.Key, obj *alpha.BackendService, m *cloud.MockAlphaBackendServices) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in BackendServices", key.String()), - } + return err } obj.Name = key.Name @@ -500,10 +490,7 @@ func UpdateAlphaBackendServiceHook(ctx context.Context, key *meta.Key, obj *alph func UpdateBetaBackendServiceHook(ctx context.Context, key *meta.Key, obj *beta.BackendService, m *cloud.MockBetaBackendServices) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in BackendServices", key.String()), - } + return err } obj.Name = key.Name @@ -519,10 +506,7 @@ func UpdateBetaBackendServiceHook(ctx context.Context, key *meta.Key, obj *beta. func UpdateURLMapHook(ctx context.Context, key *meta.Key, obj *ga.UrlMap, m *cloud.MockUrlMaps) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in UrlMaps", key.String()), - } + return err } obj.Name = key.Name @@ -538,10 +522,7 @@ func UpdateURLMapHook(ctx context.Context, key *meta.Key, obj *ga.UrlMap, m *clo func UpdateAlphaURLMapHook(ctx context.Context, key *meta.Key, obj *alpha.UrlMap, m *cloud.MockAlphaUrlMaps) error { _, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in UrlMaps", key.String()), - } + return err } obj.Name = key.Name @@ -552,14 +533,49 @@ func UpdateAlphaURLMapHook(ctx context.Context, key *meta.Key, obj *alpha.UrlMap return nil } +// UpdateAlphaURLMapHook defines the hook for updating an alpha UrlMap. +// It replaces the object with the same key in the mock with the updated object. +func UpdateAlphaRegionURLMapHook(ctx context.Context, key *meta.Key, obj *alpha.UrlMap, m *cloud.MockAlphaRegionUrlMaps) error { + _, err := m.Get(ctx, key) + if err != nil { + return err + } + + obj.Name = key.Name + projectID := m.ProjectRouter.ProjectID(ctx, "alpha", "urlMaps") + obj.SelfLink = cloud.SelfLink(meta.VersionAlpha, projectID, "urlMaps", key) + + m.Objects[*key] = &cloud.MockRegionUrlMapsObj{Obj: obj} + return nil +} + // SetTargetGlobalForwardingRuleHook defines the hook for setting the target proxy for a GlobalForwardingRule. func SetTargetGlobalForwardingRuleHook(ctx context.Context, key *meta.Key, obj *ga.TargetReference, m *cloud.MockGlobalForwardingRules) error { fw, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in UrlMaps", key.String()), - } + return err + } + + fw.Target = obj.Target + return nil +} + +// SetTargetForwardingRuleHook defines the hook for setting the target proxy for a ForwardingRule. +func SetTargetForwardingRuleHook(ctx context.Context, key *meta.Key, obj *ga.TargetReference, m *cloud.MockForwardingRules) error { + fw, err := m.Get(ctx, key) + if err != nil { + return err + } + + fw.Target = obj.Target + return nil +} + +// SetTargetAlphaForwardingRuleHook defines the hook for setting the target proxy for an Alpha ForwardingRule. +func SetTargetAlphaForwardingRuleHook(ctx context.Context, key *meta.Key, obj *alpha.TargetReference, m *cloud.MockAlphaForwardingRules) error { + fw, err := m.Get(ctx, key) + if err != nil { + return err } fw.Target = obj.Target @@ -570,10 +586,7 @@ func SetTargetGlobalForwardingRuleHook(ctx context.Context, key *meta.Key, obj * func SetTargetAlphaGlobalForwardingRuleHook(ctx context.Context, key *meta.Key, ref *alpha.TargetReference, m *cloud.MockAlphaGlobalForwardingRules) error { fw, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in UrlMaps", key.String()), - } + return err } fw.Target = ref.Target @@ -584,10 +597,29 @@ func SetTargetAlphaGlobalForwardingRuleHook(ctx context.Context, key *meta.Key, func SetURLMapTargetHTTPProxyHook(ctx context.Context, key *meta.Key, ref *ga.UrlMapReference, m *cloud.MockTargetHttpProxies) error { tp, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in TargetHttpProxies", key.String()), - } + return err + } + + tp.UrlMap = ref.UrlMap + return nil +} + +// SetURLMapTargetHTTPProxyHook defines the hook for setting the url map for a TargetHttpProxy. +func SetURLMapTargetHTTPSProxyHook(ctx context.Context, key *meta.Key, ref *ga.UrlMapReference, m *cloud.MockTargetHttpsProxies) error { + tp, err := m.Get(ctx, key) + if err != nil { + return err + } + + tp.UrlMap = ref.UrlMap + return nil +} + +// SetURLMapTargetHTTPProxyHook defines the hook for setting the url map for a TargetHttpProxy. +func SetURLMapAlphaRegionTargetHTTPSProxyHook(ctx context.Context, key *meta.Key, ref *alpha.UrlMapReference, m *cloud.MockAlphaRegionTargetHttpsProxies) error { + tp, err := m.Get(ctx, key) + if err != nil { + return err } tp.UrlMap = ref.UrlMap @@ -598,16 +630,56 @@ func SetURLMapTargetHTTPProxyHook(ctx context.Context, key *meta.Key, ref *ga.Ur func SetURLMapAlphaTargetHTTPProxyHook(ctx context.Context, key *meta.Key, ref *alpha.UrlMapReference, m *cloud.MockAlphaTargetHttpProxies) error { tp, err := m.Get(ctx, key) if err != nil { - return &googleapi.Error{ - Code: http.StatusNotFound, - Message: fmt.Sprintf("Key: %s was not found in TargetHttpProxies", key.String()), - } + return err } tp.UrlMap = ref.UrlMap return nil } +// SetURLMapAlphaTargetHTTPProxyHook defines the hook for setting the url map for a TargetHttpProxy. +func SetURLMapAlphaRegionTargetHTTPProxyHook(ctx context.Context, key *meta.Key, ref *alpha.UrlMapReference, m *cloud.MockAlphaRegionTargetHttpProxies) error { + tp, err := m.Get(ctx, key) + if err != nil { + return err + } + + tp.UrlMap = ref.UrlMap + return nil +} + +// TargetHttpsProxySetSslCertificatesHook defines the hook for setting ssl certificates on a TargetHttpsProxy. +func SetSslCertificateTargetHTTPSProxyHook(ctx context.Context, key *meta.Key, req *ga.TargetHttpsProxiesSetSslCertificatesRequest, m *cloud.MockTargetHttpsProxies) error { + tp, err := m.Get(ctx, key) + if err != nil { + return err + } + + tp.SslCertificates = req.SslCertificates + return nil +} + +// TargetHttpsProxySetSslCertificatesHook defines the hook for setting ssl certificates on a TargetHttpsProxy. +func SetSslCertificateAlphaTargetHTTPSProxyHook(ctx context.Context, key *meta.Key, req *alpha.TargetHttpsProxiesSetSslCertificatesRequest, m *cloud.MockAlphaTargetHttpsProxies) error { + tp, err := m.Get(ctx, key) + if err != nil { + return err + } + tp.SslCertificates = req.SslCertificates + return nil +} + +// TargetHttpsProxySetSslCertificatesHook defines the hook for setting ssl certificates on a TargetHttpsProxy. +func SetSslCertificateAlphaRegionTargetHTTPSProxyHook(ctx context.Context, key *meta.Key, req *alpha.TargetHttpsProxiesSetSslCertificatesRequest, m *cloud.MockAlphaRegionTargetHttpsProxies) error { + tp, err := m.Get(ctx, key) + if err != nil { + return err + } + + tp.SslCertificates = req.SslCertificates + return nil +} + // InsertFirewallsUnauthorizedErrHook mocks firewall insertion. A forbidden error will be thrown as return. func InsertFirewallsUnauthorizedErrHook(ctx context.Context, key *meta.Key, obj *ga.Firewall, m *cloud.MockFirewalls) (bool, error) { return true, &googleapi.Error{Code: http.StatusForbidden} diff --git a/vendor/modules.txt b/vendor/modules.txt index 7b6ee23ff3..6a71d14bb9 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,6 +1,6 @@ # cloud.google.com/go v0.38.0 => cloud.google.com/go v0.37.4 cloud.google.com/go/compute/metadata -# github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190612171043-2e19bb35a278 => github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190612171043-2e19bb35a278 +# github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190625070306-c3ad81d637ad => github.com/GoogleCloudPlatform/k8s-cloud-provider v0.0.0-20190625070306-c3ad81d637ad github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/filter @@ -124,8 +124,8 @@ golang.org/x/text/transform # golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 => golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/time/rate # google.golang.org/api v0.6.1-0.20190607001116-5213b8090861 => google.golang.org/api v0.6.1-0.20190607001116-5213b8090861 -google.golang.org/api/compute/v0.beta google.golang.org/api/compute/v1 +google.golang.org/api/compute/v0.beta google.golang.org/api/compute/v0.alpha google.golang.org/api/googleapi google.golang.org/api/container/v1 From 10ec2dc02a90dc058b09bcec15ddd7177c754840 Mon Sep 17 00:00:00 2001 From: Spencer Hance Date: Tue, 25 Jun 2019 12:25:14 -0700 Subject: [PATCH 2/2] Remove Loadbalancer interface and use k8s-cloud-provider mocks --- pkg/controller/controller_test.go | 13 +- pkg/loadbalancers/addresses.go | 2 +- pkg/loadbalancers/fakes.go | 421 +--------------- pkg/loadbalancers/interfaces.go | 50 -- pkg/loadbalancers/l7.go | 3 +- pkg/loadbalancers/l7s.go | 5 +- pkg/loadbalancers/l7s_test.go | 6 +- pkg/loadbalancers/loadbalancers_test.go | 609 +++++++++++++----------- 8 files changed, 364 insertions(+), 745 deletions(-) diff --git a/pkg/controller/controller_test.go b/pkg/controller/controller_test.go index 27455e4960..363d991d5c 100644 --- a/pkg/controller/controller_test.go +++ b/pkg/controller/controller_test.go @@ -17,10 +17,7 @@ limitations under the License. package controller import ( - "strings" - "testing" - "time" - + "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud" api_v1 "k8s.io/api/core/v1" extensions "k8s.io/api/extensions/v1beta1" meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -37,6 +34,9 @@ import ( "k8s.io/ingress-gce/pkg/tls" "k8s.io/ingress-gce/pkg/utils" "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" + "strings" + "testing" + "time" "k8s.io/ingress-gce/pkg/context" "k8s.io/ingress-gce/pkg/flags" @@ -52,6 +52,8 @@ func newLoadBalancerController() *LoadBalancerController { kubeClient := fake.NewSimpleClientset() backendConfigClient := backendconfigclient.NewSimpleClientset() fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) + + (fakeGCE.Compute().(*cloud.MockGCE)).MockGlobalForwardingRules.InsertHook = loadbalancers.InsertGlobalForwardingRuleHook namer := utils.NewNamer(clusterUID, "") stopCh := make(chan struct{}) @@ -66,7 +68,7 @@ func newLoadBalancerController() *LoadBalancerController { lbc := NewLoadBalancerController(ctx, stopCh) // TODO(rramkumar): Fix this so we don't have to override with our fake lbc.instancePool = instances.NewNodePool(instances.NewFakeInstanceGroups(sets.NewString(), namer), namer) - lbc.l7Pool = loadbalancers.NewLoadBalancerPool(loadbalancers.NewFakeLoadBalancers(clusterUID, namer), namer, events.RecorderProducerMock{}) + lbc.l7Pool = loadbalancers.NewLoadBalancerPool(fakeGCE, namer, events.RecorderProducerMock{}) lbc.instancePool.Init(&instances.FakeZoneLister{Zones: []string{"zone-a"}}) lbc.hasSynced = func() bool { return true } @@ -259,7 +261,6 @@ func TestIngressCreateDeleteFinalizer(t *testing.T) { if len(updatedIng.GetFinalizers()) != 1 { t.Errorf("GetFinalizers() = %+v, want 0", updatedIng.GetFinalizers()) } - continue } diff --git a/pkg/loadbalancers/addresses.go b/pkg/loadbalancers/addresses.go index 351e95a1e3..40284c966b 100644 --- a/pkg/loadbalancers/addresses.go +++ b/pkg/loadbalancers/addresses.go @@ -20,7 +20,7 @@ import ( "fmt" "net/http" - compute "google.golang.org/api/compute/v1" + "google.golang.org/api/compute/v1" "k8s.io/ingress-gce/pkg/utils" "k8s.io/klog" ) diff --git a/pkg/loadbalancers/fakes.go b/pkg/loadbalancers/fakes.go index c9c19c93cb..dcab2ee54b 100644 --- a/pkg/loadbalancers/fakes.go +++ b/pkg/loadbalancers/fakes.go @@ -17,16 +17,11 @@ limitations under the License. package loadbalancers import ( + "context" "fmt" - - "k8s.io/klog" - "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud" "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta" - compute "google.golang.org/api/compute/v1" - "k8s.io/apimachinery/pkg/util/sets" - - "k8s.io/ingress-gce/pkg/utils" + "google.golang.org/api/compute/v1" ) const FakeCertQuota = 15 @@ -42,413 +37,9 @@ func (t *testIP) ip() string { return fmt.Sprintf("0.0.0.%v", t.start) } -// Loadbalancer fakes - -// FakeLoadBalancers is a type that fakes out the loadbalancer interface. -type FakeLoadBalancers struct { - Fw []*compute.ForwardingRule - Um []*compute.UrlMap - Tp []*compute.TargetHttpProxy - Tps []*compute.TargetHttpsProxy - IP []*compute.Address - Certs []*compute.SslCertificate - name string - calls []string // list of calls that were made - - namer *utils.Namer -} - -// FWName returns the name of the firewall given the protocol. -// -// TODO: There is some duplication between these functions and the name mungers in -// loadbalancer file. -func (f *FakeLoadBalancers) FWName(https bool) string { - proto := utils.HTTPProtocol - if https { - proto = utils.HTTPSProtocol - } - return f.namer.ForwardingRule(f.name, proto) -} - -func (f *FakeLoadBalancers) UMName() string { - return f.namer.UrlMap(f.name) -} - -func (f *FakeLoadBalancers) TPName(https bool) string { - protocol := utils.HTTPProtocol - if https { - protocol = utils.HTTPSProtocol - } - return f.namer.TargetProxy(f.name, protocol) -} - -// String is the string method for FakeLoadBalancers. -func (f *FakeLoadBalancers) String() string { - msg := fmt.Sprintf( - "Loadbalancer %v,\nforwarding rules:\n", f.name) - for _, fw := range f.Fw { - msg += fmt.Sprintf("\t%v\n", fw.Name) - } - msg += fmt.Sprintf("Target proxies\n") - for _, tp := range f.Tp { - msg += fmt.Sprintf("\t%v\n", tp.Name) - } - msg += fmt.Sprintf("UrlMaps\n") - for _, um := range f.Um { - msg += fmt.Sprintf("%v\n", um.Name) - msg += fmt.Sprintf("\tHost Rules:\n") - for _, hostRule := range um.HostRules { - msg += fmt.Sprintf("\t\t%v\n", hostRule) - } - msg += fmt.Sprintf("\tPath Matcher:\n") - for _, pathMatcher := range um.PathMatchers { - msg += fmt.Sprintf("\t\t%v\n", pathMatcher.Name) - for _, pathRule := range pathMatcher.PathRules { - msg += fmt.Sprintf("\t\t\t%+v\n", pathRule) - } - } - } - msg += "Certificates:\n" - for _, cert := range f.Certs { - msg += fmt.Sprintf("\t%+v\n", cert) - } - return msg -} - -// Forwarding Rule fakes - -// GetGlobalForwardingRule returns a fake forwarding rule. -func (f *FakeLoadBalancers) GetGlobalForwardingRule(name string) (*compute.ForwardingRule, error) { - f.calls = append(f.calls, "GetGlobalForwardingRule") - for i := range f.Fw { - if f.Fw[i].Name == name { - return f.Fw[i], nil - } - } - return nil, utils.FakeGoogleAPINotFoundErr() -} - -func (f *FakeLoadBalancers) ListGlobalForwardingRules() ([]*compute.ForwardingRule, error) { - return f.Fw, nil -} - -// CreateGlobalForwardingRule fakes forwarding rule creation. -func (f *FakeLoadBalancers) CreateGlobalForwardingRule(rule *compute.ForwardingRule) error { - f.calls = append(f.calls, "CreateGlobalForwardingRule") - if rule.IPAddress == "" { - rule.IPAddress = fmt.Sprintf(testIPManager.ip()) - } - rule.SelfLink = cloud.NewGlobalForwardingRulesResourceID("mock-project", rule.Name).SelfLink(meta.VersionGA) - f.Fw = append(f.Fw, rule) - return nil -} - -// SetProxyForGlobalForwardingRule fakes setting a global forwarding rule. -func (f *FakeLoadBalancers) SetProxyForGlobalForwardingRule(forwardingRuleName, proxyLink string) error { - f.calls = append(f.calls, "SetProxyForGlobalForwardingRule") - for i := range f.Fw { - if f.Fw[i].Name == forwardingRuleName { - f.Fw[i].Target = proxyLink - } - } - return nil -} - -// DeleteGlobalForwardingRule fakes deleting a global forwarding rule. -func (f *FakeLoadBalancers) DeleteGlobalForwardingRule(name string) error { - f.calls = append(f.calls, "DeleteGlobalForwardingRule") - fw := []*compute.ForwardingRule{} - for i := range f.Fw { - if f.Fw[i].Name != name { - fw = append(fw, f.Fw[i]) - } - } - if len(f.Fw) == len(fw) { - // Nothing was deleted. - return utils.FakeGoogleAPINotFoundErr() - } - f.Fw = fw - return nil -} - -// GetForwardingRulesWithIPs returns all forwarding rules that match the given ips. -func (f *FakeLoadBalancers) GetForwardingRulesWithIPs(ip []string) (fwRules []*compute.ForwardingRule) { - f.calls = append(f.calls, "GetForwardingRulesWithIPs") - ipSet := sets.NewString(ip...) - for i := range f.Fw { - if ipSet.Has(f.Fw[i].IPAddress) { - fwRules = append(fwRules, f.Fw[i]) - } - } - return fwRules -} - -// UrlMaps fakes - -// GetURLMap fakes getting url maps from the cloud. -func (f *FakeLoadBalancers) GetURLMap(name string) (*compute.UrlMap, error) { - f.calls = append(f.calls, "GetURLMap") - for i := range f.Um { - if f.Um[i].Name == name { - return f.Um[i], nil - } - } - return nil, utils.FakeGoogleAPINotFoundErr() -} - -// CreateURLMap fakes url-map creation. -func (f *FakeLoadBalancers) CreateURLMap(urlMap *compute.UrlMap) error { - klog.V(4).Infof("CreateURLMap %+v", urlMap) - f.calls = append(f.calls, "CreateURLMap") - urlMap.SelfLink = cloud.NewUrlMapsResourceID("mock-project", urlMap.Name).SelfLink(meta.VersionGA) - f.Um = append(f.Um, urlMap) - return nil -} - -// UpdateURLMap fakes updating url-maps. -func (f *FakeLoadBalancers) UpdateURLMap(urlMap *compute.UrlMap) error { - f.calls = append(f.calls, "UpdateURLMap") - for i := range f.Um { - if f.Um[i].Name == urlMap.Name { - f.Um[i] = urlMap - return nil - } - } - return utils.FakeGoogleAPINotFoundErr() -} - -// DeleteURLMap fakes url-map deletion. -func (f *FakeLoadBalancers) DeleteURLMap(name string) error { - f.calls = append(f.calls, "DeleteURLMap") - um := []*compute.UrlMap{} - for i := range f.Um { - if f.Um[i].Name != name { - um = append(um, f.Um[i]) - } - } - if len(f.Um) == len(um) { - // Nothing was deleted. - return utils.FakeGoogleAPINotFoundErr() - } - f.Um = um - return nil -} - -// ListURLMaps fakes getting url maps from the cloud. -func (f *FakeLoadBalancers) ListURLMaps() ([]*compute.UrlMap, error) { - f.calls = append(f.calls, "ListURLMaps") - return f.Um, nil -} - -// TargetProxies fakes - -// GetTargetHTTPProxy fakes getting target http proxies from the cloud. -func (f *FakeLoadBalancers) GetTargetHTTPProxy(name string) (*compute.TargetHttpProxy, error) { - f.calls = append(f.calls, "GetTargetHTTPProxy") - for i := range f.Tp { - if f.Tp[i].Name == name { - return f.Tp[i], nil - } - } - return nil, utils.FakeGoogleAPINotFoundErr() -} - -// CreateTargetHTTPProxy fakes creating a target http proxy. -func (f *FakeLoadBalancers) CreateTargetHTTPProxy(proxy *compute.TargetHttpProxy) error { - f.calls = append(f.calls, "CreateTargetHTTPProxy") - proxy.SelfLink = cloud.NewTargetHttpProxiesResourceID("mock-project", proxy.Name).SelfLink(meta.VersionGA) - f.Tp = append(f.Tp, proxy) - return nil -} - -// DeleteTargetHTTPProxy fakes deleting a target http proxy. -func (f *FakeLoadBalancers) DeleteTargetHTTPProxy(name string) error { - f.calls = append(f.calls, "DeleteTargetHTTPProxy") - tp := []*compute.TargetHttpProxy{} - for i := range f.Tp { - if f.Tp[i].Name != name { - tp = append(tp, f.Tp[i]) - } - } - if len(f.Tp) == len(tp) { - // Nothing was deleted. - return utils.FakeGoogleAPINotFoundErr() - } - f.Tp = tp - return nil -} - -// SetURLMapForTargetHTTPProxy fakes setting an url-map for a target http proxy. -func (f *FakeLoadBalancers) SetURLMapForTargetHTTPProxy(proxy *compute.TargetHttpProxy, urlMapLink string) error { - f.calls = append(f.calls, "SetURLMapForTargetHTTPProxy") - for i := range f.Tp { - if f.Tp[i].Name == proxy.Name { - f.Tp[i].UrlMap = urlMapLink - } - } - return nil -} - -// TargetHttpsProxy fakes - -// GetTargetHTTPSProxy fakes getting target http proxies from the cloud. -func (f *FakeLoadBalancers) GetTargetHTTPSProxy(name string) (*compute.TargetHttpsProxy, error) { - f.calls = append(f.calls, "GetTargetHTTPSProxy") - for i := range f.Tps { - if f.Tps[i].Name == name { - return f.Tps[i], nil - } - } - return nil, utils.FakeGoogleAPINotFoundErr() -} - -// CreateTargetHTTPSProxy fakes creating a target http proxy. -func (f *FakeLoadBalancers) CreateTargetHTTPSProxy(proxy *compute.TargetHttpsProxy) error { - f.calls = append(f.calls, "CreateTargetHTTPSProxy") - proxy.SelfLink = cloud.NewTargetHttpProxiesResourceID("mock-project", proxy.Name).SelfLink(meta.VersionGA) - f.Tps = append(f.Tps, proxy) - return nil -} - -// DeleteTargetHTTPSProxy fakes deleting a target http proxy. -func (f *FakeLoadBalancers) DeleteTargetHTTPSProxy(name string) error { - f.calls = append(f.calls, "DeleteTargetHTTPSProxy") - tp := []*compute.TargetHttpsProxy{} - for i := range f.Tps { - if f.Tps[i].Name != name { - tp = append(tp, f.Tps[i]) - } - } - if len(f.Tps) == len(tp) { - // Nothing was deleted. - return utils.FakeGoogleAPINotFoundErr() - } - f.Tps = tp - return nil -} - -// SetURLMapForTargetHTTPSProxy fakes setting an url-map for a target http proxy. -func (f *FakeLoadBalancers) SetURLMapForTargetHTTPSProxy(proxy *compute.TargetHttpsProxy, urlMapLink string) error { - f.calls = append(f.calls, "SetURLMapForTargetHTTPSProxy") - for i := range f.Tps { - if f.Tps[i].Name == proxy.Name { - f.Tps[i].UrlMap = urlMapLink - } - } - return nil -} - -// SetSslCertificateForTargetHTTPProxy fakes out setting certificates. -func (f *FakeLoadBalancers) SetSslCertificateForTargetHTTPSProxy(proxy *compute.TargetHttpsProxy, sslCertURLs []string) error { - f.calls = append(f.calls, "SetSslCertificateForTargetHTTPSProxy") - found := false - for i := range f.Tps { - if f.Tps[i].Name == proxy.Name { - if len(sslCertURLs) > TargetProxyCertLimit { - return utils.FakeGoogleAPIForbiddenErr() - } - f.Tps[i].SslCertificates = sslCertURLs - found = true - break - } - } - if !found { - return utils.FakeGoogleAPINotFoundErr() - } - return nil -} - -// Static IP fakes - -// ReserveGlobalAddress fakes out static IP reservation. -func (f *FakeLoadBalancers) ReserveGlobalAddress(addr *compute.Address) error { - f.calls = append(f.calls, "ReserveGlobalAddress") - f.IP = append(f.IP, addr) - return nil -} - -// GetGlobalAddress fakes out static IP retrieval. -func (f *FakeLoadBalancers) GetGlobalAddress(name string) (*compute.Address, error) { - f.calls = append(f.calls, "GetGlobalAddress") - for i := range f.IP { - if f.IP[i].Name == name { - return f.IP[i], nil - } - } - return nil, utils.FakeGoogleAPINotFoundErr() -} - -// DeleteGlobalAddress fakes out static IP deletion. -func (f *FakeLoadBalancers) DeleteGlobalAddress(name string) error { - f.calls = append(f.calls, "DeleteGlobalAddress") - ip := []*compute.Address{} - for i := range f.IP { - if f.IP[i].Name != name { - ip = append(ip, f.IP[i]) - } - } - if len(f.IP) == len(ip) { - // Nothing was deleted. - return utils.FakeGoogleAPINotFoundErr() - } - f.IP = ip - return nil -} - -// SslCertificate fakes - -// GetSslCertificate fakes out getting ssl certs. -func (f *FakeLoadBalancers) GetSslCertificate(name string) (*compute.SslCertificate, error) { - f.calls = append(f.calls, "GetSslCertificate") - for i := range f.Certs { - if f.Certs[i].Name == name { - return f.Certs[i], nil - } - } - return nil, utils.FakeGoogleAPINotFoundErr() -} - -func (f *FakeLoadBalancers) ListSslCertificates() ([]*compute.SslCertificate, error) { - f.calls = append(f.calls, "ListSslCertificates") - return f.Certs, nil -} - -// CreateSslCertificate fakes out certificate creation. -func (f *FakeLoadBalancers) CreateSslCertificate(cert *compute.SslCertificate) (*compute.SslCertificate, error) { - f.calls = append(f.calls, "CreateSslCertificate") - cert.SelfLink = cloud.NewSslCertificatesResourceID("mock-project", cert.Name).SelfLink(meta.VersionGA) - if len(f.Certs) == FakeCertQuota { - // Simulate cert creation failure - return nil, fmt.Errorf("unable to create cert, Exceeded cert limit of %d.", FakeCertQuota) - } - f.Certs = append(f.Certs, cert) - return cert, nil -} - -// DeleteSslCertificate fakes out certificate deletion. -func (f *FakeLoadBalancers) DeleteSslCertificate(name string) error { - f.calls = append(f.calls, "DeleteSslCertificate") - certs := []*compute.SslCertificate{} - for i := range f.Certs { - if f.Certs[i].Name != name { - certs = append(certs, f.Certs[i]) - } - } - if len(f.Certs) == len(certs) { - // Nothing was deleted. - return utils.FakeGoogleAPINotFoundErr() - } - f.Certs = certs - return nil -} - -// NewFakeLoadBalancers creates a fake cloud client. Name is the name -// inserted into the selfLink of the associated resources for testing. -// eg: forwardingRule.SelfLink == k8-fw-name. -func NewFakeLoadBalancers(name string, namer *utils.Namer) *FakeLoadBalancers { - return &FakeLoadBalancers{ - Fw: []*compute.ForwardingRule{}, - name: name, - namer: namer, +func InsertGlobalForwardingRuleHook(ctx context.Context, key *meta.Key, obj *compute.ForwardingRule, m *cloud.MockGlobalForwardingRules) (b bool, e error) { + if obj.IPAddress == "" { + obj.IPAddress = "0.0.0.1" } + return false, nil } diff --git a/pkg/loadbalancers/interfaces.go b/pkg/loadbalancers/interfaces.go index 23f874b4a3..7353978142 100644 --- a/pkg/loadbalancers/interfaces.go +++ b/pkg/loadbalancers/interfaces.go @@ -16,56 +16,6 @@ limitations under the License. package loadbalancers -import ( - compute "google.golang.org/api/compute/v1" -) - -// LoadBalancers is an interface for managing all the gce resources needed by L7 -// loadbalancers. We don't have individual pools for each of these resources -// because none of them are usable (or acquirable) stand-alone, unlinke backends -// and instance groups. The dependency graph: -// ForwardingRule -> UrlMaps -> TargetProxies -type LoadBalancers interface { - // Forwarding Rules - GetGlobalForwardingRule(name string) (*compute.ForwardingRule, error) - CreateGlobalForwardingRule(rule *compute.ForwardingRule) error - DeleteGlobalForwardingRule(name string) error - SetProxyForGlobalForwardingRule(fw, proxy string) error - ListGlobalForwardingRules() ([]*compute.ForwardingRule, error) - - // UrlMaps - GetURLMap(name string) (*compute.UrlMap, error) - CreateURLMap(urlMap *compute.UrlMap) error - UpdateURLMap(urlMap *compute.UrlMap) error - DeleteURLMap(name string) error - ListURLMaps() ([]*compute.UrlMap, error) - - // TargetProxies - GetTargetHTTPProxy(name string) (*compute.TargetHttpProxy, error) - CreateTargetHTTPProxy(proxy *compute.TargetHttpProxy) error - DeleteTargetHTTPProxy(name string) error - SetURLMapForTargetHTTPProxy(proxy *compute.TargetHttpProxy, urlMapLink string) error - - // TargetHttpsProxies - GetTargetHTTPSProxy(name string) (*compute.TargetHttpsProxy, error) - CreateTargetHTTPSProxy(proxy *compute.TargetHttpsProxy) error - DeleteTargetHTTPSProxy(name string) error - SetURLMapForTargetHTTPSProxy(proxy *compute.TargetHttpsProxy, urlMapLink string) error - SetSslCertificateForTargetHTTPSProxy(proxy *compute.TargetHttpsProxy, sslCertURLs []string) error - - // SslCertificates - GetSslCertificate(name string) (*compute.SslCertificate, error) - ListSslCertificates() ([]*compute.SslCertificate, error) - CreateSslCertificate(certs *compute.SslCertificate) (*compute.SslCertificate, error) - DeleteSslCertificate(name string) error - - // Static IP - - ReserveGlobalAddress(addr *compute.Address) error - GetGlobalAddress(name string) (*compute.Address, error) - DeleteGlobalAddress(name string) error -} - // LoadBalancerPool is an interface to manage the cloud resources associated // with a gce loadbalancer. type LoadBalancerPool interface { diff --git a/pkg/loadbalancers/l7.go b/pkg/loadbalancers/l7.go index c118a2dbe2..6d94a0549c 100644 --- a/pkg/loadbalancers/l7.go +++ b/pkg/loadbalancers/l7.go @@ -19,6 +19,7 @@ package loadbalancers import ( "encoding/json" "fmt" + "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" "strings" "k8s.io/apimachinery/pkg/types" @@ -94,7 +95,7 @@ type L7 struct { // runtimeInfo is non-cloudprovider information passed from the controller. runtimeInfo *L7RuntimeInfo // cloud is an interface to manage loadbalancers in the GCE cloud. - cloud LoadBalancers + cloud *gce.Cloud // um is the UrlMap associated with this L7. um *compute.UrlMap // tp is the TargetHTTPProxy associated with this L7. diff --git a/pkg/loadbalancers/l7s.go b/pkg/loadbalancers/l7s.go index 93751e378c..6f729373b6 100644 --- a/pkg/loadbalancers/l7s.go +++ b/pkg/loadbalancers/l7s.go @@ -18,6 +18,7 @@ package loadbalancers import ( "fmt" + "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" "k8s.io/klog" @@ -28,7 +29,7 @@ import ( // L7s implements LoadBalancerPool. type L7s struct { - cloud LoadBalancers + cloud *gce.Cloud namer *utils.Namer recorderProducer events.RecorderProducer } @@ -41,7 +42,7 @@ func (l *L7s) Namer() *utils.Namer { // NewLoadBalancerPool returns a new loadbalancer pool. // - cloud: implements LoadBalancers. Used to sync L7 loadbalancer resources // with the cloud. -func NewLoadBalancerPool(cloud LoadBalancers, namer *utils.Namer, recorderProducer events.RecorderProducer) LoadBalancerPool { +func NewLoadBalancerPool(cloud *gce.Cloud, namer *utils.Namer, recorderProducer events.RecorderProducer) LoadBalancerPool { return &L7s{ cloud: cloud, namer: namer, diff --git a/pkg/loadbalancers/l7s_test.go b/pkg/loadbalancers/l7s_test.go index 9869454ab2..9a95e1fd0f 100644 --- a/pkg/loadbalancers/l7s_test.go +++ b/pkg/loadbalancers/l7s_test.go @@ -291,7 +291,7 @@ func newTestLoadBalancerPool() LoadBalancerPool { return NewLoadBalancerPool(fakeGCECloud, namer, ctx) } -func createFakeLoadbalancer(cloud LoadBalancers, namer *utils.Namer, key string) { +func createFakeLoadbalancer(cloud *gce.Cloud, namer *utils.Namer, key string) { lbName := namer.LoadBalancer(key) cloud.CreateGlobalForwardingRule(&compute.ForwardingRule{Name: namer.ForwardingRule(lbName, utils.HTTPProtocol)}) cloud.CreateTargetHTTPProxy(&compute.TargetHttpProxy{Name: namer.TargetProxy(lbName, utils.HTTPProtocol)}) @@ -299,7 +299,7 @@ func createFakeLoadbalancer(cloud LoadBalancers, namer *utils.Namer, key string) cloud.ReserveGlobalAddress(&compute.Address{Name: namer.ForwardingRule(lbName, utils.HTTPProtocol)}) } -func removeFakeLoadBalancer(cloud LoadBalancers, namer *utils.Namer, key string) { +func removeFakeLoadBalancer(cloud *gce.Cloud, namer *utils.Namer, key string) { lbName := namer.LoadBalancer(key) cloud.DeleteGlobalForwardingRule(namer.ForwardingRule(lbName, utils.HTTPProtocol)) cloud.DeleteTargetHTTPProxy(namer.TargetProxy(lbName, utils.HTTPProtocol)) @@ -307,7 +307,7 @@ func removeFakeLoadBalancer(cloud LoadBalancers, namer *utils.Namer, key string) cloud.DeleteGlobalAddress(namer.ForwardingRule(lbName, utils.HTTPProtocol)) } -func checkFakeLoadBalancer(cloud LoadBalancers, namer *utils.Namer, key string, expectPresent bool) error { +func checkFakeLoadBalancer(cloud *gce.Cloud, namer *utils.Namer, key string, expectPresent bool) error { var err error lbName := namer.LoadBalancer(key) _, err = cloud.GetGlobalForwardingRule(namer.ForwardingRule(lbName, utils.HTTPProtocol)) diff --git a/pkg/loadbalancers/loadbalancers_test.go b/pkg/loadbalancers/loadbalancers_test.go index fc58bfeb11..836b6fca91 100644 --- a/pkg/loadbalancers/loadbalancers_test.go +++ b/pkg/loadbalancers/loadbalancers_test.go @@ -17,11 +17,18 @@ limitations under the License. package loadbalancers import ( + "context" "fmt" - "reflect" + "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud" + "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/meta" + "github.com/GoogleCloudPlatform/k8s-cloud-provider/pkg/cloud/mock" + "google.golang.org/api/googleapi" + "k8s.io/kubernetes/pkg/cloudprovider/providers/gce" + "k8s.io/kubernetes/pkg/util/slice" + "net/http" "testing" - compute "google.golang.org/api/compute/v1" + "google.golang.org/api/compute/v1" extensions "k8s.io/api/extensions/v1beta1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/sets" @@ -46,6 +53,82 @@ var ( testDefaultBeNodePort = utils.ServicePort{NodePort: 30000, Protocol: annotations.ProtocolHTTP} ) +type testJig struct { + pool LoadBalancerPool + fakeGCE *gce.Cloud + mock *cloud.MockGCE + namer *utils.Namer + t *testing.T +} + +func newTestJig(t *testing.T) *testJig { + namer := utils.NewNamer(clusterName, "fw1") + fakeGCE := gce.NewFakeGCECloud(gce.DefaultTestClusterValues()) + mockGCE := fakeGCE.Compute().(*cloud.MockGCE) + + // Add any common hooks needed here, functions can override more specific hooks + mockGCE.MockUrlMaps.UpdateHook = mock.UpdateURLMapHook + mockGCE.MockTargetHttpProxies.SetUrlMapHook = mock.SetURLMapTargetHTTPProxyHook + mockGCE.MockTargetHttpsProxies.SetUrlMapHook = mock.SetURLMapTargetHTTPSProxyHook + mockGCE.MockTargetHttpsProxies.SetSslCertificatesHook = mock.SetSslCertificateTargetHTTPSProxyHook + mockGCE.MockSslCertificates.InsertHook = func(ctx context.Context, key *meta.Key, obj *compute.SslCertificate, m *cloud.MockSslCertificates) (b bool, e error) { + if len(m.Objects) >= FakeCertQuota { + return true, fmt.Errorf("error exceeded fake cert quota") + } + return false, nil + } + mockGCE.MockTargetHttpsProxies.SetSslCertificatesHook = func(ctx context.Context, key *meta.Key, request *compute.TargetHttpsProxiesSetSslCertificatesRequest, proxies *cloud.MockTargetHttpsProxies) error { + tp, err := proxies.Get(ctx, key) + if err != nil { + return &googleapi.Error{ + Code: http.StatusNotFound, + Message: fmt.Sprintf("Key: %s was not found in UrlMaps", key.String()), + } + } + + if len(request.SslCertificates) > TargetProxyCertLimit { + return fmt.Errorf("error exceeded target proxy cert limit") + } + + tp.SslCertificates = request.SslCertificates + return nil + } + mockGCE.MockGlobalForwardingRules.InsertHook = InsertGlobalForwardingRuleHook + + return &testJig{ + pool: newFakeLoadBalancerPool(fakeGCE, t, namer), + fakeGCE: fakeGCE, + mock: mockGCE, + namer: namer, + t: t, + } +} + +func (j *testJig) UMName(lbName string) string { + return j.namer.UrlMap(lbName) +} + +func (j *testJig) TPName(lbName string, https bool) string { + protocol := utils.HTTPProtocol + if https { + protocol = utils.HTTPSProtocol + } + return j.namer.TargetProxy(lbName, protocol) +} + +func (j *testJig) FWName(lbName string, https bool) string { + proto := utils.HTTPProtocol + if https { + proto = utils.HTTPSProtocol + } + return j.namer.ForwardingRule(lbName, proto) +} + +// TODO: (shance) implement this once we switch to composites +func (j *testJig) String() string { + return "testJig.String() Not implemented" +} + func newIngress() *extensions.Ingress { return &extensions.Ingress{ ObjectMeta: metav1.ObjectMeta{ @@ -55,75 +138,74 @@ func newIngress() *extensions.Ingress { } } -func newFakeLoadBalancerPool(f LoadBalancers, t *testing.T, namer *utils.Namer) LoadBalancerPool { +func newFakeLoadBalancerPool(cloud *gce.Cloud, t *testing.T, namer *utils.Namer) LoadBalancerPool { fakeIGs := instances.NewFakeInstanceGroups(sets.NewString(), namer) nodePool := instances.NewNodePool(fakeIGs, namer) nodePool.Init(&instances.FakeZoneLister{Zones: []string{defaultZone}}) - return NewLoadBalancerPool(f, namer, events.RecorderProducerMock{}) + return NewLoadBalancerPool(cloud, namer, events.RecorderProducerMock{}) } func TestCreateHTTPLoadBalancer(t *testing.T) { // This should NOT create the forwarding rule and target proxy // associated with the HTTPS branch of this loadbalancer. + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") lbInfo := &L7RuntimeInfo{ - Name: namer.LoadBalancer(ingressName), + Name: j.namer.LoadBalancer(ingressName), AllowHTTP: true, UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - l7, err := pool.Ensure(lbInfo) + l7, err := j.pool.Ensure(lbInfo) if err != nil || l7 == nil { t.Fatalf("Expected l7 not created, err: %v", err) } - verifyHTTPForwardingRuleAndProxyLinks(t, f) + verifyHTTPForwardingRuleAndProxyLinks(t, j) } func TestCreateHTTPSLoadBalancer(t *testing.T) { // This should NOT create the forwarding rule and target proxy // associated with the HTTP branch of this loadbalancer. + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") lbInfo := &L7RuntimeInfo{ - Name: namer.LoadBalancer(ingressName), + Name: j.namer.LoadBalancer(ingressName), AllowHTTP: false, TLS: []*TLSCerts{createCert("key", "cert", "name")}, UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - l7, err := pool.Ensure(lbInfo) + l7, err := j.pool.Ensure(lbInfo) if err != nil || l7 == nil { t.Fatalf("Expected l7 not created") } - verifyHTTPSForwardingRuleAndProxyLinks(t, f) + verifyHTTPSForwardingRuleAndProxyLinks(t, j) } -func verifyHTTPSForwardingRuleAndProxyLinks(t *testing.T, f *FakeLoadBalancers) { +func verifyHTTPSForwardingRuleAndProxyLinks(t *testing.T, j *testJig) { t.Helper() + lbName := j.namer.LoadBalancer(ingressName) - um, err := f.GetURLMap(f.UMName()) - tps, err := f.GetTargetHTTPSProxy(f.TPName(true)) + um, err := j.fakeGCE.GetURLMap(j.UMName(lbName)) + tps, err := j.fakeGCE.GetTargetHTTPSProxy(j.TPName(lbName, true)) if err != nil { - t.Fatalf("f.GetTargetHTTPSProxy(%q) = _, %v; want nil", f.TPName(true), err) + t.Fatalf("j.fakeGCE.GetTargetHTTPSProxy(%q) = _, %v; want nil", j.TPName(lbName, true), err) } if !utils.EqualResourcePaths(tps.UrlMap, um.SelfLink) { t.Fatalf("tps.UrlMap = %q, want %q", tps.UrlMap, um.SelfLink) } - fws, err := f.GetGlobalForwardingRule(f.FWName(true)) + fws, err := j.fakeGCE.GetGlobalForwardingRule(j.FWName(lbName, true)) if err != nil { - t.Fatalf("f.GetGlobalForwardingRule(%q) = _, %v, want nil", f.FWName(true), err) + t.Fatalf("j.fakeGCE.GetGlobalForwardingRule(%q) = _, %v, want nil", j.FWName(lbName, true), err) } if !utils.EqualResourcePaths(fws.Target, tps.SelfLink) { t.Fatalf("fws.Target = %q, want %q", fws.Target, tps.SelfLink) @@ -133,20 +215,21 @@ func verifyHTTPSForwardingRuleAndProxyLinks(t *testing.T, f *FakeLoadBalancers) } } -func verifyHTTPForwardingRuleAndProxyLinks(t *testing.T, f *FakeLoadBalancers) { +func verifyHTTPForwardingRuleAndProxyLinks(t *testing.T, j *testJig) { t.Helper() + lbName := j.namer.LoadBalancer(ingressName) - um, err := f.GetURLMap(f.UMName()) - tps, err := f.GetTargetHTTPProxy(f.TPName(false)) + um, err := j.fakeGCE.GetURLMap(j.UMName(lbName)) + tps, err := j.fakeGCE.GetTargetHTTPProxy(j.TPName(lbName, false)) if err != nil { - t.Fatalf("f.GetTargetHTTPProxy(%q) = _, %v; want nil", f.TPName(false), err) + t.Fatalf("j.fakeGCE.GetTargetHTTPProxy(%q) = _, %v; want nil", j.TPName(lbName, false), err) } if !utils.EqualResourcePaths(tps.UrlMap, um.SelfLink) { t.Fatalf("tp.UrlMap = %q, want %q", tps.UrlMap, um.SelfLink) } - fws, err := f.GetGlobalForwardingRule(f.FWName(false)) + fws, err := j.fakeGCE.GetGlobalForwardingRule(j.FWName(lbName, false)) if err != nil { - t.Fatalf("f.GetGlobalForwardingRule(%q) = _, %v, want nil", f.FWName(false), err) + t.Fatalf("j.fakeGCE.GetGlobalForwardingRule(%q) = _, %v, want nil", j.FWName(lbName, false), err) } if !utils.EqualResourcePaths(fws.Target, tps.SelfLink) { t.Fatalf("fw.Target = %q, want %q", fws.Target, tps.SelfLink) @@ -159,13 +242,14 @@ func verifyHTTPForwardingRuleAndProxyLinks(t *testing.T, f *FakeLoadBalancers) { // Tests that a certificate is created from the provided Key/Cert combo // and the proxy is updated to another cert when the provided cert changes func TestCertUpdate(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) - certName1 := namer.SSLCertName(lbName, GetCertHash("cert")) - certName2 := namer.SSLCertName(lbName, GetCertHash("cert2")) + lbName := j.namer.LoadBalancer(ingressName) + certName1 := j.namer.SSLCertName(lbName, GetCertHash("cert")) + certName2 := j.namer.SSLCertName(lbName, GetCertHash("cert2")) lbInfo := &L7RuntimeInfo{ Name: lbName, @@ -175,35 +259,33 @@ func TestCertUpdate(t *testing.T) { Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - // Sync first cert - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } // Verify certs t.Logf("lbName=%q, name=%q", lbName, certName1) expectCerts := map[string]string{certName1: lbInfo.TLS[0].Cert} - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Sync with different cert lbInfo.TLS = []*TLSCerts{createCert("key2", "cert2", "name")} - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } expectCerts = map[string]string{certName2: lbInfo.TLS[0].Cert} - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } // Test that multiple secrets with the same certificate value don't cause a sync error. func TestMultipleSecretsWithSameCert(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) + lbName := j.namer.LoadBalancer(ingressName) lbInfo := &L7RuntimeInfo{ Name: lbName, @@ -215,27 +297,26 @@ func TestMultipleSecretsWithSameCert(t *testing.T) { UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) // Sync first cert - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - certName := namer.SSLCertName(lbName, GetCertHash("cert")) + certName := j.namer.SSLCertName(lbName, GetCertHash("cert")) expectCerts := map[string]string{certName: lbInfo.TLS[0].Cert} - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } // Tests that controller can overwrite existing, unused certificates func TestCertCreationWithCollision(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) - certName1 := namer.SSLCertName(lbName, GetCertHash("cert")) - certName2 := namer.SSLCertName(lbName, GetCertHash("cert2")) + lbName := j.namer.LoadBalancer(ingressName) + certName1 := j.namer.SSLCertName(lbName, GetCertHash("cert")) + certName2 := j.namer.SSLCertName(lbName, GetCertHash("cert2")) lbInfo := &L7RuntimeInfo{ Name: lbName, @@ -244,29 +325,27 @@ func TestCertCreationWithCollision(t *testing.T) { UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) // Have the same name used by orphaned cert // Since name of the cert is the same, the contents of Certificate have to be the same too, since name contains a // hash of the contents. - f.CreateSslCertificate(&compute.SslCertificate{ + j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: certName1, Certificate: "cert", SelfLink: "existing", }) // Sync first cert - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } expectCerts := map[string]string{certName1: lbInfo.TLS[0].Cert} - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Create another cert where the name matches that of another cert, but contents are different - xyz != cert2. // Simulates a hash collision - f.CreateSslCertificate(&compute.SslCertificate{ + j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: certName2, Certificate: "xyz", SelfLink: "existing", @@ -274,26 +353,27 @@ func TestCertCreationWithCollision(t *testing.T) { // Sync with different cert lbInfo.TLS = []*TLSCerts{createCert("key2", "cert2", "name")} - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } expectCerts = map[string]string{certName2: "xyz"} // xyz instead of cert2 because the name collided and cert did not get updated. - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } func TestMultipleCertRetentionAfterRestart(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") cert1 := createCert("key", "cert", "name") cert2 := createCert("key2", "cert2", "name2") cert3 := createCert("key3", "cert3", "name3") - lbName := namer.LoadBalancer(ingressName) - certName1 := namer.SSLCertName(lbName, cert1.CertHash) - certName2 := namer.SSLCertName(lbName, cert2.CertHash) - certName3 := namer.SSLCertName(lbName, cert3.CertHash) + lbName := j.namer.LoadBalancer(ingressName) + certName1 := j.namer.SSLCertName(lbName, cert1.CertHash) + certName2 := j.namer.SSLCertName(lbName, cert2.CertHash) + certName3 := j.namer.SSLCertName(lbName, cert3.CertHash) expectCerts := map[string]string{} @@ -306,39 +386,39 @@ func TestMultipleCertRetentionAfterRestart(t *testing.T) { } expectCerts[certName1] = cert1.Cert - f := NewFakeLoadBalancers(lbInfo.Name, namer) - firstPool := newFakeLoadBalancerPool(f, t, namer) + firstPool := j.pool firstPool.Ensure(lbInfo) - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Update config to use 2 certs lbInfo.TLS = []*TLSCerts{cert1, cert2} expectCerts[certName2] = cert2.Cert firstPool.Ensure(lbInfo) - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Restart of controller represented by a new pool - secondPool := newFakeLoadBalancerPool(f, t, namer) + secondPool := newFakeLoadBalancerPool(j.fakeGCE, t, j.namer) secondPool.Ensure(lbInfo) // Verify both certs are still present - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Replace the 2 certs with a different, single cert lbInfo.TLS = []*TLSCerts{cert3} expectCerts = map[string]string{certName3: cert3.Cert} secondPool.Ensure(lbInfo) // Only the new cert should be present - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } //TestUpgradeToNewCertNames verifies that certs uploaded using the old naming convention // are picked up and deleted when upgrading to the new scheme. func TestUpgradeToNewCertNames(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) + lbName := j.namer.LoadBalancer(ingressName) lbInfo := &L7RuntimeInfo{ Name: lbName, AllowHTTP: false, @@ -348,26 +428,24 @@ func TestUpgradeToNewCertNames(t *testing.T) { oldCertName := "k8s-ssl-" + lbInfo.Name tlsCert := createCert("key", "cert", "name") lbInfo.TLS = []*TLSCerts{tlsCert} - newCertName := namer.SSLCertName(lbName, tlsCert.CertHash) - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) + newCertName := j.namer.SSLCertName(lbName, tlsCert.CertHash) // Manually create a target proxy and assign a legacy cert to it. sslCert := &compute.SslCertificate{Name: oldCertName, Certificate: "cert"} - f.CreateSslCertificate(sslCert) - tpName := f.TPName(true) + j.fakeGCE.CreateSslCertificate(sslCert) + tpName := j.TPName(lbName, true) newProxy := &compute.TargetHttpsProxy{ Name: tpName, Description: "fake", SslCertificates: []string{sslCert.SelfLink}, } - err := f.CreateTargetHTTPSProxy(newProxy) + err := j.fakeGCE.CreateTargetHTTPSProxy(newProxy) if err != nil { t.Fatalf("Failed to create Target proxy %v - %v", newProxy, err) } - proxyCerts, err := f.ListSslCertificates() + proxyCerts, err := j.fakeGCE.ListSslCertificates() if err != nil { - t.Fatalf("Failed to list certs for load balancer %v - %v", f, err) + t.Fatalf("Failed to list certs for load balancer %v - %v", j, err) } if len(proxyCerts) != 1 { t.Fatalf("Unexpected number of certs - Expected 1, got %d", len(proxyCerts)) @@ -377,30 +455,31 @@ func TestUpgradeToNewCertNames(t *testing.T) { t.Fatalf("Expected cert with name %s, Got %s", oldCertName, proxyCerts[0].Name) } // Sync should replace this oldCert with one following the new naming scheme - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } // We expect to see only the new cert linked to the proxy and available in the load balancer. expectCerts := map[string]string{newCertName: tlsCert.Cert} - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } // Tests uploading 15 certs which is the limit for the fake loadbalancer. Ensures that creation of the 16th cert fails. // Tests uploading 10 certs which is the target proxy limit. Uploading 11th cert should fail. func TestMaxCertsUpload(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) var tlsCerts []*TLSCerts expectCerts := make(map[string]string) expectCertsExtra := make(map[string]string) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) + lbName := j.namer.LoadBalancer(ingressName) for ix := 0; ix < FakeCertQuota; ix++ { str := strconv.Itoa(ix) tlsCerts = append(tlsCerts, createCert("key-"+str, "cert-"+str, "name-"+str)) - certName := namer.SSLCertName(lbName, GetCertHash("cert-"+str)) + certName := j.namer.SSLCertName(lbName, GetCertHash("cert-"+str)) expectCerts[certName] = "cert-" + str } lbInfo := &L7RuntimeInfo{ @@ -410,63 +489,62 @@ func TestMaxCertsUpload(t *testing.T) { UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) failCert := createCert("key100", "cert100", "name100") lbInfo.TLS = append(lbInfo.TLS, failCert) - _, err := pool.Ensure(lbInfo) + _, err := j.pool.Ensure(lbInfo) if err == nil { t.Fatalf("Creating more than %d certs should have errored out", FakeCertQuota) } - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Set cert count less than cert creation limit but more than target proxy limit lbInfo.TLS = lbInfo.TLS[:TargetProxyCertLimit+1] for _, cert := range lbInfo.TLS { - expectCertsExtra[namer.SSLCertName(lbName, cert.CertHash)] = cert.Cert + expectCertsExtra[j.namer.SSLCertName(lbName, cert.CertHash)] = cert.Cert } - _, err = pool.Ensure(lbInfo) + _, err = j.pool.Ensure(lbInfo) if err == nil { t.Fatalf("Assigning more than %d certs should have errored out", TargetProxyCertLimit) } // load balancer will contain the extra cert, but target proxy will not - verifyCertAndProxyLink(expectCertsExtra, expectCerts, f, t) + verifyCertAndProxyLink(expectCertsExtra, expectCerts, j, t) // Removing the extra cert from ingress spec should delete it lbInfo.TLS = lbInfo.TLS[:TargetProxyCertLimit] - _, err = pool.Ensure(lbInfo) + _, err = j.pool.Ensure(lbInfo) if err != nil { t.Fatalf("Unexpected error %s", err) } expectCerts = make(map[string]string) for _, cert := range lbInfo.TLS { - expectCerts[namer.SSLCertName(lbName, cert.CertHash)] = cert.Cert + expectCerts[j.namer.SSLCertName(lbName, cert.CertHash)] = cert.Cert } - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } // In case multiple certs for the same subject/hostname are uploaded, the certs will be sent in the same order they were // specified, to the targetproxy. The targetproxy will present the first occurring cert for a given hostname to the client. // This test verifies this behavior. func TestIdenticalHostnameCerts(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) var tlsCerts []*TLSCerts expectCerts := make(map[string]string) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) + lbName := j.namer.LoadBalancer(ingressName) contents := "" for ix := 0; ix < 3; ix++ { str := strconv.Itoa(ix) contents = "cert-" + str + " foo.com" tlsCerts = append(tlsCerts, createCert("key-"+str, contents, "name-"+str)) - certName := namer.SSLCertName(lbName, GetCertHash(contents)) + certName := j.namer.SSLCertName(lbName, GetCertHash(contents)) expectCerts[certName] = contents } lbInfo := &L7RuntimeInfo{ @@ -476,45 +554,42 @@ func TestIdenticalHostnameCerts(t *testing.T) { UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) // Sync multiple times to make sure ordering is preserved for i := 0; i < 10; i++ { - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Fetch the target proxy certs and go through in order - verifyProxyCertsInOrder(" foo.com", f, t) - pool.Delete(lbInfo.Name) + verifyProxyCertsInOrder(" foo.com", j, t) + j.pool.Delete(lbInfo.Name) } } func TestIdenticalHostnameCertsPreShared(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") lbInfo := &L7RuntimeInfo{ - Name: namer.LoadBalancer(ingressName), + Name: j.namer.LoadBalancer(ingressName), AllowHTTP: false, UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) // Prepare pre-shared certs. - preSharedCert1, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert1, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert", Certificate: "cert-0 foo.com", SelfLink: "existing", }) - preSharedCert2, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert2, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert1", Certificate: "cert-1 foo.com", SelfLink: "existing", }) - preSharedCert3, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert3, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert2", Certificate: "cert2", SelfLink: "existing", @@ -525,26 +600,27 @@ func TestIdenticalHostnameCertsPreShared(t *testing.T) { lbInfo.TLSName = preSharedCert1.Name + "," + preSharedCert2.Name + "," + preSharedCert3.Name // Sync multiple times to make sure ordering is preserved for i := 0; i < 10; i++ { - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Fetch the target proxy certs and go through in order - verifyProxyCertsInOrder(" foo.com", f, t) - pool.Delete(lbInfo.Name) + verifyProxyCertsInOrder(" foo.com", j, t) + j.pool.Delete(lbInfo.Name) } } // TestPreSharedToSecretBasedCertUpdate updates from pre-shared cert // to secret based cert and verifies the pre-shared cert is retained. func TestPreSharedToSecretBasedCertUpdate(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) - certName1 := namer.SSLCertName(lbName, GetCertHash("cert")) - certName2 := namer.SSLCertName(lbName, GetCertHash("cert2")) + lbName := j.namer.LoadBalancer(ingressName) + certName1 := j.namer.SSLCertName(lbName, GetCertHash("cert")) + certName2 := j.namer.SSLCertName(lbName, GetCertHash("cert2")) lbInfo := &L7RuntimeInfo{ Name: lbName, @@ -553,17 +629,14 @@ func TestPreSharedToSecretBasedCertUpdate(t *testing.T) { Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - // Prepare pre-shared certs. - preSharedCert1, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert1, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert", Certificate: "abc", SelfLink: "existing", }) // Prepare pre-shared certs. - preSharedCert2, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert2, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert2", Certificate: "xyz", SelfLink: "existing", @@ -572,55 +645,56 @@ func TestPreSharedToSecretBasedCertUpdate(t *testing.T) { lbInfo.TLSName = preSharedCert1.Name + "," + preSharedCert2.Name // Sync pre-shared certs. - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } expectCerts := map[string]string{preSharedCert1.Name: preSharedCert1.Certificate, preSharedCert2.Name: preSharedCert2.Certificate} - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Updates from pre-shared cert to secret based cert. lbInfo.TLS = []*TLSCerts{createCert("key", "cert", "name")} lbInfo.TLSName = "" - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } expectCerts[certName1] = lbInfo.TLS[0].Cert // fakeLoadBalancer contains the preshared certs as well, but proxy will use only certName1 expectCertsProxy := map[string]string{certName1: lbInfo.TLS[0].Cert} - verifyCertAndProxyLink(expectCerts, expectCertsProxy, f, t) + verifyCertAndProxyLink(expectCerts, expectCertsProxy, j, t) // Sync a different cert. lbInfo.TLS = []*TLSCerts{createCert("key2", "cert2", "name")} - pool.Ensure(lbInfo) + j.pool.Ensure(lbInfo) delete(expectCerts, certName1) expectCerts[certName2] = lbInfo.TLS[0].Cert expectCertsProxy = map[string]string{certName2: lbInfo.TLS[0].Cert} - verifyCertAndProxyLink(expectCerts, expectCertsProxy, f, t) + verifyCertAndProxyLink(expectCerts, expectCertsProxy, j, t) // Check if pre-shared certs are retained. - if cert, err := f.GetSslCertificate(preSharedCert1.Name); err != nil || cert == nil { + if cert, err := j.fakeGCE.GetSslCertificate(preSharedCert1.Name); err != nil || cert == nil { t.Fatalf("Want pre-shared certificate %v to exist, got none, err: %v", preSharedCert1.Name, err) } - if cert, err := f.GetSslCertificate(preSharedCert2.Name); err != nil || cert == nil { + if cert, err := j.fakeGCE.GetSslCertificate(preSharedCert2.Name); err != nil || cert == nil { t.Fatalf("Want pre-shared certificate %v to exist, got none, err: %v", preSharedCert2.Name, err) } } -func verifyProxyCertsInOrder(hostname string, f *FakeLoadBalancers, t *testing.T) { +func verifyProxyCertsInOrder(hostname string, j *testJig, t *testing.T) { t.Helper() - t.Logf("f =\n%s", f.String()) + t.Logf("f =\n%s", j.String()) - tps, err := f.GetTargetHTTPSProxy(f.TPName(true)) + lbName := j.namer.LoadBalancer(ingressName) + tps, err := j.fakeGCE.GetTargetHTTPSProxy(j.TPName(lbName, true)) if err != nil { - t.Fatalf("expected https proxy to exist: %v, err: %v", f.TPName(true), err) + t.Fatalf("expected https proxy to exist: %v, err: %v", j.TPName(lbName, true), err) } count := 0 tmp := "" for _, link := range tps.SslCertificates { certName, _ := utils.KeyName(link) - cert, err := f.GetSslCertificate(certName) + cert, err := j.fakeGCE.GetSslCertificate(certName) if err != nil { t.Fatalf("Failed to fetch certificate from link %s - %v", link, err) } @@ -640,21 +714,21 @@ func verifyProxyCertsInOrder(hostname string, f *FakeLoadBalancers, t *testing.T // expectCerts is the mapping of certs expected in the FakeLoadBalancer. expectCertsProxy is the mapping of certs expected // to be in use by the target proxy. Both values will be different for the PreSharedToSecretBasedCertUpdate test. // f will contain the preshared as well as secret-based certs, but target proxy will contain only one or the other. -func verifyCertAndProxyLink(expectCerts map[string]string, expectCertsProxy map[string]string, f *FakeLoadBalancers, t *testing.T) { +func verifyCertAndProxyLink(expectCerts map[string]string, expectCertsProxy map[string]string, j *testJig, t *testing.T) { t.Helper() - t.Logf("f =\n%s", f.String()) + t.Logf("f =\n%s", j.String()) // f needs to contain only the certs in expectCerts, nothing more, nothing less - allCerts, err := f.ListSslCertificates() + allCerts, err := j.fakeGCE.ListSslCertificates() if err != nil { - t.Fatalf("Failed to list certificates for %v - %v", f, err) + t.Fatalf("Failed to list certificates for %v - %v", j, err) } if len(expectCerts) != len(allCerts) { - t.Fatalf("Unexpected number of certs in FakeLoadBalancer %v, expected %d, actual %d", f, len(expectCerts), + t.Fatalf("Unexpected number of certs in FakeLoadBalancer %v, expected %d, actual %d", j, len(expectCerts), len(allCerts)) } for certName, certValue := range expectCerts { - cert, err := f.GetSslCertificate(certName) + cert, err := j.fakeGCE.GetSslCertificate(certName) if err != nil { t.Fatalf("expected ssl certificate to exist: %v, err: %v, all certs: %v", certName, err, toCertNames(allCerts)) } @@ -665,9 +739,10 @@ func verifyCertAndProxyLink(expectCerts map[string]string, expectCertsProxy map[ } // httpsproxy needs to contain only the certs in expectCerts, nothing more, nothing less - tps, err := f.GetTargetHTTPSProxy(f.TPName(true)) + lbName := j.namer.LoadBalancer(ingressName) + tps, err := j.fakeGCE.GetTargetHTTPSProxy(j.TPName(lbName, true)) if err != nil { - t.Fatalf("expected https proxy to exist: %v, err: %v", f.TPName(true), err) + t.Fatalf("expected https proxy to exist: %v, err: %v", j.TPName(lbName, true), err) } if len(tps.SslCertificates) != len(expectCertsProxy) { t.Fatalf("Expected https proxy to have %d certs, actual %d", len(expectCertsProxy), len(tps.SslCertificates)) @@ -688,6 +763,8 @@ func verifyCertAndProxyLink(expectCerts map[string]string, expectCertsProxy map[ func TestCreateHTTPSLoadBalancerAnnotationCert(t *testing.T) { // This should NOT create the forwarding rule and target proxy // associated with the HTTP branch of this loadbalancer. + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) @@ -701,54 +778,52 @@ func TestCreateHTTPSLoadBalancerAnnotationCert(t *testing.T) { Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - f.CreateSslCertificate(&compute.SslCertificate{ + j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: tlsName, }) - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - l7, err := pool.Ensure(lbInfo) + l7, err := j.pool.Ensure(lbInfo) if err != nil || l7 == nil { t.Fatalf("Expected l7 not created") } - verifyHTTPSForwardingRuleAndProxyLinks(t, f) + verifyHTTPSForwardingRuleAndProxyLinks(t, j) } func TestCreateBothLoadBalancers(t *testing.T) { // This should create 2 forwarding rules and target proxies // but they should use the same urlmap, and have the same // static ip. + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") lbInfo := &L7RuntimeInfo{ - Name: namer.LoadBalancer(ingressName), + Name: j.namer.LoadBalancer(ingressName), AllowHTTP: true, TLS: []*TLSCerts{{Key: "key", Cert: "cert"}}, UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - l7, err := pool.Ensure(lbInfo) + l7, err := j.pool.Ensure(lbInfo) if err != nil || l7 == nil { t.Fatalf("Expected l7 not created") } - verifyHTTPSForwardingRuleAndProxyLinks(t, f) - verifyHTTPForwardingRuleAndProxyLinks(t, f) + verifyHTTPSForwardingRuleAndProxyLinks(t, j) + verifyHTTPForwardingRuleAndProxyLinks(t, j) // We know the forwarding rules exist, retrieve their addresses. - fws, _ := f.GetGlobalForwardingRule(f.FWName(true)) - fw, _ := f.GetGlobalForwardingRule(f.FWName(false)) - ip, err := f.GetGlobalAddress(f.FWName(false)) + lbName := j.namer.LoadBalancer(ingressName) + fws, _ := j.fakeGCE.GetGlobalForwardingRule(j.FWName(lbName, true)) + fw, _ := j.fakeGCE.GetGlobalForwardingRule(j.FWName(lbName, false)) + ip, err := j.fakeGCE.GetGlobalAddress(j.FWName(lbName, false)) if err != nil { t.Fatalf("%v", err) } @@ -758,20 +833,22 @@ func TestCreateBothLoadBalancers(t *testing.T) { } // verifyURLMap gets the created URLMap and compares it against an expected one. -func verifyURLMap(t *testing.T, f *FakeLoadBalancers, name string, wantGCEURLMap *utils.GCEURLMap) { +func verifyURLMap(t *testing.T, j *testJig, name string, wantGCEURLMap *utils.GCEURLMap) { t.Helper() - um, err := f.GetURLMap(name) + um, err := j.fakeGCE.GetURLMap(name) if err != nil || um == nil { - t.Errorf("f.GetUrlMap(%q) = %v, %v; want _, nil", name, um, err) + t.Errorf("j.fakeGCE.GetUrlMap(%q) = %v, %v; want _, nil", name, um, err) } - wantComputeURLMap := toComputeURLMap(name, wantGCEURLMap, f.namer) + wantComputeURLMap := toComputeURLMap(name, wantGCEURLMap, j.namer) if !mapsEqual(wantComputeURLMap, um) { t.Errorf("mapsEqual() = false, got\n%+v\n want\n%+v", um, wantComputeURLMap) } } func TestUrlMapChange(t *testing.T) { + j := newTestJig(t) + um1 := utils.NewGCEURLMap() um2 := utils.NewGCEURLMap() @@ -788,31 +865,41 @@ func TestUrlMapChange(t *testing.T) { namer := utils.NewNamer(clusterName, "fw1") lbInfo := &L7RuntimeInfo{Name: namer.LoadBalancer(ingressName), AllowHTTP: true, UrlMap: um1, Ingress: newIngress()} - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - l7, err := pool.Ensure(lbInfo) + l7, err := j.pool.Ensure(lbInfo) if err != nil { t.Fatalf("%v", err) } - verifyURLMap(t, f, l7.UrlMap().Name, um1) + verifyURLMap(t, j, l7.UrlMap().Name, um1) // Change url map. lbInfo.UrlMap = um2 - if _, err = pool.Ensure(lbInfo); err != nil { + if _, err = j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - l7, err = pool.Ensure(lbInfo) + l7, err = j.pool.Ensure(lbInfo) if err != nil { t.Fatalf("%v", err) } - verifyURLMap(t, f, l7.UrlMap().Name, um2) + verifyURLMap(t, j, l7.UrlMap().Name, um2) } func TestPoolSyncNoChanges(t *testing.T) { + j := newTestJig(t) + + // Add hook to keep track of how many calls are made. + updateCalls := 0 + j.mock.MockUrlMaps.UpdateHook = func(ctx context.Context, key *meta.Key, obj *compute.UrlMap, m *cloud.MockUrlMaps) error { + updateCalls += 1 + return nil + } + if updateCalls > 0 { + t.Errorf("UpdateUrlMap() should not have been called") + } + um1 := utils.NewGCEURLMap() um2 := utils.NewGCEURLMap() @@ -832,21 +919,17 @@ func TestPoolSyncNoChanges(t *testing.T) { namer := utils.NewNamer(clusterName, "fw1") lbInfo := &L7RuntimeInfo{Name: namer.LoadBalancer(ingressName), AllowHTTP: true, UrlMap: um1, Ingress: newIngress()} - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } lbInfo.UrlMap = um2 - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - for _, call := range f.calls { - if call == "UpdateUrlMap" { - t.Errorf("UpdateUrlMap() should not have been called") - } + if updateCalls > 0 { + t.Errorf("UpdateUrlMap() should not have been called") } } @@ -870,41 +953,39 @@ func TestNameParsing(t *testing.T) { } func TestClusterNameChange(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") lbInfo := &L7RuntimeInfo{ - Name: namer.LoadBalancer(ingressName), + Name: j.namer.LoadBalancer(ingressName), AllowHTTP: true, TLS: []*TLSCerts{{Key: "key", Cert: "cert"}}, UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { - t.Fatalf("pool.Ensure() = err %v", err) + if _, err := j.pool.Ensure(lbInfo); err != nil { + t.Fatalf("j.pool.Ensure() = err %v", err) } - l7, err := pool.Ensure(lbInfo) + l7, err := j.pool.Ensure(lbInfo) if err != nil || l7 == nil { t.Fatalf("Expected l7 not created") } - verifyHTTPSForwardingRuleAndProxyLinks(t, f) - verifyHTTPForwardingRuleAndProxyLinks(t, f) + verifyHTTPSForwardingRuleAndProxyLinks(t, j) + verifyHTTPForwardingRuleAndProxyLinks(t, j) newName := "newName" - namer = pool.(*L7s).Namer() - namer.SetUID(newName) - f.name = fmt.Sprintf("%v--%v", lbInfo.Name, newName) + j.namer.SetUID(newName) // Now the components should get renamed with the next suffix. - l7, err = pool.Ensure(lbInfo) - if err != nil || namer.ParseName(l7.Name).ClusterName != newName { + lbInfo.Name = j.namer.LoadBalancer(ingressName) + l7, err = j.pool.Ensure(lbInfo) + if err != nil || j.namer.ParseName(l7.Name).ClusterName != newName { t.Fatalf("Expected L7 name to change.") } - verifyHTTPSForwardingRuleAndProxyLinks(t, f) - verifyHTTPForwardingRuleAndProxyLinks(t, f) + verifyHTTPSForwardingRuleAndProxyLinks(t, j) + verifyHTTPForwardingRuleAndProxyLinks(t, j) } func TestInvalidClusterNameChange(t *testing.T) { @@ -930,24 +1011,24 @@ func createCert(key string, contents string, name string) *TLSCerts { return &TLSCerts{Key: key, Cert: contents, Name: name, CertHash: GetCertHash(contents)} } -func syncPool(f *FakeLoadBalancers, t *testing.T, namer *utils.Namer, lbInfo *L7RuntimeInfo) { - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { - t.Fatalf("pool.Ensure() = err %v", err) +func syncPool(j *testJig, t *testing.T, lbInfo *L7RuntimeInfo) { + if _, err := j.pool.Ensure(lbInfo); err != nil { + t.Fatalf("j.pool.Ensure() = err %v", err) } - l7, err := pool.Ensure(lbInfo) + l7, err := j.pool.Ensure(lbInfo) if err != nil || l7 == nil { t.Fatalf("Expected l7 not created") } } func TestList(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") lbInfo := &L7RuntimeInfo{ - Name: namer.LoadBalancer(ingressName), + Name: j.namer.LoadBalancer(ingressName), AllowHTTP: true, TLS: []*TLSCerts{{Key: "key", Cert: "cert"}}, UrlMap: gceUrlMap, @@ -961,31 +1042,33 @@ func TestList(t *testing.T) { "k8s-um-old-l7--uid1", // Expect List() to catch old URL maps } - f := NewFakeLoadBalancers(lbInfo.Name, namer) for _, name := range names { - f.CreateURLMap(&compute.UrlMap{Name: name}) + j.fakeGCE.CreateURLMap(&compute.UrlMap{Name: name}) } - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { - t.Fatalf("pool.Ensure() = err %v", err) + if _, err := j.pool.Ensure(lbInfo); err != nil { + t.Fatalf("j.pool.Ensure() = err %v", err) } - lbNames, err := pool.List() + lbNames, err := j.pool.List() if err != nil { - t.Fatalf("pool.List() = err %v", err) + t.Fatalf("j.pool.List() = err %v", err) } expected := []string{"old-l7--uid1", "test--uid1"} - if !reflect.DeepEqual(lbNames, expected) { - t.Fatalf("pool.List() returned %+v, want %+v", lbNames, expected) + if len(lbNames) != 2 || + !slice.ContainsString(lbNames, expected[0], nil) || + !slice.ContainsString(lbNames, expected[1], nil) { + t.Fatalf("j.pool.List() returned %+v, want %+v", lbNames, expected) } } // TestSecretBasedAndPreSharedCerts creates both pre-shared and // secret-based certs and tests that all should be used. func TestSecretBasedAndPreSharedCerts(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) @@ -1001,16 +1084,13 @@ func TestSecretBasedAndPreSharedCerts(t *testing.T) { Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - // Prepare pre-shared certs. - preSharedCert1, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert1, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert", Certificate: "abc", SelfLink: "existing", }) - preSharedCert2, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert2, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert2", Certificate: "xyz", SelfLink: "existing2", @@ -1031,8 +1111,8 @@ func TestSecretBasedAndPreSharedCerts(t *testing.T) { } // Verify that both secret-based and pre-shared certs are used. - pool.Ensure(lbInfo) - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + j.pool.Ensure(lbInfo) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } // TestMaxSecretBasedAndPreSharedCerts uploads 10 secret-based certs, which is the limit for the fake target proxy. @@ -1041,6 +1121,8 @@ func TestSecretBasedAndPreSharedCerts(t *testing.T) { // Trying to use all 15 certs should fail. // After removing 5 secret-based certs, all remaining certs should be used. func TestMaxSecretBasedAndPreSharedCerts(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) @@ -1048,13 +1130,12 @@ func TestMaxSecretBasedAndPreSharedCerts(t *testing.T) { var tlsCerts []*TLSCerts expectCerts := make(map[string]string) expectCertsExtra := make(map[string]string) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) + lbName := j.namer.LoadBalancer(ingressName) for ix := 0; ix < TargetProxyCertLimit; ix++ { str := strconv.Itoa(ix) tlsCerts = append(tlsCerts, createCert("key-"+str, "cert-"+str, "name-"+str)) - certName := namer.SSLCertName(lbName, GetCertHash("cert-"+str)) + certName := j.namer.SSLCertName(lbName, GetCertHash("cert-"+str)) expectCerts[certName] = "cert-" + str expectCertsExtra[certName] = "cert-" + str } @@ -1065,26 +1146,24 @@ func TestMaxSecretBasedAndPreSharedCerts(t *testing.T) { UrlMap: gceUrlMap, Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - if _, err := pool.Ensure(lbInfo); err != nil { - t.Fatalf("pool.Ensure() = err %v", err) + if _, err := j.pool.Ensure(lbInfo); err != nil { + t.Fatalf("j.pool.Ensure() = err %v", err) } - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Create pre-shared certs up to FakeCertQuota. preSharedCerts := []*compute.SslCertificate{} tlsNames := []string{} for ix := TargetProxyCertLimit; ix < FakeCertQuota; ix++ { str := strconv.Itoa(ix) - cert, err := f.CreateSslCertificate(&compute.SslCertificate{ + cert, err := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert-" + str, Certificate: "abc-" + str, SelfLink: "existing-" + str, }) if err != nil { - t.Fatalf("f.CreateSslCertificate() = err %v", err) + t.Fatalf("j.fakeGCE.CreateSslCertificate() = err %v", err) } preSharedCerts = append(preSharedCerts, cert) tlsNames = append(tlsNames, cert.Name) @@ -1092,7 +1171,7 @@ func TestMaxSecretBasedAndPreSharedCerts(t *testing.T) { } lbInfo.TLSName = strings.Join(tlsNames, ",") - _, err := f.CreateSslCertificate(&compute.SslCertificate{ + _, err := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert-100", Certificate: "abc-100", SelfLink: "existing-100", @@ -1104,37 +1183,38 @@ func TestMaxSecretBasedAndPreSharedCerts(t *testing.T) { // Trying to use more than TargetProxyCertLimit certs should fail. // Verify that secret-based certs are still used, // and the loadbalancer also contains pre-shared certs. - if _, err := pool.Ensure(lbInfo); err == nil { + if _, err := j.pool.Ensure(lbInfo); err == nil { t.Fatalf("Trying to use more than %d certs should have errored out", TargetProxyCertLimit) } - verifyCertAndProxyLink(expectCertsExtra, expectCerts, f, t) + verifyCertAndProxyLink(expectCertsExtra, expectCerts, j, t) // Remove enough secret-based certs to make room for pre-shared certs. lbInfo.TLS = lbInfo.TLS[:TargetProxyCertLimit-len(preSharedCerts)] expectCerts = make(map[string]string) for _, cert := range lbInfo.TLS { - expectCerts[namer.SSLCertName(lbName, cert.CertHash)] = cert.Cert + expectCerts[j.namer.SSLCertName(lbName, cert.CertHash)] = cert.Cert } for _, cert := range preSharedCerts { expectCerts[cert.Name] = cert.Certificate } - if _, err = pool.Ensure(lbInfo); err != nil { - t.Fatalf("pool.Ensure() = err %v", err) + if _, err = j.pool.Ensure(lbInfo); err != nil { + t.Fatalf("j.pool.Ensure() = err %v", err) } - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } // TestSecretBasedToPreSharedCertUpdate updates from secret-based cert // to pre-shared cert and verifies the secret-based cert is still used, // until the secret is removed. func TestSecretBasedToPreSharedCertUpdate(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) - certName1 := namer.SSLCertName(lbName, GetCertHash("cert")) + lbName := j.namer.LoadBalancer(ingressName) + certName1 := j.namer.SSLCertName(lbName, GetCertHash("cert")) lbInfo := &L7RuntimeInfo{ Name: lbName, @@ -1143,20 +1223,17 @@ func TestSecretBasedToPreSharedCertUpdate(t *testing.T) { Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - // Sync secret based cert. lbInfo.TLS = []*TLSCerts{createCert("key", "cert", "name")} lbInfo.TLSName = "" - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } expectCerts := map[string]string{certName1: lbInfo.TLS[0].Cert} - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Prepare pre-shared cert. - preSharedCert1, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert1, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert", Certificate: "abc", SelfLink: "existing", @@ -1164,30 +1241,31 @@ func TestSecretBasedToPreSharedCertUpdate(t *testing.T) { lbInfo.TLSName = preSharedCert1.Name // Sync certs. - if _, err := pool.Ensure(lbInfo); err != nil { - t.Fatalf("pool.Ensure() = err %v", err) + if _, err := j.pool.Ensure(lbInfo); err != nil { + t.Fatalf("j.pool.Ensure() = err %v", err) } expectCerts[preSharedCert1.Name] = preSharedCert1.Certificate - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Delete the secret. lbInfo.TLS = []*TLSCerts{} - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } delete(expectCerts, certName1) - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) } // TestSecretBasedToPreSharedCertUpdateWithErrors tries to incorrectly update from secret-based cert // to pre-shared cert, verifying that the secret-based cert is retained. func TestSecretBasedToPreSharedCertUpdateWithErrors(t *testing.T) { + j := newTestJig(t) + gceUrlMap := utils.NewGCEURLMap() gceUrlMap.DefaultBackend = &utils.ServicePort{NodePort: 31234} gceUrlMap.PutPathRulesForHost("bar.example.com", []utils.PathRule{utils.PathRule{Path: "/bar", Backend: utils.ServicePort{NodePort: 30000}}}) - namer := utils.NewNamer(clusterName, "fw1") - lbName := namer.LoadBalancer(ingressName) - certName1 := namer.SSLCertName(lbName, GetCertHash("cert")) + lbName := j.namer.LoadBalancer(ingressName) + certName1 := j.namer.SSLCertName(lbName, GetCertHash("cert")) lbInfo := &L7RuntimeInfo{ Name: lbName, @@ -1196,20 +1274,17 @@ func TestSecretBasedToPreSharedCertUpdateWithErrors(t *testing.T) { Ingress: newIngress(), } - f := NewFakeLoadBalancers(lbInfo.Name, namer) - pool := newFakeLoadBalancerPool(f, t, namer) - // Sync secret based cert. lbInfo.TLS = []*TLSCerts{createCert("key", "cert", "name")} lbInfo.TLSName = "" - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } expectCerts := map[string]string{certName1: lbInfo.TLS[0].Cert} - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) // Prepare pre-shared certs. - preSharedCert1, _ := f.CreateSslCertificate(&compute.SslCertificate{ + preSharedCert1, _ := j.fakeGCE.CreateSslCertificate(&compute.SslCertificate{ Name: "test-pre-shared-cert", Certificate: "abc", SelfLink: "existing", @@ -1217,18 +1292,18 @@ func TestSecretBasedToPreSharedCertUpdateWithErrors(t *testing.T) { // Typo in the cert name. lbInfo.TLSName = preSharedCert1.Name + "typo" - if _, err := pool.Ensure(lbInfo); err == nil { + if _, err := j.pool.Ensure(lbInfo); err == nil { t.Fatalf("pool.Ensure() should have errored out because of the wrong cert name") } expectCertsProxy := map[string]string{certName1: lbInfo.TLS[0].Cert} expectCerts[preSharedCert1.Name] = preSharedCert1.Certificate // pre-shared cert is not used by the target proxy. - verifyCertAndProxyLink(expectCerts, expectCertsProxy, f, t) + verifyCertAndProxyLink(expectCerts, expectCertsProxy, j, t) // Fix the typo. lbInfo.TLSName = preSharedCert1.Name - if _, err := pool.Ensure(lbInfo); err != nil { + if _, err := j.pool.Ensure(lbInfo); err != nil { t.Fatalf("pool.Ensure() = err %v", err) } - verifyCertAndProxyLink(expectCerts, expectCerts, f, t) + verifyCertAndProxyLink(expectCerts, expectCerts, j, t) }