Merge 234277150a
into df64675392
This commit is contained in:
commit
e6e29a703a
3 changed files with 131 additions and 83 deletions
|
@ -595,30 +595,9 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress
|
||||||
server = servers[defServerName]
|
server = servers[defServerName]
|
||||||
}
|
}
|
||||||
|
|
||||||
// use default upstream
|
|
||||||
defBackend := upstreams[defUpstreamName]
|
|
||||||
// we need to check if the spec contains the default backend
|
|
||||||
if ing.Spec.Backend != nil {
|
|
||||||
glog.V(3).Infof("ingress rule %v/%v defines a default Backend %v/%v",
|
|
||||||
ing.Namespace,
|
|
||||||
ing.Name,
|
|
||||||
ing.Spec.Backend.ServiceName,
|
|
||||||
ing.Spec.Backend.ServicePort.String())
|
|
||||||
|
|
||||||
name := fmt.Sprintf("%v-%v-%v",
|
|
||||||
ing.GetNamespace(),
|
|
||||||
ing.Spec.Backend.ServiceName,
|
|
||||||
ing.Spec.Backend.ServicePort.String())
|
|
||||||
|
|
||||||
if defUps, ok := upstreams[name]; ok {
|
|
||||||
defBackend = defUps
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if rule.HTTP == nil &&
|
if rule.HTTP == nil &&
|
||||||
host != defServerName {
|
host != defServerName {
|
||||||
glog.V(3).Infof("ingress rule %v/%v does not contains HTTP rules. using default backend", ing.Namespace, ing.Name)
|
glog.V(3).Infof("ingress rule %v/%v does not contains HTTP rules. using default backend", ing.Namespace, ing.Name)
|
||||||
server.Locations[0].Backend = defBackend.Name
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -822,7 +801,13 @@ func (ic *GenericController) serviceEndpoints(svcKey, backendPort string,
|
||||||
return upstreams, nil
|
return upstreams, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ic *GenericController) createServers(data []interface{}, upstreams map[string]*ingress.Backend) map[string]*ingress.Server {
|
// createServers initializes a map that contains information about the list of
|
||||||
|
// FDQN referenced by ingress rules and the common name field in the referenced
|
||||||
|
// SSL certificates. Each server is configured with location / using a default
|
||||||
|
// backend specified by the user or the one inside the ingress spec.
|
||||||
|
func (ic *GenericController) createServers(data []interface{},
|
||||||
|
upstreams map[string]*ingress.Backend) map[string]*ingress.Server {
|
||||||
|
|
||||||
servers := make(map[string]*ingress.Server)
|
servers := make(map[string]*ingress.Server)
|
||||||
|
|
||||||
bdef := ic.GetDefaultBackend()
|
bdef := ic.GetDefaultBackend()
|
||||||
|
@ -834,11 +819,9 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str
|
||||||
BufferSize: bdef.ProxyBufferSize,
|
BufferSize: bdef.ProxyBufferSize,
|
||||||
}
|
}
|
||||||
|
|
||||||
dun := ic.getDefaultUpstream().Name
|
|
||||||
|
|
||||||
// This adds the Default Certificate to Default Backend and also for vhosts missing the secret
|
// This adds the Default Certificate to Default Backend and also for vhosts missing the secret
|
||||||
var defaultPemFileName, defaultPemSHA string
|
|
||||||
defaultCertificate, err := ic.getPemCertificate(ic.cfg.DefaultSSLCertificate)
|
defaultCertificate, err := ic.getPemCertificate(ic.cfg.DefaultSSLCertificate)
|
||||||
|
var defaultPemFileName, defaultPemSHA string
|
||||||
// If no default Certificate was supplied, tries to generate a new dumb one
|
// If no default Certificate was supplied, tries to generate a new dumb one
|
||||||
if err != nil {
|
if err != nil {
|
||||||
var cert *ingress.SSLCert
|
var cert *ingress.SSLCert
|
||||||
|
@ -855,7 +838,7 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str
|
||||||
defaultPemSHA = defaultCertificate.PemSHA
|
defaultPemSHA = defaultCertificate.PemSHA
|
||||||
}
|
}
|
||||||
|
|
||||||
// default server
|
// initialize the default server
|
||||||
servers[defServerName] = &ingress.Server{
|
servers[defServerName] = &ingress.Server{
|
||||||
Hostname: defServerName,
|
Hostname: defServerName,
|
||||||
SSLCertificate: defaultPemFileName,
|
SSLCertificate: defaultPemFileName,
|
||||||
|
@ -864,7 +847,7 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str
|
||||||
{
|
{
|
||||||
Path: rootLocation,
|
Path: rootLocation,
|
||||||
IsDefBackend: true,
|
IsDefBackend: true,
|
||||||
Backend: dun,
|
Backend: ic.getDefaultUpstream().Name,
|
||||||
Proxy: ngxProxy,
|
Proxy: ngxProxy,
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
|
@ -878,16 +861,86 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str
|
||||||
|
|
||||||
// check if ssl passthrough is configured
|
// check if ssl passthrough is configured
|
||||||
sslpt := ic.annotations.SSLPassthrough(ing)
|
sslpt := ic.annotations.SSLPassthrough(ing)
|
||||||
|
dun := ic.getDefaultUpstream().Name
|
||||||
|
if ing.Spec.Backend != nil {
|
||||||
|
// replace default backend
|
||||||
|
defUpstream := fmt.Sprintf("%v-%v-%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort.String())
|
||||||
|
if backendUpstream, ok := upstreams[defUpstream]; ok {
|
||||||
|
dun = backendUpstream.Name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, rule := range ing.Spec.Rules {
|
for _, rule := range ing.Spec.Rules {
|
||||||
host := rule.Host
|
host := rule.Host
|
||||||
if host == "" {
|
if host == "" {
|
||||||
host = defServerName
|
if len(ing.Spec.TLS) == 0 {
|
||||||
|
// default host already initialized
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, tls := range ing.Spec.TLS {
|
||||||
|
c, exists := ic.sslCertTracker.Get(fmt.Sprintf("%v/%v", ing.Namespace, tls.SecretName))
|
||||||
|
if !exists {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cert := c.(*ingress.SSLCert)
|
||||||
|
|
||||||
|
// configure hosts defined in TLS section
|
||||||
|
for _, host := range tls.Hosts {
|
||||||
if _, ok := servers[host]; ok {
|
if _, ok := servers[host]; ok {
|
||||||
|
servers[host].SSLPassthrough = sslpt
|
||||||
// server already configured
|
// server already configured
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
servers[host] = &ingress.Server{
|
||||||
|
Hostname: host,
|
||||||
|
SSLCertificate: cert.PemFileName,
|
||||||
|
SSLPemChecksum: cert.PemSHA,
|
||||||
|
Locations: []*ingress.Location{
|
||||||
|
{
|
||||||
|
Path: rootLocation,
|
||||||
|
IsDefBackend: true,
|
||||||
|
Backend: dun,
|
||||||
|
Proxy: ngxProxy,
|
||||||
|
},
|
||||||
|
}, SSLPassthrough: sslpt,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, cn := range cert.CN {
|
||||||
|
if !isDomainName(cn) {
|
||||||
|
glog.Warningf("'%v' is not a valid domain name (%v/%v)", cn, cert.GetNamespace, cert.GetName)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := servers[cn]; ok {
|
||||||
|
// server already configured
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
servers[cn] = &ingress.Server{
|
||||||
|
Hostname: cn,
|
||||||
|
SSLCertificate: cert.PemFileName,
|
||||||
|
SSLPemChecksum: cert.PemSHA,
|
||||||
|
Locations: []*ingress.Location{
|
||||||
|
{
|
||||||
|
Path: rootLocation,
|
||||||
|
IsDefBackend: true,
|
||||||
|
Backend: dun,
|
||||||
|
Proxy: ngxProxy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, ok := servers[host]; ok {
|
||||||
|
servers[host].SSLPassthrough = sslpt
|
||||||
|
// server already configured
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
servers[host] = &ingress.Server{
|
servers[host] = &ingress.Server{
|
||||||
Hostname: host,
|
Hostname: host,
|
||||||
Locations: []*ingress.Location{
|
Locations: []*ingress.Location{
|
||||||
|
@ -897,60 +950,7 @@ func (ic *GenericController) createServers(data []interface{}, upstreams map[str
|
||||||
Backend: dun,
|
Backend: dun,
|
||||||
Proxy: ngxProxy,
|
Proxy: ngxProxy,
|
||||||
},
|
},
|
||||||
}, SSLPassthrough: sslpt}
|
}, SSLPassthrough: sslpt,
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// configure default location and SSL
|
|
||||||
for _, ingIf := range data {
|
|
||||||
ing := ingIf.(*extensions.Ingress)
|
|
||||||
if !IsValidClass(ing, ic.cfg.IngressClass) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, rule := range ing.Spec.Rules {
|
|
||||||
host := rule.Host
|
|
||||||
if host == "" {
|
|
||||||
host = defServerName
|
|
||||||
}
|
|
||||||
|
|
||||||
// only add a certificate if the server does not have one previously configured
|
|
||||||
// TODO: TLS without secret?
|
|
||||||
if len(ing.Spec.TLS) > 0 && servers[host].SSLCertificate == "" {
|
|
||||||
tlsSecretName := ""
|
|
||||||
for _, tls := range ing.Spec.TLS {
|
|
||||||
for _, tlsHost := range tls.Hosts {
|
|
||||||
if tlsHost == host {
|
|
||||||
tlsSecretName = tls.SecretName
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
key := fmt.Sprintf("%v/%v", ing.Namespace, tlsSecretName)
|
|
||||||
bc, exists := ic.sslCertTracker.Get(key)
|
|
||||||
if exists {
|
|
||||||
cert := bc.(*ingress.SSLCert)
|
|
||||||
if isHostValid(host, cert) {
|
|
||||||
servers[host].SSLCertificate = cert.PemFileName
|
|
||||||
servers[host].SSLPemChecksum = cert.PemSHA
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
servers[host].SSLCertificate = defaultPemFileName
|
|
||||||
servers[host].SSLPemChecksum = defaultPemSHA
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ing.Spec.Backend != nil {
|
|
||||||
defUpstream := fmt.Sprintf("%v-%v-%v", ing.GetNamespace(), ing.Spec.Backend.ServiceName, ing.Spec.Backend.ServicePort.String())
|
|
||||||
if backendUpstream, ok := upstreams[defUpstream]; ok {
|
|
||||||
if host == "" || host == defServerName {
|
|
||||||
ic.recorder.Eventf(ing, api.EventTypeWarning, "MAPPING", "error: rules with Spec.Backend are allowed only with hostnames")
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
servers[host].Locations[0].Backend = backendUpstream.Name
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,3 +114,51 @@ func mergeLocationAnnotations(loc *ingress.Location, anns map[string]interface{}
|
||||||
glog.Errorf("unexpected error merging extracted annotations in location type: %v", err)
|
glog.Errorf("unexpected error merging extracted annotations in location type: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isDomainName(s string) bool {
|
||||||
|
// See RFC 1035, RFC 3696.
|
||||||
|
if len(s) == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if len(s) > 255 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if s[len(s)-1] != '.' { // simplify checking loop: make name end in dot
|
||||||
|
s += "."
|
||||||
|
}
|
||||||
|
|
||||||
|
last := byte('.')
|
||||||
|
ok := false // ok once we've seen a letter
|
||||||
|
partlen := 0
|
||||||
|
for i := 0; i < len(s); i++ {
|
||||||
|
c := s[i]
|
||||||
|
switch {
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
case 'a' <= c && c <= 'z' || 'A' <= c && c <= 'Z' || c == '_':
|
||||||
|
ok = true
|
||||||
|
partlen++
|
||||||
|
case '0' <= c && c <= '9':
|
||||||
|
// fine
|
||||||
|
partlen++
|
||||||
|
case c == '-':
|
||||||
|
// byte before dash cannot be dot
|
||||||
|
if last == '.' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
partlen++
|
||||||
|
case c == '.':
|
||||||
|
// byte before dot cannot be dot, dash
|
||||||
|
if last == '.' || last == '-' {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if partlen > 63 || partlen == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
partlen = 0
|
||||||
|
}
|
||||||
|
last = c
|
||||||
|
}
|
||||||
|
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue