From 744030a6f97f30f91bebf7e995834e5f421c42a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Sas=C3=A1k?= Date: Thu, 26 Oct 2023 17:08:13 +0200 Subject: [PATCH] feat(evaluator): inherit cve statuses for new system evaluated vulnerabilities RHINENG-2381 --- .../132-system_cve_data-evaluator.sql | 1 + database/schema/ve_db_postgresql.sql | 3 ++- evaluator/logic.py | 26 +++++++++++++++++-- evaluator/processor.py | 22 ++++++++++++++-- 4 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 database/schema/upgrade_scripts/132-system_cve_data-evaluator.sql diff --git a/database/schema/upgrade_scripts/132-system_cve_data-evaluator.sql b/database/schema/upgrade_scripts/132-system_cve_data-evaluator.sql new file mode 100644 index 000000000..e6bad75d1 --- /dev/null +++ b/database/schema/upgrade_scripts/132-system_cve_data-evaluator.sql @@ -0,0 +1 @@ +GRANT SELECT, INSERT, UPDATE ON system_cve_data TO ve_db_user_evaluator; diff --git a/database/schema/ve_db_postgresql.sql b/database/schema/ve_db_postgresql.sql index 9a41b2250..884fe0215 100644 --- a/database/schema/ve_db_postgresql.sql +++ b/database/schema/ve_db_postgresql.sql @@ -30,7 +30,7 @@ CREATE TABLE IF NOT EXISTS db_version ( ) TABLESPACE pg_default; -- set the schema version directly in the insert statement here!! -INSERT INTO db_version (name, version) VALUES ('schema_version', 131); +INSERT INTO db_version (name, version) VALUES ('schema_version', 132); -- INSERT INTO db_version (name, version) VALUES ('schema_version', :schema_version); @@ -761,6 +761,7 @@ CREATE TABLE IF NOT EXISTS system_cve_data ( CREATE INDEX ON system_cve_data(cve_id); GRANT SELECT, INSERT, UPDATE, DELETE ON system_cve_data TO ve_db_user_manager; +GRANT SELECT, INSERT, UPDATE ON system_cve_data TO ve_db_user_evaluator; GRANT DELETE ON system_cve_data TO ve_db_user_taskomatic; GRANT DELETE ON system_cve_data TO ve_db_user_vmaas_sync; diff --git a/evaluator/logic.py b/evaluator/logic.py index 8b2196c22..f8b902c1c 100644 --- a/evaluator/logic.py +++ b/evaluator/logic.py @@ -399,7 +399,25 @@ async def _compare_system_vulnerable_package( return sorted(to_insert), sorted(to_delete) - async def _insert_system_vulnerable_package(self, to_insert: List[Tuple[int, int, int]], conn: AsyncConnection): + async def _insert_system_vulnerable_package_cve_statuses( + self, vuln_packages: List[int], system_platform: SystemPlatform, conn: AsyncConnection + ): + async with conn.cursor() as cur: + await cur.execute( + """ + INSERT INTO system_cve_data + SELECT %s, cad.cve_id, cad.status_id, cad.status_text + FROM cve_account_data AS cad + JOIN vulnerable_package_cve AS vpc ON cad.cve_id = vpc.cve_id + WHERE vpc.vulnerable_package_id = ANY(%s) AND cad.rh_account_id = %s + ON CONFLICT DO NOTHING + """, + (system_platform.id, vuln_packages, system_platform.rh_account_id), + ) + + async def _insert_system_vulnerable_package( + self, to_insert: List[Tuple[int, int, int]], system_platform: SystemPlatform, conn: AsyncConnection + ): """Insert given system vulnerable packages to table""" async with conn.cursor() as cur: await cur.executemany( @@ -411,6 +429,10 @@ async def _insert_system_vulnerable_package(self, to_insert: List[Tuple[int, int to_insert, ) + await self._insert_system_vulnerable_package_cve_statuses( + list(map(lambda acc_sys_pkg: acc_sys_pkg[2], to_insert)), system_platform, conn + ) + async def _delete_system_vulnerable_package(self, to_delete: List[Tuple[int, int, int]], conn: AsyncConnection): """Delete given system vulnerable packages from table""" async with conn.cursor() as cur: @@ -508,7 +530,7 @@ async def _evaluate_vmaas_res( "system: %s, system_vulnerable_package changes, i: %s, d: %s", system_platform.inventory_id, len(to_insert), len(to_delete) ) if to_insert: - await self._insert_system_vulnerable_package(to_insert, conn) + await self._insert_system_vulnerable_package(to_insert, system_platform, conn) if to_delete: await self._delete_system_vulnerable_package(to_delete, conn) diff --git a/evaluator/processor.py b/evaluator/processor.py index 32715f603..b1f6154b3 100644 --- a/evaluator/processor.py +++ b/evaluator/processor.py @@ -120,7 +120,21 @@ async def _load_db_system_vulnerabilities(self, system_platform: SystemPlatform, ) return cve_map - async def _insert_vulnerabilities(self, to_insert: [Dict], conn: AsyncConnection) -> List[Tuple]: + async def _insert_system_cve_statuses(self, cve_ids: List[int], system_platform: SystemPlatform, conn: AsyncConnection): + """Insert system-status IDs for CVEs to which system is newly affected""" + async with conn.cursor(row_factory=dict_row) as cur: + await cur.execute( + """ + INSERT INTO system_cve_data + SELECT %s, cad.cve_id, cad.status_id, cad.status_text + FROM cve_account_data AS cad + WHERE cad.cve_id = ANY(%s) AND cad.rh_account_id = %s + ON CONFLICT DO NOTHING + """, + (system_platform.id, cve_ids, system_platform.rh_account_id), + ) + + async def _insert_vulnerabilities(self, to_insert: [Dict], system_platform: SystemPlatform, conn: AsyncConnection) -> List[Tuple]: """Insert given system_vulnerabilities""" new_sys_vulns = [] async with conn.cursor(row_factory=dict_row) as cur: @@ -140,8 +154,12 @@ async def _insert_vulnerabilities(self, to_insert: [Dict], conn: AsyncConnection to_insert, returning=True, ) + cve_ids = [] for inserted in await executemany_fetchall(cur): new_sys_vulns.append((inserted["id"], inserted["cve_id"])) + cve_ids.append(inserted["cve_id"]) + + await self._insert_system_cve_statuses(cve_ids, system_platform, conn) return new_sys_vulns async def _update_vulnerabilities(self, to_update: [Dict], conn: AsyncConnection): @@ -254,7 +272,7 @@ async def _evaluate_system(self, inventory_id: str, org_id: str, request_timesta ) new_system_vulns = [] if to_insert: - new_system_vulns = await self._insert_vulnerabilities(to_insert, conn) + new_system_vulns = await self._insert_vulnerabilities(to_insert, system_platform, conn) if to_update: await self._update_vulnerabilities(to_update, conn) if to_delete: