@@ -167,17 +167,18 @@ type testRunner interface {
167167}
168168
169169const (
170- effectiveOnFormat = "2006-01-02T15:04:05Z"
171- effectiveOnTimeout = - 90 * 24 * time .Hour // keep effective_on metadata up to 90 days
172- metadataCode = "code"
173- metadataCollections = "collections"
174- metadataDependsOn = "depends_on"
175- metadataDescription = "description"
176- metadataSeverity = "severity"
177- metadataEffectiveOn = "effective_on"
178- metadataSolution = "solution"
179- metadataTerm = "term"
180- metadataTitle = "title"
170+ effectiveOnFormat = "2006-01-02T15:04:05Z"
171+ effectiveOnTimeout = - 90 * 24 * time .Hour // keep effective_on metadata up to 90 days
172+ metadataCode = "code"
173+ metadataCollections = "collections"
174+ metadataDependsOn = "depends_on"
175+ metadataDescription = "description"
176+ metadataPipelineIntention = "pipeline_intention"
177+ metadataSeverity = "severity"
178+ metadataEffectiveOn = "effective_on"
179+ metadataSolution = "solution"
180+ metadataTerm = "term"
181+ metadataTitle = "title"
181182)
182183
183184const (
@@ -205,6 +206,7 @@ type conftestEvaluator struct {
205206 exclude * Criteria
206207 fs afero.Fs
207208 namespace []string
209+ source ecc.Source
208210}
209211
210212type conftestRunner struct {
@@ -285,7 +287,7 @@ func (r conftestRunner) Run(ctx context.Context, fileList []string) (result []Ou
285287// NewConftestEvaluator returns initialized conftestEvaluator implementing
286288// Evaluator interface
287289func NewConftestEvaluator (ctx context.Context , policySources []source.PolicySource , p ConfigProvider , source ecc.Source ) (Evaluator , error ) {
288- return NewConftestEvaluatorWithNamespace (ctx , policySources , p , source , nil )
290+ return NewConftestEvaluatorWithNamespace (ctx , policySources , p , source , [] string {} )
289291}
290292
291293// set the policy namespace
@@ -302,9 +304,11 @@ func NewConftestEvaluatorWithNamespace(ctx context.Context, policySources []sour
302304 policy : p ,
303305 fs : fs ,
304306 namespace : namespace ,
307+ source : source ,
305308 }
306309
307310 c .include , c .exclude = computeIncludeExclude (source , p )
311+
308312 dir , err := utils .CreateWorkDir (fs )
309313 if err != nil {
310314 log .Debug ("Failed to create work dir!" )
@@ -341,6 +345,9 @@ func (c conftestEvaluator) CapabilitiesPath() string {
341345
342346type policyRules map [string ]rule.Info
343347
348+ // Add a new type to track non-annotated rules separately
349+ type nonAnnotatedRules map [string ]bool
350+
344351func (r * policyRules ) collect (a * ast.AnnotationsRef ) error {
345352 if a .Annotations == nil {
346353 return nil
@@ -377,6 +384,8 @@ func (c conftestEvaluator) Evaluate(ctx context.Context, target EvaluationTarget
377384 // exist with the same code in two separate sources the collected rule
378385 // information is not deterministic
379386 rules := policyRules {}
387+ // Track non-annotated rules separately for filtering purposes only
388+ nonAnnotatedRules := nonAnnotatedRules {}
380389 // Download all sources
381390 for _ , s := range c .policySources {
382391 dir , err := s .GetPolicy (ctx , c .workDir , false )
@@ -414,32 +423,85 @@ func (c conftestEvaluator) Evaluate(ctx context.Context, target EvaluationTarget
414423 }
415424 }
416425
426+ // Collect ALL rules for filtering purposes - both with and without annotations
427+ // This ensures that rules without metadata (like fail_with_data.rego) are properly included
417428 for _ , a := range annotations {
418- if a .Annotations == nil {
419- continue
429+ if a .Annotations != nil {
430+ // Rules with annotations - collect full metadata
431+ if err := rules .collect (a ); err != nil {
432+ return nil , err
433+ }
434+ } else {
435+ // Rules without annotations - track for filtering only, not for success computation
436+ ruleRef := a .GetRule ()
437+ if ruleRef != nil {
438+ // Extract package name from the rule path
439+ packageName := ""
440+ if len (a .Path ) > 1 {
441+ // Path format is typically ["data", "package", "rule"]
442+ // We want the package part (index 1)
443+ if len (a .Path ) >= 2 {
444+ packageName = strings .ReplaceAll (a .Path [1 ].String (), `"` , "" )
445+ }
446+ }
447+
448+ // Extract short name from the rule head
449+ shortName := ruleRef .Head .Name .String ()
450+
451+ // Generate code for filtering purposes
452+ code := fmt .Sprintf ("%s.%s" , packageName , shortName )
453+
454+ // Track for filtering but don't add to rules map for success computation
455+ nonAnnotatedRules [code ] = true
456+ }
420457 }
421- if err := rules .collect (a ); err != nil {
422- return nil , err
458+ }
459+ }
460+
461+ // Filter namespaces using the new pluggable filtering system
462+ filterFactory := NewIncludeFilterFactory ()
463+ filters := filterFactory .CreateFilters (c .source )
464+ // Combine annotated and non-annotated rules for filtering
465+ allRules := make (policyRules )
466+ for code , rule := range rules {
467+ allRules [code ] = rule
468+ }
469+ // Add non-annotated rules as minimal rule.Info for filtering
470+ for code := range nonAnnotatedRules {
471+ parts := strings .Split (code , "." )
472+ if len (parts ) >= 2 {
473+ packageName := parts [len (parts )- 2 ]
474+ shortName := parts [len (parts )- 1 ]
475+ allRules [code ] = rule.Info {
476+ Code : code ,
477+ Package : packageName ,
478+ ShortName : shortName ,
423479 }
424480 }
425481 }
482+ filteredNamespaces := filterNamespaces (allRules , filters ... )
426483
427484 var r testRunner
428485 var ok bool
429486 if r , ok = ctx .Value (runnerKey ).(testRunner ); r == nil || ! ok {
430487
431- // should there be a namespace defined or not
432- allNamespaces := true
433- if len (c .namespace ) > 0 {
434- allNamespaces = false
488+ // Determine which namespaces to use
489+ namespacesToUse := c .namespace
490+
491+ // If we have filtered namespaces from the filtering system, use those
492+ if len (filteredNamespaces ) > 0 {
493+ namespacesToUse = filteredNamespaces
435494 }
436495
496+ // log the namespaces to use
497+ log .Debugf ("Namespaces to use: %v" , namespacesToUse )
498+
437499 r = & conftestRunner {
438500 runner.TestRunner {
439501 Data : []string {c .dataDir },
440502 Policy : []string {c .policyDir },
441- Namespace : c . namespace ,
442- AllNamespaces : allNamespaces ,
503+ Namespace : namespacesToUse ,
504+ AllNamespaces : false , // Always false to prevent bypassing filtering
443505 NoFail : true ,
444506 Output : c .outputFormat ,
445507 Capabilities : c .CapabilitiesPath (),
@@ -504,6 +566,7 @@ func (c conftestEvaluator) Evaluate(ctx context.Context, target EvaluationTarget
504566
505567 for i := range result .Failures {
506568 failure := result .Failures [i ]
569+ // log the failure
507570 addRuleMetadata (ctx , & failure , rules )
508571
509572 if ! c .isResultIncluded (failure , target .Target , missingIncludes ) {
0 commit comments