func WaitForCertificate()

in util/certificate/csr/csr.go [166:305]


func WaitForCertificate(ctx context.Context, client clientset.Interface, reqName string, reqUID types.UID) (certData []byte, err error) {
	fieldSelector := fields.OneTermEqualSelector("metadata.name", reqName).String()

	var lw *cache.ListWatch
	var obj runtime.Object
	for {
		// see if the v1 API is available
		if _, err := client.CertificatesV1().CertificateSigningRequests().List(ctx, metav1.ListOptions{FieldSelector: fieldSelector}); err == nil {
			// watch v1 objects
			obj = &certificatesv1.CertificateSigningRequest{}
			lw = &cache.ListWatch{
				ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
					options.FieldSelector = fieldSelector
					return client.CertificatesV1().CertificateSigningRequests().List(ctx, options)
				},
				WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
					options.FieldSelector = fieldSelector
					return client.CertificatesV1().CertificateSigningRequests().Watch(ctx, options)
				},
			}
			break
		} else {
			klog.V(2).Infof("error fetching v1 certificate signing request: %v", err)
		}

		// return if we've timed out
		if err := ctx.Err(); err != nil {
			return nil, wait.ErrWaitTimeout
		}

		// see if the v1beta1 API is available
		if _, err := client.CertificatesV1beta1().CertificateSigningRequests().List(ctx, metav1.ListOptions{FieldSelector: fieldSelector}); err == nil {
			// watch v1beta1 objects
			obj = &certificatesv1beta1.CertificateSigningRequest{}
			lw = &cache.ListWatch{
				ListFunc: func(options metav1.ListOptions) (runtime.Object, error) {
					options.FieldSelector = fieldSelector
					return client.CertificatesV1beta1().CertificateSigningRequests().List(ctx, options)
				},
				WatchFunc: func(options metav1.ListOptions) (watch.Interface, error) {
					options.FieldSelector = fieldSelector
					return client.CertificatesV1beta1().CertificateSigningRequests().Watch(ctx, options)
				},
			}
			break
		} else {
			klog.V(2).Infof("error fetching v1beta1 certificate signing request: %v", err)
		}

		// return if we've timed out
		if err := ctx.Err(); err != nil {
			return nil, wait.ErrWaitTimeout
		}

		// wait and try again
		time.Sleep(time.Second)
	}

	var issuedCertificate []byte
	_, err = watchtools.UntilWithSync(
		ctx,
		lw,
		obj,
		nil,
		func(event watch.Event) (bool, error) {
			switch event.Type {
			case watch.Modified, watch.Added:
			case watch.Deleted:
				return false, fmt.Errorf("csr %q was deleted", reqName)
			default:
				return false, nil
			}

			switch csr := event.Object.(type) {
			case *certificatesv1.CertificateSigningRequest:
				if csr.UID != reqUID {
					return false, fmt.Errorf("csr %q changed UIDs", csr.Name)
				}
				approved := false
				for _, c := range csr.Status.Conditions {
					if c.Type == certificatesv1.CertificateDenied {
						return false, fmt.Errorf("certificate signing request is denied, reason: %v, message: %v", c.Reason, c.Message)
					}
					if c.Type == certificatesv1.CertificateFailed {
						return false, fmt.Errorf("certificate signing request failed, reason: %v, message: %v", c.Reason, c.Message)
					}
					if c.Type == certificatesv1.CertificateApproved {
						approved = true
					}
				}
				if approved {
					if len(csr.Status.Certificate) > 0 {
						klog.V(2).Infof("certificate signing request %s is issued", csr.Name)
						issuedCertificate = csr.Status.Certificate
						return true, nil
					}
					klog.V(2).Infof("certificate signing request %s is approved, waiting to be issued", csr.Name)
				}

			case *certificatesv1beta1.CertificateSigningRequest:
				if csr.UID != reqUID {
					return false, fmt.Errorf("csr %q changed UIDs", csr.Name)
				}
				approved := false
				for _, c := range csr.Status.Conditions {
					if c.Type == certificatesv1beta1.CertificateDenied {
						return false, fmt.Errorf("certificate signing request is denied, reason: %v, message: %v", c.Reason, c.Message)
					}
					if c.Type == certificatesv1beta1.CertificateFailed {
						return false, fmt.Errorf("certificate signing request failed, reason: %v, message: %v", c.Reason, c.Message)
					}
					if c.Type == certificatesv1beta1.CertificateApproved {
						approved = true
					}
				}
				if approved {
					if len(csr.Status.Certificate) > 0 {
						klog.V(2).Infof("certificate signing request %s is issued", csr.Name)
						issuedCertificate = csr.Status.Certificate
						return true, nil
					}
					klog.V(2).Infof("certificate signing request %s is approved, waiting to be issued", csr.Name)
				}

			default:
				return false, fmt.Errorf("unexpected type received: %T", event.Object)
			}

			return false, nil
		},
	)
	if err == wait.ErrWaitTimeout {
		return nil, wait.ErrWaitTimeout
	}
	if err != nil {
		return nil, formatError("cannot watch on the certificate signing request: %v", err)
	}

	return issuedCertificate, nil
}