mirror of
https://github.com/projectcapsule/capsule.git
synced 2026-02-14 18:09:58 +00:00
Implementing Capsule certificate validation (#44)
This commit is contained in:
committed by
GitHub
parent
ef51e6dee0
commit
1767bcee12
@@ -20,6 +20,7 @@ import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
@@ -49,6 +50,50 @@ func (r *CaReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
Complete(r)
|
||||
}
|
||||
|
||||
func (r CaReconciler) UpdateValidatingWebhookConfiguration(wg *sync.WaitGroup, ch chan error, caBundle []byte) {
|
||||
defer wg.Done()
|
||||
|
||||
var err error
|
||||
|
||||
ch <- retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
vw := &v1.ValidatingWebhookConfiguration{}
|
||||
err = r.Get(context.TODO(), types.NamespacedName{Name: "capsule-validating-webhook-configuration"}, vw)
|
||||
if err != nil {
|
||||
r.Log.Error(err, "cannot retrieve ValidatingWebhookConfiguration")
|
||||
return err
|
||||
}
|
||||
for i, w := range vw.Webhooks {
|
||||
// Updating CABundle only in case of an internal service reference
|
||||
if w.ClientConfig.Service != nil {
|
||||
vw.Webhooks[i].ClientConfig.CABundle = caBundle
|
||||
}
|
||||
}
|
||||
return r.Update(context.TODO(), vw, &client.UpdateOptions{})
|
||||
})
|
||||
}
|
||||
|
||||
func (r CaReconciler) UpdateMutatingWebhookConfiguration(wg *sync.WaitGroup, ch chan error, caBundle []byte) {
|
||||
defer wg.Done()
|
||||
|
||||
var err error
|
||||
|
||||
ch <- retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
mw := &v1.MutatingWebhookConfiguration{}
|
||||
err = r.Get(context.TODO(), types.NamespacedName{Name: "capsule-mutating-webhook-configuration"}, mw)
|
||||
if err != nil {
|
||||
r.Log.Error(err, "cannot retrieve MutatingWebhookConfiguration")
|
||||
return err
|
||||
}
|
||||
for i, w := range mw.Webhooks {
|
||||
// Updating CABundle only in case of an internal service reference
|
||||
if w.ClientConfig.Service != nil {
|
||||
mw.Webhooks[i].ClientConfig.CABundle = caBundle
|
||||
}
|
||||
}
|
||||
return r.Update(context.TODO(), mw, &client.UpdateOptions{})
|
||||
})
|
||||
}
|
||||
|
||||
func (r CaReconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
|
||||
var err error
|
||||
|
||||
@@ -93,48 +138,21 @@ func (r CaReconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
|
||||
certSecretKey: crt.Bytes(),
|
||||
privateKeySecretKey: key.Bytes(),
|
||||
}
|
||||
// Updating ValidatingWebhookConfiguration CA bundle
|
||||
err = retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
vw := &v1.ValidatingWebhookConfiguration{}
|
||||
err = r.Get(context.TODO(), types.NamespacedName{Name: "capsule-validating-webhook-configuration"}, vw)
|
||||
|
||||
wg := &sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
ch := make(chan error, 2)
|
||||
|
||||
go r.UpdateMutatingWebhookConfiguration(wg, ch, crt.Bytes())
|
||||
go r.UpdateValidatingWebhookConfiguration(wg, ch, crt.Bytes())
|
||||
|
||||
wg.Wait()
|
||||
close(ch)
|
||||
|
||||
for err = range ch {
|
||||
if err != nil {
|
||||
r.Log.Error(err, "cannot retrieve ValidatingWebhookConfiguration")
|
||||
return err
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
for i, w := range vw.Webhooks {
|
||||
// Updating CABundle only in case of an internal service reference
|
||||
if w.ClientConfig.Service != nil {
|
||||
vw.Webhooks[i].ClientConfig.CABundle = instance.Data[certSecretKey]
|
||||
}
|
||||
}
|
||||
err = retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
return r.Update(context.TODO(), vw, &client.UpdateOptions{})
|
||||
})
|
||||
if err != nil {
|
||||
r.Log.Error(err, "cannot update MutatingWebhookConfiguration webhooks CA bundle")
|
||||
return err
|
||||
}
|
||||
return r.Update(context.TODO(), vw, &client.UpdateOptions{})
|
||||
})
|
||||
// Updating MutatingWebhookConfiguration CA bundle
|
||||
err = retry.RetryOnConflict(retry.DefaultBackoff, func() error {
|
||||
mw := &v1.MutatingWebhookConfiguration{}
|
||||
err = r.Get(context.TODO(), types.NamespacedName{Name: "capsule-mutating-webhook-configuration"}, mw)
|
||||
if err != nil {
|
||||
r.Log.Error(err, "cannot retrieve MutatingWebhookConfiguration")
|
||||
return err
|
||||
}
|
||||
for i, w := range mw.Webhooks {
|
||||
// Updating CABundle only in case of an internal service reference
|
||||
if w.ClientConfig.Service != nil {
|
||||
mw.Webhooks[i].ClientConfig.CABundle = instance.Data[certSecretKey]
|
||||
}
|
||||
}
|
||||
return r.Update(context.TODO(), mw, &client.UpdateOptions{})
|
||||
})
|
||||
if err != nil {
|
||||
r.Log.Error(err, "cannot update MutatingWebhookConfiguration webhooks CA bundle")
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ func (r TlsReconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
|
||||
for _, key := range []string{certSecretKey, privateKeySecretKey} {
|
||||
if _, ok := instance.Data[key]; !ok {
|
||||
shouldCreate = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@@ -99,9 +100,11 @@ func (r TlsReconciler) Reconcile(request ctrl.Request) (ctrl.Result, error) {
|
||||
return reconcile.Result{}, err
|
||||
}
|
||||
|
||||
rq = time.Duration(c.NotAfter.Unix()-time.Now().Unix()) * time.Second
|
||||
if time.Now().After(c.NotAfter) {
|
||||
r.Log.Info("Capsule TLS is expired, cleaning to obtain a new one")
|
||||
rq = time.Until(c.NotAfter)
|
||||
|
||||
err = ca.ValidateCert(c)
|
||||
if err != nil {
|
||||
r.Log.Info("Capsule TLS is expired or invalid, cleaning to obtain a new one")
|
||||
instance.Data = map[string][]byte{}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ type Ca interface {
|
||||
CaCertificatePem() (b *bytes.Buffer, err error)
|
||||
CaPrivateKeyPem() (b *bytes.Buffer, err error)
|
||||
ExpiresIn(now time.Time) (time.Duration, error)
|
||||
ValidateCert(certificate *x509.Certificate) error
|
||||
}
|
||||
|
||||
type CapsuleCa struct {
|
||||
@@ -39,6 +40,17 @@ type CapsuleCa struct {
|
||||
privateKey *rsa.PrivateKey
|
||||
}
|
||||
|
||||
func (c CapsuleCa) ValidateCert(certificate *x509.Certificate) (err error) {
|
||||
pool := x509.NewCertPool()
|
||||
pool.AddCert(c.ca)
|
||||
|
||||
_, err = certificate.Verify(x509.VerifyOptions{
|
||||
Roots: pool,
|
||||
CurrentTime: time.Time{},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
func (c CapsuleCa) isAlreadyValid(now time.Time) bool {
|
||||
return now.After(c.ca.NotBefore)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user