Skip to content

Commit

Permalink
Merge pull request #1454 from stlaz/podsecurity_metrics
Browse files Browse the repository at this point in the history
AUTH-336: UPSTREAM: <carry>: PSa metrics: log platform namespaces in audit denies
  • Loading branch information
openshift-merge-robot committed Feb 13, 2023
2 parents 149fe52 + 4e34ec5 commit c729678
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 24 deletions.
53 changes: 33 additions & 20 deletions staging/src/k8s.io/pod-security-admission/metrics/metrics.go
Expand Up @@ -98,15 +98,27 @@ 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") {
namespace = "non-platform"
}

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 +168,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 +207,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 +244,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,16 +71,19 @@ 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"
}
expectedNamespace := "non-platform"

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
`, decision, mode, level, expectedVersion, strings.ToLower(string(op)), expectedResource)
pod_security_evaluations_total{decision="%s",mode="%s",ocp_namespace="%s",policy_level="%s",policy_version="%s",request_operation="%s",resource="%s",subresource=""} 1
`, decision, mode, expectedNamespace, level, expectedVersion, strings.ToLower(string(op)), expectedResource)
expected = expectCachedMetrics("pod_security_evaluations_total", expected)

assert.NoError(t, testutil.GatherAndCompare(registry, bytes.NewBufferString(expected), "pod_security_evaluations_total"))
Expand Down Expand Up @@ -162,8 +165,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 c729678

Please sign in to comment.