Ctrl K
ComunidadGuías…

internal/checks/silencers_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
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)
	}
}