Skip to content

Commit

Permalink
UPSTREAM: <carry>: PSa metrics: log platform namespaces in audit denies
Browse files Browse the repository at this point in the history
We need this in order to be able to retrieve better reports from
PodSecurityViolation alerts.

UPSTREAM: <carry>: PSa metrics: unset ocp_namespace on non-platform namespaces
  • Loading branch information
stlaz authored and bertinatto committed Jul 25, 2023
1 parent f1349ff commit c066c21
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 23 deletions.
54 changes: 34 additions & 20 deletions staging/src/k8s.io/pod-security-admission/metrics/metrics.go
Expand Up @@ -98,15 +98,28 @@ func (r *PrometheusRecorder) RecordEvaluation(decision Decision, policy api.Leve
}
}

r.evaluationsCounter.CachedInc(evaluationsLabels{
decision: string(decision),
level: string(policy.Level),
version: version,
mode: string(evalMode),
operation: operationLabel(attrs.GetOperation()),
resource: resourceLabel(attrs.GetResource()),
subresource: attrs.GetSubresource(),
})
// prevent cardinality explosion by only recording the platform namespaces
namespace := attrs.GetNamespace()
if !(namespace == "openshift" ||
strings.HasPrefix(namespace, "openshift-") ||
strings.HasPrefix(namespace, "kube-") ||
namespace == "default") {
// remove non-OpenShift platform namespace names to prevent cardinality explosion
namespace = ""
}

el := evaluationsLabels{
decision: string(decision),
level: string(policy.Level),
version: version,
mode: string(evalMode),
operation: operationLabel(attrs.GetOperation()),
resource: resourceLabel(attrs.GetResource()),
subresource: attrs.GetSubresource(),
ocpNamespace: namespace,
}

r.evaluationsCounter.CachedInc(el)
}

func (r *PrometheusRecorder) RecordExemption(attrs api.Attributes) {
Expand Down Expand Up @@ -156,17 +169,18 @@ func operationLabel(op admissionv1.Operation) string {
}

type evaluationsLabels struct {
decision string
level string
version string
mode string
operation string
resource string
subresource string
decision string
level string
version string
mode string
operation string
resource string
subresource string
ocpNamespace string
}

func (l *evaluationsLabels) labels() []string {
return []string{l.decision, l.level, l.version, l.mode, l.operation, l.resource, l.subresource}
return []string{l.decision, l.level, l.version, l.mode, l.operation, l.resource, l.subresource, l.ocpNamespace}
}

type exemptionsLabels struct {
Expand Down Expand Up @@ -194,7 +208,7 @@ func newEvaluationsCounter() *evaluationsCounter {
Help: "Number of policy evaluations that occurred, not counting ignored or exempt requests.",
StabilityLevel: metrics.ALPHA,
},
[]string{"decision", "policy_level", "policy_version", "mode", "request_operation", "resource", "subresource"},
[]string{"decision", "policy_level", "policy_version", "mode", "request_operation", "resource", "subresource", "ocp_namespace"},
),
cache: make(map[evaluationsLabels]metrics.CounterMetric),
}
Expand Down Expand Up @@ -231,8 +245,8 @@ func (c *evaluationsCounter) Reset() {

func (c *evaluationsCounter) populateCache() {
labelsToCache := []evaluationsLabels{
{decision: "allow", level: "privileged", version: "latest", mode: "enforce", operation: "create", resource: "pod", subresource: ""},
{decision: "allow", level: "privileged", version: "latest", mode: "enforce", operation: "update", resource: "pod", subresource: ""},
{decision: "allow", level: "privileged", version: "latest", mode: "enforce", operation: "create", resource: "pod", subresource: "", ocpNamespace: ""},
{decision: "allow", level: "privileged", version: "latest", mode: "enforce", operation: "update", resource: "pod", subresource: "", ocpNamespace: ""},
}
for _, l := range labelsToCache {
c.cache[l] = c.CounterVec.WithLabelValues(l.labels()...)
Expand Down
Expand Up @@ -71,15 +71,17 @@ func TestRecordEvaluation(t *testing.T) {
recorder.RecordEvaluation(decision, levelVersion(level, version), mode, &api.AttributesRecord{
Resource: resource,
Operation: op,
Namespace: "some-namespace",
})

if level == api.LevelPrivileged {
expectedVersion = "latest"
}

expected := fmt.Sprintf(`
# HELP pod_security_evaluations_total [ALPHA] Number of policy evaluations that occurred, not counting ignored or exempt requests.
# TYPE pod_security_evaluations_total counter
pod_security_evaluations_total{decision="%s",mode="%s",policy_level="%s",policy_version="%s",request_operation="%s",resource="%s",subresource=""} 1
pod_security_evaluations_total{decision="%s",mode="%s",ocp_namespace="",policy_level="%s",policy_version="%s",request_operation="%s",resource="%s",subresource=""} 1
`, decision, mode, level, expectedVersion, strings.ToLower(string(op)), expectedResource)
expected = expectCachedMetrics("pod_security_evaluations_total", expected)

Expand Down Expand Up @@ -162,8 +164,8 @@ func levelVersion(level api.Level, version string) api.LevelVersion {
// The cached metrics should always be present (value 0 if not counted).
var expectedCachedMetrics = map[string][]string{
"pod_security_evaluations_total": {
`pod_security_evaluations_total{decision="allow",mode="enforce",policy_level="privileged",policy_version="latest",request_operation="create",resource="pod",subresource=""}`,
`pod_security_evaluations_total{decision="allow",mode="enforce",policy_level="privileged",policy_version="latest",request_operation="update",resource="pod",subresource=""}`,
`pod_security_evaluations_total{decision="allow",mode="enforce",ocp_namespace="",policy_level="privileged",policy_version="latest",request_operation="create",resource="pod",subresource=""}`,
`pod_security_evaluations_total{decision="allow",mode="enforce",ocp_namespace="",policy_level="privileged",policy_version="latest",request_operation="update",resource="pod",subresource=""}`,
},
"pod_security_exemptions_total": {
`pod_security_exemptions_total{request_operation="create",resource="controller",subresource=""}`,
Expand Down

0 comments on commit c066c21

Please sign in to comment.