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:
parent
e2cf6cea5a
commit
a981957a9d
3 changed files with 33 additions and 37 deletions
|
@ -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(),
|
||||||
|
|
|
@ -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{}) {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Reference in a new issue