Merge pull request #424 from aledbf/ca-auth
Manually sync secrets from certificate authentication annotations
This commit is contained in:
commit
448a42a67a
3 changed files with 55 additions and 12 deletions
|
@ -17,8 +17,11 @@ limitations under the License.
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
|
|
||||||
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
|
"k8s.io/ingress/core/pkg/ingress/annotations/auth"
|
||||||
|
@ -47,11 +50,13 @@ type extractorConfig interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type annotationExtractor struct {
|
type annotationExtractor struct {
|
||||||
annotations map[string]parser.IngressAnnotation
|
secretResolver resolver.Secret
|
||||||
|
annotations map[string]parser.IngressAnnotation
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAnnotationExtractor(cfg extractorConfig) annotationExtractor {
|
func newAnnotationExtractor(cfg extractorConfig) annotationExtractor {
|
||||||
return annotationExtractor{
|
return annotationExtractor{
|
||||||
|
cfg,
|
||||||
map[string]parser.IngressAnnotation{
|
map[string]parser.IngressAnnotation{
|
||||||
"BasicDigestAuth": auth.NewParser(auth.AuthDirectory, cfg),
|
"BasicDigestAuth": auth.NewParser(auth.AuthDirectory, cfg),
|
||||||
"ExternalAuth": authreq.NewParser(),
|
"ExternalAuth": authreq.NewParser(),
|
||||||
|
@ -104,6 +109,7 @@ const (
|
||||||
healthCheck = "HealthCheck"
|
healthCheck = "HealthCheck"
|
||||||
sslPassthrough = "SSLPassthrough"
|
sslPassthrough = "SSLPassthrough"
|
||||||
sessionAffinity = "SessionAffinity"
|
sessionAffinity = "SessionAffinity"
|
||||||
|
certificateAuth = "CertificateAuth"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (e *annotationExtractor) SecureUpstream(ing *extensions.Ingress) bool {
|
func (e *annotationExtractor) SecureUpstream(ing *extensions.Ingress) bool {
|
||||||
|
@ -125,3 +131,17 @@ func (e *annotationExtractor) SessionAffinity(ing *extensions.Ingress) *sessiona
|
||||||
val, _ := e.annotations[sessionAffinity].Parse(ing)
|
val, _ := e.annotations[sessionAffinity].Parse(ing)
|
||||||
return val.(*sessionaffinity.AffinityConfig)
|
return val.(*sessionaffinity.AffinityConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (e *annotationExtractor) ContainsCertificateAuth(ing *extensions.Ingress) bool {
|
||||||
|
val, _ := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing)
|
||||||
|
return val != ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *annotationExtractor) CertificateAuthSecret(ing *extensions.Ingress) (*api.Secret, error) {
|
||||||
|
val, _ := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing)
|
||||||
|
if val == "" {
|
||||||
|
return nil, fmt.Errorf("ingress rule %v/%v does not contains the auth-tls-secret annotation", ing.Namespace, ing.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.secretResolver.GetSecret(val)
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -68,13 +69,18 @@ func (ic *GenericController) syncSecret(k interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// create certificates and add or update the item in the store
|
// create certificates and add or update the item in the store
|
||||||
_, exists = ic.sslCertTracker.Get(key)
|
cur, exists := ic.sslCertTracker.Get(key)
|
||||||
if exists {
|
if exists {
|
||||||
glog.V(3).Infof("updating secret %v/%v in the store ", sec.Namespace, sec.Name)
|
s := cur.(*ingress.SSLCert)
|
||||||
|
if reflect.DeepEqual(s, cert) {
|
||||||
|
// no need to update
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
glog.V(3).Infof("updating secret %v/%v in the store", sec.Namespace, sec.Name)
|
||||||
ic.sslCertTracker.Update(key, cert)
|
ic.sslCertTracker.Update(key, cert)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
glog.V(3).Infof("adding secret %v/%v to the store ", sec.Namespace, sec.Name)
|
glog.V(3).Infof("adding secret %v/%v to the store", sec.Namespace, sec.Name)
|
||||||
ic.sslCertTracker.Add(key, cert)
|
ic.sslCertTracker.Add(key, cert)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -100,13 +106,13 @@ func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLC
|
||||||
|
|
||||||
var s *ingress.SSLCert
|
var s *ingress.SSLCert
|
||||||
if okcert && okkey {
|
if okcert && okkey {
|
||||||
glog.V(3).Infof("Found certificate and private key, configuring %v as a TLS Secret", secretName)
|
glog.V(3).Infof("found certificate and private key, configuring %v as a TLS Secret", secretName)
|
||||||
s, err = ssl.AddOrUpdateCertAndKey(nsSecName, cert, key, ca)
|
s, err = ssl.AddOrUpdateCertAndKey(nsSecName, cert, key, ca)
|
||||||
} else if ca != nil {
|
} else if ca != nil {
|
||||||
glog.V(3).Infof("Found only ca.crt, configuring %v as an Certificate Authentication secret", secretName)
|
glog.V(3).Infof("found only ca.crt, configuring %v as an Certificate Authentication secret", secretName)
|
||||||
s, err = ssl.AddCertAuth(nsSecName, ca)
|
s, err = ssl.AddCertAuth(nsSecName, ca)
|
||||||
} else {
|
} else {
|
||||||
return nil, fmt.Errorf("No keypair or CA cert could be found in %v", secretName)
|
return nil, fmt.Errorf("ko keypair or CA cert could be found in %v", secretName)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -122,10 +128,14 @@ func (ic *GenericController) getPemCertificate(secretName string) (*ingress.SSLC
|
||||||
func (ic *GenericController) secrReferenced(name, namespace string) bool {
|
func (ic *GenericController) secrReferenced(name, namespace string) bool {
|
||||||
for _, ingIf := range ic.ingLister.Store.List() {
|
for _, ingIf := range ic.ingLister.Store.List() {
|
||||||
ing := ingIf.(*extensions.Ingress)
|
ing := ingIf.(*extensions.Ingress)
|
||||||
str, err := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing)
|
|
||||||
if err == nil && str == fmt.Sprintf("%v/%v", namespace, name) {
|
if ic.annotations.ContainsCertificateAuth(ing) {
|
||||||
return true
|
str, _ := parser.GetStringAnnotation("ingress.kubernetes.io/auth-tls-secret", ing)
|
||||||
|
if str == fmt.Sprintf("%v/%v", namespace, name) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ing.Namespace != namespace {
|
if ing.Namespace != namespace {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,6 +170,12 @@ func newIngressController(config *Configuration) *GenericController {
|
||||||
}
|
}
|
||||||
ic.recorder.Eventf(addIng, api.EventTypeNormal, "CREATE", fmt.Sprintf("Ingress %s/%s", addIng.Namespace, addIng.Name))
|
ic.recorder.Eventf(addIng, api.EventTypeNormal, "CREATE", fmt.Sprintf("Ingress %s/%s", addIng.Namespace, addIng.Name))
|
||||||
ic.syncQueue.Enqueue(obj)
|
ic.syncQueue.Enqueue(obj)
|
||||||
|
if ic.annotations.ContainsCertificateAuth(addIng) {
|
||||||
|
s, err := ic.annotations.CertificateAuthSecret(addIng)
|
||||||
|
if err == nil {
|
||||||
|
ic.syncSecret(fmt.Sprintf("%v/%v", s.Namespace, s.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
DeleteFunc: func(obj interface{}) {
|
DeleteFunc: func(obj interface{}) {
|
||||||
delIng := obj.(*extensions.Ingress)
|
delIng := obj.(*extensions.Ingress)
|
||||||
|
@ -209,6 +215,13 @@ func newIngressController(config *Configuration) *GenericController {
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if ic.annotations.ContainsCertificateAuth(upIng) {
|
||||||
|
s, err := ic.annotations.CertificateAuthSecret(upIng)
|
||||||
|
if err == nil {
|
||||||
|
ic.syncSecret(fmt.Sprintf("%v/%v", s.Namespace, s.Name))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ic.syncQueue.Enqueue(cur)
|
ic.syncQueue.Enqueue(cur)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -280,11 +293,11 @@ func newIngressController(config *Configuration) *GenericController {
|
||||||
&api.Endpoints{}, ic.cfg.ResyncPeriod, eventHandler)
|
&api.Endpoints{}, ic.cfg.ResyncPeriod, eventHandler)
|
||||||
|
|
||||||
ic.secrLister.Store, ic.secrController = cache.NewInformer(
|
ic.secrLister.Store, ic.secrController = cache.NewInformer(
|
||||||
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "secrets", ic.cfg.Namespace, fields.Everything()),
|
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "secrets", api.NamespaceAll, fields.Everything()),
|
||||||
&api.Secret{}, ic.cfg.ResyncPeriod, secrEventHandler)
|
&api.Secret{}, ic.cfg.ResyncPeriod, secrEventHandler)
|
||||||
|
|
||||||
ic.mapLister.Store, ic.mapController = cache.NewInformer(
|
ic.mapLister.Store, ic.mapController = cache.NewInformer(
|
||||||
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", ic.cfg.Namespace, fields.Everything()),
|
cache.NewListWatchFromClient(ic.cfg.Client.Core().RESTClient(), "configmaps", api.NamespaceAll, fields.Everything()),
|
||||||
&api.ConfigMap{}, ic.cfg.ResyncPeriod, mapEventHandler)
|
&api.ConfigMap{}, ic.cfg.ResyncPeriod, mapEventHandler)
|
||||||
|
|
||||||
ic.svcLister.Indexer, ic.svcController = cache.NewIndexerInformer(
|
ic.svcLister.Indexer, ic.svcController = cache.NewIndexerInformer(
|
||||||
|
|
Loading…
Reference in a new issue