Skip to content

Commit

Permalink
Feat: Add kind attribute in the Metrics filter (#442)
Browse files Browse the repository at this point in the history
Signed-off-by: Abdul Jabbar <[email protected]>
  • Loading branch information
abdul-jabbar01 committed May 28, 2024
1 parent d09888d commit 2230842
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 13 deletions.
1 change: 1 addition & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type MetricsFilter struct {
Severities ValueFilter `mapstructure:"severities"`
Status ValueFilter `mapstructure:"status"`
Sources ValueFilter `mapstructure:"sources"`
Kinds ValueFilter `mapstructure:"kinds"`
}

type TargetBaseOptions struct {
Expand Down
1 change: 1 addition & 0 deletions pkg/config/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ func (r *Resolver) RegisterMetricsListener() {
ToRuleSet(r.config.Metrics.Filter.Policies),
ToRuleSet(r.config.Metrics.Filter.Sources),
ToRuleSet(r.config.Metrics.Filter.Severities),
ToRuleSet(r.config.Metrics.Filter.Kinds),
),
metrics.NewReportFilter(
ToRuleSet(r.config.Metrics.Filter.Namespaces),
Expand Down
2 changes: 1 addition & 1 deletion pkg/listener/metrics/cluster_result_detailed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func Test_DetailedClusterResultMetricGeneration(t *testing.T) {
Results: []v1alpha2.PolicyReportResult{fixtures.FailResult, fixtures.FailDisallowRuleResult},
}

filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"disallow-policy"}}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"disallow-policy"}}, validate.RuleSets{}, validate.RuleSets{}, (validate.RuleSets{}))
handler := metrics.CreateDetailedClusterResultMetricListener(filter, gauge)

t.Run("Added Metric", func(t *testing.T) {
Expand Down
12 changes: 11 additions & 1 deletion pkg/listener/metrics/filter.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (
"github.com/kyverno/policy-reporter/pkg/validate"
)

func NewResultFilter(namespace, status, policy, source, severity validate.RuleSets) *report.ResultFilter {
func NewResultFilter(namespace, status, policy, source, severity, kind validate.RuleSets) *report.ResultFilter {
f := &report.ResultFilter{}
if namespace.Count() > 0 {
f.AddValidation(func(r v1alpha2.PolicyReportResult) bool {
Expand Down Expand Up @@ -42,6 +42,16 @@ func NewResultFilter(namespace, status, policy, source, severity validate.RuleSe
})
}

if kind.Count() > 0 {
f.AddValidation(func(r v1alpha2.PolicyReportResult) bool {
if !r.HasResource() {
return true
}

return validate.Kind(r.GetResource().Kind, kind)
})
}

return f
}

Expand Down
18 changes: 9 additions & 9 deletions pkg/listener/metrics/filter_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,62 +11,62 @@ import (

func Test_Vaildate(t *testing.T) {
t.Run("Allow ClusterReport", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{Include: []string{"test"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{Include: []string{"test"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
if !filter.Validate(fixtures.PassNamespaceResult) {
t.Error("Expected Validate returns true if Report is a ClusterPolicyReport without namespace")
}
})
t.Run("Disallow if Report include not match", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{Include: []string{"dev"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{Include: []string{"dev"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
if filter.Validate(fixtures.FailPodResult) {
t.Error("Expected Validate returns false if Report namespace not match include rule")
}
})

t.Run("Allow Report with matching include Namespace", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{Include: []string{"test"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{Include: []string{"test"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
if !filter.Validate(fixtures.FailPodResult) {
t.Error("Expected Validate returns true if Report namespace matches include pattern")
}
})

t.Run("Disallow Report with matching exclude Namespace", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{Exclude: []string{"test"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{Exclude: []string{"test"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
if filter.Validate(fixtures.FailPodResult) {
t.Error("Expected Validate returns false if Report namespace matches exclude pattern")
}
})

t.Run("Ignores exclude pattern if include namespaces provided", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{Exclude: []string{"test"}, Include: []string{"test"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{Exclude: []string{"test"}, Include: []string{"test"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
if !filter.Validate(fixtures.FailPodResult) {
t.Error("Expected Validate returns true because exclude patterns ignored if include patterns provided")
}
})

t.Run("Disallow Report with matching exclude Policy", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"require-requests-*"}}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"require-requests-*"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
if filter.Validate(fixtures.FailPodResult) {
t.Error("Expected Validate returns false if Report policy matches exclude pattern")
}
})

t.Run("Disallow Report with matching exclude Status", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{Exclude: []string{v1alpha2.StatusFail}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{Exclude: []string{v1alpha2.StatusFail}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
if filter.Validate(fixtures.FailPodResult) {
t.Error("Expected Validate returns false if Report status matches exclude pattern")
}
})

t.Run("Disallow Report with matching exclude Severity", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{v1alpha2.SeverityHigh}})
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{v1alpha2.SeverityHigh}}, validate.RuleSets{})
if filter.Validate(fixtures.FailResult) {
t.Error("Expected Validate returns false if Report severity matches exclude pattern")
}
})

t.Run("Disallow Report with matching exclude Source", func(t *testing.T) {
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"Kyverno"}}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"Kyverno"}}, validate.RuleSets{}, validate.RuleSets{})
if filter.Validate(fixtures.FailPodResult) {
t.Error("Expected Validate returns false if Report source matches exclude pattern")
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/listener/metrics/result_custom_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func Test_CustomResultMetricGeneration(t *testing.T) {
Results: []v1alpha2.PolicyReportResult{fixtures.FailResult, fixtures.FailPodResult, fixtures.FailDisallowRuleResult},
}

filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"disallow-policy"}}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"disallow-policy"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})

t.Run("Added Metric", func(t *testing.T) {
handler := metrics.CreateCustomResultMetricsListener(filter, gauge, metrics.CreateLabelGenerator([]string{"namespace", "policy", "status", "source", "label:app", "property:xyz"}, []string{"namespace", "policy", "status", "source", "app", "xyz"}))
Expand Down
2 changes: 1 addition & 1 deletion pkg/listener/metrics/result_detailed_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ func Test_DetailedResultMetricGeneration(t *testing.T) {
Results: []v1alpha2.PolicyReportResult{fixtures.PassResult, fixtures.FailDisallowRuleResult},
}

filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"disallow-policy"}}, validate.RuleSets{}, validate.RuleSets{})
filter := metrics.NewResultFilter(validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{Exclude: []string{"disallow-policy"}}, validate.RuleSets{}, validate.RuleSets{}, validate.RuleSets{})
handler := metrics.CreateDetailedResultMetricListener(filter, gauge)

t.Run("Added Metric", func(t *testing.T) {
Expand Down
8 changes: 8 additions & 0 deletions pkg/validate/validate.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ func Namespace(namespace string, namespaces RuleSets) bool {
return MatchRuleSet(namespace, namespaces)
}

func Kind(kind string, kinds RuleSets) bool {
if kind == "" {
return true
}

return MatchRuleSet(kind, kinds)
}

func MatchRuleSet(value string, rules RuleSets) bool {
if len(rules.Include) > 0 {
for _, ns := range rules.Include {
Expand Down

0 comments on commit 2230842

Please sign in to comment.