Skip to content
This repository has been archived by the owner on Apr 17, 2019. It is now read-only.

Commit

Permalink
ingress: nginx controller watches referenced tls secrets
Browse files Browse the repository at this point in the history
* reload certificates on change
  • Loading branch information
simonswine committed Jun 3, 2016
1 parent 9d2871e commit 9b9c7da
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 4 deletions.
81 changes: 77 additions & 4 deletions ingress/controllers/nginx/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,12 @@ type loadBalancerController struct {
ingController *framework.Controller
endpController *framework.Controller
svcController *framework.Controller
secrController *framework.Controller
mapController *framework.Controller
ingLister StoreToIngressLister
svcLister cache.StoreToServiceLister
endpLister cache.StoreToEndpointsLister
secrLister StoreToSecretsLister
mapLister StoreToConfigmapLister
nginx *nginx.Manager
podInfo *podInfo
Expand Down Expand Up @@ -165,6 +167,32 @@ func newLoadBalancerController(kubeClient *client.Client, resyncPeriod time.Dura
},
}

secrEventHandler := framework.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
addSecr := obj.(*api.Secret)
if lbc.secrReferenced(addSecr.Namespace, addSecr.Name) {
lbc.recorder.Eventf(addSecr, api.EventTypeNormal, "CREATE", fmt.Sprintf("%s/%s", addSecr.Namespace, addSecr.Name))
lbc.syncQueue.enqueue(obj)
}
},
DeleteFunc: func(obj interface{}) {
delSecr := obj.(*api.Secret)
if lbc.secrReferenced(delSecr.Namespace, delSecr.Name) {
lbc.recorder.Eventf(delSecr, api.EventTypeNormal, "DELETE", fmt.Sprintf("%s/%s", delSecr.Namespace, delSecr.Name))
lbc.syncQueue.enqueue(obj)
}
},
UpdateFunc: func(old, cur interface{}) {
if !reflect.DeepEqual(old, cur) {
upSecr := cur.(*api.Secret)
if lbc.secrReferenced(upSecr.Namespace, upSecr.Name) {
lbc.recorder.Eventf(upSecr, api.EventTypeNormal, "UPDATE", fmt.Sprintf("%s/%s", upSecr.Namespace, upSecr.Name))
lbc.syncQueue.enqueue(cur)
}
}
},
}

eventHandler := framework.ResourceEventHandlerFuncs{
AddFunc: func(obj interface{}) {
lbc.syncQueue.enqueue(obj)
Expand Down Expand Up @@ -214,6 +242,13 @@ func newLoadBalancerController(kubeClient *client.Client, resyncPeriod time.Dura
},
&api.Service{}, resyncPeriod, framework.ResourceEventHandlerFuncs{})

lbc.secrLister.Store, lbc.secrController = framework.NewInformer(
&cache.ListWatch{
ListFunc: secretsListFunc(lbc.client, namespace),
WatchFunc: secretsWatchFunc(lbc.client, namespace),
},
&api.Secret{}, resyncPeriod, secrEventHandler)

lbc.mapLister.Store, lbc.mapController = framework.NewInformer(
&cache.ListWatch{
ListFunc: mapListFunc(lbc.client, namespace),
Expand Down Expand Up @@ -260,6 +295,18 @@ func endpointsWatchFunc(c *client.Client, ns string) func(options api.ListOption
}
}

func secretsListFunc(c *client.Client, ns string) func(api.ListOptions) (runtime.Object, error) {
return func(opts api.ListOptions) (runtime.Object, error) {
return c.Secrets(ns).List(opts)
}
}

func secretsWatchFunc(c *client.Client, ns string) func(options api.ListOptions) (watch.Interface, error) {
return func(options api.ListOptions) (watch.Interface, error) {
return c.Secrets(ns).Watch(options)
}
}

func mapListFunc(c *client.Client, ns string) func(api.ListOptions) (runtime.Object, error) {
return func(opts api.ListOptions) (runtime.Object, error) {
return c.ConfigMaps(ns).List(opts)
Expand All @@ -273,8 +320,11 @@ func mapWatchFunc(c *client.Client, ns string) func(options api.ListOptions) (wa
}

func (lbc *loadBalancerController) controllersInSync() bool {
return lbc.ingController.HasSynced() && lbc.svcController.HasSynced() &&
lbc.endpController.HasSynced() && lbc.mapController.HasSynced()
return lbc.ingController.HasSynced() &&
lbc.svcController.HasSynced() &&
lbc.endpController.HasSynced() &&
lbc.secrController.HasSynced() &&
lbc.mapController.HasSynced()
}

func (lbc *loadBalancerController) getConfigMap(ns, name string) (*api.ConfigMap, error) {
Expand Down Expand Up @@ -759,6 +809,7 @@ func (lbc *loadBalancerController) createUpstreams(ngxCfg nginx.Configuration, d

svcKey := fmt.Sprintf("%v/%v", ing.GetNamespace(), path.Backend.ServiceName)
svcObj, svcExists, err := lbc.svcLister.Store.GetByKey(svcKey)

if err != nil {
glog.Infof("error getting service %v from the cache: %v", svcKey, err)
continue
Expand Down Expand Up @@ -833,14 +884,19 @@ func (lbc *loadBalancerController) getPemsFromIngress(data []interface{}) map[st

for _, ingIf := range data {
ing := ingIf.(*extensions.Ingress)

for _, tls := range ing.Spec.TLS {
secretName := tls.SecretName
secret, err := lbc.client.Secrets(ing.Namespace).Get(secretName)
secretKey := fmt.Sprintf("%s/%s", ing.Namespace, secretName)
secretInterface, exists, err := lbc.secrLister.Store.GetByKey(secretKey)
if err != nil {
glog.Warningf("Error retriveing secret %v for ing %v: %v", secretName, ing.Name, err)
continue
}
if !exists {
glog.Warningf("Secret %v is not existing", secretKey)
continue
}
secret := secretInterface.(*api.Secret)
cert, ok := secret.Data[api.TLSCertKey]
if !ok {
glog.Warningf("Secret %v has no private key", secretName)
Expand Down Expand Up @@ -882,6 +938,22 @@ func (lbc *loadBalancerController) getPemsFromIngress(data []interface{}) map[st
return pems
}

// check if secret is referenced in this controller's config
func (lbc *loadBalancerController) secrReferenced(namespace string, name string) bool {
for _, ingIf := range lbc.ingLister.Store.List() {
ing := ingIf.(*extensions.Ingress)
if ing.Namespace != namespace {
continue
}
for _, tls := range ing.Spec.TLS {
if tls.SecretName == name {
return true
}
}
}
return false
}

// getEndpoints returns a list of <endpoint ip>:<port> for a given service/target port combination.
func (lbc *loadBalancerController) getEndpoints(s *api.Service, servicePort intstr.IntOrString, proto api.Protocol, hz *healthcheck.Upstream) []nginx.UpstreamServer {
glog.V(3).Infof("getting endpoints for service %v/%v and port %v", s.Namespace, s.Name, servicePort.String())
Expand Down Expand Up @@ -1026,6 +1098,7 @@ func (lbc *loadBalancerController) Run() {
go lbc.ingController.Run(lbc.stopCh)
go lbc.endpController.Run(lbc.stopCh)
go lbc.svcController.Run(lbc.stopCh)
go lbc.secrController.Run(lbc.stopCh)
go lbc.mapController.Run(lbc.stopCh)

go lbc.syncQueue.run(time.Second, lbc.stopCh)
Expand Down
5 changes: 5 additions & 0 deletions ingress/controllers/nginx/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ type StoreToIngressLister struct {
cache.Store
}

// StoreToSecretsLister makes a Store that lists Secrets.
type StoreToSecretsLister struct {
cache.Store
}

// StoreToConfigmapLister makes a Store that lists Configmap.
type StoreToConfigmapLister struct {
cache.Store
Expand Down

0 comments on commit 9b9c7da

Please sign in to comment.