1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-31 03:45:17 +00:00

feat: fetch tls certificate dynamically (#3851)

Signed-off-by: Charles-Edouard Brétéché <charled.breteche@gmail.com>
This commit is contained in:
Charles-Edouard Brétéché 2022-05-10 11:55:39 +02:00 committed by GitHub
parent e2cf6cea5a
commit a981957a9d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 33 additions and 37 deletions

View file

@ -335,7 +335,7 @@ func main() {
setupLog.Error(err, "failed to initialize CertRenewer") setupLog.Error(err, "failed to initialize CertRenewer")
os.Exit(1) os.Exit(1)
} }
certManager, err := certmanager.NewController(kubeKyvernoInformer.Core().V1().Secrets(), kubeClient, certRenewer) certManager, err := certmanager.NewController(kubeKyvernoInformer.Core().V1().Secrets(), certRenewer)
if err != nil { if err != nil {
setupLog.Error(err, "failed to initialize CertManager") setupLog.Error(err, "failed to initialize CertManager")
os.Exit(1) os.Exit(1)
@ -383,13 +383,6 @@ func main() {
// the webhook server runs across all instances // the webhook server runs across all instances
openAPIController := startOpenAPIController(dynamicClient, stopCh) openAPIController := startOpenAPIController(dynamicClient, stopCh)
var tlsPair *tls.PemPair
tlsPair, err = certManager.GetTLSPemPair()
if err != nil {
setupLog.Error(err, "Failed to get TLS key/certificate pair")
os.Exit(1)
}
// WEBHOOK // WEBHOOK
// - https server to provide endpoints called based on rules defined in Mutating & Validation webhook configuration // - https server to provide endpoints called based on rules defined in Mutating & Validation webhook configuration
// - reports the results based on the response from the policy engine: // - reports the results based on the response from the policy engine:
@ -399,7 +392,7 @@ func main() {
server, err := webhooks.NewWebhookServer( server, err := webhooks.NewWebhookServer(
kyvernoClient, kyvernoClient,
dynamicClient, dynamicClient,
tlsPair, certManager.GetTLSPemPair,
kyvernoInformer.Kyverno().V1beta1().UpdateRequests(), kyvernoInformer.Kyverno().V1beta1().UpdateRequests(),
kyvernoV1.ClusterPolicies(), kyvernoV1.ClusterPolicies(),
kubeInformer.Rbac().V1().RoleBindings(), kubeInformer.Rbac().V1().RoleBindings(),

View file

@ -6,12 +6,11 @@ import (
"strings" "strings"
"time" "time"
"github.com/kyverno/kyverno/pkg/common"
"github.com/kyverno/kyverno/pkg/config" "github.com/kyverno/kyverno/pkg/config"
"github.com/kyverno/kyverno/pkg/tls" "github.com/kyverno/kyverno/pkg/tls"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
informerv1 "k8s.io/client-go/informers/core/v1" informerv1 "k8s.io/client-go/informers/core/v1"
"k8s.io/client-go/kubernetes" listersv1 "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/cache"
) )
@ -28,16 +27,16 @@ type Controller interface {
} }
type controller struct { type controller struct {
renewer *tls.CertRenewer renewer *tls.CertRenewer
secretInformer informerv1.SecretInformer secretLister listersv1.SecretLister
secretQueue chan bool secretQueue chan bool
} }
func NewController(secretInformer informerv1.SecretInformer, kubeClient kubernetes.Interface, certRenewer *tls.CertRenewer) (Controller, error) { func NewController(secretInformer informerv1.SecretInformer, certRenewer *tls.CertRenewer) (Controller, error) {
manager := &controller{ manager := &controller{
renewer: certRenewer, renewer: certRenewer,
secretInformer: secretInformer, secretLister: secretInformer.Lister(),
secretQueue: make(chan bool, 1), secretQueue: make(chan bool, 1),
} }
secretInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ secretInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: manager.addSecretFunc, AddFunc: manager.addSecretFunc,
@ -73,19 +72,14 @@ func (m *controller) InitTLSPemPair() {
} }
func (m *controller) GetTLSPemPair() (*tls.PemPair, error) { func (m *controller) GetTLSPemPair() (*tls.PemPair, error) {
var keyPair *tls.PemPair secret, err := m.secretLister.Secrets(config.KyvernoNamespace).Get(m.renewer.GenerateTLSPairSecretName())
var err error if err != nil {
retryReadTLS := func() error { return nil, err
keyPair, err = tls.ReadTLSPair(m.renewer.ClientConfig(), m.renewer.Client())
if err != nil {
return err
}
logger.Info("read TLS pem pair from the secret")
return nil
} }
msg := "failed to read TLS pair" return &tls.PemPair{
f := common.RetryFunc(time.Second, time.Minute, retryReadTLS, msg, logger.WithName("GetTLSPemPair/Retry")) Certificate: secret.Data[v1.TLSCertKey],
return keyPair, f() PrivateKey: secret.Data[v1.TLSPrivateKeyKey],
}, nil
} }
func (m *controller) Run(stopCh <-chan struct{}) { func (m *controller) Run(stopCh <-chan struct{}) {

View file

@ -97,7 +97,7 @@ type WebhookServer struct {
func NewWebhookServer( func NewWebhookServer(
kyvernoClient kyvernoclient.Interface, kyvernoClient kyvernoclient.Interface,
client client.Interface, client client.Interface,
tlsPair *tlsutils.PemPair, tlsPair func() (*tlsutils.PemPair, error),
urInformer urinformer.UpdateRequestInformer, urInformer urinformer.UpdateRequestInformer,
pInformer kyvernoinformer.ClusterPolicyInformer, pInformer kyvernoinformer.ClusterPolicyInformer,
rbInformer rbacinformer.RoleBindingInformer, rbInformer rbacinformer.RoleBindingInformer,
@ -122,10 +122,6 @@ func NewWebhookServer(
if tlsPair == nil { if tlsPair == nil {
return nil, errors.New("NewWebhookServer is not initialized properly") return nil, errors.New("NewWebhookServer is not initialized properly")
} }
pair, err := tls.X509KeyPair(tlsPair.Certificate, tlsPair.PrivateKey)
if err != nil {
return nil, err
}
ws := &WebhookServer{ ws := &WebhookServer{
client: client, client: client,
kyvernoClient: kyvernoClient, kyvernoClient: kyvernoClient,
@ -158,8 +154,21 @@ func NewWebhookServer(
mux.HandlerFunc("GET", config.LivenessServicePath, handlers.Probe(ws.webhookRegister.Check)) mux.HandlerFunc("GET", config.LivenessServicePath, handlers.Probe(ws.webhookRegister.Check))
mux.HandlerFunc("GET", config.ReadinessServicePath, handlers.Probe(nil)) mux.HandlerFunc("GET", config.ReadinessServicePath, handlers.Probe(nil))
ws.server = &http.Server{ ws.server = &http.Server{
Addr: ":9443", // Listen on port for HTTPS requests Addr: ":9443", // Listen on port for HTTPS requests
TLSConfig: &tls.Config{Certificates: []tls.Certificate{pair}, MinVersion: tls.VersionTLS12}, TLSConfig: &tls.Config{
GetCertificate: func(*tls.ClientHelloInfo) (*tls.Certificate, error) {
tlsPair, err := tlsPair()
if err != nil {
return nil, err
}
pair, err := tls.X509KeyPair(tlsPair.Certificate, tlsPair.PrivateKey)
if err != nil {
return nil, err
}
return &pair, nil
},
MinVersion: tls.VersionTLS12,
},
Handler: mux, Handler: mux,
ReadTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second,