From bd676922c30b94d835214b486aae61e7fc427338 Mon Sep 17 00:00:00 2001 From: Gary Kramlich Date: Tue, 7 Jan 2020 09:26:08 -0600 Subject: [PATCH] k8s Ingress: fix crash on rules with nil http --- .../Ingress-one-rule-host-only_ingress.yml | 9 +++ pkg/provider/kubernetes/ingress/kubernetes.go | 68 ++++++++++--------- .../kubernetes/ingress/kubernetes_test.go | 11 +++ 3 files changed, 56 insertions(+), 32 deletions(-) create mode 100644 pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-host-only_ingress.yml diff --git a/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-host-only_ingress.yml b/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-host-only_ingress.yml new file mode 100644 index 000000000..5c979351c --- /dev/null +++ b/pkg/provider/kubernetes/ingress/fixtures/Ingress-one-rule-host-only_ingress.yml @@ -0,0 +1,9 @@ +kind: Ingress +apiVersion: extensions/v1beta1 +metadata: + name: "" + namespace: testing + +spec: + rules: + - host: testing.example.com diff --git a/pkg/provider/kubernetes/ingress/kubernetes.go b/pkg/provider/kubernetes/ingress/kubernetes.go index f81bf6369..84268cca0 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes.go +++ b/pkg/provider/kubernetes/ingress/kubernetes.go @@ -313,53 +313,57 @@ func (p *Provider) loadConfigurationFromIngresses(ctx context.Context, client Cl conf.HTTP.Services["default-backend"] = service } } + for _, rule := range ingress.Spec.Rules { if err := checkStringQuoteValidity(rule.Host); err != nil { log.FromContext(ctx).Errorf("Invalid syntax for host: %s", rule.Host) continue } - for _, p := range rule.HTTP.Paths { - service, err := loadService(client, ingress.Namespace, p.Backend) - if err != nil { - log.FromContext(ctx). - WithField("serviceName", p.Backend.ServiceName). - WithField("servicePort", p.Backend.ServicePort.String()). - Errorf("Cannot create service: %v", err) - continue - } + if rule.HTTP != nil { + for _, p := range rule.HTTP.Paths { + service, err := loadService(client, ingress.Namespace, p.Backend) + if err != nil { + log.FromContext(ctx). + WithField("serviceName", p.Backend.ServiceName). + WithField("servicePort", p.Backend.ServicePort.String()). + Errorf("Cannot create service: %v", err) + continue + } - if err = checkStringQuoteValidity(p.Path); err != nil { - log.FromContext(ctx).Errorf("Invalid syntax for path: %s", p.Path) - continue - } + if err = checkStringQuoteValidity(p.Path); err != nil { + log.FromContext(ctx).Errorf("Invalid syntax for path: %s", p.Path) + continue + } - serviceName := provider.Normalize(ingress.Namespace + "-" + p.Backend.ServiceName + "-" + p.Backend.ServicePort.String()) - var rules []string - if len(rule.Host) > 0 { - rules = []string{"Host(`" + rule.Host + "`)"} - } + serviceName := provider.Normalize(ingress.Namespace + "-" + p.Backend.ServiceName + "-" + p.Backend.ServicePort.String()) + var rules []string + if len(rule.Host) > 0 { + rules = []string{"Host(`" + rule.Host + "`)"} + } - if len(p.Path) > 0 { - rules = append(rules, "PathPrefix(`"+p.Path+"`)") - } + if len(p.Path) > 0 { + rules = append(rules, "PathPrefix(`"+p.Path+"`)") + } - routerKey := strings.TrimPrefix(provider.Normalize(rule.Host+p.Path), "-") - conf.HTTP.Routers[routerKey] = &dynamic.Router{ - Rule: strings.Join(rules, " && "), - Service: serviceName, - } - - if len(ingress.Spec.TLS) > 0 { - // TLS enabled for this ingress, add TLS router - conf.HTTP.Routers[routerKey+"-tls"] = &dynamic.Router{ + routerKey := strings.TrimPrefix(provider.Normalize(rule.Host+p.Path), "-") + conf.HTTP.Routers[routerKey] = &dynamic.Router{ Rule: strings.Join(rules, " && "), Service: serviceName, - TLS: &dynamic.RouterTLSConfig{}, } + + if len(ingress.Spec.TLS) > 0 { + // TLS enabled for this ingress, add TLS router + conf.HTTP.Routers[routerKey+"-tls"] = &dynamic.Router{ + Rule: strings.Join(rules, " && "), + Service: serviceName, + TLS: &dynamic.RouterTLSConfig{}, + } + } + conf.HTTP.Services[serviceName] = service } - conf.HTTP.Services[serviceName] = service } + err := p.updateIngressStatus(ingress, client) if err != nil { log.FromContext(ctx).Errorf("Error while updating ingress status: %v", err) diff --git a/pkg/provider/kubernetes/ingress/kubernetes_test.go b/pkg/provider/kubernetes/ingress/kubernetes_test.go index a75c4356d..66fca43db 100644 --- a/pkg/provider/kubernetes/ingress/kubernetes_test.go +++ b/pkg/provider/kubernetes/ingress/kubernetes_test.go @@ -38,6 +38,17 @@ func TestLoadConfigurationFromIngresses(t *testing.T) { }, }, }, + { + desc: "Ingress one rule host only", + expected: &dynamic.Configuration{ + TCP: &dynamic.TCPConfiguration{}, + HTTP: &dynamic.HTTPConfiguration{ + Routers: map[string]*dynamic.Router{}, + Middlewares: map[string]*dynamic.Middleware{}, + Services: map[string]*dynamic.Service{}, + }, + }, + }, { desc: "Ingress with a basic rule on one path", expected: &dynamic.Configuration{