diff --git a/0001-fix-some-apis-which-has-filter-fault.patch b/0001-fix-some-apis-which-has-filter-fault.patch deleted file mode 100644 index 796fa51e0173576fc83f0a6eefd476c2777c12f1..0000000000000000000000000000000000000000 --- a/0001-fix-some-apis-which-has-filter-fault.patch +++ /dev/null @@ -1,147 +0,0 @@ -From ca1388c59c97d31dbbdae3c48e7033dbc2d11b47 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Mon, 29 May 2023 17:05:17 +0800 -Subject: [PATCH] fix issue where some fields of the interface cannot support filtering -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - apollo/database/proxy/cve.py | 12 +++++------- - apollo/database/proxy/host.py | 7 ++++--- - apollo/database/proxy/task.py | 14 ++++---------- - apollo/function/schema/task.py | 3 ++- - 4 files changed, 15 insertions(+), 21 deletions(-) - -diff --git a/apollo/database/proxy/cve.py b/apollo/database/proxy/cve.py -index ed4c1d2..9dc96ae 100644 ---- a/apollo/database/proxy/cve.py -+++ b/apollo/database/proxy/cve.py -@@ -867,17 +867,15 @@ class CveProxy(CveMysqlProxy, CveEsProxy): - exist_cve_query = self.session.query(CveHostAssociation.cve_id) \ - .join(Host, Host.host_id == CveHostAssociation.host_id) \ - .filter(Host.user == username, CveHostAssociation.affected == 1, CveHostAssociation.fixed == 0) -- # get first column value from tuple to list -- exist_cve_list = list(zip(*exist_cve_query))[0] - - related_cve_query = self.session.query(CveAffectedPkgs.cve_id) \ -- .filter(CveAffectedPkgs.package.in_(pkg_list)) \ -- .filter(CveAffectedPkgs.cve_id.in_(exist_cve_list)) -- related_cve = set(list(zip(*related_cve_query))[0]) -+ .filter(CveAffectedPkgs.package.in_(pkg_list),CveAffectedPkgs.cve_id.in_(exist_cve_query.subquery())) \ -+ .distinct() - -- related_cve.remove(cve_id) -- return list(related_cve) -+ related_cve = [row[0] for row in related_cve_query.all() if row[0] != cve_id] - -+ return related_cve -+ - @staticmethod - def _cve_info_row2dict(row, description_dict, pkg_list): - """ -diff --git a/apollo/database/proxy/host.py b/apollo/database/proxy/host.py -index f3fe51e..a9431a9 100644 ---- a/apollo/database/proxy/host.py -+++ b/apollo/database/proxy/host.py -@@ -514,7 +514,8 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - Returns: - set - """ -- filters = {CveHostAssociation.fixed == filter_dict.get("fixed", False)} -+ fixed = filter_dict.get("fixed", False) -+ filters = {CveHostAssociation.fixed == fixed} - - if not filter_dict: - return filters -@@ -525,9 +526,9 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - if filter_dict.get("severity"): - filters.add(Cve.severity.in_(filter_dict["severity"])) - -- if filter_dict.get("hotpatch") and filter_dict.get("fixed") is True: -+ if filter_dict.get("hotpatch") and fixed is True: - filters.add(CveHostAssociation.fixed_by_hp.in_(filter_dict["hotpatch"])) -- elif filter_dict.get("hotpatch") and filter_dict.get("fixed") is False: -+ elif filter_dict.get("hotpatch") and fixed is False: - filters.add(CveHostAssociation.support_hp.in_(filter_dict["hotpatch"])) - - if "affected" in filter_dict: -diff --git a/apollo/database/proxy/task.py b/apollo/database/proxy/task.py -index f457043..e660f02 100644 ---- a/apollo/database/proxy/task.py -+++ b/apollo/database/proxy/task.py -@@ -924,9 +924,7 @@ class TaskMysqlProxy(MysqlProxy): - filters = set() - - if filter_dict.get("cve_id"): -- filters.add(Cve.cve_id.like("%" + filter_dict["cve_id"] + "%")) -- if filter_dict.get("reboot"): -- filters.add(Cve.reboot == filter_dict["reboot"]) -+ filters.add(CveHostAssociation.cve_id.like("%" + filter_dict["cve_id"] + "%")) - return filters - - def _query_cve_task(self, username, task_id, filters): -@@ -948,12 +946,11 @@ class TaskMysqlProxy(MysqlProxy): - } - """ - task_cve_query = self.session.query(TaskCveHostAssociation.cve_id, -- Cve.reboot, - CveAffectedPkgs.package, - TaskCveHostAssociation.host_id, - TaskCveHostAssociation.status) \ -- .outerjoin(Cve, Cve.cve_id == TaskCveHostAssociation.cve_id) \ -- .outerjoin(CveAffectedPkgs, CveAffectedPkgs.cve_id == Cve.cve_id) \ -+ .outerjoin(CveHostAssociation, CveHostAssociation.cve_id == TaskCveHostAssociation.cve_id) \ -+ .outerjoin(CveAffectedPkgs, CveAffectedPkgs.cve_id == CveHostAssociation.cve_id) \ - .outerjoin(Task, Task.task_id == TaskCveHostAssociation.task_id) \ - .filter(Task.task_id == task_id, Task.username == username) \ - .filter(*filters) -@@ -969,7 +966,6 @@ class TaskMysqlProxy(MysqlProxy): - { - "cve_id": "CVE-2021-0001", - "package": "tensorflow", -- "reboot": True, - "host_id": "id1", - "status": "fixed" - } -@@ -979,7 +975,6 @@ class TaskMysqlProxy(MysqlProxy): - [{ - "cve_id": "CVE-2021-0001", - "package": "tensorflow", -- "reboot": True, - "host_num": 3, - "status": "running" - }] -@@ -991,8 +986,7 @@ class TaskMysqlProxy(MysqlProxy): - for row in task_cve_query: - cve_id = row.cve_id - if cve_id not in cve_dict: -- cve_dict[cve_id] = {"package": {row.package}, "reboot": row.reboot, -- "host_set": {row.host_id}, "status_set": {row.status}} -+ cve_dict[cve_id] = {"package": {row.package}, "host_set": {row.host_id}, "status_set": {row.status}} - else: - cve_dict[cve_id]["package"].add(row.package) - cve_dict[cve_id]["host_set"].add(row.host_id) -diff --git a/apollo/function/schema/task.py b/apollo/function/schema/task.py -index 1fa776c..472fd53 100644 ---- a/apollo/function/schema/task.py -+++ b/apollo/function/schema/task.py -@@ -19,6 +19,7 @@ from marshmallow import Schema - from marshmallow import fields - from marshmallow import validate - -+from apollo.conf.constant import TaskType - - class TaskListFilterSchema(Schema): - """ -@@ -26,7 +27,7 @@ class TaskListFilterSchema(Schema): - """ - task_name = fields.String(required=False, validate=lambda s: len(s) > 0) - task_type = fields.List(fields.String( -- validate=validate.OneOf(["cve fix", "repo set"])), required=False) -+ validate=validate.OneOf([getattr(TaskType,p) for p in dir(TaskType) if p.isupper()])), required=False) - - - class GetTaskListSchema(Schema): --- - diff --git a/0002-fix-bug-and-update-the-code-of-parsing.patch b/0002-fix-bug-and-update-the-code-of-parsing.patch deleted file mode 100644 index 2fd0f7f4e093a85e40c5226965c05474d466acb6..0000000000000000000000000000000000000000 --- a/0002-fix-bug-and-update-the-code-of-parsing.patch +++ /dev/null @@ -1,91 +0,0 @@ -From 313271160b4826c9c2d2b3afe2f0489c4a95fef9 Mon Sep 17 00:00:00 2001 -From: wang-guangge -Date: Thu, 1 Jun 2023 21:31:58 +0800 -Subject: [PATCH] fix bug and update the code of parsing src.rpm - ---- - .../aops_apollo_tool/gen_updateinfo.py | 42 ++++++++++++++----- - 1 file changed, 32 insertions(+), 10 deletions(-) - mode change 100755 => 100644 aops-apollo-tool/aops_apollo_tool/gen_updateinfo.py - -diff --git a/aops-apollo-tool/aops_apollo_tool/gen_updateinfo.py b/aops-apollo-tool/aops_apollo_tool/gen_updateinfo.py -old mode 100755 -new mode 100644 -index 26f3226..2204b10 ---- a/aops-apollo-tool/aops_apollo_tool/gen_updateinfo.py -+++ b/aops-apollo-tool/aops_apollo_tool/gen_updateinfo.py -@@ -26,7 +26,7 @@ import rpm - import configparser - - # get updateinfo global config --UPDATEINFO_FILE = "/etc/gen_updateinfo/updateinfo_config.ini" -+UPDATEINFO_FILE = "/etc/aops_apollo_tool/updateinfo_config.ini" - CONF = configparser.ConfigParser() - CONF.read(filenames=UPDATEINFO_FILE) - -@@ -69,6 +69,21 @@ def check_uniqueness_of_advisory_id(root: ET, advisory_id: str) -> int: - sys.exit(1) - existed_adv_id.add(update_adv_id) - -+def parse_src_rpm_info_by_filename(filename: str) -> tuple: -+ """ -+ Parse source rpm package information by filename, the filename should be 'name-version-release.src.rpm'. -+ -+ Returns: -+ name, version, release -+ """ -+ nevra_pos = filename.rindex('.src.rpm') -+ nevra = filename[:nevra_pos] -+ release_pos = nevra.rindex('-') -+ version_pos = nevra.rindex('-', 0, release_pos) -+ name, version, release = nevra[0:version_pos], nevra[ -+ version_pos+1:release_pos], nevra[release_pos+1:] -+ -+ return name, version, release - - def generate_package_list(package_dir: str) -> Element: - """ -@@ -107,21 +122,27 @@ def generate_package_list(package_dir: str) -> Element: - except rpm.error: - print("error: %s cannot be successfully parsed" % package_path) - sys.exit(1) -+ -+ filename = Element('filename') -+ if pkg.endswith('.src.rpm'): -+ # parse source rpm information by filename, and the arch information is not marked -+ name, version, release = parse_src_rpm_info_by_filename(pkg) -+ package.attrib['name'] = name -+ package.attrib['version'] = version -+ package.attrib['release'] = release -+ filename.text = pkg - -- try: -+ else: - package.attrib['arch'] = pkg_info[rpm.RPMTAG_ARCH] - package.attrib['name'] = pkg_info[rpm.RPMTAG_NAME] - package.attrib['version'] = pkg_info[rpm.RPMTAG_VERSION] - package.attrib['release'] = pkg_info[rpm.RPMTAG_R] -- except rpm.error: -- print("error: key information is lost in %s" % package_path) -- sys.exit(1) - -- filename = Element('filename') -- filename.text = "%s-%s-%s.%s.rpm" % (package.attrib['name'], -- package.attrib['release'], -- package.attrib['version'], -- package.attrib['arch']) -+ filename.text = "%s-%s-%s.%s.rpm" % (package.attrib['name'], -+ package.attrib['release'], -+ package.attrib['version'], -+ package.attrib['arch']) -+ - package.append(filename) - collection.append(package) - -@@ -306,3 +327,4 @@ def main(): - - main() - -+ --- -Gitee diff --git a/0003-fix-hotpatch-updateinfo-for-search-hotpatch-info.patch b/0003-fix-hotpatch-updateinfo-for-search-hotpatch-info.patch deleted file mode 100644 index bfec3025441cfe9a3e9b6df358c3ee1b31f8ee10..0000000000000000000000000000000000000000 --- a/0003-fix-hotpatch-updateinfo-for-search-hotpatch-info.patch +++ /dev/null @@ -1,381 +0,0 @@ -From faeec6eff1e80be893916d16fb6bd3cd8f0246c9 Mon Sep 17 00:00:00 2001 -From: wang-guangge -Date: Wed, 31 May 2023 18:06:22 +0800 -Subject: [PATCH] fix hotpatch updateinfo for search hotpatch information -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - hotpatch/baseclass.py | 14 ++-- - hotpatch/hot-updateinfo.py | 118 +++++++++----------------------- - hotpatch/hotpatch.py | 13 ++-- - hotpatch/hotpatch_updateinfo.py | 58 ++++++++++------ - 4 files changed, 83 insertions(+), 120 deletions(-) - -diff --git a/hotpatch/baseclass.py b/hotpatch/baseclass.py -index d88ef40..2542a03 100644 ---- a/hotpatch/baseclass.py -+++ b/hotpatch/baseclass.py -@@ -115,7 +115,7 @@ class Hotpatch(object): - - - class Cve(object): -- __slots__ = ['_cve_id', '_hotpatch'] -+ __slots__ = ['_cve_id', '_hotpatches'] - - def __init__(self, - id, -@@ -124,15 +124,14 @@ class Cve(object): - id: str - """ - self._cve_id = id -- self._hotpatch = None -+ self._hotpatches = [] - - @property -- def hotpatch(self): -- return self._hotpatch -+ def hotpatches(self): -+ return self._hotpatches - -- @hotpatch.setter -- def hotpatch(self, hotpatch: Hotpatch): -- self._hotpatch = hotpatch -+ def add_hotpatch(self, hotpatch: Hotpatch): -+ self._hotpatches.append(hotpatch) - - @property - def cve_id(self): -@@ -206,3 +205,4 @@ class Advisory(object): - - def add_hotpatch(self, hotpatch: Hotpatch): - self._hotpatches.append(hotpatch) -+ -diff --git a/hotpatch/hot-updateinfo.py b/hotpatch/hot-updateinfo.py -index 779337b..d1e6d58 100644 ---- a/hotpatch/hot-updateinfo.py -+++ b/hotpatch/hot-updateinfo.py -@@ -4,46 +4,6 @@ from dnf.cli.commands.updateinfo import UpdateInfoCommand - import hawkey - from .hotpatch_updateinfo import HotpatchUpdateInfo - -- --class Versions: -- """ -- Version number processing -- """ -- -- separator = (".", "-") -- _connector = "&" -- -- def _order(self, version, separator=None): -- """ -- Version of the cutting -- Args: -- version: version -- separator: separator -- -- Returns: -- -- """ -- if not separator: -- separator = self._connector -- return tuple([int(v) for v in version.split(separator) if v.isdigit()]) -- -- def lgt(self, version, compare_version): -- """ -- Returns true if the size of the compared version is greater -- than that of the compared version, or false otherwise -- -- """ -- for separator in self.separator: -- version = self._connector.join( -- [v for v in version.split(separator)]) -- compare_version = self._connector.join( -- [v for v in compare_version.split(separator)] -- ) -- version = self._order(version) -- compare_version = self._order(compare_version) -- return version >= compare_version -- -- - @dnf.plugin.register_command - class HotUpdateinfoCommand(dnf.cli.Command): - aliases = ['hot-updateinfo'] -@@ -118,26 +78,13 @@ class HotUpdateinfoCommand(dnf.cli.Command): - - return mapping_nevra_cve - -- def _filter_and_format_list_output(self, echo_lines: list, fixed_cve_id: set, fixed_coldpatches: set): -+ def _filter_and_format_list_output(self, echo_lines: list, fixed_cve_id: set): - """ - Only show specified cve information that have not been fixed, and format output - """ -- def is_patch_fixed(coldpatch, fixed_coldpatches): -- """ -- Check whether the coldpatch is fixed -- """ -- for fixed_coldpatch in fixed_coldpatches: -- pkg_name, pkg_evr, _ = coldpatch -- fixed_pkg_name, fixed_pkg_evr, _ = fixed_coldpatch -- if pkg_name != fixed_pkg_name: -- continue -- if version.lgt(fixed_pkg_evr, pkg_evr): -- return True -- return False - - idw = tiw = ciw = 0 - format_lines = set() -- version = Versions() - for echo_line in echo_lines: - cve_id, adv_type, coldpatch, hotpatch = echo_line[0], echo_line[1], echo_line[2], echo_line[3] - if self.filter_cves is not None and cve_id not in self.filter_cves: -@@ -145,11 +92,8 @@ class HotUpdateinfoCommand(dnf.cli.Command): - if cve_id in fixed_cve_id: - continue - if not isinstance(coldpatch, str): -- if is_patch_fixed(coldpatch, fixed_coldpatches): -- continue -- else: -- pkg_name, pkg_evr, pkg_arch = coldpatch -- coldpatch = '%s-%s.%s' % (pkg_name, pkg_evr, pkg_arch) -+ pkg_name, pkg_evr, pkg_arch = coldpatch -+ coldpatch = '%s-%s.%s' % (pkg_name, pkg_evr, pkg_arch) - - idw = max(idw, len(cve_id)) - tiw = max(tiw, len(adv_type)) -@@ -178,41 +122,43 @@ class HotUpdateinfoCommand(dnf.cli.Command): - mapping_nevra_cve = self.get_mapping_nevra_cve() - echo_lines = [] - fixed_cve_id = set() -- fixed_coldpatches = set() - iterated_cve_id = set() - for ((nevra), aupdated), id2type in sorted(mapping_nevra_cve.items(), key=lambda x: x[0]): - pkg_name, pkg_evr, pkg_arch = nevra - for cve_id, atypesev in id2type.items(): - iterated_cve_id.add(cve_id) -- label = type2label(self.updateinfo, *atypesev) -- echo_line = [cve_id, label, nevra, '-'] -- echo_lines.append(echo_line) -- if cve_id not in self.hp_hawkey.hotpatch_cves: -+ label = type2label(self.updateinfo, *atypesev) -+ if cve_id not in self.hp_hawkey.hotpatch_cves or not self.hp_hawkey.hotpatch_cves[cve_id].hotpatches: -+ echo_line = [cve_id, label, nevra, '-'] -+ echo_lines.append(echo_line) - continue -- hotpatch = self.hp_hawkey.hotpatch_cves[cve_id].hotpatch -- if hotpatch is None or hotpatch.src_pkg_nevre[0] != pkg_name: -- continue -- if hotpatch.state == self.hp_hawkey.INSTALLED: -- # record the fixed cves -- for cve_id in hotpatch.cves: -- fixed_cve_id.add(cve_id) -- # record the fixed coldpatch to filter the cves of the corresponding coldpatch with the lower version -- fixed_coldpatches.add((nevra)) -- echo_lines.pop() -- elif hotpatch.state == self.hp_hawkey.INSTALLABLE: -- echo_lines[-1][3] = hotpatch.nevra -+ -+ for hotpatch in self.hp_hawkey.hotpatch_cves[cve_id].hotpatches: -+ echo_line = [cve_id, label, nevra, '-'] -+ echo_lines.append(echo_line) -+ if hotpatch.src_pkg_nevre[0] != pkg_name: -+ continue -+ if hotpatch.state == self.hp_hawkey.INSTALLED: -+ # record the fixed cves -+ for cve_id in hotpatch.cves: -+ fixed_cve_id.add(cve_id) -+ echo_lines.pop() -+ elif hotpatch.state == self.hp_hawkey.INSTALLABLE: -+ echo_lines[-1][3] = hotpatch.nevra -+ - - hp_cve_list = list(set(self.hp_hawkey.hotpatch_cves.keys()).difference(iterated_cve_id)) - for cve_id in hp_cve_list: -- hotpatch = self.hp_hawkey.hotpatch_cves[cve_id].hotpatch -- if hotpatch is None: -- continue -- echo_line = [cve_id, hotpatch.advisory.severity + '/Sec.', '-', '-'] -- if hotpatch.state == self.hp_hawkey.INSTALLED: -- continue -- elif hotpatch.state == self.hp_hawkey.INSTALLABLE: -- echo_line = [cve_id, hotpatch.advisory.severity + '/Sec.', '-', hotpatch.nevra] -- echo_lines.append(echo_line) -+ for hotpatch in self.hp_hawkey.hotpatch_cves[cve_id].hotpatches: -+ echo_line = [cve_id, hotpatch.advisory.severity + '/Sec.', '-', '-'] -+ if hotpatch.state == self.hp_hawkey.INSTALLED: -+ # record the fixed cves -+ fixed_cve_id.add(cve_id) -+ continue -+ elif hotpatch.state == self.hp_hawkey.INSTALLABLE: -+ echo_line = [cve_id, hotpatch.advisory.severity + '/Sec.', '-', hotpatch.nevra] -+ echo_lines.append(echo_line) - - self._filter_and_format_list_output( -- echo_lines, fixed_cve_id, fixed_coldpatches) -+ echo_lines, fixed_cve_id) -+ -diff --git a/hotpatch/hotpatch.py b/hotpatch/hotpatch.py -index 0704a08..ccef636 100644 ---- a/hotpatch/hotpatch.py -+++ b/hotpatch/hotpatch.py -@@ -102,12 +102,12 @@ class HotpatchCommand(dnf.cli.Command): - hotpatch_cves = self.hp_hawkey.hotpatch_cves - echo_lines = [] - for cve_id in hotpatch_cves.keys(): -- hotpatch = hotpatch_cves[cve_id].hotpatch -- status = self.hp_hawkey._get_hotpatch_status_in_syscare(hotpatch) -- if status == '': -- continue -- echo_line = [cve_id, hotpatch.syscare_name, status] -- echo_lines.append(echo_line) -+ for hotpatch in hotpatch_cves[cve_id].hotpatches: -+ status = self.hp_hawkey._get_hotpatch_status_in_syscare(hotpatch) -+ if status == '': -+ continue -+ echo_line = [cve_id, hotpatch.syscare_name, status] -+ echo_lines.append(echo_line) - - self._filter_and_format_list_output(echo_lines) - -@@ -133,3 +133,4 @@ class HotpatchCommand(dnf.cli.Command): - else: - logger.info(_("%s hot patch '%s' succeed"), operate, self.base.output.term.bold(target_patch)) - -+ -diff --git a/hotpatch/hotpatch_updateinfo.py b/hotpatch/hotpatch_updateinfo.py -index 6689553..399e05c 100644 ---- a/hotpatch/hotpatch_updateinfo.py -+++ b/hotpatch/hotpatch_updateinfo.py -@@ -67,7 +67,7 @@ class HotpatchUpdateInfo(object): - """ - Initialize hotpatch information from repos - """ -- # get xxx-hotpatch.xml.gz file paths by traversing the system_cachedir(/var/cache/dnf) -+ # get xxx-updateinfo.xml.gz file paths by traversing the system_cachedir(/var/cache/dnf) - system_cachedir = self.cli.base.conf.system_cachedir - all_repos = self.cli.base.repos - map_repo_updateinfoxml = {} -@@ -80,9 +80,9 @@ class HotpatchUpdateInfo(object): - continue - - for xml_file in os.listdir(repodata_path): -- # the hotpatch relevant updateinfo is recorded in xxx-hotpatch.xml.gz -- if "hotpatch" in xml_file: -- repo_name = file.split("-")[0] -+ # the hotpatch relevant updateinfo is recorded in xxx-updateinfo.xml.gz -+ if "updateinfo" in xml_file: -+ repo_name = file.rsplit("-")[0] - cache_updateinfo_xml_path = os.path.join( - repodata_path, xml_file) - map_repo_updateinfoxml[repo_name] = cache_updateinfo_xml_path -@@ -99,7 +99,7 @@ class HotpatchUpdateInfo(object): - Parse the pkglist information, filter the hotpatches with different arches - """ - hotpatches = [] -- hot_patch_collection = pkglist.find('collection') -+ hot_patch_collection = pkglist.find('hot_patch_collection') - arches = self.base.sack.list_arches() - if not hot_patch_collection: - return hotpatches -@@ -171,14 +171,19 @@ class HotpatchUpdateInfo(object): - advisory.cves = advisory_cves - - for hotpatch_kwargs in advisory_hotpatches: -+ # parse the id string of the package to list -+ # e.g. parse the id of "CVE-2021-2023,CVE-2021-2024" to ["CVE-2021-2023", "CVE-2021-2024"] -+ hotpatch_ref_id = hotpatch_kwargs.pop('id') -+ hotpatch_ref_id = hotpatch_ref_id.split(',') -+ - hotpatch = Hotpatch(**hotpatch_kwargs) - hotpatch.advisory = advisory -- hotpatch.cves = advisory_cves.keys() -+ hotpatch.cves = hotpatch_ref_id - - advisory.add_hotpatch(hotpatch) -- -- for cve in advisory_cves.values(): -- cve.hotpatch = hotpatch -+ -+ for ref_id in hotpatch_ref_id: -+ advisory_cves[ref_id].add_hotpatch(hotpatch) - - self._hotpatch_advisories[advisory_kwargs['id']] = advisory - -@@ -213,9 +218,9 @@ class HotpatchUpdateInfo(object): - - def _parse_and_store_from_xml(self, updateinfoxml): - """ -- Parse and store hotpatch update information from xxx-hotpatch.xml.gz -+ Parse and store hotpatch update information from xxx-updateinfo.xml.gz - -- xxx-hotpatch.xml.gz e.g. -+ xxx-updateinfo.xml.gz e.g. - - - -@@ -226,19 +231,26 @@ class HotpatchUpdateInfo(object): - openEuler - - -- -+ -+ - - patch-redis-6.2.5-1-HP001.(CVE-2022-24048) - -- -+ - openEuler -- -- patch-redis-6.2.5-1-HP001-0-1.aarch64.rpm -+ -+ patch-redis-6.2.5-1-HP001-1-1.aarch64.rpm -+ -+ -+ patch-redis-6.2.5-1-HP001-1-1.x86_64.rpm -+ -+ -+ patch-redis-6.2.5-1-HP002-1-1.aarch64.rpm - -- -- patch-redis-6.2.5-1-HP001-0-1.x86_64.rpm -+ -+ patch-redis-6.2.5-1-HP002-1-1.x86_64.rpm - -- -+ - - - ... -@@ -248,6 +260,9 @@ class HotpatchUpdateInfo(object): - tree = ET.parse(content) - root = tree.getroot() - for update in root.iter('update'): -+ # check whether the hotpatch relevant package information is in each advisory -+ if not update.find('pkglist/hot_patch_collection'): -+ continue - advisory = self._parse_advisory(update) - self._store_advisory_info(advisory) - -@@ -288,9 +303,9 @@ class HotpatchUpdateInfo(object): - mapping_cve_hotpatches[cve_id] = [] - if cve_id not in self.hotpatch_cves: - continue -- hotpatch = self.hotpatch_cves[cve_id].hotpatch -- if hotpatch is not None and hotpatch.state == self.INSTALLABLE: -- mapping_cve_hotpatches[cve_id].append(hotpatch.nevra) -+ for hotpatch in self.hotpatch_cves[cve_id].hotpatches: -+ if hotpatch.state == self.INSTALLABLE: -+ mapping_cve_hotpatches[cve_id].append(hotpatch.nevra) - return mapping_cve_hotpatches - - def get_hotpatches_from_advisories(self, advisories: list[str]) -> dict(): -@@ -317,3 +332,4 @@ class HotpatchUpdateInfo(object): - mapping_advisory_hotpatches[advisory_id].append( - hotpatch.nevra) - return mapping_advisory_hotpatches -+ --- -Gitee diff --git a/0004-add-dnf-full-repair.patch b/0004-add-dnf-full-repair.patch deleted file mode 100644 index 5b53a1058b0545a18c909fae66689d2e00ad5667..0000000000000000000000000000000000000000 --- a/0004-add-dnf-full-repair.patch +++ /dev/null @@ -1,100 +0,0 @@ -From 66356dfbe509f2e9d445a2185ff68abdfaa1cd3a Mon Sep 17 00:00:00 2001 -From: gongzt -Date: Fri, 2 Jun 2023 19:24:22 +0800 -Subject: [PATCH 1/1] Add dnf full repair - ---- - hotpatch/hotupgrade.py | 57 +++++++++++++++++++++++++++++++++++++++--- - 1 file changed, 53 insertions(+), 4 deletions(-) - -diff --git a/hotpatch/hotupgrade.py b/hotpatch/hotupgrade.py -index 4f6a6fb..6adafda 100644 ---- a/hotpatch/hotupgrade.py -+++ b/hotpatch/hotupgrade.py -@@ -20,9 +20,11 @@ from dnf.cli.option_parser import OptionParser - from dnf.cli.output import Output - from dnfpluginscore import _, logger - --from .syscare import Syscare -+from .syscare import Syscare, cmd_output, SUCCEED - from .hotpatch_updateinfo import HotpatchUpdateInfo - -+EMPTY_TAG = "-" -+ - - @dnf.plugin.register_command - class HotupgradeCommand(dnf.cli.Command): -@@ -61,7 +63,8 @@ class HotupgradeCommand(dnf.cli.Command): - advisory_pkgs = self.get_hotpatch_based_on_advisory(self.opts.advisory) - self.hp_list = cve_pkgs + advisory_pkgs - else: -- raise dnf.exceptions.Error(_('No qualified rpm package name or cve/advisory id.')) -+ self.hp_list = self.upgrade_all() -+ logger.info(_("Gonna apply these hot patches:%s"), self.hp_list) - - hp_target_map = self._get_available_hotpatches(self.hp_list) - if not hp_target_map: -@@ -177,8 +180,8 @@ class HotupgradeCommand(dnf.cli.Command): - def _remove_hot_patches(self, target_patch_map: dict) -> None: - output = Output(self.base, dnf.conf.Conf()) - logger.info(_("Gonna remove these hot patches: %s"), list(target_patch_map.values())) -- #remove_flag = output.userconfirm() -- #if not remove_flag: -+ # remove_flag = output.userconfirm() -+ # if not remove_flag: - # raise dnf.exceptions.Error(_('Operation aborted.')) - - self.syscare.save() -@@ -266,3 +269,49 @@ class HotupgradeCommand(dnf.cli.Command): - for hp in advisory_hp_dict.values(): - hp_list += hp - return list(set(hp_list)) -+ -+ @staticmethod -+ def get_hot_updateinfo_list(): -+ """ -+ Find all hotpatches and upgrade all -+ use command : dnf hot-updateinfo list cves -+ Last metadata expiration check: 0:48:26 ago on 2023年06月01日 星期四 20时29分55秒. -+ CVE-2023-3332 Low/Sec. - - -+ CVE-2023-3331 Low/Sec. - - -+ CVE-2023-1112 Important/Sec. - patch-redis-6.2.5-1-HP001-1-1.x86_64 -+ CVE-2023-1111 Important/Sec. - patch-redis-6.2.5-1-HP001-1-1.x86_64 -+ -+ return:list -+ [["CVE-2023-3332","Low/Sec.", "-" ,"-"]] -+ -+ """ -+ cmd = ["dnf", "hot-updateinfo", "list", "cves"] -+ -+ output, return_code = cmd_output(cmd) -+ if return_code != SUCCEED: -+ return [] -+ -+ content = output.split('\n') -+ if len(content) <= 2: -+ return [] -+ result = [] -+ for item in content[1:-1]: -+ tmp = item.split() -+ result.append(tmp) -+ return result -+ -+ def upgrade_all(self): -+ """ -+ upgrade all exist cve and hot patches -+ -+ Return: -+ find all patches and return patches list -+ e.g.: -+ ['patch-redis-6.2.5-1-HP2-1-1.x86_64'] -+ """ -+ hotpatchs_info = self.get_hot_updateinfo_list() -+ hp_list = [] -+ for item in hotpatchs_info: -+ if item[-1] != EMPTY_TAG: -+ hp_list.append(item[-1]) -+ return list(set(hp_list)) --- -2.33.0 - diff --git a/0005-fix-generate-task-is-not-verified-host-and-cve.patch b/0005-fix-generate-task-is-not-verified-host-and-cve.patch deleted file mode 100644 index 5ae3ebff1e155c1325f96a27fb93173a763e7e90..0000000000000000000000000000000000000000 --- a/0005-fix-generate-task-is-not-verified-host-and-cve.patch +++ /dev/null @@ -1,105 +0,0 @@ -From a032e1e0b11365a0dc5d725fd234771cd53c0858 Mon Sep 17 00:00:00 2001 -From: gongzt -Date: Fri, 2 Jun 2023 14:29:57 +0800 -Subject: [PATCH] Repair Host cve verification is not performed in a generation task -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - apollo/database/proxy/task.py | 37 +++++++++++++++++++++++++++++ - apollo/handler/task_handler/view.py | 20 ++++++++++++++++ - 2 files changed, 57 insertions(+) - -diff --git a/apollo/database/proxy/task.py b/apollo/database/proxy/task.py -index e660f02..edba161 100644 ---- a/apollo/database/proxy/task.py -+++ b/apollo/database/proxy/task.py -@@ -3208,3 +3208,40 @@ class TaskProxy(TaskMysqlProxy, TaskEsProxy): - - # insert task id and username into es - self._init_task_in_es(task_id, data["username"]) -+ -+ def validate_cves(self, cve_id: list) -> bool: -+ """ -+ Verifying cve validity -+ -+ Args: -+ cve_id: id of the cve to be validate -+ -+ Returns: -+ bool: A return of true indicates that the validation passed -+ """ -+ -+ try: -+ exists_cve_count = self.session.query(CveHostAssociation).filter( -+ CveHostAssociation.cve_id.in_(cve_id)).count() -+ -+ return True if exists_cve_count == len(cve_id) else False -+ except SQLAlchemyError as error: -+ LOGGER.error(error) -+ return False -+ -+ def validate_hosts(self, host_id: list) -> bool: -+ """ -+ Verifying host validity -+ -+ Args: -+ host_id: id of the host to be validate -+ -+ Returns: -+ bool: A return of true indicates that the validation passed -+ """ -+ try: -+ exists_host_count = self.session.query(Host).filter(Host.host_id.in_(host_id)).count() -+ return True if exists_host_count == len(host_id) else False -+ except SQLAlchemyError as error: -+ LOGGER.error(error) -+ return False -diff --git a/apollo/handler/task_handler/view.py b/apollo/handler/task_handler/view.py -index 214053c..314f7bb 100644 ---- a/apollo/handler/task_handler/view.py -+++ b/apollo/handler/task_handler/view.py -@@ -287,6 +287,14 @@ class VulGenerateCveTask(BaseResponse): - "task_id": "id1" - } - """ -+ host_ids = [host["host_id"] for hosts in params["info"] for host in hosts["host_info"]] -+ if not callback.validate_hosts(host_id=list(set(host_ids))): -+ return self.response(code=PARAM_ERROR) -+ -+ cve_ids = [cve["cve_id"] for cve in params["info"]] -+ if not callback.validate_cves(cve_id=list(set(cve_ids))): -+ return self.response(code=PARAM_ERROR) -+ - status_code, data = self._handle(callback, params) - return self.response(code=status_code, data=data) - -@@ -488,6 +496,10 @@ class VulGenerateRepoTask(BaseResponse): - "task_id": "1" - } - """ -+ host_ids = [host["host_id"] for host in params["info"]] -+ if not callback.validate_hosts(host_id=list(set(host_ids))): -+ return self.response(code=PARAM_ERROR) -+ - status_code, data = self._handle(callback, params) - return self.response(code=status_code, data=data) - -@@ -836,6 +848,14 @@ class VulGenerateCveRollback(BaseResponse): - "task_id": "1" - } - """ -+ host_ids = [host["host_id"] for host in params["info"]] -+ if not callback.validate_hosts(host_id=list(set(host_ids))): -+ return self.response(code=PARAM_ERROR) -+ -+ cve_ids = [cve["cve_id"] for host in params["info"] for cve in host["cves"]] -+ if not callback.validate_cves(cve_id=list(set(cve_ids))): -+ return self.response(code=PARAM_ERROR) -+ - status_code, data = self._handle(callback, params) - return self.response(code=status_code, data=data) - --- -Gitee diff --git a/0006-update-hotpatch-status-related-operation-support.patch b/0006-update-hotpatch-status-related-operation-support.patch deleted file mode 100644 index 979268b41caaee9f0063f57db9805e4e188e84d3..0000000000000000000000000000000000000000 --- a/0006-update-hotpatch-status-related-operation-support.patch +++ /dev/null @@ -1,218 +0,0 @@ -From 5d699207efd9164bef54b10e31c2082980e37f38 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Thu, 1 Jun 2023 15:53:34 +0800 -Subject: [PATCH] update hot patch status related operation support -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - apollo/database/proxy/cve.py | 20 ++++++++++++++++---- - apollo/database/proxy/host.py | 8 +++++--- - apollo/database/proxy/task.py | 7 +++++-- - apollo/database/table.py | 3 ++- - apollo/function/schema/cve.py | 2 ++ - apollo/function/schema/host.py | 1 + - apollo/function/schema/task.py | 4 +++- - 7 files changed, 34 insertions(+), 11 deletions(-) - -diff --git a/apollo/database/proxy/cve.py b/apollo/database/proxy/cve.py -index 9dc96ae..13a1ae6 100644 ---- a/apollo/database/proxy/cve.py -+++ b/apollo/database/proxy/cve.py -@@ -224,7 +224,10 @@ class CveMysqlProxy(MysqlProxy): - Returns: - set - """ -- filters = {CveHostAssociation.fixed == filter_dict.get("fixed", False)} -+ # when fixed does not have a value, the query data is not meaningful -+ # the default query is unfixed CVE information -+ fixed = filter_dict.get("fixed", False) -+ filters = {CveHostAssociation.fixed == fixed} - if not filter_dict: - return filters - -@@ -235,6 +238,12 @@ class CveMysqlProxy(MysqlProxy): - filters.add(Host.host_group_name.in_(filter_dict["host_group"])) - if filter_dict.get("repo"): - filters.add(Host.repo_name.in_(filter_dict["repo"])) -+ if filter_dict.get("hp_status"): -+ filters.add(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) -+ if filter_dict.get("hotpatch") and fixed is True: -+ filters.add(CveHostAssociation.fixed_by_hp.in_(filter_dict["hotpatch"])) -+ elif filter_dict.get("hotpatch") and fixed is False: -+ filters.add(CveHostAssociation.support_hp.in_(filter_dict["hotpatch"])) - return filters - - def _query_cve_hosts(self, username, cve_id, filters): -@@ -250,7 +259,8 @@ class CveMysqlProxy(MysqlProxy): - """ - cve_query = self.session.query(Host.host_id, Host.host_name, Host.host_ip, Host.host_group_name, - Host.repo_name, Host.last_scan, CveHostAssociation.support_hp, -- CveHostAssociation.fixed, CveHostAssociation.fixed_by_hp) \ -+ CveHostAssociation.fixed, CveHostAssociation.fixed_by_hp, -+ CveHostAssociation.hp_status ) \ - .join(CveHostAssociation, Host.host_id == CveHostAssociation.host_id) \ - .filter(Host.user == username, CveHostAssociation.cve_id == cve_id) \ - .filter(*filters) -@@ -268,7 +278,8 @@ class CveMysqlProxy(MysqlProxy): - "host_group": row.host_group_name, - "repo": row.repo_name, - "last_scan": row.last_scan, -- "hotpatch": row.fixed_by_hp if row.fixed is True else row.support_hp -+ "hotpatch": row.fixed_by_hp if row.fixed is True else row.support_hp, -+ "hp_status": row.hp_status - } - result.append(host_info) - return result -@@ -382,7 +393,8 @@ class CveMysqlProxy(MysqlProxy): - sqlalchemy.orm.query.Query - """ - cve_query = self.session.query(CveHostAssociation.cve_id, Host.host_id, Host.host_name, Host.host_ip, -- CveHostAssociation.support_hp, CveHostAssociation.fixed_by_hp, CveHostAssociation.fixed) \ -+ CveHostAssociation.support_hp, CveHostAssociation.fixed_by_hp, -+ CveHostAssociation.fixed) \ - .join(CveHostAssociation, Host.host_id == CveHostAssociation.host_id) \ - .filter(CveHostAssociation.cve_id.in_(cve_list)) \ - .filter(*filters) -diff --git a/apollo/database/proxy/host.py b/apollo/database/proxy/host.py -index a9431a9..3fdf97b 100644 ---- a/apollo/database/proxy/host.py -+++ b/apollo/database/proxy/host.py -@@ -525,7 +525,8 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - "%" + filter_dict["cve_id"] + "%")) - if filter_dict.get("severity"): - filters.add(Cve.severity.in_(filter_dict["severity"])) -- -+ if filter_dict.get("hp_status"): -+ filters.add(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) - if filter_dict.get("hotpatch") and fixed is True: - filters.add(CveHostAssociation.fixed_by_hp.in_(filter_dict["hotpatch"])) - elif filter_dict.get("hotpatch") and fixed is False: -@@ -548,7 +549,7 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - """ - host_cve_query = self.session.query(CveHostAssociation.cve_id, Cve.publish_time, Cve.severity, Cve.cvss_score, - CveHostAssociation.fixed, CveHostAssociation.support_hp, -- CveHostAssociation.fixed_by_hp) \ -+ CveHostAssociation.fixed_by_hp, CveHostAssociation.hp_status) \ - .select_from(CveHostAssociation) \ - .outerjoin(Cve, CveHostAssociation.cve_id == Cve.cve_id) \ - .outerjoin(Host, Host.host_id == CveHostAssociation.host_id) \ -@@ -577,7 +578,8 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - "severity": row.severity, - "description": description_dict[cve_id] if description_dict.get(cve_id) else "", - "cvss_score": row.cvss_score, -- "hotpatch": row.fixed_by_hp if row.fixed is True else row.support_hp -+ "hotpatch": row.fixed_by_hp if row.fixed is True else row.support_hp, -+ "hp_status": row.hp_status - } - result.append(cve_info) - return result -diff --git a/apollo/database/proxy/task.py b/apollo/database/proxy/task.py -index e660f02..ac15485 100644 ---- a/apollo/database/proxy/task.py -+++ b/apollo/database/proxy/task.py -@@ -265,7 +265,8 @@ class TaskMysqlProxy(MysqlProxy): - "affected": True, - "fixed": True, - "fixed_by_hp": fix_cve.get("fixed_by_hp"), -- "support_hp": None -+ "support_hp": None, -+ "hp_status": fix_cve.get("hp_status") - } - - self.session.query(CveHostAssociation) \ -@@ -1397,6 +1398,7 @@ class TaskMysqlProxy(MysqlProxy): - "task_name": basic_task.task_name, - "task_type": basic_task.task_type, - "check_items": basic_task.check_items.split(',') if basic_task.check_items else [], -+ "accepted": basic_task.accepted, - "total_hosts": [], - "tasks": [] - } -@@ -1423,7 +1425,7 @@ class TaskMysqlProxy(MysqlProxy): - Returns: - sqlalchemy.orm.Query - """ -- task_query = self.session.query(Task.task_id, Task.task_name, Task.task_type, Task.check_items) \ -+ task_query = self.session.query(Task.task_id, Task.task_name, Task.task_type, Task.check_items, Task.accepted) \ - .filter(Task.task_id == task_id) - return task_query - -@@ -2606,6 +2608,7 @@ class TaskProxy(TaskMysqlProxy, TaskEsProxy): - "auto_reboot": True, - "create_time": 1, - "check_items": "", -+ "accepted": True - "info": [ - { - "cve_id": "cve1", -diff --git a/apollo/database/table.py b/apollo/database/table.py -index 251aaeb..33f4380 100644 ---- a/apollo/database/table.py -+++ b/apollo/database/table.py -@@ -37,7 +37,7 @@ class CveHostAssociation(Base, MyBase): - fixed = Column(Boolean) - support_hp = Column(Boolean, default=None) - fixed_by_hp = Column(Boolean, default=None) -- -+ hp_status = Column(String(20)) - - class CveAffectedPkgs(Base, MyBase): - """ -@@ -144,6 +144,7 @@ class Task(Base, MyBase): - create_time = Column(Integer) - host_num = Column(Integer) - check_items = Column(String(32)) -+ accepted = Column(Boolean, default=False) - - username = Column(String(40), ForeignKey('user.username')) - -diff --git a/apollo/function/schema/cve.py b/apollo/function/schema/cve.py -index 635e5eb..6584941 100644 ---- a/apollo/function/schema/cve.py -+++ b/apollo/function/schema/cve.py -@@ -61,6 +61,8 @@ class CveHostFilterSchema(Schema): - repo = fields.List(fields.String( - validate=lambda s: len(s) != 0), required=False) - fixed = fields.Boolean(required=True, validate=validate.OneOf([True, False])) -+ hotpatch = fields.List(fields.Boolean(validate=validate.OneOf([True, False])), required=False) -+ hp_status = fields.List(fields.String(validate=validate.OneOf(["ACCEPTED", "ACTIVED"])), required=False) - - - class GetCveHostsSchema(Schema): -diff --git a/apollo/function/schema/host.py b/apollo/function/schema/host.py -index 84dcfbe..a0cc4b5 100644 ---- a/apollo/function/schema/host.py -+++ b/apollo/function/schema/host.py -@@ -93,6 +93,7 @@ class HostCvesFilterSchema(Schema): - hotpatch = fields.List(fields.Boolean( - validate=validate.OneOf([True, False])), required=False) - fixed = fields.Boolean(validate=validate.OneOf([True, False])) -+ hp_status = fields.List(fields.String(validate=validate.OneOf(["ACCEPTED", "ACTIVED"])), required=False) - - - class GetHostCvesSchema(Schema): -diff --git a/apollo/function/schema/task.py b/apollo/function/schema/task.py -index 472fd53..415c2ca 100644 ---- a/apollo/function/schema/task.py -+++ b/apollo/function/schema/task.py -@@ -89,7 +89,8 @@ class GenerateCveTaskSchema(Schema): - task_name = fields.String(required=True, validate=lambda s: len(s) != 0) - description = fields.String( - required=True, validate=lambda s: 0 < len(s) <= 50) -- auto_reboot = fields.Boolean(required=False, default=True) -+ auto_reboot = fields.Boolean(required=False, default=False) -+ accepted = fields.Boolean(required=True, validate=validate.OneOf([True, False])) - check_items = fields.String(required=False, validate=lambda s: 0 < len(s) <= 32) - info = fields.List(fields.Nested(CveInfoDictSchema), required=True, validate=lambda s: len(s) > 0) - -@@ -226,6 +227,7 @@ class InstallPcakageInfoSchema(Schema): - class FixedCveInfoSchema(Schema): - cve_id = fields.String(required=True, validate=lambda s: len(s) != 0) - fixed_by_hp = fields.Boolean(required=True, validate=validate.OneOf([True, False])) -+ hp_status = fields.String(validate=validate.OneOf(["ACCEPTED", "ACTIVED"]), required=False) - - - class CveScanCallbackSchema(Schema): --- diff --git a/0007-fix-hotpatch-status-filter-exception.patch b/0007-fix-hotpatch-status-filter-exception.patch deleted file mode 100644 index 4e0202946c224c9f1820d0be5adf007f2aa9bf7b..0000000000000000000000000000000000000000 --- a/0007-fix-hotpatch-status-filter-exception.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 8bfb66a3f9a6e1293b7cc4d72cc02e455be9cea9 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Thu, 8 Jun 2023 10:39:45 +0800 -Subject: [PATCH] fix issue: hotpatch status filter exception - ---- - apollo/database/proxy/cve.py | 22 +++++++++++++++------- - apollo/database/proxy/host.py | 22 +++++++++++++++++----- - 2 files changed, 32 insertions(+), 12 deletions(-) - -diff --git a/apollo/database/proxy/cve.py b/apollo/database/proxy/cve.py -index 13a1ae6..24245de 100644 ---- a/apollo/database/proxy/cve.py -+++ b/apollo/database/proxy/cve.py -@@ -187,8 +187,7 @@ class CveMysqlProxy(MysqlProxy): - - cve_id = data["cve_id"] - filters = self._get_cve_hosts_filters(data.get("filter", {})) -- cve_hosts_query = self._query_cve_hosts( -- data["username"], cve_id, filters) -+ cve_hosts_query = self._query_cve_hosts(data["username"], cve_id, filters, data.get("filter", {})) - - total_count = cve_hosts_query.count() - if not total_count: -@@ -238,33 +237,42 @@ class CveMysqlProxy(MysqlProxy): - filters.add(Host.host_group_name.in_(filter_dict["host_group"])) - if filter_dict.get("repo"): - filters.add(Host.repo_name.in_(filter_dict["repo"])) -- if filter_dict.get("hp_status"): -- filters.add(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) -+ - if filter_dict.get("hotpatch") and fixed is True: - filters.add(CveHostAssociation.fixed_by_hp.in_(filter_dict["hotpatch"])) - elif filter_dict.get("hotpatch") and fixed is False: - filters.add(CveHostAssociation.support_hp.in_(filter_dict["hotpatch"])) - return filters - -- def _query_cve_hosts(self, username, cve_id, filters): -+ def _query_cve_hosts(self, username: str, cve_id: str, filters: set, filter_dict: dict): - """ - query needed cve hosts info - Args: - username (str): user name of the request - cve_id (str): cve id - filters (set): filter given by user -- -+ filter_dict { -+ "fixed": bool, -+ "hotpatch": [true, false], -+ "hp_status": [accepted, active] -+ } - Returns: - sqlalchemy.orm.query.Query - """ - cve_query = self.session.query(Host.host_id, Host.host_name, Host.host_ip, Host.host_group_name, - Host.repo_name, Host.last_scan, CveHostAssociation.support_hp, - CveHostAssociation.fixed, CveHostAssociation.fixed_by_hp, -- CveHostAssociation.hp_status ) \ -+ CveHostAssociation.hp_status) \ - .join(CveHostAssociation, Host.host_id == CveHostAssociation.host_id) \ - .filter(Host.user == username, CveHostAssociation.cve_id == cve_id) \ - .filter(*filters) - -+ if filter_dict.get("fixed"): -+ if filter_dict.get("hotpatch") == [True] and filter_dict.get("hp_status"): -+ return cve_query.filter(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) -+ elif len(filter_dict.get("hotpatch")) != 1 and filter_dict.get("hp_status"): -+ return cve_query.filter(CveHostAssociation.hp_status.in_(filter_dict["hp_status"]), -+ CveHostAssociation.fixed_by_hp == True).union(cve_query.filter(CveHostAssociation.fixed_by_hp == False)) - return cve_query - - @staticmethod -diff --git a/apollo/database/proxy/host.py b/apollo/database/proxy/host.py -index 3fdf97b..bc30288 100644 ---- a/apollo/database/proxy/host.py -+++ b/apollo/database/proxy/host.py -@@ -475,7 +475,7 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - host_id = data["host_id"] - filters = self._get_host_cve_filters(data.get("filter", {})) - host_cve_query = self._query_host_cve( -- data["username"], host_id, filters) -+ data["username"], host_id, filters, data.get("filter", {})) - - total_count = host_cve_query.count() - if not total_count: -@@ -514,6 +514,8 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - Returns: - set - """ -+ # when fixed does not have a value, the query data is not meaningful -+ # the default query is unfixed CVE information - fixed = filter_dict.get("fixed", False) - filters = {CveHostAssociation.fixed == fixed} - -@@ -525,8 +527,6 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - "%" + filter_dict["cve_id"] + "%")) - if filter_dict.get("severity"): - filters.add(Cve.severity.in_(filter_dict["severity"])) -- if filter_dict.get("hp_status"): -- filters.add(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) - if filter_dict.get("hotpatch") and fixed is True: - filters.add(CveHostAssociation.fixed_by_hp.in_(filter_dict["hotpatch"])) - elif filter_dict.get("hotpatch") and fixed is False: -@@ -536,17 +536,22 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - filters.add(CveHostAssociation.affected == filter_dict["affected"]) - return filters - -- def _query_host_cve(self, username, host_id, filters): -+ def _query_host_cve(self, username: str, host_id: int, filters: set, filter_dict: dict): - """ - query needed host CVEs info - Args: - username (str): user name of the request - host_id (int): host id - filters (set): filter given by user -- -+ filter_dict { -+ "fixed": bool, -+ "hotpatch": [true, false], -+ "hp_status": [accepted, active] -+ } - Returns: - sqlalchemy.orm.query.Query - """ -+ - host_cve_query = self.session.query(CveHostAssociation.cve_id, Cve.publish_time, Cve.severity, Cve.cvss_score, - CveHostAssociation.fixed, CveHostAssociation.support_hp, - CveHostAssociation.fixed_by_hp, CveHostAssociation.hp_status) \ -@@ -556,6 +561,13 @@ class HostProxy(HostMysqlProxy, CveEsProxy): - .filter(CveHostAssociation.host_id == host_id, Host.user == username) \ - .filter(*filters) - -+ if filter_dict.get("fixed"): -+ if filter_dict.get("hotpatch") == [True] and filter_dict.get("hp_status"): -+ return host_cve_query.filter(CveHostAssociation.hp_status.in_(filter_dict["hp_status"])) -+ -+ elif len(filter_dict.get("hotpatch")) != 1 and filter_dict.get("hp_status"): -+ return host_cve_query.filter(CveHostAssociation.hp_status.in_(filter_dict["hp_status"]), -+ CveHostAssociation.fixed_by_hp == True).union(host_cve_query.filter(CveHostAssociation.fixed_by_hp == False)) - return host_cve_query - - @staticmethod --- -Gitee - diff --git a/0008-update-validation-rules-for-paging-parameters.patch b/0008-update-validation-rules-for-paging-parameters.patch deleted file mode 100644 index b1284dcb59ec26e9cff34cc0b8d544755bbb666c..0000000000000000000000000000000000000000 --- a/0008-update-validation-rules-for-paging-parameters.patch +++ /dev/null @@ -1,175 +0,0 @@ -From 4ada4a45e7c73e34e73ce4e8a48d434e459063f6 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Tue, 6 Jun 2023 16:22:54 +0800 -Subject: [PATCH] update validation rules for paging parameters -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - apollo/function/schema/cve.py | 10 +++------- - apollo/function/schema/host.py | 10 +++------- - apollo/function/schema/task.py | 13 ++++--------- - 3 files changed, 10 insertions(+), 23 deletions(-) - -diff --git a/apollo/function/schema/cve.py b/apollo/function/schema/cve.py -index 6584941..d18e454 100644 ---- a/apollo/function/schema/cve.py -+++ b/apollo/function/schema/cve.py -@@ -18,7 +18,7 @@ Description: For cve related restful interfaces schema - from marshmallow import Schema - from marshmallow import fields - from marshmallow import validate -- -+from vulcanus.restful.serialize.validate import PaginationSchema - - class CveListFilterSchema(Schema): - """ -@@ -31,7 +31,7 @@ class CveListFilterSchema(Schema): - fixed = fields.Boolean(required=True, default=True, validate=validate.OneOf([True, False])) - - --class GetCveListSchema(Schema): -+class GetCveListSchema(PaginationSchema): - """ - validators for parameter of /vulnerability/cve/list/get - """ -@@ -39,8 +39,6 @@ class GetCveListSchema(Schema): - ["cve_id", "publish_time", "cvss_score", "host_num"])) - direction = fields.String(required=False, validate=validate.OneOf( - ["asc", "desc"])) -- page = fields.Integer(required=False, validate=lambda s: s > 0) -- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) - filter = fields.Nested(CveListFilterSchema, required=False) - - -@@ -65,7 +63,7 @@ class CveHostFilterSchema(Schema): - hp_status = fields.List(fields.String(validate=validate.OneOf(["ACCEPTED", "ACTIVED"])), required=False) - - --class GetCveHostsSchema(Schema): -+class GetCveHostsSchema(PaginationSchema): - """ - validators for parameter of /vulnerability/cve/host/get - """ -@@ -74,8 +72,6 @@ class GetCveHostsSchema(Schema): - ["last_scan"])) - direction = fields.String(required=False, validate=validate.OneOf( - ["asc", "desc"])) -- page = fields.Integer(required=False, validate=lambda s: s > 0) -- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) - filter = fields.Nested(CveHostFilterSchema, required=False) - - -diff --git a/apollo/function/schema/host.py b/apollo/function/schema/host.py -index a0cc4b5..c609fd4 100644 ---- a/apollo/function/schema/host.py -+++ b/apollo/function/schema/host.py -@@ -18,7 +18,7 @@ Description: For host related restful interfaces schema - from marshmallow import Schema - from marshmallow import fields - from marshmallow import validate -- -+from vulcanus.restful.serialize.validate import PaginationSchema - - class ScanHostFilterSchema(Schema): - """ -@@ -61,7 +61,7 @@ class GetHostListFilterSchema(Schema): - required=False) - - --class GetHostListSchema(Schema): -+class GetHostListSchema(PaginationSchema): - """ - validators for parameter of /vulnerability/host/list/get - """ -@@ -69,8 +69,6 @@ class GetHostListSchema(Schema): - ["last_scan", "cve_num"])) - direction = fields.String(required=False, validate=validate.OneOf( - ["asc", "desc"])) -- page = fields.Integer(required=False, validate=lambda s: s > 0) -- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) - filter = fields.Nested(GetHostListFilterSchema, required=False) - - -@@ -96,7 +94,7 @@ class HostCvesFilterSchema(Schema): - hp_status = fields.List(fields.String(validate=validate.OneOf(["ACCEPTED", "ACTIVED"])), required=False) - - --class GetHostCvesSchema(Schema): -+class GetHostCvesSchema(PaginationSchema): - """ - validators for parameter of /vulnerability/host/cve/get - """ -@@ -105,6 +103,4 @@ class GetHostCvesSchema(Schema): - ["publish_time", "cvss_score"])) - direction = fields.String(required=False, validate=validate.OneOf( - ["asc", "desc"])) -- page = fields.Integer(required=False, validate=lambda s: s > 0) -- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) - filter = fields.Nested(HostCvesFilterSchema, required=False) -diff --git a/apollo/function/schema/task.py b/apollo/function/schema/task.py -index 415c2ca..5e8744b 100644 ---- a/apollo/function/schema/task.py -+++ b/apollo/function/schema/task.py -@@ -20,6 +20,7 @@ from marshmallow import fields - from marshmallow import validate - - from apollo.conf.constant import TaskType -+from vulcanus.restful.serialize.validate import PaginationSchema - - class TaskListFilterSchema(Schema): - """ -@@ -30,7 +31,7 @@ class TaskListFilterSchema(Schema): - validate=validate.OneOf([getattr(TaskType,p) for p in dir(TaskType) if p.isupper()])), required=False) - - --class GetTaskListSchema(Schema): -+class GetTaskListSchema(PaginationSchema): - """ - validators for parameter of /vulnerability/task/list/get - """ -@@ -38,8 +39,6 @@ class GetTaskListSchema(Schema): - ["host_num", "create_time"])) - direction = fields.String(required=False, validate=validate.OneOf( - ["asc", "desc"])) -- page = fields.Integer(required=False, validate=lambda s: s > 0) -- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) - filter = fields.Nested(TaskListFilterSchema, required=False) - - -@@ -105,15 +104,13 @@ class CveTaskInfoFilterSchema(Schema): - ["succeed", "fail", "running", "unknown"])), required=False) - - --class GetCveTaskInfoSchema(Schema): -+class GetCveTaskInfoSchema(PaginationSchema): - """ - validators for parameter of /vulnerability/task/cve/info/get - """ - task_id = fields.String(required=True, validate=lambda s: len(s) != 0) - sort = fields.String(required=False, validate=validate.OneOf(["host_num"])) - direction = fields.String(required=False, validate=validate.OneOf(["asc", "desc"])) -- page = fields.Integer(required=False, validate=lambda s: s > 0) -- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) - filter = fields.Nested(CveTaskInfoFilterSchema, required=False) - - -@@ -169,13 +166,11 @@ class RepoTaskInfoFilterSchema(Schema): - required=False) - - --class GetRepoTaskInfoSchema(Schema): -+class GetRepoTaskInfoSchema(PaginationSchema): - """ - validators for parameter of /vulnerability/task/repo/info/get - """ - task_id = fields.String(required=True, validate=lambda s: len(s) != 0) -- page = fields.Integer(required=False, validate=lambda s: s > 0) -- per_page = fields.Integer(required=False, validate=lambda s: 0 < s < 50) - filter = fields.Nested(RepoTaskInfoFilterSchema, required=False) - - --- -Gitee - diff --git a/0009-cve-fix-task-generate-api-return-500-when-request-without-auto-reboot.patch b/0009-cve-fix-task-generate-api-return-500-when-request-without-auto-reboot.patch deleted file mode 100644 index bfbbaea8ac3bca4f1f1177e853efa103680932c0..0000000000000000000000000000000000000000 --- a/0009-cve-fix-task-generate-api-return-500-when-request-without-auto-reboot.patch +++ /dev/null @@ -1,27 +0,0 @@ -From f54492ae8e957888bb10e8947904490c95e47f48 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Fri, 9 Jun 2023 17:19:52 +0800 -Subject: [PATCH ] fix bug: API return 500 when create cve fix task without parameter auto_reboot -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - apollo/function/schema/task.py | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/apollo/function/schema/task.py b/apollo/function/schema/task.py -index 5e8744b..ec6315e 100644 ---- a/apollo/function/schema/task.py -+++ b/apollo/function/schema/task.py -@@ -88,7 +88,7 @@ class GenerateCveTaskSchema(Schema): - task_name = fields.String(required=True, validate=lambda s: len(s) != 0) - description = fields.String( - required=True, validate=lambda s: 0 < len(s) <= 50) -- auto_reboot = fields.Boolean(required=False, default=False) -+ auto_reboot = fields.Boolean(required=True, default=False) - accepted = fields.Boolean(required=True, validate=validate.OneOf([True, False])) - check_items = fields.String(required=False, validate=lambda s: 0 < len(s) <= 32) - info = fields.List(fields.Nested(CveInfoDictSchema), required=True, validate=lambda s: len(s) > 0) --- - diff --git a/0010-modify-the-interface-of-get_hotpatches_from_cve.patch b/0010-modify-the-interface-of-get_hotpatches_from_cve.patch deleted file mode 100644 index 612840baa3083a8f21f228e83f335ef8f9dae6ee..0000000000000000000000000000000000000000 --- a/0010-modify-the-interface-of-get_hotpatches_from_cve.patch +++ /dev/null @@ -1,52 +0,0 @@ -From 59a7c96963736f496e8a7574725b50d105b28c87 Mon Sep 17 00:00:00 2001 -From: wang-guangge -Date: Mon, 12 Jun 2023 12:22:08 +0800 -Subject: [PATCH] modify the interface of get_hotpatches_from_cve - ---- - hotpatch/hotpatch_updateinfo.py | 13 +++++++++++-- - 1 file changed, 11 insertions(+), 2 deletions(-) - -diff --git a/hotpatch/hotpatch_updateinfo.py b/hotpatch/hotpatch_updateinfo.py -index 399e05c..4b39969 100644 ---- a/hotpatch/hotpatch_updateinfo.py -+++ b/hotpatch/hotpatch_updateinfo.py -@@ -5,6 +5,7 @@ from typing import Optional - import gzip - import xml.etree.ElementTree as ET - import datetime -+import re - - - class HotpatchUpdateInfo(object): -@@ -287,7 +288,8 @@ class HotpatchUpdateInfo(object): - - def get_hotpatches_from_cve(self, cves: list[str]) -> dict(): - """ -- Get hotpatches from specified cve -+ Get hotpatches from specified cve. If there are several hotpatches for the same source package for a cve, only return the -+ hotpatch with the highest version. - - Args: - cves: [cve_id_1, cve_id_2] -@@ -303,9 +305,16 @@ class HotpatchUpdateInfo(object): - mapping_cve_hotpatches[cve_id] = [] - if cve_id not in self.hotpatch_cves: - continue -+ # find the hotpatch with the highest version for the same source package -+ mapping_src_pkg_to_hotpatches = dict() - for hotpatch in self.hotpatch_cves[cve_id].hotpatches: - if hotpatch.state == self.INSTALLABLE: -- mapping_cve_hotpatches[cve_id].append(hotpatch.nevra) -+ mapping_src_pkg_to_hotpatches.setdefault(hotpatch.src_pkg, []).append([hotpatch.hotpatch_name, hotpatch]) -+ for src_pkg, hotpatches in mapping_src_pkg_to_hotpatches.items(): -+ # extract the number in HPxxx and sort hotpatches in descending order according to the number -+ hotpatches = sorted(hotpatches, key=lambda x: int(re.findall("\d+", x[0])[0]), reverse=True) -+ mapping_cve_hotpatches[cve_id].append(hotpatches[0][1].nevra) -+ - return mapping_cve_hotpatches - - def get_hotpatches_from_advisories(self, advisories: list[str]) -> dict(): --- -2.33.0 - diff --git a/aops-apollo-v1.2.1.tar.gz b/aops-apollo-v1.2.1.tar.gz deleted file mode 100644 index f1a152960f87bf42a887037b859c0f438ce0e1f0..0000000000000000000000000000000000000000 Binary files a/aops-apollo-v1.2.1.tar.gz and /dev/null differ diff --git a/aops-apollo-v1.2.2.tar.gz b/aops-apollo-v1.2.2.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..fe2a60184f2e3568b50f6ad47fd120b28f56ef95 Binary files /dev/null and b/aops-apollo-v1.2.2.tar.gz differ diff --git a/aops-apollo.spec b/aops-apollo.spec index 4eafc821c74375386e32b872bc45c9c5b6a005fd..a75382ea1acf63257943c2dc5bee752bf8d0af8f 100644 --- a/aops-apollo.spec +++ b/aops-apollo.spec @@ -1,20 +1,10 @@ Name: aops-apollo -Version: v1.2.1 -Release: 6 +Version: v1.2.2 +Release: 1 Summary: Cve management service, monitor machine vulnerabilities and provide fix functions. License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} Source0: %{name}-%{version}.tar.gz -Patch0001: 0001-fix-some-apis-which-has-filter-fault.patch -Patch0002: 0002-fix-bug-and-update-the-code-of-parsing.patch -Patch0003: 0003-fix-hotpatch-updateinfo-for-search-hotpatch-info.patch -Patch0004: 0004-add-dnf-full-repair.patch -Patch0005: 0005-fix-generate-task-is-not-verified-host-and-cve.patch -Patch0006: 0006-update-hotpatch-status-related-operation-support.patch -Patch0007: 0007-fix-hotpatch-status-filter-exception.patch -Patch0008: 0008-update-validation-rules-for-paging-parameters.patch -Patch0009: 0009-cve-fix-task-generate-api-return-500-when-request-without-auto-reboot.patch -Patch0010: 0010-modify-the-interface-of-get_hotpatches_from_cve.patch BuildRequires: python3-setuptools Requires: aops-vulcanus >= v1.2.0 @@ -85,6 +75,9 @@ cp -r hotpatch %{buildroot}/%{python3_sitelib}/dnf-plugins/ %{python3_sitelib}/aops_apollo_tool/* %changelog +* Tue Jun 20 2023 gongzhengtang - v1.2.2-1 +- Fixes numerous known issues + * Mon Jun 12 2023 wangguangge - v1.2.1-6 - modify the interface of get_hotpatches_from_cve