mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-28 02:18:15 +00:00
refactor: create a package for controllers and move certmanager in it (#3782)
* refactor: use typed informers and add tombstone support to webhookconfig Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com> * refactor: remove unstructured usage from webhookconfig Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com> * refactor: cert manager controller Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
This commit is contained in:
parent
207459cc40
commit
400e486b46
4 changed files with 38 additions and 57 deletions
|
@ -24,6 +24,7 @@ import (
|
|||
kyvernoinformer "github.com/kyverno/kyverno/pkg/client/informers/externalversions"
|
||||
"github.com/kyverno/kyverno/pkg/common"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/controllers/certmanager"
|
||||
"github.com/kyverno/kyverno/pkg/cosign"
|
||||
dclient "github.com/kyverno/kyverno/pkg/dclient"
|
||||
event "github.com/kyverno/kyverno/pkg/event"
|
||||
|
@ -342,13 +343,7 @@ func main() {
|
|||
)
|
||||
|
||||
certRenewer := ktls.NewCertRenewer(kubeClient, clientConfig, ktls.CertRenewalInterval, ktls.CertValidityDuration, serverIP, log.Log.WithName("CertRenewer"))
|
||||
certManager, err := webhookconfig.NewCertManager(
|
||||
kubeKyvernoInformer.Core().V1().Secrets(),
|
||||
kubeClient,
|
||||
certRenewer,
|
||||
log.Log.WithName("CertManager"),
|
||||
stopCh,
|
||||
)
|
||||
certManager, err := certmanager.NewController(kubeKyvernoInformer.Core().V1().Secrets(), kubeClient, certRenewer)
|
||||
if err != nil {
|
||||
setupLog.Error(err, "failed to initialize CertManager")
|
||||
os.Exit(1)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package webhookconfig
|
||||
package certmanager
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
@ -6,7 +6,6 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/go-logr/logr"
|
||||
"github.com/kyverno/kyverno/pkg/common"
|
||||
"github.com/kyverno/kyverno/pkg/config"
|
||||
"github.com/kyverno/kyverno/pkg/tls"
|
||||
|
@ -16,7 +15,7 @@ import (
|
|||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
type Controller interface {
|
||||
// Run starts the certManager
|
||||
Run(stopCh <-chan struct{})
|
||||
|
||||
|
@ -27,143 +26,119 @@ type Interface interface {
|
|||
// GetTLSPemPair gets the existing TLSPemPair from the secret
|
||||
GetTLSPemPair() (*tls.PemPair, error)
|
||||
}
|
||||
type certManager struct {
|
||||
|
||||
type controller struct {
|
||||
renewer *tls.CertRenewer
|
||||
secretInformer informerv1.SecretInformer
|
||||
secretQueue chan bool
|
||||
stopCh <-chan struct{}
|
||||
log logr.Logger
|
||||
}
|
||||
|
||||
func NewCertManager(secretInformer informerv1.SecretInformer, kubeClient kubernetes.Interface, certRenewer *tls.CertRenewer, log logr.Logger, stopCh <-chan struct{}) (Interface, error) {
|
||||
manager := &certManager{
|
||||
func NewController(secretInformer informerv1.SecretInformer, kubeClient kubernetes.Interface, certRenewer *tls.CertRenewer) (Controller, error) {
|
||||
manager := &controller{
|
||||
renewer: certRenewer,
|
||||
secretInformer: secretInformer,
|
||||
secretQueue: make(chan bool, 1),
|
||||
stopCh: stopCh,
|
||||
log: log,
|
||||
}
|
||||
|
||||
secretInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
|
||||
AddFunc: manager.addSecretFunc,
|
||||
UpdateFunc: manager.updateSecretFunc,
|
||||
})
|
||||
|
||||
return manager, nil
|
||||
}
|
||||
|
||||
func (m *certManager) addSecretFunc(obj interface{}) {
|
||||
func (m *controller) addSecretFunc(obj interface{}) {
|
||||
secret := obj.(*v1.Secret)
|
||||
if secret.GetNamespace() != config.KyvernoNamespace {
|
||||
return
|
||||
}
|
||||
|
||||
val, ok := secret.GetAnnotations()[tls.SelfSignedAnnotation]
|
||||
if !ok || val != "true" {
|
||||
return
|
||||
}
|
||||
|
||||
m.secretQueue <- true
|
||||
}
|
||||
|
||||
func (m *certManager) updateSecretFunc(oldObj interface{}, newObj interface{}) {
|
||||
func (m *controller) updateSecretFunc(oldObj interface{}, newObj interface{}) {
|
||||
old := oldObj.(*v1.Secret)
|
||||
new := newObj.(*v1.Secret)
|
||||
if new.GetNamespace() != config.KyvernoNamespace {
|
||||
return
|
||||
}
|
||||
|
||||
val, ok := new.GetAnnotations()[tls.SelfSignedAnnotation]
|
||||
if !ok || val != "true" {
|
||||
return
|
||||
}
|
||||
|
||||
if reflect.DeepEqual(old.DeepCopy().Data, new.DeepCopy().Data) {
|
||||
return
|
||||
}
|
||||
|
||||
m.secretQueue <- true
|
||||
m.log.V(4).Info("secret updated, reconciling webhook configurations")
|
||||
logger.V(4).Info("secret updated, reconciling webhook configurations")
|
||||
}
|
||||
|
||||
func (m *certManager) InitTLSPemPair() {
|
||||
func (m *controller) InitTLSPemPair() {
|
||||
_, err := m.renewer.InitTLSPemPair()
|
||||
if err != nil {
|
||||
m.log.Error(err, "initialization error")
|
||||
logger.Error(err, "initialization error")
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
func (m *certManager) GetTLSPemPair() (*tls.PemPair, error) {
|
||||
func (m *controller) GetTLSPemPair() (*tls.PemPair, error) {
|
||||
var keyPair *tls.PemPair
|
||||
var err error
|
||||
|
||||
retryReadTLS := func() error {
|
||||
keyPair, err = tls.ReadTLSPair(m.renewer.ClientConfig(), m.renewer.Client())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
m.log.Info("read TLS pem pair from the secret")
|
||||
logger.Info("read TLS pem pair from the secret")
|
||||
return nil
|
||||
}
|
||||
|
||||
msg := "failed to read TLS pair"
|
||||
f := common.RetryFunc(time.Second, time.Minute, retryReadTLS, msg, m.log.WithName("GetTLSPemPair/Retry"))
|
||||
err = f()
|
||||
|
||||
return keyPair, err
|
||||
f := common.RetryFunc(time.Second, time.Minute, retryReadTLS, msg, logger.WithName("GetTLSPemPair/Retry"))
|
||||
return keyPair, f()
|
||||
}
|
||||
|
||||
func (m *certManager) Run(stopCh <-chan struct{}) {
|
||||
m.log.Info("start managing certificate")
|
||||
func (m *controller) Run(stopCh <-chan struct{}) {
|
||||
logger.Info("start managing certificate")
|
||||
certsRenewalTicker := time.NewTicker(tls.CertRenewalInterval)
|
||||
defer certsRenewalTicker.Stop()
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-certsRenewalTicker.C:
|
||||
valid, err := m.renewer.ValidCert()
|
||||
if err != nil {
|
||||
m.log.Error(err, "failed to validate cert")
|
||||
|
||||
logger.Error(err, "failed to validate cert")
|
||||
if !strings.Contains(err.Error(), tls.ErrorsNotFound) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if valid {
|
||||
continue
|
||||
}
|
||||
|
||||
m.log.Info("rootCA is about to expire, trigger a rolling update to renew the cert")
|
||||
logger.Info("rootCA is about to expire, trigger a rolling update to renew the cert")
|
||||
if err := m.renewer.RollingUpdate(); err != nil {
|
||||
m.log.Error(err, "unable to trigger a rolling update to renew rootCA, force restarting")
|
||||
logger.Error(err, "unable to trigger a rolling update to renew rootCA, force restarting")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
case <-m.secretQueue:
|
||||
valid, err := m.renewer.ValidCert()
|
||||
if err != nil {
|
||||
m.log.Error(err, "failed to validate cert")
|
||||
|
||||
logger.Error(err, "failed to validate cert")
|
||||
if !strings.Contains(err.Error(), tls.ErrorsNotFound) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if valid {
|
||||
continue
|
||||
}
|
||||
|
||||
m.log.Info("rootCA has changed, updating webhook configurations")
|
||||
logger.Info("rootCA has changed, updating webhook configurations")
|
||||
if err := m.renewer.RollingUpdate(); err != nil {
|
||||
m.log.Error(err, "unable to trigger a rolling update to re-register webhook server, force restarting")
|
||||
logger.Error(err, "unable to trigger a rolling update to re-register webhook server, force restarting")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
case <-m.stopCh:
|
||||
m.log.V(2).Info("stopping cert renewer")
|
||||
case <-stopCh:
|
||||
logger.V(2).Info("stopping cert renewer")
|
||||
return
|
||||
}
|
||||
}
|
5
pkg/controllers/certmanager/log.go
Normal file
5
pkg/controllers/certmanager/log.go
Normal file
|
@ -0,0 +1,5 @@
|
|||
package certmanager
|
||||
|
||||
import "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
|
||||
var logger = log.Log.WithName("certmanager-controller")
|
6
pkg/controllers/controller.go
Normal file
6
pkg/controllers/controller.go
Normal file
|
@ -0,0 +1,6 @@
|
|||
package controllers
|
||||
|
||||
type Controller interface {
|
||||
// Run starts the controller
|
||||
Run(stopCh <-chan struct{})
|
||||
}
|
Loading…
Add table
Reference in a new issue