Skip to content

Commit

Permalink
Merge pull request #653 from jcmoraisjr/jm-sync-default
Browse files Browse the repository at this point in the history
Fix tracking and partial parsing of spec.backend
  • Loading branch information
jcmoraisjr authored Aug 31, 2020
2 parents f1c0885 + dc5f63e commit 9830c26
Show file tree
Hide file tree
Showing 5 changed files with 119 additions and 48 deletions.
40 changes: 27 additions & 13 deletions pkg/converters/ingress/ingress.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ func (c *converter) syncDefaultCrt() {

func (c *converter) syncDefaultBackend() {
if c.options.DefaultBackend != "" {
if backend, err := c.addBackend(&annotations.Source{}, "*", "/", c.options.DefaultBackend, "", map[string]string{}); err == nil {
if backend, err := c.addBackend(&annotations.Source{}, hatypes.DefaultHost, "/", c.options.DefaultBackend, "", map[string]string{}); err == nil {
c.haproxy.Backends().SetDefaultBackend(backend)
} else {
c.logger.Error("error reading default service: %v", err)
Expand Down Expand Up @@ -298,27 +298,40 @@ func (c *converter) syncPartial() {
func (c *converter) trackAddedIngress() {
for _, ing := range c.changed.IngressesAdd {
name := ing.Namespace + "/" + ing.Name
if ing.Spec.Backend != nil {
backend := c.findBackend(ing.Namespace, ing.Spec.Backend)
if backend != nil {
c.tracker.TrackBackend(convtypes.IngressType, name, backend.BackendID())
}
}
for _, rule := range ing.Spec.Rules {
c.tracker.TrackHostname(convtypes.IngressType, name, rule.Host)
if rule.HTTP != nil {
for _, path := range rule.HTTP.Paths {
svcName, svcPort := readServiceNamePort(&path.Backend)
fullSvcName := ing.Namespace + "/" + svcName
if svc, err := c.cache.GetService(fullSvcName); err == nil {
port := convutils.FindServicePort(svc, svcPort)
if port != nil {
backend := c.haproxy.Backends().FindBackend(ing.Namespace, svcName, port.TargetPort.String())
if backend != nil {
c.tracker.TrackBackend(convtypes.IngressType, name, backend.BackendID())
}
}
backend := c.findBackend(ing.Namespace, &path.Backend)
if backend != nil {
c.tracker.TrackBackend(convtypes.IngressType, name, backend.BackendID())
}
}
}
}
}
}

func (c *converter) findBackend(namespace string, backend *networking.IngressBackend) *hatypes.Backend {
svcName, svcPort := readServiceNamePort(backend)
fullSvcName := namespace + "/" + svcName
svc, err := c.cache.GetService(fullSvcName)
if err != nil {
return nil
}
port := convutils.FindServicePort(svc, svcPort)
if port == nil {
return nil
}
return c.haproxy.Backends().FindBackend(namespace, svcName, port.TargetPort.String())
}

func sortIngress(ingress []*networking.Ingress) {
sort.Slice(ingress, func(i, j int) bool {
i1 := ingress[i]
Expand Down Expand Up @@ -351,7 +364,7 @@ func (c *converter) syncIngress(ing *networking.Ingress) {
}
hostname := rule.Host
if hostname == "" {
hostname = "*"
hostname = hatypes.DefaultHost
}
host := c.addHost(hostname, source, annHost)
for _, path := range rule.HTTP.Paths {
Expand Down Expand Up @@ -484,7 +497,7 @@ func (c *converter) readPathType(path networking.HTTPIngressPath, ann string) ha
}

func (c *converter) addDefaultHostBackend(source *annotations.Source, fullSvcName, svcPort string, annHost, annBack map[string]string) error {
hostname := "*"
hostname := hatypes.DefaultHost
uri := "/"
if fr := c.haproxy.Hosts().FindHost(hostname); fr != nil {
if fr.FindPath(uri) != nil {
Expand All @@ -493,6 +506,7 @@ func (c *converter) addDefaultHostBackend(source *annotations.Source, fullSvcNam
}
backend, err := c.addBackend(source, hostname, uri, fullSvcName, svcPort, annBack)
if err != nil {
c.tracker.TrackHostname(convtypes.IngressType, source.FullName(), hostname)
return err
}
host := c.addHost(hostname, source, annHost)
Expand Down
96 changes: 78 additions & 18 deletions pkg/converters/ingress/ingress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ func TestSyncBackendDefault(t *testing.T) {
c.Sync(c.createIng2("default/echo", "echo:8080"))

c.compareConfigDefaultFront(`
hostname: '*'
hostname: <default>
paths:
- path: /
backend: default_echo_8080`)
Expand Down Expand Up @@ -777,15 +777,11 @@ func TestSyncDefaultBackendReusedPath1(t *testing.T) {
c.createSvc1("default/echo1", "8080", "172.17.0.11")
c.createSvc1("default/echo2", "8080", "172.17.0.12")
c.Sync(
c.createIng1("default/echo1", "'*'", "/", "echo1:8080"),
c.createIng1("default/echo1", hatypes.DefaultHost, "/", "echo1:8080"),
c.createIng2("default/echo2", "echo2:8080"),
)

c.compareConfigDefaultFront(`
hostname: '*'
paths:
- path: /
backend: default_echo1_8080`)
c.compareConfigDefaultFront(defaultDefaultFrontendConfig)

c.compareConfigBack(`
- id: default_echo1_8080
Expand All @@ -805,14 +801,10 @@ func TestSyncDefaultBackendReusedPath2(t *testing.T) {
c.createSvc1("default/echo2", "8080", "172.17.0.12")
c.Sync(
c.createIng2("default/echo1", "echo1:8080"),
c.createIng1("default/echo2", "'*'", "/", "echo2:8080"),
c.createIng1("default/echo2", hatypes.DefaultHost, "/", "echo2:8080"),
)

c.compareConfigDefaultFront(`
hostname: '*'
paths:
- path: /
backend: default_echo1_8080`)
c.compareConfigDefaultFront(defaultDefaultFrontendConfig)

c.compareConfigBack(`
- id: default_echo1_8080
Expand Down Expand Up @@ -840,7 +832,7 @@ func TestSyncEmptyHost(t *testing.T) {
c.Sync(c.createIng1("default/echo", "", "/", "echo:8080"))

c.compareConfigDefaultFront(`
hostname: '*'
hostname: <default>
paths:
- path: /
backend: default_echo_8080`)
Expand Down Expand Up @@ -893,6 +885,7 @@ func TestSyncPartial(t *testing.T) {
secTLSDefault := [][]string{
{"default/tls1"},
}
expDefaultFrontDefault := defaultDefaultFrontendConfig
expFrontDefault := `
- hostname: echo.example.com
paths:
Expand Down Expand Up @@ -921,9 +914,10 @@ func TestSyncPartial(t *testing.T) {
//
endpoints [][]string
//
expFront string
expBack string
logging string
expFront string
expDefaultFront string
expBack string
logging string
}{
// 0
{
Expand Down Expand Up @@ -1209,6 +1203,49 @@ WARN using default certificate due to an error reading secret 'default/tls1' on
- ip: 172.17.0.11
port: 8080
balancealgorithm: leastcon
- id: _default_backend
endpoints:
- ip: 172.17.0.99
port: 8080`,
},
// 13
{
ing: [][]string{
{"default/echo1", "echo1:8080"},
},
svcAdd: svcDefault,
logging: `INFO-V(2) syncing 1 host(s) and 0 backend(s)`,
expDefaultFront: expDefaultFrontDefault,
expBack: `
- id: default_echo1_8080
endpoints:
- ip: 172.17.0.11
port: 8080
- id: _default_backend
endpoints:
- ip: 172.17.0.99
port: 8080`,
},
// 14
{
svc: svcDefault,
ing: ingDefault,
ingAdd: [][]string{
{"default/echo0", "echo1:8080", "ingress.kubernetes.io/balance-algorithm=leastcon"},
},
logging: `INFO-V(2) syncing 1 host(s) and 2 backend(s)`,
expDefaultFront: expDefaultFrontDefault,
expFront: expFrontDefault,
expBack: `
- id: default_echo1_8080
endpoints:
- ip: 172.17.0.11
port: 8080
balancealgorithm: leastcon
- id: default_echo2_8080
endpoints:
- ip: 172.17.0.12
port: 8080
- id: _default_backend
endpoints:
- ip: 172.17.0.99
Expand All @@ -1223,7 +1260,14 @@ WARN using default certificate due to an error reading secret 'default/tls1' on
c.createSvc1(svc[0], svc[1], svc[2])
}
for _, ing := range test.ing {
c.cache.IngList = append(c.cache.IngList, c.createIng1(ing[0], ing[1], ing[2], ing[3]))
var item *networking.Ingress
switch len(ing) {
case 2:
item = c.createIng2(ing[0], ing[1])
case 4:
item = c.createIng1(ing[0], ing[1], ing[2], ing[3])
}
c.cache.IngList = append(c.cache.IngList, item)
}
for _, ing := range test.ingtls {
c.cache.IngList = append(c.cache.IngList, c.createIngTLS1(ing[0], ing[1], ing[2], ing[3], ing[4]))
Expand All @@ -1247,6 +1291,9 @@ WARN using default certificate due to an error reading secret 'default/tls1' on
for _, param := range params {
var ing *networking.Ingress
switch len(param) {
case 3:
ing = c.createIng2(param[0], param[1])
ing.SetAnnotations(paramToMap(param[2:]))
case 4:
ing = c.createIng1(param[0], param[1], param[2], param[3])
case 5:
Expand Down Expand Up @@ -1285,7 +1332,14 @@ WARN using default certificate due to an error reading secret 'default/tls1' on
endp(&c.cache.Changed.Endpoints, test.endpoints)
c.Sync()

if test.expFront == "" {
test.expFront = "[]"
}
c.compareConfigFront(test.expFront)
if test.expDefaultFront == "" {
test.expDefaultFront = "[]"
}
c.compareConfigDefaultFront(test.expDefaultFront)
c.compareConfigBack(test.expBack)
c.logger.CompareLogging(test.logging)

Expand Down Expand Up @@ -1656,6 +1710,12 @@ func (c *testConfig) teardown() {
c.logger.CompareLogging("")
}

var defaultDefaultFrontendConfig = `
hostname: ` + hatypes.DefaultHost + `
paths:
- path: /
backend: default_echo1_8080`

var defaultBackendConfig = `
- id: _default_backend
endpoints:
Expand Down
4 changes: 2 additions & 2 deletions pkg/haproxy/instance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1390,7 +1390,7 @@ func TestInstanceDefaultHost(t *testing.T) {
var b *hatypes.Backend

b = c.config.Backends().AcquireBackend("d1", "app", "8080")
h = c.config.Hosts().AcquireHost("*")
h = c.config.Hosts().AcquireHost(hatypes.DefaultHost)
h.AddPath(b, "/", hatypes.MatchBegin)
h.TLS.TLSFilename = "/var/haproxy/ssl/certs/default.pem"
h.TLS.TLSHash = "0"
Expand Down Expand Up @@ -1513,7 +1513,7 @@ func TestInstanceStrictHostDefaultHost(t *testing.T) {

b = c.config.Backends().AcquireBackend("d2", "app", "8080")
b.Endpoints = []*hatypes.Endpoint{endpointS21}
h = c.config.Hosts().AcquireHost("*")
h = c.config.Hosts().AcquireHost(hatypes.DefaultHost)
h.AddPath(b, "/", hatypes.MatchBegin)

c.config.Global().StrictHost = true
Expand Down
22 changes: 9 additions & 13 deletions pkg/haproxy/types/host.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,20 +45,13 @@ func (h *Hosts) AcquireHost(hostname string) *Host {
return host
}
host := h.createHost(hostname)
if host.Hostname != "*" {
h.items[hostname] = host
h.itemsAdd[hostname] = host
} else {
h.defaultHost = host
}
h.items[hostname] = host
h.itemsAdd[hostname] = host
return host
}

// FindHost ...
func (h *Hosts) FindHost(hostname string) *Host {
if hostname == "*" && h.defaultHost != nil {
return h.defaultHost
}
return h.items[hostname]
}

Expand Down Expand Up @@ -109,10 +102,13 @@ func (h *Hosts) createHost(hostname string) *Host {
func (h *Hosts) BuildSortedItems() []*Host {
items := make([]*Host, len(h.items))
var i int
for _, item := range h.items {
items[i] = item
i++
for hostname, item := range h.items {
if hostname != DefaultHost {
items[i] = item
i++
}
}
items = items[:i]
sort.Slice(items, func(i, j int) bool {
return items[i].Hostname < items[j].Hostname
})
Expand All @@ -139,7 +135,7 @@ func (h *Hosts) ItemsDel() map[string]*Host {

// DefaultHost ...
func (h *Hosts) DefaultHost() *Host {
return h.defaultHost
return h.items[DefaultHost]
}

// HasSSLPassthrough ...
Expand Down
5 changes: 3 additions & 2 deletions pkg/haproxy/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,12 +298,13 @@ type Frontend struct {
DefaultCrtHash string
}

// DefaultHost ...
const DefaultHost = "<default>"

// Hosts ...
type Hosts struct {
items, itemsAdd, itemsDel map[string]*Host
//
defaultHost *Host
//
sslPassthroughCount int
}

Expand Down

0 comments on commit 9830c26

Please sign in to comment.