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

Added TLS annotation check in the initContainer (#2956)

* Added TLS annotation check in the initContainer

Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com>

* Error checks

Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com>

* Refactor annotation addition code

Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com>

* Strict error reporting

Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com>

* Error handling for Secrets

Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com>

* Updated error conditions

Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com>

* Update for nil error

Signed-off-by: Kumar Mallikarjuna <kumar@nirmata.com>
This commit is contained in:
Kumar Mallikarjuna 2022-01-11 14:17:24 +05:30 committed by GitHub
parent 6b9798f76f
commit 037a320fba
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 73 additions and 30 deletions

View file

@ -6,6 +6,7 @@ package main
import (
"context"
"flag"
"fmt"
"os"
"sync"
"time"
@ -15,6 +16,7 @@ import (
"github.com/kyverno/kyverno/pkg/leaderelection"
"github.com/kyverno/kyverno/pkg/policyreport"
"github.com/kyverno/kyverno/pkg/signal"
"github.com/kyverno/kyverno/pkg/tls"
"github.com/kyverno/kyverno/pkg/utils"
coord "k8s.io/api/coordination/v1"
"k8s.io/apimachinery/pkg/api/errors"
@ -119,8 +121,55 @@ func main() {
failure := false
run := func() {
_, err := kubeClientLeaderElection.CoordinationV1().Leases(getKyvernoNameSpace()).Get(ctx, "kyvernopre-lock", v1.GetOptions{})
certProps, err := tls.GetTLSCertProps(clientConfig)
if err != nil {
log.Log.Info("failed to get cert properties: %v", err.Error())
os.Exit(1)
}
depl, err := client.GetResource("", "Deployment", getKyvernoNameSpace(), config.KyvernoDeploymentName)
deplHash := ""
if err != nil {
log.Log.Info("failed to fetch deployment '%v': %v", config.KyvernoDeploymentName, err.Error())
os.Exit(1)
}
deplHash = fmt.Sprintf("%v", depl.GetUID())
name := tls.GenerateRootCASecretName(certProps)
secretUnstr, err := client.GetResource("", "Secret", getKyvernoNameSpace(), name)
if err != nil {
log.Log.Info("failed to fetch secret '%v': %v", name, err.Error())
if !errors.IsNotFound(err) {
os.Exit(1)
}
} else if tls.CanAddAnnotationToSecret(deplHash, secretUnstr) {
secretUnstr.SetAnnotations(map[string]string{tls.MasterDeploymentUID: deplHash})
_, err = client.UpdateResource("", "Secret", certProps.Namespace, secretUnstr, false)
if err != nil {
log.Log.Info("failed to update cert: %v", err.Error())
os.Exit(1)
}
}
name = tls.GenerateTLSPairSecretName(certProps)
secretUnstr, err = client.GetResource("", "Secret", getKyvernoNameSpace(), name)
if err != nil {
log.Log.Info("failed to fetch secret '%v': %v", name, err.Error())
if !errors.IsNotFound(err) {
os.Exit(1)
}
} else if tls.CanAddAnnotationToSecret(deplHash, secretUnstr) {
secretUnstr.SetAnnotations(map[string]string{tls.MasterDeploymentUID: deplHash})
_, err = client.UpdateResource("", "Secret", certProps.Namespace, secretUnstr, false)
if err != nil {
log.Log.Info("failed to update cert: %v", err.Error())
os.Exit(1)
}
}
_, err = kubeClientLeaderElection.CoordinationV1().Leases(getKyvernoNameSpace()).Get(ctx, "kyvernopre-lock", v1.GetOptions{})
if err != nil {
log.Log.Info("Lease 'kyvernopre-lock' not found. Starting clean-up...")
} else {

View file

@ -117,7 +117,7 @@ func (c *CertRenewer) buildTLSPemPairAndWriteToSecrets(props CertificateProps, s
// WriteCACertToSecret stores the CA cert in secret
func (c *CertRenewer) WriteCACertToSecret(caPEM *PemPair, props CertificateProps) error {
logger := c.log.WithName("CAcert")
name := generateRootCASecretName(props)
name := GenerateRootCASecretName(props)
depl, err := c.client.GetResource("", "Deployment", props.Namespace, config.KyvernoDeploymentName)
@ -126,16 +126,7 @@ func (c *CertRenewer) WriteCACertToSecret(caPEM *PemPair, props CertificateProps
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{
@ -167,7 +158,7 @@ func (c *CertRenewer) WriteCACertToSecret(caPEM *PemPair, props CertificateProps
}
}
return err
} else if managedByKyverno && (!ok || deplHashSec != deplHash) {
} else if CanAddAnnotationToSecret(deplHash, secretUnstr) {
_, err = c.client.UpdateResource("", "Secret", props.Namespace, secret, false)
if err == nil {
logger.Info("secret updated", "name", name, "namespace", props.Namespace)
@ -199,7 +190,7 @@ func (c *CertRenewer) WriteCACertToSecret(caPEM *PemPair, props CertificateProps
func (c *CertRenewer) WriteTLSPairToSecret(props CertificateProps, pemPair *PemPair) error {
logger := c.log.WithName("WriteTLSPair")
name := generateTLSPairSecretName(props)
name := GenerateTLSPairSecretName(props)
depl, err := c.client.GetResource("", "Deployment", props.Namespace, config.KyvernoDeploymentName)
@ -208,16 +199,7 @@ func (c *CertRenewer) WriteTLSPairToSecret(props CertificateProps, pemPair *PemP
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{
@ -249,7 +231,7 @@ func (c *CertRenewer) WriteTLSPairToSecret(props CertificateProps, pemPair *PemP
}
}
return err
} else if managedByKyverno && (!ok || deplHashSec != deplHash) {
} else if CanAddAnnotationToSecret(deplHash, secretUnstr) {
_, err = c.client.UpdateResource("", "Secret", props.Namespace, secretPtr, false)
if err == nil {
logger.Info("secret updated", "name", name, "namespace", props.Namespace)
@ -337,8 +319,8 @@ func (c *CertRenewer) ValidCert() (bool, error) {
return false, nil
}
var managedByKyverno bool
snameTLS := generateTLSPairSecretName(certProps)
snameCA := generateRootCASecretName(certProps)
snameTLS := GenerateTLSPairSecretName(certProps)
snameCA := GenerateRootCASecretName(certProps)
unstrSecret, err := c.client.GetResource("", "Secret", certProps.Namespace, snameTLS)
if err != nil {
return false, nil
@ -444,10 +426,22 @@ func IsKyvernoInRollingUpdate(deploy map[string]interface{}, logger logr.Logger)
return false
}
func generateTLSPairSecretName(props CertificateProps) string {
func GenerateTLSPairSecretName(props CertificateProps) string {
return generateInClusterServiceName(props) + ".kyverno-tls-pair"
}
func generateRootCASecretName(props CertificateProps) string {
func GenerateRootCASecretName(props CertificateProps) string {
return generateInClusterServiceName(props) + ".kyverno-tls-ca"
}
func CanAddAnnotationToSecret(deplHash string, secret *unstructured.Unstructured) bool {
var deplHashSec string = "default"
var ok, managedByKyverno bool
if label, ok := secret.GetLabels()[ManagedByLabel]; ok {
managedByKyverno = label == "kyverno"
}
deplHashSec, ok = secret.GetAnnotations()[MasterDeploymentUID]
return managedByKyverno && (!ok || deplHashSec != deplHash)
}

View file

@ -32,7 +32,7 @@ func ReadRootCASecret(restConfig *rest.Config, client *client.Client) (result []
var deplHashSec string = "default"
var ok, managedByKyverno bool
sname := generateRootCASecretName(certProps)
sname := GenerateRootCASecretName(certProps)
stlsca, err := client.GetResource("", "Secret", certProps.Namespace, sname)
if err != nil {
return nil, err
@ -76,7 +76,7 @@ func ReadTLSPair(restConfig *rest.Config, client *client.Client) (*PemPair, erro
var deplHashSec string = "default"
var ok, managedByKyverno bool
sname := generateTLSPairSecretName(certProps)
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)
@ -93,7 +93,7 @@ func ReadTLSPair(restConfig *rest.Config, client *client.Client) (*PemPair, erro
// As the root CA used to sign the certificate is required for webhook configuration, check if the corresponding secret is created
annotations := unstrSecret.GetAnnotations()
if _, ok := annotations[SelfSignedAnnotation]; ok {
sname := generateRootCASecretName(certProps)
sname := GenerateRootCASecretName(certProps)
_, err := client.GetResource("", "Secret", certProps.Namespace, sname)
if err != nil {
return nil, fmt.Errorf("rootCA secret is required while using self-signed certificate TLS pair, defaulting to generating new TLS pair %s/%s", certProps.Namespace, sname)