func()

in admission/admission.go [316:376]


func (a *Admission) ValidatePod(ctx context.Context, attrs api.Attributes) *admissionv1.AdmissionResponse {
	// short-circuit on ignored subresources
	if ignoredPodSubresources[attrs.GetSubresource()] {
		return sharedAllowedResponse
	}
	// short-circuit on exempt namespaces and users
	if a.exemptNamespace(attrs.GetNamespace()) {
		a.Metrics.RecordExemption(attrs)
		return sharedAllowedByNamespaceExemptionResponse
	}

	if a.exemptUser(attrs.GetUserName()) {
		a.Metrics.RecordExemption(attrs)
		return sharedAllowedByUserExemptionResponse
	}

	// short-circuit on privileged enforce+audit+warn namespaces
	namespace, err := a.NamespaceGetter.GetNamespace(ctx, attrs.GetNamespace())
	if err != nil {
		klog.ErrorS(err, "failed to fetch pod namespace", "namespace", attrs.GetNamespace())
		a.Metrics.RecordError(true, attrs)
		return errorResponse(err, &apierrors.NewInternalError(fmt.Errorf("failed to lookup namespace %s", attrs.GetNamespace())).ErrStatus)
	}
	nsPolicy, nsPolicyErrs := a.PolicyToEvaluate(namespace.Labels)
	if len(nsPolicyErrs) == 0 && nsPolicy.Enforce.Level == api.LevelPrivileged && nsPolicy.Warn.Level == api.LevelPrivileged && nsPolicy.Audit.Level == api.LevelPrivileged {
		a.Metrics.RecordEvaluation(metrics.DecisionAllow, nsPolicy.Enforce, metrics.ModeEnforce, attrs)
		return sharedAllowedPrivilegedResponse
	}

	obj, err := attrs.GetObject()
	if err != nil {
		klog.ErrorS(err, "failed to decode object")
		a.Metrics.RecordError(true, attrs)
		return errorResponse(err, &apierrors.NewBadRequest("failed to decode object").ErrStatus)
	}
	pod, ok := obj.(*corev1.Pod)
	if !ok {
		klog.InfoS("failed to assert pod type", "type", reflect.TypeOf(obj))
		a.Metrics.RecordError(true, attrs)
		return errorResponse(nil, &apierrors.NewBadRequest("failed to decode pod").ErrStatus)
	}
	if attrs.GetOperation() == admissionv1.Update {
		oldObj, err := attrs.GetOldObject()
		if err != nil {
			klog.ErrorS(err, "failed to decode old object")
			a.Metrics.RecordError(true, attrs)
			return errorResponse(err, &apierrors.NewBadRequest("failed to decode old object").ErrStatus)
		}
		oldPod, ok := oldObj.(*corev1.Pod)
		if !ok {
			klog.InfoS("failed to assert old pod type", "type", reflect.TypeOf(oldObj))
			a.Metrics.RecordError(true, attrs)
			return errorResponse(nil, &apierrors.NewBadRequest("failed to decode old pod").ErrStatus)
		}
		if !isSignificantPodUpdate(pod, oldPod) {
			// Nothing we care about changed, so always allow the update.
			return sharedAllowedResponse
		}
	}
	return a.EvaluatePod(ctx, nsPolicy, nsPolicyErrs.ToAggregate(), &pod.ObjectMeta, &pod.Spec, attrs, true)
}