From d234bb097662dd48fe591f9cad3cb555603ec9bd Mon Sep 17 00:00:00 2001 From: Darick Tong Date: Fri, 25 Oct 2019 11:05:33 -0700 Subject: [PATCH] Support multiple pre-shared-certs. --- .../gcp/loadbalancer/loadbalancersyncer.go | 7 +-- .../pkg/gcp/sslcert/fake_sslcertsyncer.go | 6 +- app/kubemci/pkg/gcp/sslcert/interfaces.go | 10 +-- app/kubemci/pkg/gcp/sslcert/sslcertsyncer.go | 36 +++++++---- .../pkg/gcp/sslcert/sslcertsyncer_test.go | 61 +++++++++++-------- .../gcp/targetproxy/fake_targetproxysyncer.go | 10 +-- app/kubemci/pkg/gcp/targetproxy/interfaces.go | 2 +- .../pkg/gcp/targetproxy/targetproxysyncer.go | 16 ++--- .../gcp/targetproxy/targetproxysyncer_test.go | 37 ++++++++--- 9 files changed, 110 insertions(+), 75 deletions(-) diff --git a/app/kubemci/pkg/gcp/loadbalancer/loadbalancersyncer.go b/app/kubemci/pkg/gcp/loadbalancer/loadbalancersyncer.go index 8cb4db365..33136723f 100644 --- a/app/kubemci/pkg/gcp/loadbalancer/loadbalancersyncer.go +++ b/app/kubemci/pkg/gcp/loadbalancer/loadbalancersyncer.go @@ -185,15 +185,14 @@ func (l *Syncer) CreateLoadBalancer(ing *v1beta1.Ingress, forceUpdate, validate if (ingAnnotations.UseNamedTLS() != "") || len(ing.Spec.TLS) > 0 { // Note that we expect to load the cert from any cluster, // so users are required to create the secret in all clusters. - certLink, cErr := l.scs.EnsureSSLCert(l.lbName, ing, client, forceUpdate) + certLinks, cErr := l.scs.EnsureSSLCerts(l.lbName, ing, client, forceUpdate) if cErr != nil { // Aggregate errors and return all at the end. cErr = fmt.Errorf("Error ensuring SSL certs: %s", cErr) fmt.Println(cErr) err = multierror.Append(err, cErr) } - - tpLink, tpErr := l.tps.EnsureHTTPSTargetProxy(l.lbName, umLink, certLink, forceUpdate) + tpLink, tpErr := l.tps.EnsureHTTPSTargetProxy(l.lbName, umLink, certLinks, forceUpdate) if tpErr != nil { // Aggregate errors and return all at the end. tpErr = fmt.Errorf("Error ensuring HTTPS target proxy: %s", tpErr) @@ -246,7 +245,7 @@ func (l *Syncer) DeleteLoadBalancer(ing *v1beta1.Ingress, forceDelete bool) erro // Aggregate errors and return all at the end. err = multierror.Append(err, tpErr) } - if scErr := l.scs.DeleteSSLCert(); scErr != nil { + if scErr := l.scs.DeleteSSLCerts(); scErr != nil { // Aggregate errors and return all at the end. err = multierror.Append(err, scErr) } diff --git a/app/kubemci/pkg/gcp/sslcert/fake_sslcertsyncer.go b/app/kubemci/pkg/gcp/sslcert/fake_sslcertsyncer.go index 35e3dae3c..3e7e1d2b6 100644 --- a/app/kubemci/pkg/gcp/sslcert/fake_sslcertsyncer.go +++ b/app/kubemci/pkg/gcp/sslcert/fake_sslcertsyncer.go @@ -45,17 +45,17 @@ var _ SyncerInterface = &fakeSSLCertSyncer{} // EnsureSSLCert ensures that the required ssl certs exist for the given load balancer. // See interface for more details. -func (f *fakeSSLCertSyncer) EnsureSSLCert(lbName string, ing *v1beta1.Ingress, client kubeclient.Interface, forceUpdate bool) (string, error) { +func (f *fakeSSLCertSyncer) EnsureSSLCerts(lbName string, ing *v1beta1.Ingress, client kubeclient.Interface, forceUpdate bool) ([]string, error) { f.EnsuredSSLCerts = append(f.EnsuredSSLCerts, fakeSSLCert{ LBName: lbName, Ingress: ing, }) - return FakeSSLCertSelfLink, nil + return []string{FakeSSLCertSelfLink}, nil } // DeleteSSLCert deletes the ssl certs that EnsureSSLCert would have created. // See interface for more details. -func (f *fakeSSLCertSyncer) DeleteSSLCert() error { +func (f *fakeSSLCertSyncer) DeleteSSLCerts() error { f.EnsuredSSLCerts = nil return nil } diff --git a/app/kubemci/pkg/gcp/sslcert/interfaces.go b/app/kubemci/pkg/gcp/sslcert/interfaces.go index 45fad256a..0d53c2fc0 100644 --- a/app/kubemci/pkg/gcp/sslcert/interfaces.go +++ b/app/kubemci/pkg/gcp/sslcert/interfaces.go @@ -22,10 +22,10 @@ import ( // SyncerInterface is an interface to manage GCP ssl certs. type SyncerInterface interface { - // EnsureSSLCert ensures that the required ssl cert exists for the given ingress. - // Will only change an existing SSL cert if forceUpdate=True. + // EnsureSSLCerts ensures that the required ssl cert exists for the given ingress. + // Will only change existing SSL certs if forceUpdate=True. // Returns the self link for the ensured ssl cert. - EnsureSSLCert(lbName string, ing *v1beta1.Ingress, client kubeclient.Interface, forceUpdate bool) (string, error) - // DeleteSSLCert deletes the ssl cert that EnsureSSLCert would have created. - DeleteSSLCert() error + EnsureSSLCerts(lbName string, ing *v1beta1.Ingress, client kubeclient.Interface, forceUpdate bool) ([]string, error) + // DeleteSSLCerts deletes the ssl certs that EnsureSSLCerts would have created. + DeleteSSLCerts() error } diff --git a/app/kubemci/pkg/gcp/sslcert/sslcertsyncer.go b/app/kubemci/pkg/gcp/sslcert/sslcertsyncer.go index d6c001570..a433b3a5f 100644 --- a/app/kubemci/pkg/gcp/sslcert/sslcertsyncer.go +++ b/app/kubemci/pkg/gcp/sslcert/sslcertsyncer.go @@ -18,6 +18,7 @@ import ( "fmt" "net/http" "reflect" + "strings" compute "google.golang.org/api/compute/v1" @@ -53,27 +54,36 @@ var _ SyncerInterface = &Syncer{} // EnsureSSLCert ensures that the required ssl certs exist for the given ingress. // See the interface for more details. -func (s *Syncer) EnsureSSLCert(lbName string, ing *v1beta1.Ingress, client kubeclient.Interface, forceUpdate bool) (string, error) { +func (s *Syncer) EnsureSSLCerts(lbName string, ing *v1beta1.Ingress, client kubeclient.Interface, forceUpdate bool) ([]string, error) { fmt.Println("Ensuring ssl cert") annotations := annotations.FromIngress(ing) if annotations.UseNamedTLS() != "" { - return s.ensurePreSharedSSLCert(lbName, ing, forceUpdate) + return s.ensurePreSharedSSLCerts(lbName, ing, forceUpdate) } - return s.ensureSecretSSLCert(lbName, ing, client, forceUpdate) + // TODO: Support multiple secret SSL certs. + cert, err := s.ensureSecretSSLCert(lbName, ing, client, forceUpdate) + if err != nil { + return nil, err + } + return []string{cert}, err } -func (s *Syncer) ensurePreSharedSSLCert(lbName string, ing *v1beta1.Ingress, forceUpdate bool) (string, error) { +func (s *Syncer) ensurePreSharedSSLCerts(lbName string, ing *v1beta1.Ingress, forceUpdate bool) ([]string, error) { ingAnnotations := annotations.FromIngress(ing) - certName := ingAnnotations.UseNamedTLS() - if certName == "" { - return "", fmt.Errorf("unexpected empty value for %s annotation", annotations.PreSharedCertKey) + certNames := ingAnnotations.UseNamedTLS() + if certNames == "" { + return nil, fmt.Errorf("unexpected empty value for %s annotation", annotations.PreSharedCertKey) } - // Fetch the certificate and return its self link. - cert, err := s.scp.GetSslCertificate(certName) - if err != nil { - return "", err + var certs []string + for _, certName := range strings.Split(certNames, ",") { + // Fetch the certificate and return its self link. + cert, err := s.scp.GetSslCertificate(certName) + if err != nil { + return nil, err + } + certs = append(certs, cert.SelfLink) } - return cert.SelfLink, nil + return certs, nil } func (s *Syncer) ensureSecretSSLCert(lbName string, ing *v1beta1.Ingress, client kubeclient.Interface, forceUpdate bool) (string, error) { @@ -110,7 +120,7 @@ func (s *Syncer) ensureSecretSSLCert(lbName string, ing *v1beta1.Ingress, client // DeleteSSLCert deletes the ssl certs that EnsureSSLCert would have created. // See the interface for more details. -func (s *Syncer) DeleteSSLCert() error { +func (s *Syncer) DeleteSSLCerts() error { name := s.namer.SSLCertName() fmt.Println("Deleting SSL cert", name) err := s.scp.DeleteSslCertificate(name) diff --git a/app/kubemci/pkg/gcp/sslcert/sslcertsyncer_test.go b/app/kubemci/pkg/gcp/sslcert/sslcertsyncer_test.go index 3070113ad..29c136a7b 100644 --- a/app/kubemci/pkg/gcp/sslcert/sslcertsyncer_test.go +++ b/app/kubemci/pkg/gcp/sslcert/sslcertsyncer_test.go @@ -34,7 +34,7 @@ import ( "github.com/golang/glog" ) -func TestEnsureSSLCertForSecret(t *testing.T) { +func TestEnsureSSLCertsForSecret(t *testing.T) { lbName := "lb-name" scp := ingresslb.NewFakeLoadBalancers("" /* name */, nil /* namer */) namer := utilsnamer.NewNamer("mci1", lbName) @@ -79,10 +79,10 @@ func TestEnsureSSLCertForSecret(t *testing.T) { } ing, client := setupIng(true /* withSecret */) - if _, err := scs.EnsureSSLCert(lbName, ing, client, false /*forceUpdate*/); err != nil { + if _, err := scs.EnsureSSLCerts(lbName, ing, client, false /*forceUpdate*/); err != nil { for _, c := range testCases { glog.Infof("\nTest case: %s", c.desc) - ensuredCertName, err := scs.EnsureSSLCert(c.lBName, ing, client, c.forceUpdate) + ensuredCertNames, err := scs.EnsureSSLCerts(c.lBName, ing, client, c.forceUpdate) if (err != nil) != c.ensureErr { t.Errorf("Ensuring SSL cert... expected err? %v. actual: %v", c.ensureErr, err) } @@ -90,8 +90,8 @@ func TestEnsureSSLCertForSecret(t *testing.T) { t.Logf("Skipping validation.") continue } - if ensuredCertName != certName { - t.Errorf("unexpected cert name, expected: %s, actual: %s", certName, ensuredCertName) + if ensuredCertNames[0] != certName { + t.Errorf("unexpected cert name, expected: %s, actual: %s", certName, ensuredCertNames[0]) } // Verify that GET does not return NotFound. cert, err := scp.GetSslCertificate(certName) @@ -105,44 +105,53 @@ func TestEnsureSSLCertForSecret(t *testing.T) { } } -func TestEnsureSSLCertForPreShared(t *testing.T) { +func TestEnsureSSLCertsForPreShared(t *testing.T) { lbName := "lb-name" - certName := "testCert" + certNames := []string{"testCert1", "testCert2"} scp := ingresslb.NewFakeLoadBalancers("" /* name */, nil /* namer */) namer := utilsnamer.NewNamer("mci1", lbName) scs := NewSSLCertSyncer(namer, scp) // GET should return NotFound. - if _, err := scp.GetSslCertificate(certName); err == nil { - t.Fatalf("expected NotFound error, got nil") + for _, certName := range certNames { + if _, err := scp.GetSslCertificate(certName); err == nil { + t.Fatalf("expected NotFound error, got nil") + } } ing, client := setupIng(false /* withSecret */) - // EnsureSSLCert should give an error when both the secret and pre shared annotation are missing. - _, err := scs.EnsureSSLCert(lbName, ing, client, false /*forceUpdate*/) + // EnsureSSLCerts should give an error when both the secret and pre shared annotation are missing. + _, err := scs.EnsureSSLCerts(lbName, ing, client, false /*forceUpdate*/) if err == nil { t.Errorf("unexpected nil error, expected error since both secret and pre shared cert annotation are missing") } // Adding the annotation without a cert should still return an error. ing.ObjectMeta.Annotations = map[string]string{ - annotations.PreSharedCertKey: certName, + annotations.PreSharedCertKey: strings.Join(certNames, ","), } - _, err = scs.EnsureSSLCert(lbName, ing, client, false /*forceUpdate*/) + _, err = scs.EnsureSSLCerts(lbName, ing, client, false /*forceUpdate*/) if err == nil { t.Errorf("unexpected nil error, expected error since the pre shared cert is missing") } - // EnsureSSLCert should return success if the cert exists as expected. - if _, err := scp.CreateSslCertificate(&compute.SslCertificate{ - Name: certName, - }); err != nil { - t.Errorf("unexpected error in creating ssl cert: %s", err) + // EnsureSSLCerts should return success if the cert exists as expected. + for _, certName := range certNames { + if _, err := scp.CreateSslCertificate(&compute.SslCertificate{ + Name: certName, + }); err != nil { + t.Errorf("unexpected error in creating ssl cert: %s", err) + } } - ensuredCertName, err := scs.EnsureSSLCert(lbName, ing, client, false /*forceUpdate*/) + ensuredCertNames, err := scs.EnsureSSLCerts(lbName, ing, client, false /*forceUpdate*/) if err != nil { t.Errorf("unexpected error in ensuring ssl cert: %s", err) } - if ensuredCertName != certName { - t.Errorf("unexpected ensured cert name, expected: %s, actual: %s", certName, ensuredCertName) + if len(ensuredCertNames) != len(certNames) { + t.Errorf("unexpected number of ensured cert names, expected: %d, actual: %d", len(certNames), len(ensuredCertNames)) + } + for i, certName := range certNames { + if ensuredCertNames[i] != certName { + t.Errorf("unexpected ensured cert name, expected: %s, actual: %s", certName, ensuredCertNames[i]) + } } } @@ -185,26 +194,26 @@ func setupIngAndClientForSecret(ing *v1beta1.Ingress, client *fake.Clientset, se }) } -func TestDeleteSSLCert(t *testing.T) { +func TestDeleteSSLCerts(t *testing.T) { lbName := "lb-name" // Should create the ssl cert as expected. scp := ingresslb.NewFakeLoadBalancers("" /* name */, nil /* namer */) namer := utilsnamer.NewNamer("mci1", lbName) certName := namer.SSLCertName() scs := NewSSLCertSyncer(namer, scp) - // Calling DeleteSSLCert when cert does not exist should not return an error. - if err := scs.DeleteSSLCert(); err != nil { + // Calling DeleteSSLCerts when cert does not exist should not return an error. + if err := scs.DeleteSSLCerts(); err != nil { t.Fatalf("unexpected err while deleting SSL cert that does not exist: %s", err) } ing, client := setupIng(true /* withSecret */) - if _, err := scs.EnsureSSLCert(lbName, ing, client, false /*forceUpdate*/); err != nil { + if _, err := scs.EnsureSSLCerts(lbName, ing, client, false /*forceUpdate*/); err != nil { t.Fatalf("expected no error in ensuring ssl cert, actual: %v", err) } if _, err := scp.GetSslCertificate(certName); err != nil { t.Fatalf("expected nil error, actual: %v", err) } // Verify that GET fails after DELETE - if err := scs.DeleteSSLCert(); err != nil { + if err := scs.DeleteSSLCerts(); err != nil { t.Fatalf("unexpected err while deleting SSL cert: %s", err) } if _, err := scp.GetSslCertificate(certName); err == nil { diff --git a/app/kubemci/pkg/gcp/targetproxy/fake_targetproxysyncer.go b/app/kubemci/pkg/gcp/targetproxy/fake_targetproxysyncer.go index dad699507..9916ad499 100644 --- a/app/kubemci/pkg/gcp/targetproxy/fake_targetproxysyncer.go +++ b/app/kubemci/pkg/gcp/targetproxy/fake_targetproxysyncer.go @@ -23,7 +23,7 @@ type fakeTargetProxy struct { LBName string UmLink string // Link to the SSL certificate. This is present only for HTTPS target proxies. - CertLink string + CertLinks []string } // FakeTargetProxySyncer is a fake implementation of SyncerInterface to be used in tests. @@ -52,11 +52,11 @@ func (f *FakeTargetProxySyncer) EnsureHTTPTargetProxy(lbName, umLink string, for // EnsureHTTPSTargetProxy ensures that a https target proxy exists for the given load balancer. // See interface comments for details. -func (f *FakeTargetProxySyncer) EnsureHTTPSTargetProxy(lbName, umLink, certLink string, forceUpdate bool) (string, error) { +func (f *FakeTargetProxySyncer) EnsureHTTPSTargetProxy(lbName, umLink string, certLinks []string, forceUpdate bool) (string, error) { f.EnsuredTargetProxies = append(f.EnsuredTargetProxies, fakeTargetProxy{ - LBName: lbName, - UmLink: umLink, - CertLink: certLink, + LBName: lbName, + UmLink: umLink, + CertLinks: certLinks, }) return FakeTargetProxySelfLink, nil } diff --git a/app/kubemci/pkg/gcp/targetproxy/interfaces.go b/app/kubemci/pkg/gcp/targetproxy/interfaces.go index 8007a4d20..a732a8399 100644 --- a/app/kubemci/pkg/gcp/targetproxy/interfaces.go +++ b/app/kubemci/pkg/gcp/targetproxy/interfaces.go @@ -27,7 +27,7 @@ type SyncerInterface interface { // overwrite an existing and different http target proxy if forceUpdate // is true. // Returns the self link for the ensured proxy. - EnsureHTTPSTargetProxy(lbName, urlMapLink, certLink string, forceUpdate bool) (string, error) + EnsureHTTPSTargetProxy(lbName, urlMapLink string, certLinks []string, forceUpdate bool) (string, error) // DeleteTargetProxies deletes the target proxies that EnsureHTTPTargetProxy // and EnsureHTTPSTargetProxy would have created. DeleteTargetProxies() error diff --git a/app/kubemci/pkg/gcp/targetproxy/targetproxysyncer.go b/app/kubemci/pkg/gcp/targetproxy/targetproxysyncer.go index 347760e86..c0b964b10 100644 --- a/app/kubemci/pkg/gcp/targetproxy/targetproxysyncer.go +++ b/app/kubemci/pkg/gcp/targetproxy/targetproxysyncer.go @@ -63,10 +63,10 @@ func (s *Syncer) EnsureHTTPTargetProxy(lbName, umLink string, forceUpdate bool) // EnsureHTTPSTargetProxy ensures that the required https target proxy exists for the given url map. // Does nothing if it exists already, else creates a new one. -func (s *Syncer) EnsureHTTPSTargetProxy(lbName, umLink, certLink string, forceUpdate bool) (string, error) { +func (s *Syncer) EnsureHTTPSTargetProxy(lbName, umLink string, certLinks []string, forceUpdate bool) (string, error) { fmt.Println("Ensuring http target proxy.") var err error - tpLink, proxyErr := s.ensureHTTPSProxy(lbName, umLink, certLink, forceUpdate) + tpLink, proxyErr := s.ensureHTTPSProxy(lbName, umLink, certLinks, forceUpdate) if proxyErr != nil { proxyErr = fmt.Errorf("Error in ensuring https target proxy: %s", proxyErr) err = multierror.Append(err, proxyErr) @@ -147,8 +147,8 @@ func (s *Syncer) updateHTTPTargetProxy(desiredHTTPProxy *compute.TargetHttpProxy name := desiredHTTPProxy.Name fmt.Println("Updating existing target http proxy", name, "to match the desired state") // There is no UpdateTargetHTTPProxy method. - // Apart from name, UrlMap is the only field that can be different. We update that field directly. - // TODO(nikhiljindal): Handle description field differences: + // We can only update the UrlMap via SetUrlMapForTargetHttpProxy. + // TODO(nikhiljindal): Handle sslcert and description field differences: // https://github.com/GoogleCloudPlatform/k8s-multicluster-ingress/issues/94. urlMap := &compute.UrlMap{SelfLink: desiredHTTPProxy.UrlMap} glog.Infof("Setting URL Map to:%+v", urlMap) @@ -211,9 +211,9 @@ func (s *Syncer) desiredHTTPTargetProxy(lbName, umLink string) *compute.TargetHt // ensureHTTPSProxy ensures that the required target proxy exists for the given port. // Does nothing if it exists already, else creates a new one. // Returns the self link for the ensured https proxy. -func (s *Syncer) ensureHTTPSProxy(lbName, umLink, certLink string, forceUpdate bool) (string, error) { +func (s *Syncer) ensureHTTPSProxy(lbName, umLink string, certLinks []string, forceUpdate bool) (string, error) { fmt.Println("Ensuring target https proxy") - desiredHTTPSProxy := s.desiredHTTPSTargetProxy(lbName, umLink, certLink) + desiredHTTPSProxy := s.desiredHTTPSTargetProxy(lbName, umLink, certLinks) name := desiredHTTPSProxy.Name // Check if target proxy already exists. existingHTTPSProxy, err := s.tpp.GetTargetHttpsProxy(name) @@ -292,12 +292,12 @@ func targetHTTPSProxyMatches(desiredHTTPSProxy, existingHTTPSProxy compute.Targe } return equal } -func (s *Syncer) desiredHTTPSTargetProxy(lbName, umLink, certLink string) *compute.TargetHttpsProxy { +func (s *Syncer) desiredHTTPSTargetProxy(lbName, umLink string, certLinks []string) *compute.TargetHttpsProxy { // Compute the desired target https proxy. return &compute.TargetHttpsProxy{ Name: s.namer.TargetHTTPSProxyName(), Description: fmt.Sprintf("Target https proxy for kubernetes multicluster loadbalancer %s", lbName), UrlMap: umLink, - SslCertificates: []string{certLink}, + SslCertificates: certLinks, } } diff --git a/app/kubemci/pkg/gcp/targetproxy/targetproxysyncer_test.go b/app/kubemci/pkg/gcp/targetproxy/targetproxysyncer_test.go index 2d8004adb..63a724a2b 100644 --- a/app/kubemci/pkg/gcp/targetproxy/targetproxysyncer_test.go +++ b/app/kubemci/pkg/gcp/targetproxy/targetproxysyncer_test.go @@ -107,7 +107,7 @@ func TestEnsureTargetHttpsProxy(t *testing.T) { desc string // In's umLink string - certLink string + certLinks []string forceUpdate bool // Out's ensureErr bool @@ -115,35 +115,47 @@ func TestEnsureTargetHttpsProxy(t *testing.T) { { desc: "initial write (force=false)", umLink: "http://google/compute/v1/projects/p/global/urlMaps/map", - certLink: "http://google/compute/v1/projects/p/global/sslCerts/cert", + certLinks: []string{"http://google/compute/v1/projects/p/global/sslCerts/cert"}, forceUpdate: false, ensureErr: false, }, { desc: "write same (force=false)", umLink: "http://google/compute/v1/projects/p/global/urlMaps/map", - certLink: "http://google/compute/v1/projects/p/global/sslCerts/cert", + certLinks: []string{"http://google/compute/v1/projects/p/global/sslCerts/cert"}, forceUpdate: false, ensureErr: false, }, { desc: "write different (force=false)", umLink: "http://google/compute/v1/projects/p/global/urlMaps/map2", - certLink: "http://google/compute/v1/projects/p/global/sslCerts/cert", + certLinks: []string{"http://google/compute/v1/projects/p/global/sslCerts/cert"}, forceUpdate: false, ensureErr: true, }, { desc: "write different (force=true)", umLink: "http://google/compute/v1/projects/p/global/urlMaps/map3", - certLink: "http://google/compute/v1/projects/p/global/sslCerts/cert", + certLinks: []string{"http://google/compute/v1/projects/p/global/sslCerts/cert"}, forceUpdate: true, ensureErr: false, }, + // https://github.com/GoogleCloudPlatform/k8s-multicluster-ingress/issues/94 + // { + // desc: "changed ssl certs", + // umLink: "http://google/compute/v1/projects/p/global/urlMaps/map", + // certLinks: []string{ + // "http://google/compute/v1/projects/p/global/sslCerts/cert1", + // "http://google/compute/v1/projects/p/global/sslCerts/cert2", + // "http://google/compute/v1/projects/p/global/sslCerts/cert3", + // }, + // forceUpdate: false, + // ensureErr: false, + // }, } for _, c := range testCases { glog.Infof("test case:%v", c.desc) - tpLink, err := tps.EnsureHTTPSTargetProxy(lbName, c.umLink, c.certLink, c.forceUpdate) + tpLink, err := tps.EnsureHTTPSTargetProxy(lbName, c.umLink, c.certLinks, c.forceUpdate) if (err != nil) != c.ensureErr { glog.Errorf("expected_error:%v Got Error:%v", c.ensureErr, err) t.Errorf("in ensuring target proxy, expected error? %v, actual: %v", c.ensureErr, err) @@ -160,8 +172,13 @@ func TestEnsureTargetHttpsProxy(t *testing.T) { if tp.UrlMap != c.umLink { t.Errorf("unexpected UrlMap link in target proxy. expected: %s, actual: %s", c.umLink, tp.UrlMap) } - if len(tp.SslCertificates) != 1 || tp.SslCertificates[0] != c.certLink { - t.Errorf("unexpected certificates link in target proxy. expected: %s, actual: %s", c.certLink, tp.SslCertificates) + if len(tp.SslCertificates) != len(c.certLinks) { + t.Errorf("unexpected number of certificates link in target proxy. expected: %d, actual: %d", len(c.certLinks), len(tp.SslCertificates)) + } + for i, certLink := range c.certLinks { + if tp.SslCertificates[i] != certLink { + t.Errorf("unexpected certificate link %d in target proxy. expected: %s, actual: %s", i, certLink, tp.SslCertificates[i]) + } } if tp.SelfLink != tpLink { t.Errorf("unexpected target proxy self link. expected: %s, got: %s", tpLink, tp.SelfLink) @@ -172,7 +189,7 @@ func TestEnsureTargetHttpsProxy(t *testing.T) { func TestDeleteTargetProxies(t *testing.T) { lbName := "lb-name" umLink := "selfLink" - certLink := "certSelfLink" + certLinks := []string{"certSelfLink1", "certSelfLink2"} tpp := ingresslb.NewFakeLoadBalancers("" /*name*/, nil /*namer*/) namer := utilsnamer.NewNamer("mci1", lbName) httpTpName := namer.TargetHTTPProxyName() @@ -189,7 +206,7 @@ func TestDeleteTargetProxies(t *testing.T) { if _, err := tpp.GetTargetHttpProxy(httpTpName); err != nil { t.Fatalf("expected nil error, actual: %v", err) } - if _, err := tps.EnsureHTTPSTargetProxy(lbName, umLink, certLink, false /*forceUpdate*/); err != nil { + if _, err := tps.EnsureHTTPSTargetProxy(lbName, umLink, certLinks, false /*forceUpdate*/); err != nil { t.Fatalf("expected no error in ensuring https target proxy, actual: %v", err) } if _, err := tpp.GetTargetHttpsProxy(httpsTpName); err != nil {