// updateSecret will store the provided secret data into the target secret
// named on the Certificate resource.
// - If the secret is empty, a new one will be created containing the data
// - If a secret already exists, its contents will be overwritten
// - If the provided certificate is a temporary certificate and the certificate
//   stored in the secret is already a temporary certificate, then the Secret
//   **will not** be updated.
updateSecret will store the provided secret data into the target secret
named on the Certificate resource.
- If the secret is empty, a new one will be created containing the data
- If a secret already exists, its contents will be overwritten
- If the provided certificate is a temporary certificate and the certificate
stored in the secret is already a temporary certificate, then the Secret
will not** be updated.
// updateSecret will store the provided secret data into the target secret // named on the Certificate resource . // - If the secret is empty a new one will be created containing the data // - If a secret already exists its contents will be overwritten // - If the provided certificate is a temporary certificate and the certificate // stored in the secret is already a temporary certificate then the Secret // ** will not ** be updated .
func (c *Controller) updateSecret(crt *v1alpha1.Certificate, namespace string, cert, key, ca []byte) (*corev1.Secret, error) {
	if len(key) == 0 {
		return nil, fmt.Errorf("private key data must be set")
	}
	privKey, err := pki.DecodePrivateKeyBytes(key)
	if err != nil {
		return nil, fmt.Errorf("error decoding private key: %v", err)
	}
	secret, err := c.secretLister.Secrets(namespace).Get(crt.Spec.SecretName)
	if err != nil && !k8sErrors.IsNotFound(err) {
		return nil, err
	}
	if secret == nil {
		secret = &corev1.Secret{
			ObjectMeta: metav1.ObjectMeta{
				Name:      crt.Spec.SecretName,
				Namespace: namespace,
			},
			Type: corev1.SecretTypeTLS,
			Data: map[string][]byte{},
		}
	}
	if secret.Data == nil {
		secret.Data = map[string][]byte{}
	}
	if secret.Annotations == nil {
		secret.Annotations = make(map[string]string)
	}
	if secret.Labels == nil {
		secret.Labels = make(map[string]string)
	}
	var existingCert *x509.Certificate
	existingCertData := secret.Data[corev1.TLSCertKey]
	if len(existingCertData) > 0 {
		existingCert, err = pki.DecodeX509CertificateBytes(existingCertData)
		if err != nil {
			klog.Errorf("error decoding existing x509 certificate bytes, continuing anyway: %v", err)
		}
	}
	var x509Cert *x509.Certificate
	switch {
	case len(cert) > 0:
		x509Cert, err = pki.DecodeX509CertificateBytes(cert)
		if err != nil {
			return nil, fmt.Errorf("invalid certificate data: %v", err)
		}
	case isTemporaryCertificate(existingCert):
		matches, err := pki.PublicKeyMatchesCertificate(privKey.Public(), existingCert)
		if err == nil && matches {
			cert = existingCertData
			x509Cert = existingCert
			break
		}
		fallthrough
	default:
		cert, err = c.localTemporarySigner(crt, key)
		if err != nil {
			return nil, fmt.Errorf("error signing locally generated certificate: %v", err)
		}
		x509Cert, err = pki.DecodeX509CertificateBytes(cert)
		if err != nil {
			return nil, fmt.Errorf("invalid certificate data: %v", err)
		}
		c.Recorder.Event(crt, corev1.EventTypeNormal, "GenerateSelfSigned", "Generated temporary self signed certificate")
	}
	secret.Annotations[v1alpha1.IssuerNameAnnotationKey] = crt.Spec.IssuerRef.Name
	secret.Annotations[v1alpha1.IssuerKindAnnotationKey] = issuerKind(crt)
	secret.Annotations[v1alpha1.CommonNameAnnotationKey] = x509Cert.Subject.CommonName
	secret.Annotations[v1alpha1.AltNamesAnnotationKey] = strings.Join(x509Cert.DNSNames, ",")
	secret.Annotations[v1alpha1.IPSANAnnotationKey] = strings.Join(pki.IPAddressesToString(x509Cert.IPAddresses), ",")
	secret.Labels[v1alpha1.CertificateNameKey] = crt.Name
	secret.Data[corev1.TLSCertKey] = cert
	secret.Data[corev1.TLSPrivateKeyKey] = key
	secret.Data[TLSCAKey] = ca
	if secret.SelfLink == "" {
		enableOwner := c.CertificateOptions.EnableOwnerRef
		if enableOwner {
			secret.SetOwnerReferences(append(secret.GetOwnerReferences(), ownerRef(crt)))
		}
		secret, err = c.Client.CoreV1().Secrets(namespace).Create(secret)
	} else {
		secret, err = c.Client.CoreV1().Secrets(namespace).Update(secret)
	}
	if err != nil {
		return nil, err
	}
	return secret, nil
}
func ( c * Controller ) updateSecret ( crt * v1alpha1 . Certificate , namespace string , cert , key , ca [ ] byte ) ( * corev1 . Secret , error ) { if len ( key ) == 0 { return nil , fmt . Errorf ( " " ) } privKey , err := pki . DecodePrivateKeyBytes ( key ) if err != nil { return nil , fmt . Errorf ( " " , err ) } secret , err := c . secretLister . Secrets ( namespace ) . Get ( crt . Spec . SecretName ) if err != nil && ! k8sErrors . IsNotFound ( err ) { return nil , err } if secret == nil { secret = & corev1 . Secret { ObjectMeta : metav1 . ObjectMeta { Name : crt . Spec . SecretName , Namespace : namespace , } , Type : corev1 . SecretTypeTLS , Data : map [ string ] [ ] byte { } , } } if secret . Data == nil { secret . Data = map [ string ] [ ] byte { } } if secret . Annotations == nil { secret . Annotations = make ( map [ string ] string ) } if secret . Labels == nil { secret . Labels = make ( map [ string ] string ) } var existingCert * x509 . Certificate existingCertData := secret . Data [ corev1 . TLSCertKey ] if len ( existingCertData ) > 0 { existingCert , err = pki . DecodeX509CertificateBytes ( existingCertData ) if err != nil { klog . Errorf ( " " , err ) } } var x509Cert * x509 . Certificate switch { case len ( cert ) > 0 : x509Cert , err = pki . DecodeX509CertificateBytes ( cert ) if err != nil { return nil , fmt . Errorf ( " " , err ) } case isTemporaryCertificate ( existingCert ) : matches , err := pki . PublicKeyMatchesCertificate ( privKey . Public ( ) , existingCert ) if err == nil && matches { cert = existingCertData x509Cert = existingCert break } fallthrough default : cert , err = c . localTemporarySigner ( crt , key ) if err != nil { return nil , fmt . Errorf ( " " , err ) } x509Cert , err = pki . DecodeX509CertificateBytes ( cert ) if err != nil { return nil , fmt . Errorf ( " " , err ) } c . Recorder . Event ( crt , corev1 . EventTypeNormal , " " , " " ) } secret . Annotations [ v1alpha1 . IssuerNameAnnotationKey ] = crt . Spec . IssuerRef . Name secret . Annotations [ v1alpha1 . IssuerKindAnnotationKey ] = issuerKind ( crt ) secret . Annotations [ v1alpha1 . CommonNameAnnotationKey ] = x509Cert . Subject . CommonName secret . Annotations [ v1alpha1 . AltNamesAnnotationKey ] = strings . Join ( x509Cert . DNSNames , " " ) secret . Annotations [ v1alpha1 . IPSANAnnotationKey ] = strings . Join ( pki . IPAddressesToString ( x509Cert . IPAddresses ) , " " ) secret . Labels [ v1alpha1 . CertificateNameKey ] = crt . Name secret . Data [ corev1 . TLSCertKey ] = cert secret . Data [ corev1 . TLSPrivateKeyKey ] = key secret . Data [ TLSCAKey ] = ca if secret . SelfLink == " " { enableOwner := c . CertificateOptions . EnableOwnerRef if enableOwner { secret . SetOwnerReferences ( append ( secret . GetOwnerReferences ( ) , ownerRef ( crt ) ) ) } secret , err = c . Client . CoreV1 ( ) . Secrets ( namespace ) . Create ( secret ) } else { secret , err = c . Client . CoreV1 ( ) . Secrets ( namespace ) . Update ( secret ) } if err != nil { return nil , err } return secret , nil }
updateSecret will store the provided secret data into the target secret
named on the Certificate resource.
updateSecret will store the provided secret data into the target secret named on the Certificate resource .
// if the key is not set, we bail out early. // this function should always be called with at least a private key. // in future we'll likely need to relax this requirement, but for now we'll // keep this here to be safe. // get a copy of the current secret resource // if the resource does not already exist, we will create a new one // include this clause in case the existing secret has nil data // if the existing certificate is a temporary one, and the certificate // being written in this call to updateSecret is not set, then we do // not want to keep re-issuing new temporary certificates // if the issuer returns a private key but not certificate data, we // generate and store a temporary certificate that we can later // recognise and force later calls to the issuer's Issue method // TODO: move metadata setting out of this method, and support // retrospectively adding metadata annotations on every Sync iteration and // not just when a new certificate is issued // Always set the certificate name label on the target secret // set the actual values in the secret // if it is a new resource