internal/checks/silencers_test.go
Rama main · réplica de lectura del repositorio original.
package checks
import (
"strconv"
"strings"
"testing"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"github.com/sophotechlabs/spinoza/internal/api"
)
const silencingRule = `[{
"id": "the-node-agents",
"silences": "privileged-containers",
"match": "DaemonSet",
"expr": "object.metadata.labels[\"tier\"] == \"system\"",
"reason": "a node agent is meant to be privileged here"
}]`
func tagged(obj *unstructured.Unstructured, labels map[string]string) *unstructured.Unstructured {
obj.SetLabels(labels)
return obj
}
func privilegedDaemonSet(name string) *unstructured.Unstructured {
return workload("DaemonSet", name, podSpec(container("app", map[string]any{
"securityContext": map[string]any{"privileged": true},
})))
}
func withSilencers(t *testing.T, raw string, objects ...*unstructured.Unstructured) api.CheckReport {
t.Helper()
keep := wholeCluster()
keep.Rules = ParseRules(raw)
keep.Silencers = Silencers(keep.Rules)
keep.ShowMuted = true
return Run(t.Context(), newLister(objects...), descriptors(), api.Metrics{}, keep, 0)
}
func TestARuleOfYourOwnCanSilenceACheckWithAReason(t *testing.T) {
report := withSilencers(t, silencingRule,
tagged(privilegedDaemonSet("agent"), map[string]string{"tier": "system"}))
finding := onlyFinding(t, report, privilegedCheck)
if finding.MutedBy != ScopeRule {
t.Fatalf("the finding was silenced as %q, want a rule", finding.MutedBy)
}
if !strings.Contains(finding.Reason, "node agent") {
t.Fatalf("the reason was %q, want what the rule said", finding.Reason)
}
}
func TestASilencingRuleLeavesWhatItDoesNotMatch(t *testing.T) {
report := withSilencers(t, silencingRule,
tagged(privilegedDaemonSet("agent"), map[string]string{"tier": "app"}))
if finding := onlyFinding(t, report, privilegedCheck); finding.Muted {
t.Fatalf("a workload the rule does not match was silenced: %+v", finding)
}
}
func TestASilencingRuleOnlyQuietensTheCheckItNames(t *testing.T) {
report := withSilencers(t, silencingRule,
tagged(privilegedDaemonSet("agent"), map[string]string{"tier": "system"}))
group := groupNamed(t, report, "capabilities-not-dropped")
if group.Total == 0 {
t.Fatal("the control check stopped firing, so this proves nothing")
}
for _, finding := range group.Findings {
if finding.Muted {
t.Fatal("a rule silencing one check quietened another")
}
}
}
func TestASilencingRuleOnlyJudgesTheKindItNames(t *testing.T) {
report := withSilencers(t, silencingRule,
tagged(privilegedDeployment("api"), map[string]string{"tier": "system"}))
if finding := onlyFinding(t, report, privilegedCheck); finding.Muted {
t.Fatal("a rule matching DaemonSet silenced a Deployment")
}
}
func TestASilencingRuleIsNotACheckOfItsOwn(t *testing.T) {
report := withSilencers(t, silencingRule, privilegedDaemonSet("agent"))
for _, group := range report.Groups {
if group.ID == "the-node-agents" {
t.Fatal("a rule that silences a check was registered as a check")
}
}
}
func TestASilencingRuleThatDoesNotCompileQuietensNothing(t *testing.T) {
raw := `[{"id":"broken","silences":"privileged-containers","expr":"object.nope(","reason":"x"}]`
report := withSilencers(t, raw, privilegedDaemonSet("agent"))
if finding := onlyFinding(t, report, privilegedCheck); finding.Muted {
t.Fatal("a rule that does not compile silenced a finding")
}
if !strings.Contains(report.Error, `silencer "broken"`) ||
!strings.Contains(report.Error, "DaemonSet "+testNamespace+"/agent") {
t.Fatalf("error = %q, want the rule and object named", report.Error)
}
}
func TestASilencingRuleThatErrorsOnAnObjectQuietensNothing(t *testing.T) {
raw := `[{"id":"reaches","silences":"privileged-containers","expr":"object.spec.nothingHere == 1","reason":"x"}]`
report := withSilencers(t, raw, privilegedDaemonSet("agent"))
if finding := onlyFinding(t, report, privilegedCheck); finding.Muted {
t.Fatal("a rule that errored on the object silenced the finding anyway")
}
if !strings.Contains(report.Error, `silencer "reaches"`) ||
!strings.Contains(report.Error, "DaemonSet "+testNamespace+"/agent") ||
!strings.Contains(report.Error, "nothingHere") {
t.Fatalf("error = %q, want the rule, object, and evaluation fault", report.Error)
}
}
func TestASilencingRuleThatEvaluatesFalseReportsNoFault(t *testing.T) {
raw := `[{"id":"other","silences":"privileged-containers","expr":"object.metadata.name == 'elsewhere'","reason":"x"}]`
report := withSilencers(t, raw, privilegedDaemonSet("agent"))
if report.Error != "" {
t.Fatalf("a false expression was reported as %q", report.Error)
}
}
func TestRepeatedSilencerFailuresAreCountedWithoutRepeatingTheError(t *testing.T) {
raw := `[{"id":"reaches","silences":"privileged-containers","expr":"object.spec.nothingHere == 1","reason":"x"}]`
report := withSilencers(t, raw, privilegedDaemonSet("agent"), privilegedDaemonSet("other"))
if strings.Count(report.Error, `silencer "reaches"`) != 1 {
t.Fatalf("error = %q, want the rule named once", report.Error)
}
if !strings.Contains(report.Error, "and 1 other object") {
t.Fatalf("error = %q, want the other affected object counted", report.Error)
}
}
func TestSeveralSilencerFailuresUseThePluralObjectCount(t *testing.T) {
raw := `[{"id":"reaches","silences":"privileged-containers","expr":"object.spec.nothingHere == 1","reason":"x"}]`
report := withSilencers(
t, raw,
privilegedDaemonSet("one"),
privilegedDaemonSet("two"),
privilegedDaemonSet("three"),
)
if !strings.Contains(report.Error, "and 2 other objects") {
t.Fatalf("error = %q, want the other objects counted", report.Error)
}
}
func TestSeveralFindingsOnOneObjectCountAsOneSilencerFailure(t *testing.T) {
raw := `[{"id":"reaches","silences":"privileged-containers","expr":"object.spec.nothingHere == 1","reason":"x"}]`
object := workload("DaemonSet", "agent", podSpec(
container("one", map[string]any{"securityContext": map[string]any{"privileged": true}}),
container("two", map[string]any{"securityContext": map[string]any{"privileged": true}}),
))
report := withSilencers(t, raw, object)
if strings.Contains(report.Error, "other object") {
t.Fatalf("one object with several findings was reported as several objects: %q", report.Error)
}
}
func TestYourOwnMuteWinsOverASilencingRule(t *testing.T) {
keep := wholeCluster()
keep.Rules = ParseRules(silencingRule)
keep.Silencers = Silencers(keep.Rules)
keep.ShowMuted = true
keep.Mutes = []Mute{{
Check: privilegedCheck,
Ref: RefKey(api.ObjectRef{Group: "apps", Version: "v1", Resource: "daemonsets", Namespace: testNamespace, Name: "agent"}),
Reason: "I decided this one myself",
}}
report := Run(t.Context(), newLister(
tagged(privilegedDaemonSet("agent"), map[string]string{"tier": "system"}),
), descriptors(), api.Metrics{}, keep, 0)
finding := onlyFinding(t, report, privilegedCheck)
if finding.MutedBy != ScopeObject {
t.Fatalf("the finding was silenced as %q, want the mute the operator made", finding.MutedBy)
}
if !strings.Contains(finding.Reason, "myself") {
t.Fatalf("the reason was %q", finding.Reason)
}
}
func TestASilencedFindingIsStillCountedAndStillInTheBaseline(t *testing.T) {
objects := []*unstructured.Unstructured{
tagged(privilegedDaemonSet("agent"), map[string]string{"tier": "system"}),
}
base := Fingerprint(t.Context(), newLister(objects...), descriptors(), api.Metrics{}, wholeCluster())
report := withSilencers(t, silencingRule, objects...)
if group := groupNamed(t, report, privilegedCheck); group.Muted != 1 {
t.Fatalf("counted %d silenced, want the one the rule quietened", group.Muted)
}
if base.Counts[privilegedCheck] != 1 {
t.Fatalf("the baseline counted %d, want the finding a rule silences to still be recorded",
base.Counts[privilegedCheck])
}
}
func TestASilencingRuleNamingNoRealCheckIsNamedAsAFault(t *testing.T) {
faults := Faults(`[{"id":"typo","silences":"no-such-check","expr":"true","reason":"x"}]`)
if len(faults) != 1 || !strings.Contains(faults[0].Reason, "no check goes by the name") {
t.Fatalf("reported %v", faults)
}
}
func TestASilencingRuleWithNoReasonIsNamedAsAFault(t *testing.T) {
faults := Faults(`[{"id":"quiet","silences":"privileged-containers","expr":"true"}]`)
if len(faults) != 1 || !strings.Contains(faults[0].Reason, "has to say why") {
t.Fatalf("reported %v", faults)
}
}
func TestASilencerCannotReadFieldsTheFindingDoesNotCarry(t *testing.T) {
for _, tc := range []struct {
name string
check string
expr string
}{
{"a ConfigMap's data", "orphaned-config-map", `object.data.size() > 0`},
{"a Secret's labels", "orphaned-secret", `object.metadata.labels["tier"] == "system"`},
{"a claim's spec", "claim-nothing-mounts", `object.spec.storageClassName == "local"`},
{"a field through brackets", "orphaned-config-map", `object["data"].size() > 0`},
{"a dynamic bracket", "orphaned-config-map", `object[object.metadata.name] == "value"`},
{"a non-string bracket", "orphaned-config-map", `object[0] == "value"`},
{"a metadata iteration", "orphaned-config-map", `object.metadata.exists(k, k == "name")`},
} {
t.Run(tc.name, func(t *testing.T) {
raw := `[{"id":"quiet","silences":"` + tc.check + `","expr":` + strconv.Quote(tc.expr) +
`,"reason":"expected here"}]`
faults := Faults(raw)
if len(faults) != 1 || !strings.Contains(faults[0].Reason, "only exposes") {
t.Fatalf("reported %v", faults)
}
})
}
}
func TestASilencerCanReadEveryFieldAMetadataOnlyFindingCarries(t *testing.T) {
for _, expr := range []string{
`object.apiVersion == 'v1' && object.kind == 'ConfigMap' && object.metadata.name == 'settings' && object.metadata.namespace == 'prod'`,
`object["metadata"]["name"] == 'settings'`,
} {
raw := `[{"id":"quiet","silences":"orphaned-config-map","expr":` + strconv.Quote(expr) +
`,"reason":"expected here"}]`
if faults := Faults(raw); len(faults) != 0 {
t.Fatalf("%q reported %v", expr, faults)
}
}
}
func TestASilencingRuleThatReadsHasNoFaults(t *testing.T) {
if faults := Faults(silencingRule); len(faults) != 0 {
t.Fatalf("a rule that reads was reported as %v", faults)
}
}