mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-31 03:45:17 +00:00
Fix TLS inconsitency in HA (#2910)
* Fix TLS inconsitency in HA Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com> * Add error checks Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com> * Remove rendundant err definitions Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com> * Handle all Secret errors Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com>
This commit is contained in:
parent
1208e51b68
commit
214f338ec3
3 changed files with 142 additions and 51 deletions
|
@ -14,6 +14,7 @@ import (
|
|||
client "github.com/kyverno/kyverno/pkg/dclient"
|
||||
"github.com/pkg/errors"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
k8errors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"k8s.io/client-go/rest"
|
||||
|
@ -21,7 +22,8 @@ import (
|
|||
|
||||
const (
|
||||
// ManagedByLabel is added to Kyverno managed secrets
|
||||
ManagedByLabel string = "cert.kyverno.io/managed-by"
|
||||
ManagedByLabel string = "cert.kyverno.io/managed-by"
|
||||
MasterDeploymentUID string = "cert.kyverno.io/master-deployment-uid"
|
||||
|
||||
SelfSignedAnnotation string = "self-signed-cert"
|
||||
RootCAKey string = "rootCA.crt"
|
||||
|
@ -117,32 +119,58 @@ func (c *CertRenewer) WriteCACertToSecret(caPEM *PemPair, props CertificateProps
|
|||
logger := c.log.WithName("CAcert")
|
||||
name := generateRootCASecretName(props)
|
||||
|
||||
secretUnstr, err := c.client.GetResource("", "Secret", props.Namespace, name)
|
||||
if err != nil {
|
||||
secret := &v1.Secret{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: props.Namespace,
|
||||
Annotations: map[string]string{
|
||||
SelfSignedAnnotation: "true",
|
||||
},
|
||||
Labels: map[string]string{
|
||||
ManagedByLabel: "kyverno",
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
RootCAKey: caPEM.Certificate,
|
||||
},
|
||||
Type: v1.SecretTypeOpaque,
|
||||
}
|
||||
depl, err := c.client.GetResource("", "Deployment", props.Namespace, config.KyvernoDeploymentName)
|
||||
|
||||
_, err := c.client.CreateResource("", "Secret", props.Namespace, secret, false)
|
||||
deplHash := ""
|
||||
if err == nil {
|
||||
deplHash = fmt.Sprintf("%v", depl.GetUID())
|
||||
}
|
||||
|
||||
var deplHashSec string = "default"
|
||||
var ok, managedByKyverno bool
|
||||
|
||||
secretUnstr, err := c.client.GetResource("", "Secret", props.Namespace, name)
|
||||
if err == nil {
|
||||
if label, ok := secretUnstr.GetLabels()[ManagedByLabel]; ok {
|
||||
managedByKyverno = label == "kyverno"
|
||||
}
|
||||
deplHashSec, ok = secretUnstr.GetAnnotations()[MasterDeploymentUID]
|
||||
}
|
||||
|
||||
secret := &v1.Secret{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: props.Namespace,
|
||||
Annotations: map[string]string{
|
||||
SelfSignedAnnotation: "true",
|
||||
MasterDeploymentUID: deplHash,
|
||||
},
|
||||
Labels: map[string]string{
|
||||
ManagedByLabel: "kyverno",
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
RootCAKey: caPEM.Certificate,
|
||||
},
|
||||
Type: v1.SecretTypeOpaque,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if k8errors.IsNotFound(err) {
|
||||
_, err = c.client.CreateResource("", "Secret", props.Namespace, secret, false)
|
||||
if err == nil {
|
||||
logger.Info("secret created", "name", name, "namespace", props.Namespace)
|
||||
}
|
||||
}
|
||||
return err
|
||||
} else if managedByKyverno && (!ok || deplHashSec != deplHash) {
|
||||
_, err = c.client.UpdateResource("", "Secret", props.Namespace, secret, false)
|
||||
if err == nil {
|
||||
logger.Info("secret created", "name", name, "namespace", props.Namespace)
|
||||
logger.Info("secret updated", "name", name, "namespace", props.Namespace)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
@ -154,7 +182,7 @@ func (c *CertRenewer) WriteCACertToSecret(caPEM *PemPair, props CertificateProps
|
|||
dataMap := map[string]interface{}{
|
||||
RootCAKey: base64.StdEncoding.EncodeToString(caPEM.Certificate)}
|
||||
|
||||
if err := unstructured.SetNestedMap(secretUnstr.Object, dataMap, "data"); err != nil {
|
||||
if err = unstructured.SetNestedMap(secretUnstr.Object, dataMap, "data"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -172,30 +200,59 @@ func (c *CertRenewer) WriteTLSPairToSecret(props CertificateProps, pemPair *PemP
|
|||
logger := c.log.WithName("WriteTLSPair")
|
||||
|
||||
name := generateTLSPairSecretName(props)
|
||||
secretUnstr, err := c.client.GetResource("", "Secret", props.Namespace, name)
|
||||
if err != nil {
|
||||
secret := &v1.Secret{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: props.Namespace,
|
||||
Labels: map[string]string{
|
||||
ManagedByLabel: "kyverno",
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
v1.TLSCertKey: pemPair.Certificate,
|
||||
v1.TLSPrivateKeyKey: pemPair.PrivateKey,
|
||||
},
|
||||
Type: v1.SecretTypeTLS,
|
||||
}
|
||||
|
||||
_, err := c.client.CreateResource("", "Secret", props.Namespace, secret, false)
|
||||
depl, err := c.client.GetResource("", "Deployment", props.Namespace, config.KyvernoDeploymentName)
|
||||
|
||||
deplHash := ""
|
||||
if err == nil {
|
||||
deplHash = fmt.Sprintf("%v", depl.GetUID())
|
||||
}
|
||||
|
||||
var deplHashSec string = "default"
|
||||
var ok, managedByKyverno bool
|
||||
|
||||
secretUnstr, err := c.client.GetResource("", "Secret", props.Namespace, name)
|
||||
if err == nil {
|
||||
if label, ok := secretUnstr.GetLabels()[ManagedByLabel]; ok {
|
||||
managedByKyverno = label == "kyverno"
|
||||
}
|
||||
deplHashSec, ok = secretUnstr.GetAnnotations()[MasterDeploymentUID]
|
||||
}
|
||||
|
||||
secretPtr := &v1.Secret{
|
||||
TypeMeta: metav1.TypeMeta{
|
||||
Kind: "Secret",
|
||||
APIVersion: "v1",
|
||||
},
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: props.Namespace,
|
||||
Annotations: map[string]string{
|
||||
MasterDeploymentUID: deplHash,
|
||||
},
|
||||
Labels: map[string]string{
|
||||
ManagedByLabel: "kyverno",
|
||||
},
|
||||
},
|
||||
Data: map[string][]byte{
|
||||
v1.TLSCertKey: pemPair.Certificate,
|
||||
v1.TLSPrivateKeyKey: pemPair.PrivateKey,
|
||||
},
|
||||
Type: v1.SecretTypeTLS,
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
if k8errors.IsNotFound(err) {
|
||||
_, err = c.client.CreateResource("", "Secret", props.Namespace, secretPtr, false)
|
||||
if err == nil {
|
||||
logger.Info("secret created", "name", name, "namespace", props.Namespace)
|
||||
}
|
||||
}
|
||||
return err
|
||||
} else if managedByKyverno && (!ok || deplHashSec != deplHash) {
|
||||
_, err = c.client.UpdateResource("", "Secret", props.Namespace, secretPtr, false)
|
||||
if err == nil {
|
||||
logger.Info("secret created", "name", name, "namespace", props.Namespace)
|
||||
logger.Info("secret updated", "name", name, "namespace", props.Namespace)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -22,12 +22,30 @@ func ReadRootCASecret(restConfig *rest.Config, client *client.Client) (result []
|
|||
return nil, errors.Wrap(err, "failed to get TLS Cert Properties")
|
||||
}
|
||||
|
||||
depl, err := client.GetResource("", "Deployment", certProps.Namespace, config.KyvernoDeploymentName)
|
||||
|
||||
deplHash := ""
|
||||
if err == nil {
|
||||
deplHash = fmt.Sprintf("%v", depl.GetUID())
|
||||
}
|
||||
|
||||
var deplHashSec string = "default"
|
||||
var ok, managedByKyverno bool
|
||||
|
||||
sname := generateRootCASecretName(certProps)
|
||||
stlsca, err := client.GetResource("", "Secret", certProps.Namespace, sname)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if label, ok := stlsca.GetLabels()[ManagedByLabel]; ok {
|
||||
managedByKyverno = label == "kyverno"
|
||||
}
|
||||
deplHashSec, ok = stlsca.GetAnnotations()[MasterDeploymentUID]
|
||||
if managedByKyverno && (!ok || deplHashSec != deplHash) {
|
||||
return nil, fmt.Errorf("outdated secret")
|
||||
}
|
||||
|
||||
tlsca, err := convertToSecret(stlsca)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "failed to convert secret %s/%s", certProps.Namespace, sname)
|
||||
|
@ -48,11 +66,28 @@ func ReadTLSPair(restConfig *rest.Config, client *client.Client) (*PemPair, erro
|
|||
return nil, errors.Wrap(err, "failed to get TLS Cert Properties")
|
||||
}
|
||||
|
||||
depl, err := client.GetResource("", "Deployment", certProps.Namespace, config.KyvernoDeploymentName)
|
||||
|
||||
deplHash := ""
|
||||
if err == nil {
|
||||
deplHash = fmt.Sprintf("%v", depl.GetUID())
|
||||
}
|
||||
|
||||
var deplHashSec string = "default"
|
||||
var ok, managedByKyverno bool
|
||||
|
||||
sname := generateTLSPairSecretName(certProps)
|
||||
unstrSecret, err := client.GetResource("", "Secret", certProps.Namespace, sname)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get secret %s/%s: %v", certProps.Namespace, sname, err)
|
||||
}
|
||||
if label, ok := unstrSecret.GetLabels()[ManagedByLabel]; ok {
|
||||
managedByKyverno = label == "kyverno"
|
||||
}
|
||||
deplHashSec, ok = unstrSecret.GetAnnotations()[MasterDeploymentUID]
|
||||
if managedByKyverno && (!ok || deplHashSec != deplHash) {
|
||||
return nil, fmt.Errorf("outdated secret")
|
||||
}
|
||||
|
||||
// If secret contains annotation 'self-signed-cert', then it's created using helper scripts to setup self-signed certificates.
|
||||
// As the root CA used to sign the certificate is required for webhook configuration, check if the corresponding secret is created
|
||||
|
|
|
@ -248,10 +248,9 @@ func (wrc *Register) cleanupKyvernoResource() bool {
|
|||
logger := wrc.log.WithName("cleanupKyvernoResource")
|
||||
deploy, err := wrc.client.GetResource("", "Deployment", deployNamespace, deployName)
|
||||
if err != nil {
|
||||
logger.Error(err, "failed to get deployment, cleanup kyverno resources anyway")
|
||||
return true
|
||||
logger.Error(err, "failed to get deployment, not cleaning up kyverno resources")
|
||||
return false
|
||||
}
|
||||
|
||||
if deploy.GetDeletionTimestamp() != nil {
|
||||
logger.Info("Kyverno is terminating, cleanup Kyverno resources")
|
||||
return true
|
||||
|
|
Loading…
Add table
Reference in a new issue