reuse previous evaluation

This commit is contained in:
wongearl 2021-10-28 09:36:21 +08:00 committed by Jordan Liggitt
parent d8b6dc3e06
commit 50e4f24ea8

View File

@ -444,12 +444,13 @@ func (a *Admission) EvaluatePod(ctx context.Context, nsPolicy api.Policy, nsPoli
if klog.V(5).Enabled() { if klog.V(5).Enabled() {
klog.InfoS("PodSecurity evaluation", "policy", fmt.Sprintf("%v", nsPolicy), "op", attrs.GetOperation(), "resource", attrs.GetResource(), "namespace", attrs.GetNamespace(), "name", attrs.GetName()) klog.InfoS("PodSecurity evaluation", "policy", fmt.Sprintf("%v", nsPolicy), "op", attrs.GetOperation(), "resource", attrs.GetResource(), "namespace", attrs.GetNamespace(), "name", attrs.GetName())
} }
cachedResults := make(map[api.LevelVersion]policy.AggregateCheckResult)
response := allowedResponse() response := allowedResponse()
if enforce { if enforce {
auditAnnotations[api.EnforcedPolicyAnnotationKey] = nsPolicy.Enforce.String() auditAnnotations[api.EnforcedPolicyAnnotationKey] = nsPolicy.Enforce.String()
if result := policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Enforce, podMetadata, podSpec)); !result.Allowed { result := policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Enforce, podMetadata, podSpec))
if !result.Allowed {
response = forbiddenResponse(fmt.Sprintf( response = forbiddenResponse(fmt.Sprintf(
"pod violates PodSecurity %q: %s", "pod violates PodSecurity %q: %s",
nsPolicy.Enforce.String(), nsPolicy.Enforce.String(),
@ -459,27 +460,38 @@ func (a *Admission) EvaluatePod(ctx context.Context, nsPolicy api.Policy, nsPoli
} else { } else {
a.Metrics.RecordEvaluation(metrics.DecisionAllow, nsPolicy.Enforce, metrics.ModeEnforce, attrs) a.Metrics.RecordEvaluation(metrics.DecisionAllow, nsPolicy.Enforce, metrics.ModeEnforce, attrs)
} }
cachedResults[nsPolicy.Enforce] = result
} }
// TODO: reuse previous evaluation if audit level+version is the same as enforce level+version // reuse previous evaluation if audit level+version is the same as enforce level+version
if result := policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Audit, podMetadata, podSpec)); !result.Allowed {
auditResult, ok := cachedResults[nsPolicy.Audit]
if !ok {
auditResult = policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Audit, podMetadata, podSpec))
cachedResults[nsPolicy.Audit] = auditResult
}
if !auditResult.Allowed {
auditAnnotations[api.AuditViolationsAnnotationKey] = fmt.Sprintf( auditAnnotations[api.AuditViolationsAnnotationKey] = fmt.Sprintf(
"would violate PodSecurity %q: %s", "would violate PodSecurity %q: %s",
nsPolicy.Audit.String(), nsPolicy.Audit.String(),
result.ForbiddenDetail(), auditResult.ForbiddenDetail(),
) )
a.Metrics.RecordEvaluation(metrics.DecisionDeny, nsPolicy.Audit, metrics.ModeAudit, attrs) a.Metrics.RecordEvaluation(metrics.DecisionDeny, nsPolicy.Audit, metrics.ModeAudit, attrs)
} }
// avoid adding warnings to a request we're already going to reject with an error // avoid adding warnings to a request we're already going to reject with an error
if response.Allowed { if response.Allowed {
// TODO: reuse previous evaluation if warn level+version is the same as audit or enforce level+version // reuse previous evaluation if warn level+version is the same as audit or enforce level+version
if result := policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Warn, podMetadata, podSpec)); !result.Allowed { warnResult, ok := cachedResults[nsPolicy.Warn]
if !ok {
warnResult = policy.AggregateCheckResults(a.Evaluator.EvaluatePod(nsPolicy.Warn, podMetadata, podSpec))
}
if !warnResult.Allowed {
// TODO: Craft a better user-facing warning message // TODO: Craft a better user-facing warning message
response.Warnings = append(response.Warnings, fmt.Sprintf( response.Warnings = append(response.Warnings, fmt.Sprintf(
"would violate PodSecurity %q: %s", "would violate PodSecurity %q: %s",
nsPolicy.Warn.String(), nsPolicy.Warn.String(),
result.ForbiddenDetail(), warnResult.ForbiddenDetail(),
)) ))
a.Metrics.RecordEvaluation(metrics.DecisionDeny, nsPolicy.Warn, metrics.ModeWarn, attrs) a.Metrics.RecordEvaluation(metrics.DecisionDeny, nsPolicy.Warn, metrics.ModeWarn, attrs)
} }