Skip to content

Commit

Permalink
Don't update the mutating webhook if we aren't managing it automatica…
Browse files Browse the repository at this point in the history
…lly (#344)

* If the webhook is missing from cache, fetch it

I'm not sure under what circumstances the cache will be missing the
webhook config, but it seems to happen sometimes.

* Only fetch the webhook if flagAutoName is used; otherwise we don't know the webhook to patch

* Rename updateWebhook to updateCertificate

* Use Lister instead of using cache directly
  • Loading branch information
Christopher Swenson authored May 17, 2022
1 parent ccf81fa commit 15a80ff
Showing 1 changed file with 18 additions and 16 deletions.
34 changes: 18 additions & 16 deletions subcommand/injector/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"k8s.io/client-go/informers"
informerv1 "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/listers/admissionregistration/v1"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/cache"
)
Expand Down Expand Up @@ -357,7 +358,7 @@ func (c *Command) certWatcher(ctx context.Context, ch <-chan cert.Bundle, client
<-timer.C
}

err := c.updateWebhook(ctx, clientset, bundle, webhooksCache, leaderElector, log)
err := c.updateCertificate(ctx, clientset, bundle, webhooksCache, leaderElector, log)
if err != nil {
// retry after a delay
timer.Reset(expBackoff.NextBackOff())
Expand All @@ -368,20 +369,11 @@ func (c *Command) certWatcher(ctx context.Context, ch <-chan cert.Bundle, client
}
}

func (c *Command) updateWebhook(ctx context.Context, clientset *kubernetes.Clientset, bundle cert.Bundle, webhooksCache cache.Store, leaderElector leader.Elector, log hclog.Logger) error {
item, exists, err := webhooksCache.GetByKey(c.flagAutoName)
if !exists {
log.Warn("Could not find webhook config in cache. Trying again...", "item", item)
return fmt.Errorf("could not find webhook config in cache")
} else if err != nil {
log.Warn(fmt.Sprintf("Could not find webhook config in cache: %s. Trying again...", err))
return err
}
config, ok := item.(*adminv1.MutatingWebhookConfiguration)
if !ok {
log.Error("Got unknown object from cache; expected &MutatingWebhookConfiguration", "item", item)
}
func (c *Command) fetchWebhook(ctx context.Context, clientset *kubernetes.Clientset) (*adminv1.MutatingWebhookConfiguration, error) {
return clientset.AdmissionregistrationV1().MutatingWebhookConfigurations().Get(ctx, c.flagAutoName, metav1.GetOptions{})
}

func (c *Command) updateCertificate(ctx context.Context, clientset *kubernetes.Clientset, bundle cert.Bundle, webhooksCache v1.MutatingWebhookConfigurationLister, leaderElector leader.Elector, log hclog.Logger) error {
crt, err := tls.X509KeyPair(bundle.Cert, bundle.Key)
if err != nil {
log.Warn(fmt.Sprintf("Could not load TLS keypair: %s. Trying again...", err))
Expand All @@ -401,6 +393,16 @@ func (c *Command) updateWebhook(ctx context.Context, clientset *kubernetes.Clien

// If there is an MWC name set, then update the CA bundle.
if isLeader && c.flagAutoName != "" && len(bundle.CACert) > 0 {
config, err := webhooksCache.Get(c.flagAutoName)
if err != nil {
log.Warn("Getting webhook config from cache failed", "err", err)
config, err = c.fetchWebhook(ctx, clientset)
if err != nil {
log.Warn("Fetching webhook config directly failed; will try again", "err", err)
return err
}
}

// Check the current bundles and only update if necessary.
if len(config.Webhooks) == 0 || !bytes.Equal(config.Webhooks[0].ClientConfig.CABundle, bundle.CACert) {
err = c.updateCABundle(ctx, &bundle, clientset)
Expand All @@ -418,7 +420,7 @@ func (c *Command) updateWebhook(ctx context.Context, clientset *kubernetes.Clien
return nil
}

func watchWebhooks(ctx context.Context, clientset *kubernetes.Clientset) (cache.Store, <-chan interface{}, error) {
func watchWebhooks(ctx context.Context, clientset *kubernetes.Clientset) (v1.MutatingWebhookConfigurationLister, <-chan interface{}, error) {
factory := informers.NewSharedInformerFactoryWithOptions(clientset, 0)
webhooks := factory.Admissionregistration().V1().MutatingWebhookConfigurations()
go webhooks.Informer().Run(ctx.Done())
Expand All @@ -427,7 +429,7 @@ func watchWebhooks(ctx context.Context, clientset *kubernetes.Clientset) (cache.
}
notifyCh := make(webhookWatcher)
webhooks.Informer().AddEventHandler(notifyCh)
return webhooks.Informer().GetStore(), notifyCh, nil
return webhooks.Lister(), notifyCh, nil
}

type webhookWatcher chan interface{}
Expand Down

0 comments on commit 15a80ff

Please sign in to comment.