func()

in cmd/gcp-controller-manager/node_csr_approver.go [123:191]


func (a *nodeApprover) handle(csr *capi.CertificateSigningRequest) error {
	recordMetric := csrmetrics.ApprovalStartRecorder(authFlowLabelNone)
	if len(csr.Status.Certificate) != 0 {
		return nil
	}
	if approved, denied := certificates.GetCertApprovalCondition(&csr.Status); approved || denied {
		return nil
	}
	klog.Infof("approver got CSR %q", csr.Name)

	x509cr, err := certutil.ParseCSR(csr.Spec.Request)
	if err != nil {
		recordMetric(csrmetrics.ApprovalStatusParseError)
		return fmt.Errorf("unable to parse csr %q: %v", csr.Name, err)
	}

	for _, r := range a.validators {
		recordValidatorMetric := csrmetrics.ApprovalStartRecorder(r.authFlowLabel)
		if !r.recognize(csr, x509cr) {
			continue
		}
		klog.Infof("validator %q: matched CSR %q", r.name, csr.Name)
		if r.validate != nil {
			ok, err := r.validate(a.ctx, csr, x509cr)
			if err != nil {
				return fmt.Errorf("validating CSR %q: %v", csr.Name, err)
			}
			if !ok {
				klog.Infof("validator %q: denied CSR %q", r.name, csr.Name)
				recordValidatorMetric(csrmetrics.ApprovalStatusDeny)
				return a.updateCSR(csr, false, r.denyMsg)
			}
		}
		klog.Infof("CSR %q validation passed", csr.Name)

		approved, err := a.authorizeSAR(csr, r.permission)
		if err != nil {
			if time.Since(startupTime) < startupErrorsThreshold {
				recordValidatorMetric(csrmetrics.ApprovalStatusSARErrorAtStartup)
			} else {
				recordValidatorMetric(csrmetrics.ApprovalStatusSARError)
			}
			return err
		}
		if !approved {
			if time.Since(startupTime) < startupErrorsThreshold {
				recordValidatorMetric(csrmetrics.ApprovalStatusSARRejectAtStartup)
			} else {
				recordValidatorMetric(csrmetrics.ApprovalStatusSARReject)
			}
			return certificates.IgnorableError("recognized csr %q as %q but subject access review was not approved", csr.Name, r.name)
		}
		klog.Infof("validator %q: SubjectAccessReview approved for CSR %q", r.name, csr.Name)
		if r.preApproveHook != nil {
			if err := r.preApproveHook(a.ctx, csr, x509cr); err != nil {
				klog.Warningf("validator %q: preApproveHook failed for CSR %q: %v", r.name, csr.Name, err)
				recordValidatorMetric(csrmetrics.ApprovalStatusPreApproveHookError)
				return err
			}
			klog.Infof("validator %q: preApproveHook passed for CSR %q", r.name, csr.Name)
		}
		recordValidatorMetric(csrmetrics.ApprovalStatusApprove)
		return a.updateCSR(csr, true, r.approveMsg)
	}

	klog.Infof("no validators matched CSR %q", csr.Name)
	recordMetric(csrmetrics.ApprovalStatusIgnore)
	return nil
}