Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement LeaderElectionRunnable interface for CertRotator #45

Merged
merged 2 commits into from
Sep 28, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 49 additions & 23 deletions pkg/rotator/rotator.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const (

var crLog = logf.Log.WithName("cert-rotation")

//WebhookType it the type of webhook, either validating/mutating webhook, a CRD conversion webhook, or an extension API server
// WebhookType it the type of webhook, either validating/mutating webhook, a CRD conversion webhook, or an extension API server
type WebhookType int

const (
Expand All @@ -61,8 +61,20 @@ const (
)

var _ manager.Runnable = &CertRotator{}
var _ manager.LeaderElectionRunnable = &CertRotator{}
var _ manager.Runnable = controllerWrapper{}
var _ manager.LeaderElectionRunnable = controllerWrapper{}

//WebhookInfo is used by the rotator to receive info about resources to be updated with certificates
type controllerWrapper struct {
controller.Controller
needLeaderElection bool
}

func (cw controllerWrapper) NeedLeaderElection() bool {
return cw.needLeaderElection
}

// WebhookInfo is used by the rotator to receive info about resources to be updated with certificates
type WebhookInfo struct {
//Name is the name of the webhook for a validating or mutating webhook, or the CRD name in case of a CRD conversion webhook
Name string
Expand Down Expand Up @@ -104,13 +116,14 @@ func AddRotator(mgr manager.Manager, cr *CertRotator) error {
}

reconciler := &ReconcileWH{
cache: cache,
writer: mgr.GetClient(), // TODO
scheme: mgr.GetScheme(),
ctx: context.Background(),
secretKey: cr.SecretKey,
wasCAInjected: cr.wasCAInjected,
webhooks: cr.Webhooks,
cache: cache,
writer: mgr.GetClient(), // TODO
scheme: mgr.GetScheme(),
ctx: context.Background(),
secretKey: cr.SecretKey,
wasCAInjected: cr.wasCAInjected,
webhooks: cr.Webhooks,
needLeaderElection: cr.RequireLeaderElection,
}
if err := addController(mgr, reconciler); err != nil {
return err
Expand Down Expand Up @@ -147,8 +160,9 @@ type SyncingReader interface {

// CertRotator contains cert artifacts and a channel to close when the certs are ready.
type CertRotator struct {
reader SyncingReader
writer client.Writer
reader SyncingReader
writer client.Writer

SecretKey types.NamespacedName
CertDir string
CAName string
Expand All @@ -158,10 +172,18 @@ type CertRotator struct {
Webhooks []WebhookInfo
RestartOnSecretRefresh bool
ExtKeyUsages *[]x509.ExtKeyUsage
certsMounted chan struct{}
certsNotMounted chan struct{}
wasCAInjected *atomic.Bool
caNotInjected chan struct{}
// RequireLeaderElection should be set to true if the CertRotator needs to
// be run in the leader election mode.
RequireLeaderElection bool

certsMounted chan struct{}
certsNotMounted chan struct{}
wasCAInjected *atomic.Bool
caNotInjected chan struct{}
}

func (cr *CertRotator) NeedLeaderElection() bool {
return cr.RequireLeaderElection
}

// Start starts the CertRotator runnable to rotate certs and ensure the certs are ready.
Expand Down Expand Up @@ -578,10 +600,13 @@ func reconcileSecretAndWebhookMapFunc(webhook WebhookInfo, r *ReconcileWH) func(
// add adds a new Controller to mgr with r as the reconcile.Reconciler
func addController(mgr manager.Manager, r *ReconcileWH) error {
// Create a new controller
c, err := controller.New("cert-rotator", mgr, controller.Options{Reconciler: r})
c, err := controller.NewUnmanaged("cert-rotator", mgr, controller.Options{Reconciler: r})
if err != nil {
return err
}
if err := mgr.Add(controllerWrapper{c, r.needLeaderElection}); err != nil {
return err
}

err = c.Watch(
source.NewKindWithCache(&corev1.Secret{}, r.cache),
Expand Down Expand Up @@ -611,13 +636,14 @@ var _ reconcile.Reconciler = &ReconcileWH{}
// ReconcileWH reconciles a validatingwebhookconfiguration, making sure it
// has the appropriate CA cert
type ReconcileWH struct {
writer client.Writer
cache cache.Cache
scheme *runtime.Scheme
ctx context.Context
secretKey types.NamespacedName
webhooks []WebhookInfo
wasCAInjected *atomic.Bool
writer client.Writer
cache cache.Cache
scheme *runtime.Scheme
ctx context.Context
secretKey types.NamespacedName
webhooks []WebhookInfo
wasCAInjected *atomic.Bool
needLeaderElection bool
}

// Reconcile reads that state of the cluster for a validatingwebhookconfiguration
Expand Down