diff --git a/pkg/issuer/acme/http/ingress.go b/pkg/issuer/acme/http/ingress.go index 847622aa8..bdadcc956 100644 --- a/pkg/issuer/acme/http/ingress.go +++ b/pkg/issuer/acme/http/ingress.go @@ -87,10 +87,18 @@ func (s *Solver) ensureIngress(ctx context.Context, ch *cmacme.Challenge, svcNam if err != nil { return nil, err } - if len(existingIngresses) == 1 { + if len(existingIngresses) == 1 && ingressServiceName(existingIngresses[0]) == svcName { logf.WithRelatedResource(log, existingIngresses[0]).Info("found one existing HTTP01 solver ingress") return existingIngresses[0], nil } + if len(existingIngresses) == 1 && ingressServiceName(existingIngresses[0]) != svcName { + log.Info("service name changed. cleaning up all existing ingresses.") + err := s.cleanupIngresses(ctx, ch) + if err != nil { + return nil, err + } + return nil, fmt.Errorf("service name changed, existing challenge solver ingresses found and cleaned up. retrying challenge sync") + } if len(existingIngresses) > 1 { log.Info("multiple challenge solver ingresses found for challenge. cleaning up all existing ingresses.") err := s.cleanupIngresses(ctx, ch) @@ -104,6 +112,10 @@ func (s *Solver) ensureIngress(ctx context.Context, ch *cmacme.Challenge, svcNam return s.createIngress(ch, svcName) } +func ingressServiceName(ing *extv1beta1.Ingress) string { + return ing.Spec.Rules[0].IngressRuleValue.HTTP.Paths[0].Backend.ServiceName +} + // createIngress will create a challenge solving pod for the given certificate, // domain, token and key. func (s *Solver) createIngress(ch *cmacme.Challenge, svcName string) (*extv1beta1.Ingress, error) { diff --git a/pkg/issuer/acme/http/ingress_test.go b/pkg/issuer/acme/http/ingress_test.go index ff334a3a3..560580b26 100644 --- a/pkg/issuer/acme/http/ingress_test.go +++ b/pkg/issuer/acme/http/ingress_test.go @@ -25,6 +25,7 @@ import ( "k8s.io/api/extensions/v1beta1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/diff" "k8s.io/apimachinery/pkg/util/intstr" @@ -378,3 +379,52 @@ func TestCleanupIngresses(t *testing.T) { }) } } + +func TestEnsureIngress(t *testing.T) { + tests := map[string]solverFixture{ + "should clean up if service name changes": { + Challenge: &cmacme.Challenge{ + Spec: cmacme.ChallengeSpec{ + DNSName: "example.com", + Solver: &cmacme.ACMEChallengeSolver{ + HTTP01: &cmacme.ACMEChallengeSolverHTTP01{ + Ingress: &cmacme.ACMEChallengeSolverHTTP01Ingress{}, + }, + }, + }, + }, + Err: true, + PreFn: func(t *testing.T, s *solverFixture) { + _, err := s.Solver.createIngress(s.Challenge, "anotherfakeservice") + if err != nil { + t.Errorf("error preparing test: %v", err) + } + s.Builder.Sync() + }, + CheckFn: func(t *testing.T, s *solverFixture, args ...interface{}) { + ingresses, err := s.Solver.ingressLister.List(labels.NewSelector()) + if err != nil { + t.Errorf("error listing ingresses: %v", err) + t.Fail() + return + } + if len(ingresses) != 0 { + t.Errorf("expected ingresses to have been cleaned up, but there were %d ingresses left", len(ingresses)) + } + }, + }, + } + for name, test := range tests { + t.Run(name, func(t *testing.T) { + test.Setup(t) + resp, err := test.Solver.ensureIngress(context.TODO(), test.Challenge, "fakeservice") + if err != nil && !test.Err { + t.Errorf("Expected function to not error, but got: %v", err) + } + if err == nil && test.Err { + t.Errorf("Expected function to get an error, but got: %v", err) + } + test.Finish(t, resp, err) + }) + } +}