func()

in pkg/admission/webhook_manager.go [658:771]


func (wm *webhookManagerImpl) loadCaCertificatesInternal() (bool, error) {
	wm.Lock()
	defer wm.Unlock()

	namespace := wm.conf.GetNamespace()
	secret, err := wm.clientset.CoreV1().Secrets(namespace).Get(ctx.Background(), secretName, metav1.GetOptions{})
	if err != nil {
		log.Log(log.AdmissionWebhook).Error("Unable to retrieve admission-controller-secrets secrets", zap.Error(err))
		return false, err
	}

	// initially, data may not be present
	if secret.Data == nil {
		secret.Data = make(map[string][]byte)
	}

	dirty := false

	cert1, key1, err := getAndValidateCertificate(secret.Data, caCert1Path, caPrivateKey1Path)
	if err != nil {
		log.Log(log.AdmissionWebhook).Info("Unable to get CA certificate #1", zap.Error(err))
	}

	cert2, key2, err := getAndValidateCertificate(secret.Data, caCert2Path, caPrivateKey2Path)
	if err != nil {
		log.Log(log.AdmissionWebhook).Info("Unable to get CA certificate #2", zap.Error(err))
	}

	if cert1 == nil {
		log.Log(log.AdmissionWebhook).Info("Generating CA Certificate #1...")
		notAfter := time.Now().AddDate(1, 0, 0)
		if cert2 == nil {
			// stagger expiration dates so that there is ~ 6 months between them
			notAfter = notAfter.AddDate(0, -6, 0)
		}
		cert1, key1, err = pki.GenerateCACertificate(notAfter)
		if err != nil {
			log.Log(log.AdmissionWebhook).Error("Unable to generate CA certificate #1", zap.Error(err))
			return false, err
		}
		dirty = true
	}

	if cert2 == nil {
		log.Log(log.AdmissionWebhook).Info("Generating CA Certificate #2...")
		cert2, key2, err = pki.GenerateCACertificate(time.Now().AddDate(1, 0, 0))
		if err != nil {
			log.Log(log.AdmissionWebhook).Error("Unable to generate CA certificate #2", zap.Error(err))
			return false, err
		}
		dirty = true
	}

	if dirty {
		log.Log(log.AdmissionWebhook).Info("CA certificates have changed, updating secrets")

		cert1Pem, err := pki.EncodeCertificatePem(cert1)
		if err != nil {
			log.Log(log.AdmissionWebhook).Error("Unable to encode CA certificate #1", zap.Error(err))
			return false, err
		}
		key1Pem, err := pki.EncodePrivateKeyPem(key1)
		if err != nil {
			log.Log(log.AdmissionWebhook).Error("Unable to encode CA private key #1", zap.Error(err))
			return false, err
		}
		cert2Pem, err := pki.EncodeCertificatePem(cert2)
		if err != nil {
			log.Log(log.AdmissionWebhook).Error("Unable to encode CA certificate #2", zap.Error(err))
			return false, err
		}
		key2Pem, err := pki.EncodePrivateKeyPem(key2)
		if err != nil {
			log.Log(log.AdmissionWebhook).Error("Unable to encode CA private key #2", zap.Error(err))
			return false, err
		}
		secret.Data[caCert1Path] = *cert1Pem
		secret.Data[caPrivateKey1Path] = *key1Pem
		secret.Data[caCert2Path] = *cert2Pem
		secret.Data[caPrivateKey2Path] = *key2Pem

		_, err = wm.clientset.CoreV1().Secrets(namespace).Update(ctx.Background(), secret, metav1.UpdateOptions{})
		if err != nil {
			if apierrors.IsConflict(err) {
				// signal to caller that we need to be run again
				return true, nil
			}
			// report error to caller
			log.Log(log.AdmissionWebhook).Error("Unable to update secrets", zap.Error(err))
			return false, err
		}

		// update successful, tell caller to re-run
		return true, err
	}

	log.Log(log.AdmissionWebhook).Info("Got CA certificate #1",
		zap.Int64("serialNumber", cert1.SerialNumber.Int64()),
		zap.Time("notAfter", cert1.NotAfter))
	log.Log(log.AdmissionWebhook).Info("Got CA certificate #2",
		zap.Int64("serialNumber", cert2.SerialNumber.Int64()),
		zap.Time("notAfter", cert2.NotAfter))

	wm.caCert1 = cert1
	wm.caKey1 = key1
	wm.caCert2 = cert2
	wm.caKey2 = key2
	wm.expiration = cert1.NotAfter
	if cert2.NotAfter.Before(cert1.NotAfter) {
		wm.expiration = cert2.NotAfter
	}

	return false, nil
}