Fix nginx ingress variables for definitions with Backend

This commit is contained in:
Manuel Alejandro de Brito Fontes 2020-12-04 23:37:47 -03:00
parent 0b6d115236
commit 77234fcde0
3 changed files with 91 additions and 41 deletions

View file

@ -567,7 +567,10 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in
addLoc := true
for _, loc := range server.Locations {
if loc.Path == nginxPath {
if loc.Path != nginxPath {
continue
}
// Same paths but different types are allowed
// (same type means overlap in the path definition)
if !apiequality.Semantic.DeepEqual(loc.PathType, path.PathType) {
@ -596,9 +599,9 @@ func (n *NGINXController) getBackendServers(ingresses []*ingress.Ingress) ([]*in
if loc.Redirect.FromToWWW {
server.RedirectFromToWWW = true
}
break
}
}
// new location
if addLoc {
@ -1048,15 +1051,15 @@ func (n *NGINXController) createServers(data []*ingress.Ingress,
// special "catch all" case, Ingress with a backend but no rule
defLoc := servers[defServerName].Locations[0]
if defLoc.IsDefBackend && len(ing.Spec.Rules) == 0 {
klog.V(2).Infof("Ingress %q defines a backend but no rule. Using it to configure the catch-all server %q",
ingKey, defServerName)
defLoc.IsDefBackend = false
defLoc.Backend = backendUpstream.Name
defLoc.Service = backendUpstream.Service
defLoc.Ingress = ing
if defLoc.IsDefBackend && len(ing.Spec.Rules) == 0 {
klog.V(2).Infof("Ingress %q defines a backend but no rule. Using it to configure the catch-all server %q", ingKey, defServerName)
defLoc.IsDefBackend = false
// TODO: Redirect and rewrite can affect the catch all behavior, skip for now
originalRedirect := defLoc.Redirect
originalRewrite := defLoc.Rewrite
@ -1064,8 +1067,7 @@ func (n *NGINXController) createServers(data []*ingress.Ingress,
defLoc.Redirect = originalRedirect
defLoc.Rewrite = originalRewrite
} else {
klog.V(3).Infof("Ingress %q defines both a backend and rules. Using its backend as default upstream for all its rules.",
ingKey)
klog.V(3).Infof("Ingress %q defines both a backend and rules. Using its backend as default upstream for all its rules.", ingKey)
}
}
}
@ -1081,12 +1083,12 @@ func (n *NGINXController) createServers(data []*ingress.Ingress,
continue
}
pathTypePrefix := networking.PathTypePrefix
loc := &ingress.Location{
Path: rootLocation,
PathType: &pathTypePrefix,
IsDefBackend: true,
Backend: un,
Ingress: ing,
Service: &apiv1.Service{},
}
locationApplyAnnotations(loc, anns)

View file

@ -890,7 +890,15 @@ func getIngressInformation(i, h, p interface{}) *ingressInformation {
}
for _, rPath := range rule.HTTP.Paths {
if path == rPath.Path {
if path != rPath.Path {
continue
}
if info.Service != "" && rPath.Backend.ServiceName == "" {
// empty rule. Only contains a Path and PathType
return info
}
info.Service = rPath.Backend.ServiceName
if rPath.Backend.ServicePort.String() != "0" {
info.ServicePort = rPath.Backend.ServicePort.String()
@ -899,7 +907,6 @@ func getIngressInformation(i, h, p interface{}) *ingressInformation {
return info
}
}
}
return info
}

View file

@ -22,6 +22,9 @@ import (
"strings"
"github.com/onsi/ginkgo"
networking "k8s.io/api/networking/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/ingress-nginx/test/e2e/framework"
)
@ -49,4 +52,42 @@ var _ = framework.IngressNginxDescribe("[Ingress] definition without host", func
Expect().
Status(http.StatusOK)
})
ginkgo.It("should set ingress details variables for ingresses with host without IngressRuleValue, only Backend", func() {
f.NewEchoDeployment()
ing := &networking.Ingress{
ObjectMeta: metav1.ObjectMeta{
Name: "backend",
Namespace: f.Namespace,
},
Spec: networking.IngressSpec{
Backend: &networking.IngressBackend{
ServiceName: framework.EchoService,
ServicePort: intstr.FromInt(80),
},
Rules: []networking.IngressRule{
{
Host: "only-backend",
},
},
},
}
f.EnsureIngress(ing)
f.WaitForNginxServer("only-backend",
func(server string) bool {
return strings.Contains(server, fmt.Sprintf(`set $namespace "%v";`, f.Namespace)) &&
strings.Contains(server, fmt.Sprintf(`set $ingress_name "%v";`, ing.Name)) &&
strings.Contains(server, fmt.Sprintf(`set $service_name "%v";`, framework.EchoService)) &&
strings.Contains(server, `set $service_port "80";`) &&
strings.Contains(server, `set $location_path "/";`)
})
f.HTTPTestClient().
GET("/").
WithHeader("Host", "only-backend").
Expect().
Status(http.StatusOK)
})
})