From 9ff4c6fe9be779f01ce072d7119852e3be5e9bcb Mon Sep 17 00:00:00 2001 From: rossfuhrman Date: Mon, 6 Oct 2025 08:53:06 -0500 Subject: [PATCH 1/4] Save Sec Inventory filters for all projects We need to to save security inventory filters for all projects in order to find projects in all scenarios, including when a project doesn't have any security jobs Changelog: fixed EE: true --- .../analyzers_status/update_service.rb | 2 - .../analyzer_status_update_service.rb | 38 ++++++++++++------- .../analyzers_status/update_service_spec.rb | 9 ++++- .../analyzer_status_update_service_spec.rb | 4 +- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/ee/app/services/security/analyzers_status/update_service.rb b/ee/app/services/security/analyzers_status/update_service.rb index 11db9808c438a4..841bc08b596822 100644 --- a/ee/app/services/security/analyzers_status/update_service.rb +++ b/ee/app/services/security/analyzers_status/update_service.rb @@ -129,8 +129,6 @@ def aggregated_statuses(analyzers_statuses) end def upsert_analyzers_statuses - return unless analyzers_statuses.present? - AnalyzerProjectStatus.upsert_all(analyzers_statuses.values, unique_by: [:project_id, :analyzer_type]) InventoryFilters::AnalyzerStatusUpdateService.execute([project], analyzers_statuses.values) end diff --git a/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb b/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb index d854a2db9df410..e58fda3ffb3ae1 100644 --- a/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb +++ b/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb @@ -25,19 +25,23 @@ def execute attr_reader :projects, :analyzer_statuses, :analyzer_type def upsert_inventory_filters_analyzer_statuses - return if inventory_filters_data.empty? - - grouped_by_keys = inventory_filters_data.group_by do |record| - analyzer_keys = record.keys.select { |k| k.in?(Enums::Security.extended_analyzer_types.keys) } - analyzer_keys.sort - end - - # upsert in groups based on analyzers records keys. There should be a single update for single project, - # and upto 2 updated for many projects because the bulk setting based update can only pass - # setting type and the aggregated type as input to this service. - grouped_by_keys.each_value do |records| - Security::InventoryFilter.upsert_all(records, unique_by: :project_id) - end + if inventory_filters_data.empty? && analyzer_statuses.present? + # NO-OP, this means there were projects and analyzer_statuses, but they didn't match up + elsif inventory_filters_data.empty? + # we need to create blank filter records for projects that don't have any analyzer_statuses + Security::InventoryFilter.upsert_all(projects_with_no_analyzer_statuses, unique_by: :project_id) + else + grouped_by_keys = inventory_filters_data.group_by do |record| + analyzer_keys = record.keys.select { |k| k.in?(Enums::Security.extended_analyzer_types.keys) } + analyzer_keys.sort + end + + # upsert in groups based on analyzers records keys. There should be a single update for single project, + # and upto 2 updated for many projects because the bulk setting based update can only pass + # setting type and the aggregated type as input to this service. + grouped_by_keys.each_value do |records| + Security::InventoryFilter.upsert_all(records, unique_by: :project_id) + end end def project_id_to_attributes @@ -55,13 +59,19 @@ def inventory_filters_data build_inventory_filter_for_project(project_id, statuses) end end + + def projects_with_no_analyzer_statuses + projects.filter_map do |project| + build_inventory_filter_for_project(project.id, {}) + end + end def grouped_analyzer_statuses @grouped_analyzer_statuses ||= analyzer_statuses.group_by { |status| status[:project_id] } end def build_inventory_filter_for_project(project_id, statuses) - return unless project_id.present? && statuses.present? + return unless project_id.present? project_attributes = project_id_to_attributes[project_id] return unless project_attributes.present? diff --git a/ee/spec/services/security/analyzers_status/update_service_spec.rb b/ee/spec/services/security/analyzers_status/update_service_spec.rb index 19fb8e35235a18..d39d278bfadd0f 100644 --- a/ee/spec/services/security/analyzers_status/update_service_spec.rb +++ b/ee/spec/services/security/analyzers_status/update_service_spec.rb @@ -359,7 +359,14 @@ }.from(nil).to('not_configured') end - include_examples 'does not call inventory filters service' + it 'calls InventoryFilters service with pipeline and aggregated statuses' do + expect(inventory_filters_update_service).to receive(:execute).once.with( + [project], [] + ) + + execute + end + include_examples 'calls namespace related services' end diff --git a/ee/spec/services/security/inventory_filters/analyzer_status_update_service_spec.rb b/ee/spec/services/security/inventory_filters/analyzer_status_update_service_spec.rb index 091b4805161ab8..18a96facdc6500 100644 --- a/ee/spec/services/security/inventory_filters/analyzer_status_update_service_spec.rb +++ b/ee/spec/services/security/inventory_filters/analyzer_status_update_service_spec.rb @@ -82,8 +82,8 @@ context 'when analyzer_statuses is empty' do let(:analyzer_statuses) { [] } - it 'returns early' do - expect { service.execute }.not_to change { Security::InventoryFilter.count } + it 'processes the project' do + expect { service.execute }.to change { Security::InventoryFilter.count } end end -- GitLab From 2ff5942463f174231e5c6795f13f243d9ff69a45 Mon Sep 17 00:00:00 2001 From: Ross Fuhrman Date: Mon, 6 Oct 2025 23:03:19 -0500 Subject: [PATCH 2/4] rubocop --- .../services/security/analyzers_status/update_service_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ee/spec/services/security/analyzers_status/update_service_spec.rb b/ee/spec/services/security/analyzers_status/update_service_spec.rb index d39d278bfadd0f..d01e954a0ae868 100644 --- a/ee/spec/services/security/analyzers_status/update_service_spec.rb +++ b/ee/spec/services/security/analyzers_status/update_service_spec.rb @@ -361,9 +361,9 @@ it 'calls InventoryFilters service with pipeline and aggregated statuses' do expect(inventory_filters_update_service).to receive(:execute).once.with( - [project], [] + [project], [] ) - + execute end -- GitLab From 6b34370f2f111bff1ee61631ad60f51ea79099cf Mon Sep 17 00:00:00 2001 From: Ross Fuhrman Date: Mon, 6 Oct 2025 23:09:57 -0500 Subject: [PATCH 3/4] Rubo --- .../inventory_filters/analyzer_status_update_service.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb b/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb index e58fda3ffb3ae1..c570431b4cc331 100644 --- a/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb +++ b/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb @@ -59,7 +59,7 @@ def inventory_filters_data build_inventory_filter_for_project(project_id, statuses) end end - + def projects_with_no_analyzer_statuses projects.filter_map do |project| build_inventory_filter_for_project(project.id, {}) -- GitLab From 70e9c7b000353565b48d03e55b23efec69968662 Mon Sep 17 00:00:00 2001 From: Ross Fuhrman Date: Mon, 6 Oct 2025 23:37:00 -0500 Subject: [PATCH 4/4] Add the end --- .../security/inventory_filters/analyzer_status_update_service.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb b/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb index c570431b4cc331..ae7728826320e9 100644 --- a/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb +++ b/ee/app/services/security/inventory_filters/analyzer_status_update_service.rb @@ -42,6 +42,7 @@ def upsert_inventory_filters_analyzer_statuses grouped_by_keys.each_value do |records| Security::InventoryFilter.upsert_all(records, unique_by: :project_id) end + end end def project_id_to_attributes -- GitLab