1
0
Fork 0
mirror of https://github.com/kyverno/kyverno.git synced 2025-03-28 02:18:15 +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")
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 {
setupLog.Error(err, "failed to initialize CertManager")
os.Exit(1)
@ -383,13 +383,6 @@ func main() {
// the webhook server runs across all instances
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
// - 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:
@ -399,7 +392,7 @@ func main() {
server, err := webhooks.NewWebhookServer(
kyvernoClient,
dynamicClient,
tlsPair,
certManager.GetTLSPemPair,
kyvernoInformer.Kyverno().V1beta1().UpdateRequests(),
kyvernoV1.ClusterPolicies(),
kubeInformer.Rbac().V1().RoleBindings(),

View file

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

View file

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