From 17f81c77ce123998033702d67ffe775e0b08f50d Mon Sep 17 00:00:00 2001 From: Conrado Costa Date: Wed, 18 Jan 2023 18:58:28 -0500 Subject: [PATCH] Add validation for components of software collection --- .secrets.baseline | 4 ++-- docs/CHANGELOG.md | 1 + osidb/constants.py | 3 +++ osidb/models.py | 45 +++++++++++++++++++++++++++++++++++++++- osidb/tests/test_flaw.py | 36 ++++++++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 3 deletions(-) diff --git a/.secrets.baseline b/.secrets.baseline index 8ed9e9337..d06bc9b43 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -213,7 +213,7 @@ "filename": "osidb/models.py", "hashed_secret": "c7e672880d394aa5dd924e04465c986652ba7291", "is_verified": false, - "line_number": 147, + "line_number": 152, "is_secret": false } ], @@ -236,5 +236,5 @@ } ] }, - "generated_at": "2023-01-12T10:04:51Z" + "generated_at": "2023-01-18T23:57:53Z" } diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index a260ae8b5..f84c8c569 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Implement validation for flaw without affect (OSIDB-353) - Implement validation for changes in flaws with high criticicity with open tracker (OSIDB-347) - Implement validation for components affected by flaws closed as NOTABUG (OSIDB-363) +- Implement validation for invalid components in software collection (OSIDB-356) ### Changed - Change logging of celery and django to filesystem (OSIDB-418) diff --git a/osidb/constants.py b/osidb/constants.py index 32172450f..584bc7b7a 100644 --- a/osidb/constants.py +++ b/osidb/constants.py @@ -43,3 +43,6 @@ # update streams instead of ps_modules for affects, any issues after this one # belong to the "new way" in which ps_modules are more heavily enforced BZ_ID_SENTINEL = 1489716 + +# Lists of components from RHSCL without collection +COMPONENTS_WITHOUT_COLLECTION = ["source-to-image", "scl-utils"] diff --git a/osidb/models.py b/osidb/models.py index 133df5df9..dbd0c1068 100644 --- a/osidb/models.py +++ b/osidb/models.py @@ -24,7 +24,12 @@ from apps.osim.workflow import WorkflowModel from collectors.bzimport.constants import FLAW_PLACEHOLDER_KEYWORD -from .constants import BZ_ID_SENTINEL, CVSS3_SEVERITY_SCALE, OSIDB_API_VERSION +from .constants import ( + BZ_ID_SENTINEL, + COMPONENTS_WITHOUT_COLLECTION, + CVSS3_SEVERITY_SCALE, + OSIDB_API_VERSION, +) from .mixins import ( ACLMixin, ACLMixinManager, @@ -1085,6 +1090,44 @@ def _validate_affect_in_notabug_flaw(self): f"{self.ps_component} is affected by a flaw solved as NOTABUG.", ) + def _validate_sofware_collection(self): + """ + Check that all RHSCL components in flaw's affects start with a valid collection. + """ + if ( + not self.ps_module.startswith("rhscl") + or self.ps_component in COMPONENTS_WITHOUT_COLLECTION + ): + return + + streams = PsUpdateStream.objects.filter(ps_module__name=self.ps_module) + collections = streams.values_list("collections", flat=True).all() + + is_valid_component = False + is_meta_package = False + for collection in collections: + for component in collection: + if self.ps_component == component: + is_meta_package = True + if self.ps_component.startswith(component + "-"): + is_valid_component = True + + is_valid_component = is_valid_component and not is_meta_package + + if is_meta_package: + self.alert( + "flaw_affects_rhscl_collection_only", + f"PSComponent {self.ps_component} for {self.ps_module} indicates collection " + "meta-package rather than a specific component in the collection", + ) + + if not is_valid_component: + self.alert( + "flaw_affects_rhscl_invalid_collection", + f"PSComponent {self.ps_component} for {self.ps_module} " + "does not match any valid collection", + ) + @property def delegated_resolution(self): """affect delegated resolution based on resolutions of related trackers""" diff --git a/osidb/tests/test_flaw.py b/osidb/tests/test_flaw.py index 102eaa67e..acfb68ea6 100644 --- a/osidb/tests/test_flaw.py +++ b/osidb/tests/test_flaw.py @@ -25,6 +25,8 @@ FlawCommentFactory, FlawFactory, FlawMetaFactory, + PsModuleFactory, + PsUpdateStreamFactory, TrackerFactory, ) @@ -1158,3 +1160,37 @@ def test_validate_notabug_flaw_affected( flaw.affects.add(affect) flaw.save() assert should_raise == bool("notabug_affect_ps_component" in flaw._alerts) + + @pytest.mark.parametrize( + "ps_module,ps_component,alerts", + [ + ("rhscl-module", "valid-component", []), + ("rhscl-module", "source-to-image", []), + ("not-rhscl-module", "valid-component", []), + ("not-rhscl-module", "valid", []), + ("not-rhscl-module", "invalid-component", []), + ("not-rhscl-module", "source-to-image", []), + ( + "rhscl-module", + "valid", + [ + "flaw_affects_rhscl_collection_only", + "flaw_affects_rhscl_invalid_collection", + ], + ), + ( + "rhscl-module", + "invalid-component", + ["flaw_affects_rhscl_invalid_collection"], + ), + ], + ) + def test_flaw_affects_rhscl_invalid_collection( + self, ps_module, ps_component, alerts + ): + VALID_COLLECTIONS = ["valid"] + module_obj = PsModuleFactory(name=ps_module) + PsUpdateStreamFactory(collections=VALID_COLLECTIONS, ps_module=module_obj) + affect = AffectFactory(ps_module=ps_module, ps_component=ps_component) + if alerts: + assert set(alerts).issubset(affect._alerts)