Add scan cover columns update logic

What does this MR do and why?

Extends AnalyzerStatusUpdateService to recompute aggregate boolean columns (has_scanners, has_failed_or_warning, has_stale) on security_inventory_filters whenever analyzer statuses are upserted.

The recompute runs within the same transaction as the upsert, ensuring the booleans are always consistent with the underlying analyzer status columns. Because these boolean columns are meant to reflect the state of the underlying columns, allowing one to fail could introduce drift.

Changelog: added
EE: true

Changes

  • AnalyzerStatusUpdateService: added recompute_aggregate_booleans that builds a single SQL UPDATE from all 14 analyzer columns, gated behind the inventory_filter_aggregate_booleans feature flag (wip)
  • Security::InventoryFilter: added ANALYZER_COLUMNS constant used by the recompute logic
  • Feature flag check runs before the transaction to reduce calls inside the transaction

Query plans

Raw SQL
UPDATE
    "security_inventory_filters"
SET
    has_scanners = (sast != 0
        OR sast_advanced != 0
        OR sast_iac != 0
        OR dast != 0
        OR dependency_scanning != 0
        OR container_scanning != 0
        OR secret_detection != 0
        OR coverage_fuzzing != 0
        OR api_fuzzing != 0
        OR cluster_image_scanning != 0
        OR secret_detection_secret_push_protection != 0
        OR container_scanning_for_registry != 0
        OR secret_detection_pipeline_based != 0
        OR container_scanning_pipeline_based != 0),
    has_failed_or_warning = (sast = 2
        OR sast_advanced = 2
        OR sast_iac = 2
        OR dast = 2
        OR dependency_scanning = 2
        OR container_scanning = 2
        OR secret_detection = 2
        OR coverage_fuzzing = 2
        OR api_fuzzing = 2
        OR cluster_image_scanning = 2
        OR secret_detection_secret_push_protection = 2
        OR container_scanning_for_registry = 2
        OR secret_detection_pipeline_based = 2
        OR container_scanning_pipeline_based = 2),
    has_stale = (sast = 3
        OR sast_advanced = 3
        OR sast_iac = 3
        OR dast = 3
        OR dependency_scanning = 3
        OR container_scanning = 3
        OR secret_detection = 3
        OR coverage_fuzzing = 3
        OR api_fuzzing = 3
        OR cluster_image_scanning = 3
        OR secret_detection_secret_push_protection = 3
        OR container_scanning_for_registry = 3
        OR secret_detection_pipeline_based = 3
        OR container_scanning_pipeline_based = 3)
WHERE
    "security_inventory_filters"."project_id" = 69782606
Plan

See this.

 ModifyTable on public.security_inventory_filters  (cost=0.43..3.56 rows=0 width=0) (actual time=23.787..23.788 rows=0 loops=1)
   Buffers: shared hit=59 read=25 dirtied=9
   WAL: records=8 fpi=8 bytes=43758
   ->  Index Scan using index_security_inventory_filters_on_project_id on public.security_inventory_filters  (cost=0.43..3.56 rows=1 width=9) (actual time=4.675..4.681 rows=1 loops=1)
         Index Cond: (security_inventory_filters.project_id = 69782606)
         Buffers: shared hit=3 read=4
Settings: effective_cache_size = '338688MB', jit = 'off', random_page_cost = '1.5', work_mem = '100MB', seq_page_cost = '4'

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Related to [Backend] Implementation suggestion: Aggregated... (#596691) • Gal Katz

Edited by Gal Katz

Merge request reports

Loading