Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix precedence on hosts/alias without regexp #149

Merged
merged 1 commit into from
May 8, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 50 additions & 17 deletions pkg/controller/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
api "k8s.io/api/core/v1"
"os"
"regexp"
"sort"
"strings"
)

Expand Down Expand Up @@ -172,30 +173,49 @@ func (cfg *haConfig) createHAProxyServers() {
isDefaultServer := server.Hostname == "_"
isCACert := server.CertificateAuth.AuthSSLCert.CAFileName != ""
haServer := types.HAProxyServer{
IsDefaultServer: isDefaultServer,
IsCACert: isCACert,
UseHTTP: server.SSLCertificate == "" || !sslRedirect || isDefaultServer,
UseHTTPS: server.SSLCertificate != "" || isDefaultServer,
Hostname: server.Hostname,
HostnameLabel: labelizeHostname(server.Hostname),
HostnameSocket: sockHostname(labelizeHostname(server.Hostname)),
ACLLabel: labelizeACL(server.Hostname),
SSLCertificate: server.SSLCertificate,
SSLPemChecksum: server.SSLPemChecksum,
RootLocation: haRootLocation,
Locations: haLocations,
SSLRedirect: sslRedirect,
HSTS: serverHSTS(server),
HasRateLimit: serverHasRateLimit(server),
CertificateAuth: server.CertificateAuth,
Alias: server.Alias,
IsDefaultServer: isDefaultServer,
IsCACert: isCACert,
UseHTTP: server.SSLCertificate == "" || !sslRedirect || isDefaultServer,
UseHTTPS: server.SSLCertificate != "" || isDefaultServer,
Hostname: server.Hostname,
HostnameIsWildcard: idHasWildcard(server.Hostname),
HostnameLabel: labelizeHostname(server.Hostname),
HostnameSocket: sockHostname(labelizeHostname(server.Hostname)),
ACLLabel: labelizeACL(server.Hostname),
SSLCertificate: server.SSLCertificate,
SSLPemChecksum: server.SSLPemChecksum,
RootLocation: haRootLocation,
Locations: haLocations,
SSLRedirect: sslRedirect,
HSTS: serverHSTS(server),
HasRateLimit: serverHasRateLimit(server),
CertificateAuth: server.CertificateAuth,
Alias: server.Alias,
AliasIsRegex: idHasRegex(server.Alias),
}
if isDefaultServer {
haDefaultServer = &haServer
} else {
haServers = append(haServers, &haServer)
}
}
sort.SliceStable(haServers, func(i, j int) bool {
// Move hosts without wildcard and alias without regex to the top,
// following are hosts without wildcard whose alias has regex, and
// finally with the least precedence are hosts with wildcards
a, b := 0, 0
if haServers[i].HostnameIsWildcard {
a = 2
} else if haServers[i].AliasIsRegex {
a = 1
}
if haServers[j].HostnameIsWildcard {
b = 2
} else if haServers[j].AliasIsRegex {
b = 1
}
return a < b
})
cfg.haServers = haServers
cfg.haDefaultServer = haDefaultServer
}
Expand Down Expand Up @@ -275,6 +295,19 @@ func sockHostname(hostname string) string {
return hostname
}

var (
regexHasWildcard = regexp.MustCompile(`^\*\.`)
regexIsValidIdent = regexp.MustCompile(`^[a-zA-Z0-9\-.]+$`)
)

func idHasWildcard(identifier string) bool {
return regexHasWildcard.MatchString(identifier)
}

func idHasRegex(identifier string) bool {
return identifier != "" && !regexIsValidIdent.MatchString(identifier)
}

// This could be improved creating a list of auth secrets (or even configMaps)
// on Ingress and saving usr(s)/pwd in auth.BasicDigest struct
func (cfg *haConfig) createUserlists() {
Expand Down
6 changes: 0 additions & 6 deletions pkg/controller/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,6 @@ var funcMap = gotemplate.FuncMap{
rtn := regexp.MustCompile(`\.`).ReplaceAllLiteralString(hostname, "\\.")
return "^" + rtn + "(:[0-9]+)?$"
},
"isWildcardHostname": func(identifier string) bool {
return regexp.MustCompile(`^\*\.`).MatchString(identifier)
},
"isRegexHostname": func(identifier string) bool {
return !regexp.MustCompile(`^[a-zA-Z0-9\-.]+$`).MatchString(identifier)
},
"sizeSuffix": func(size string) string {
value, err := utils.SizeSuffixToInt64(size)
if err != nil {
Expand Down
36 changes: 19 additions & 17 deletions pkg/types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,23 +100,25 @@ type (
// HAProxyServer and HAProxyLocation build some missing pieces
// from ingress.Server used by HAProxy
HAProxyServer struct {
IsDefaultServer bool `json:"isDefaultServer"`
IsCACert bool `json:"isCACert"`
UseHTTP bool `json:"useHTTP"`
UseHTTPS bool `json:"useHTTPS"`
Hostname string `json:"hostname"`
HostnameLabel string `json:"hostnameLabel"`
HostnameSocket string `json:"hostnameSocket"`
ACLLabel string `json:"aclLabel"`
SSLCertificate string `json:"sslCertificate"`
SSLPemChecksum string `json:"sslPemChecksum"`
RootLocation *HAProxyLocation `json:"defaultLocation"`
Locations []*HAProxyLocation `json:"locations,omitempty"`
SSLRedirect bool `json:"sslRedirect"`
HSTS *hsts.Config `json:"hsts"`
HasRateLimit bool `json:"hasRateLimit"`
CertificateAuth authtls.AuthSSLConfig `json:"certificateAuth,omitempty"`
Alias string `json:"alias,omitempty"`
IsDefaultServer bool `json:"isDefaultServer"`
IsCACert bool `json:"isCACert"`
UseHTTP bool `json:"useHTTP"`
UseHTTPS bool `json:"useHTTPS"`
Hostname string `json:"hostname"`
HostnameIsWildcard bool `json:"hostnameIsWildcard"`
HostnameLabel string `json:"hostnameLabel"`
HostnameSocket string `json:"hostnameSocket"`
ACLLabel string `json:"aclLabel"`
SSLCertificate string `json:"sslCertificate"`
SSLPemChecksum string `json:"sslPemChecksum"`
RootLocation *HAProxyLocation `json:"defaultLocation"`
Locations []*HAProxyLocation `json:"locations,omitempty"`
SSLRedirect bool `json:"sslRedirect"`
HSTS *hsts.Config `json:"hsts"`
HasRateLimit bool `json:"hasRateLimit"`
CertificateAuth authtls.AuthSSLConfig `json:"certificateAuth,omitempty"`
Alias string `json:"alias,omitempty"`
AliasIsRegex bool `json:"aliasIsRegex"`
}
// HAProxyLocation has location data as a HAProxy friendly syntax
HAProxyLocation struct {
Expand Down
4 changes: 2 additions & 2 deletions rootfs/etc/haproxy/template/haproxy.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -399,13 +399,13 @@ frontend httpfront-{{ if $isShared }}shared-frontend{{ else if $isDefault }}defa
{{- $fetch := .p3 }}
{{- $needport := .p4 }}
{{- if ne $server.ACLLabel "" }}
{{- if isWildcardHostname $server.Hostname }}
{{- if $server.HostnameIsWildcard }}
acl {{ $server.ACLLabel }} {{ $fetch }} -m reg -i {{ hostnameRegex $server.Hostname }}
{{- else }}
acl {{ $server.ACLLabel }} {{ $fetch }} -i {{ $server.Hostname }}{{ if $needport }} {{ $server.Hostname }}:80 {{ $server.Hostname }}:443{{ if and $cfg.HTTPStoHTTPPort (ne $cfg.HTTPStoHTTPPort 80) }} {{ $server.Hostname }}:{{ $cfg.HTTPStoHTTPPort }}{{ end }}{{ end }}
{{- end }}
{{- if ne $server.Alias "" }}
{{- if isRegexHostname $server.Alias }}
{{- if $server.AliasIsRegex }}
acl {{ $server.ACLLabel }} {{ $fetch }} -m reg -i '{{ aliasRegex $server.Alias }}'
{{- else }}
acl {{ $server.ACLLabel }} {{ $fetch }} -i {{ $server.Alias }}{{ if $needport }} {{ $server.Alias }}:80 {{ $server.Alias }}:443{{ end }}
Expand Down