diff --git a/.gitignore b/.gitignore index ebbf2ace8..b1e076249 100755 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,7 @@ DevSecOps_Remote_Config .*DS_Store Pipfile -#Distribucioes de lib +#Distribuciones de lib **dist** **.egg-info/ *.pyc @@ -22,11 +22,20 @@ Pipfile **tools/build/** **build/lib** -#Ignorar cualquir archivo TXT +#Ignorar cualquier archivo TXT scanned_images.txt *.pyc data +#Ignorar carpetas/archivos de agentes +.agents +.clinerules +.cursor +.github +.opencode +.windsurf +AGENTS.md + #Archivos de Pruebas .env test-output.xml diff --git a/tools/devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py b/tools/devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py index 4c644f108..e37e9389a 100644 --- a/tools/devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py +++ b/tools/devsecops_engine_tools/engine_core/src/domain/usecases/handle_risk.py @@ -86,12 +86,30 @@ def _filter_engagements(self, engagements, service, initial_services, risk_confi return filtered_engagements - def _exclude_services(self, dict_args, pipeline_name, service_list): + def _exclude_services(self, dict_args, pipeline_name, service_list, risk_config): risk_exclusions = self.remote_config_source_gateway.get_remote_config( dict_args["remote_config_repo"], "engine_risk/Exclusions.json", dict_args["remote_config_branch"], ) + + ignore_pattern = risk_config.get("IGNORE_ANALYSIS_PATTERN") + if ignore_pattern: + pattern_excluded = [ + engagement + for engagement in service_list + if re.match(ignore_pattern, engagement.name, re.IGNORECASE) + ] + if pattern_excluded: + print( + f"Services excluded by pattern: {[e.name for e in pattern_excluded]}" + ) + service_list = [ + engagement + for engagement in service_list + if not re.match(ignore_pattern, engagement.name, re.IGNORECASE) + ] + if ( pipeline_name in risk_exclusions and risk_exclusions[pipeline_name].get("SKIP_SERVICE", 0) @@ -219,7 +237,7 @@ def process(self, dict_args: any, remote_config: any): service_list += [build_engagement] new_service_list = self._exclude_services( - dict_args, pipeline_name, service_list + dict_args, pipeline_name, service_list, risk_config ) for engagement in new_service_list: diff --git a/tools/devsecops_engine_tools/engine_core/test/domain/usecases/test_handle_risk.py b/tools/devsecops_engine_tools/engine_core/test/domain/usecases/test_handle_risk.py index e3bcbd29e..992fa9e77 100644 --- a/tools/devsecops_engine_tools/engine_core/test/domain/usecases/test_handle_risk.py +++ b/tools/devsecops_engine_tools/engine_core/test/domain/usecases/test_handle_risk.py @@ -191,6 +191,7 @@ def test_exclude_services(self): MagicMock(name="service_1"), MagicMock(name="service_2"), ] + risk_config = {"IGNORE_ANALYSIS_PATTERN": None} self.remote_config_source_gateway.get_remote_config.return_value = { "pipeline_name": { "SKIP_SERVICE": {"services": ["code_service_1", "code_service_2"]} @@ -199,12 +200,33 @@ def test_exclude_services(self): # Call the process method result = self.handle_risk._exclude_services( - dict_args, pipeline_name, service_list + dict_args, pipeline_name, service_list, risk_config ) # Assert the expected values assert type(result) == list + def test_exclude_services_ignore_pattern(self): + dict_args = { + "remote_config_repo": "test_repo", + "remote_config_branch": "" + } + pipeline_name = "pipeline_name" + eng1 = MagicMock() + eng1.name = "skip_service_1" + eng2 = MagicMock() + eng2.name = "keep_service_1" + service_list = [eng1, eng2] + risk_config = {"IGNORE_ANALYSIS_PATTERN": "^skip_.*"} + self.remote_config_source_gateway.get_remote_config.return_value = {} + + result = self.handle_risk._exclude_services( + dict_args, pipeline_name, service_list, risk_config + ) + + assert len(result) == 1 + assert result[0].name == "keep_service_1" + def test_should_skip_analysis(self): remote_config = {"IGNORE_ANALYSIS_PATTERN": "pattern"} pipeline_name = "pipeline"