Skip to content

Commit

Permalink
feat(parser) allow configuration of multi-port Kubernetes services
Browse files Browse the repository at this point in the history
- Include the port in upstream names, such that the format is
serviceName.namespace.port.svc, e.g. fooserv.default.80.svc. This
correctly handles cases where a service exposes multiple ports, whereas
previously both would attempt the same upstream and conflict.
- Add test to confirm that a rule using multiple ports on the same
Kubernetes Service results in multiple Kong services with different
ports.

From #404
  • Loading branch information
Travis Raines authored and hbagdi committed Oct 17, 2019
1 parent 71a7653 commit c5f79e6
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 6 deletions.
6 changes: 3 additions & 3 deletions internal/ingress/controller/parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ func (p *Parser) parseIngressRules(
service = Service{
Service: kong.Service{
Name: kong.String(serviceName),
Host: kong.String(rule.Backend.ServiceName + "." + ingress.Namespace + ".svc"),
Host: kong.String(rule.Backend.ServiceName + "." + ingress.Namespace + "." + rule.Backend.ServicePort.String() + ".svc"),
Port: kong.Int(80),
Protocol: kong.String("http"),
Path: kong.String("/"),
Expand Down Expand Up @@ -409,7 +409,7 @@ func (p *Parser) parseIngressRules(
service = Service{
Service: kong.Service{
Name: kong.String(serviceName),
Host: kong.String(defaultBackend.ServiceName + "." + ingress.Namespace + ".svc"),
Host: kong.String(defaultBackend.ServiceName + "." + ingress.Namespace + "." + defaultBackend.ServicePort.String() + ".svc"),
Port: kong.Int(80),
},
Namespace: ingress.Namespace,
Expand Down Expand Up @@ -555,7 +555,7 @@ func overrideUpstream(upstream *Upstream,
func (p *Parser) getUpstreams(serviceMap map[string]Service) ([]Upstream, error) {
var upstreams []Upstream
for _, service := range serviceMap {
upstreamName := service.Backend.ServiceName + "." + service.Namespace + ".svc"
upstreamName := service.Backend.ServiceName + "." + service.Namespace + "." + service.Backend.ServicePort.String() + ".svc"
upstream := Upstream{
Upstream: kong.Upstream{
Name: kong.String(upstreamName),
Expand Down
55 changes: 52 additions & 3 deletions internal/ingress/controller/parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -418,6 +418,47 @@ func TestParseIngressRules(t *testing.T) {
},
},
},
// 6
{
ObjectMeta: metav1.ObjectMeta{
Name: "foo",
Namespace: "foo-namespace",
},
Spec: networking.IngressSpec{
Rules: []networking.IngressRule{
{
Host: "example.com",
IngressRuleValue: networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{
{
Backend: networking.IngressBackend{
ServiceName: "foo-svc",
ServicePort: intstr.FromInt(80),
},
},
},
},
},
},
{
Host: "example.net",
IngressRuleValue: networking.IngressRuleValue{
HTTP: &networking.HTTPIngressRuleValue{
Paths: []networking.HTTPIngressPath{
{
Backend: networking.IngressBackend{
ServiceName: "foo-svc",
ServicePort: intstr.FromInt(8000),
},
},
},
},
},
},
},
},
},
}
t.Run("no ingress returns empty info", func(t *testing.T) {
parsedInfo, err := p.parseIngressRules([]*networking.Ingress{})
Expand All @@ -432,7 +473,7 @@ func TestParseIngressRules(t *testing.T) {
ingressList[0],
})
assert.Equal(1, len(parsedInfo.ServiceNameToServices))
assert.Equal("foo-svc.foo-namespace.svc", *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Host)
assert.Equal("foo-svc.foo-namespace.80.svc", *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Host)
assert.Equal(80, *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Port)

assert.Equal("/", *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Routes[0].Paths[0])
Expand All @@ -445,7 +486,7 @@ func TestParseIngressRules(t *testing.T) {
ingressList[2],
})
assert.Equal(2, len(parsedInfo.ServiceNameToServices))
assert.Equal("foo-svc.foo-namespace.svc", *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Host)
assert.Equal("foo-svc.foo-namespace.80.svc", *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Host)
assert.Equal(80, *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Port)

assert.Equal("/", *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Routes[0].Paths[0])
Expand All @@ -471,7 +512,7 @@ func TestParseIngressRules(t *testing.T) {
ingressList[3],
})
assert.Equal(1, len(parsedInfo.ServiceNameToServices))
assert.Equal("cert-manager-solver-pod.foo-namespace.svc", *parsedInfo.ServiceNameToServices["foo-namespace.cert-manager-solver-pod.80"].Host)
assert.Equal("cert-manager-solver-pod.foo-namespace.80.svc", *parsedInfo.ServiceNameToServices["foo-namespace.cert-manager-solver-pod.80"].Host)
assert.Equal(80, *parsedInfo.ServiceNameToServices["foo-namespace.cert-manager-solver-pod.80"].Port)

assert.Equal("/.well-known/acme-challenge/yolo", *parsedInfo.ServiceNameToServices["foo-namespace.cert-manager-solver-pod.80"].Routes[0].Paths[0])
Expand All @@ -497,6 +538,14 @@ func TestParseIngressRules(t *testing.T) {
assert.Nil(err)
})
})
t.Run("Ingress rules with multiple ports for one Service use separate hostnames for each port", func(t *testing.T) {
parsedInfo, err := p.parseIngressRules([]*networking.Ingress{
ingressList[6],
})
assert.Equal("foo-svc.foo-namespace.80.svc", *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.80"].Host)
assert.Equal("foo-svc.foo-namespace.8000.svc", *parsedInfo.ServiceNameToServices["foo-namespace.foo-svc.8000"].Host)
assert.Nil(err)
})
}

func TestOverrideService(t *testing.T) {
Expand Down

0 comments on commit c5f79e6

Please sign in to comment.