Refactor ssl-passthroug using go to handle TLS hello

This commit is contained in:
Manuel de Brito Fontes 2017-04-09 20:51:38 -03:00
parent d2c7e9008f
commit de14e2f4f1
11 changed files with 432 additions and 122 deletions

View file

@ -49,6 +49,7 @@ import (
"k8s.io/ingress/core/pkg/ingress/defaults"
"k8s.io/ingress/core/pkg/ingress/resolver"
"k8s.io/ingress/core/pkg/ingress/status"
"k8s.io/ingress/core/pkg/ingress/status/leaderelection/resourcelock"
"k8s.io/ingress/core/pkg/ingress/store"
"k8s.io/ingress/core/pkg/k8s"
"k8s.io/ingress/core/pkg/net/ssl"
@ -211,6 +212,11 @@ func newIngressController(config *Configuration) *GenericController {
eventHandler := cache.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
ep := obj.(*api.Endpoints)
_, found := ep.Annotations[resourcelock.LeaderElectionRecordAnnotationKey]
if found {
return
}
ic.syncQueue.Enqueue(obj)
},
DeleteFunc: func(obj interface{}) {
@ -218,6 +224,12 @@ func newIngressController(config *Configuration) *GenericController {
},
UpdateFunc: func(old, cur interface{}) {
if !reflect.DeepEqual(old, cur) {
ep := cur.(*api.Endpoints)
_, found := ep.Annotations[resourcelock.LeaderElectionRecordAnnotationKey]
if found {
return
}
ic.syncQueue.Enqueue(cur)
}
},
@ -276,7 +288,7 @@ func newIngressController(config *Configuration) *GenericController {
ic.nodeLister.Store, ic.nodeController = cache.NewInformer(
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "nodes", api.NamespaceAll, fields.Everything()),
&api.Node{}, ic.cfg.ResyncPeriod, eventHandler)
&api.Node{}, ic.cfg.ResyncPeriod, cache.ResourceEventHandlerFuncs{})
if config.UpdateStatus {
ic.syncStatus = status.NewStatusSyncer(status.Config{
@ -381,6 +393,8 @@ func (ic *GenericController) syncIngress(key interface{}) error {
passUpstreams = append(passUpstreams, &ingress.SSLPassthroughBackend{
Backend: loc.Backend,
Hostname: server.Hostname,
Service: loc.Service,
Port: loc.Port,
})
break
}
@ -620,6 +634,8 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress
loc.Backend = ups.Name
loc.IsDefBackend = false
loc.Backend = ups.Name
loc.Port = ups.Port
loc.Service = ups.Service
mergeLocationAnnotations(loc, anns)
break
}
@ -631,6 +647,8 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress
Path: nginxPath,
Backend: ups.Name,
IsDefBackend: false,
Service: ups.Service,
Port: ups.Port,
}
mergeLocationAnnotations(loc, anns)
server.Locations = append(server.Locations, loc)
@ -641,7 +659,6 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress
// Configure Backends[].SSLPassthrough
for _, upstream := range upstreams {
isHTTP := false
isHTTPSfrom := []*ingress.Server{}
for _, server := range servers {
for _, location := range server.Locations {
@ -650,26 +667,18 @@ func (ic *GenericController) getBackendServers() ([]*ingress.Backend, []*ingress
if location.Path == rootLocation {
if location.Backend == defUpstreamName {
glog.Warningf("ignoring ssl passthrough of %v as it doesn't have a default backend (root context)", server.Hostname)
} else {
isHTTPSfrom = append(isHTTPSfrom, server)
continue
}
isHTTPSfrom = append(isHTTPSfrom, server)
}
} else {
isHTTP = true
continue
}
}
}
}
if len(isHTTPSfrom) > 0 {
if isHTTP {
for _, server := range isHTTPSfrom {
glog.Warningf("backend type mismatch on %v, assuming HTTP on ssl passthrough host %v", upstream.Name, server.Hostname)
// removing this server from the PassthroughBackends slice
server.SSLPassthrough = false
}
} else {
upstream.SSLPassthrough = true
}
upstream.SSLPassthrough = true
}
}
@ -761,36 +770,43 @@ func (ic *GenericController) createUpstreams(data []interface{}) map[string]*ing
path.Backend.ServiceName,
path.Backend.ServicePort.String())
upstream, ok := upstreams[name]
isNewUpstream := !ok
if isNewUpstream {
glog.V(3).Infof("creating upstream %v", name)
upstream = newUpstream(name)
upstreams[name] = upstream
if _, ok := upstreams[name]; ok {
continue
}
if !upstream.Secure {
upstream.Secure = secUpstream
glog.V(3).Infof("creating upstream %v", name)
upstreams[name] = newUpstream(name)
if !upstreams[name].Secure {
upstreams[name].Secure = secUpstream
}
if upstream.SessionAffinity.AffinityType == "" {
upstream.SessionAffinity.AffinityType = affinity.AffinityType
if upstreams[name].SessionAffinity.AffinityType == "" {
upstreams[name].SessionAffinity.AffinityType = affinity.AffinityType
if affinity.AffinityType == "cookie" {
upstream.SessionAffinity.CookieSessionAffinity.Name = affinity.CookieConfig.Name
upstream.SessionAffinity.CookieSessionAffinity.Hash = affinity.CookieConfig.Hash
upstreams[name].SessionAffinity.CookieSessionAffinity.Name = affinity.CookieConfig.Name
upstreams[name].SessionAffinity.CookieSessionAffinity.Hash = affinity.CookieConfig.Hash
}
}
if isNewUpstream {
svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), path.Backend.ServiceName)
endp, err := ic.serviceEndpoints(svcKey, path.Backend.ServicePort.String(), hz)
if err != nil {
glog.Warningf("error obtaining service endpoints: %v", err)
continue
}
upstream.Endpoints = endp
svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), path.Backend.ServiceName)
endp, err := ic.serviceEndpoints(svcKey, path.Backend.ServicePort.String(), hz)
if err != nil {
glog.Warningf("error obtaining service endpoints: %v", err)
continue
}
upstreams[name].Endpoints = endp
s, exists, err := ic.svcLister.Store.GetByKey(svcKey)
if err != nil {
glog.Warningf("error obtaining service: %v", err)
continue
}
if exists {
upstreams[name].Service = s.(*api.Service)
} else {
glog.Warningf("service %v does not exists", svcKey)
}
upstreams[name].Port = path.Backend.ServicePort
}
}
}
@ -926,6 +942,7 @@ func (ic *GenericController) createServers(data []interface{},
// server already configured
continue
}
servers[host] = &ingress.Server{
Hostname: host,
Locations: []*ingress.Location{
@ -1132,7 +1149,7 @@ func (ic GenericController) Start() {
go ic.secrController.Run(ic.stopCh)
go ic.mapController.Run(ic.stopCh)
go ic.syncQueue.Run(5*time.Second, ic.stopCh)
go ic.syncQueue.Run(10*time.Second, ic.stopCh)
go wait.Forever(ic.syncSecret, 10*time.Second)