diff --git a/0001-update-func-named-set-hotpatch-status-by-dnf-plugin.patch b/0001-update-func-named-set-hotpatch-status-by-dnf-plugin.patch deleted file mode 100644 index 861f4dc..0000000 --- a/0001-update-func-named-set-hotpatch-status-by-dnf-plugin.patch +++ /dev/null @@ -1,64 +0,0 @@ -From d6be0a82ace5d07d31a91a628369f71534834441 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Wed, 13 Sep 2023 10:58:16 +0800 -Subject: [PATCH 1/1] update func named set_hotpatch_status_by_dnf_plugin - ---- - ceres/manages/vulnerability_manage.py | 30 ++++++++++++++++++++------- - 1 file changed, 22 insertions(+), 8 deletions(-) - -diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py -index f45c1f2..ab4b41c 100644 ---- a/ceres/manages/vulnerability_manage.py -+++ b/ceres/manages/vulnerability_manage.py -@@ -615,12 +615,11 @@ class VulnerabilityManage: - if not self.takeover and self.accepted: - try: - hotpatch_name = hotpatch_pkg.rsplit(".", 1)[0].split("-", 1)[1] -- status_set_result, log = self._set_hotpatch_status_by_dnf_plugin(hotpatch_name, "accept") -- if not status_set_result: -- stdout += "\n" + log -+ _, log = self._set_hotpatch_status_by_dnf_plugin(hotpatch_name, "accept") -+ stdout += f"\n\n{log}" - except IndexError as error: - LOGGER.error(error) -- stdout += "\n" + "hotpatch status set failed due to can't get correct hotpatch name!" -+ stdout += f"\n\nhotpatch status set failed due to can't get correct hotpatch name!" - - return TaskExecuteRes.SUCCEED, stdout - -@@ -637,12 +636,27 @@ class VulnerabilityManage: - Tuple[bool, str] - a tuple containing two elements (operation result, operation log). - """ -- code, stdout, stderr = execute_shell_command(f"dnf hotpatch --{operation} {hotpatch}") -- if code != CommandExitCode.SUCCEED: -+ -+ # replace -ACC to /ACC or -SGL to /SGL -+ # Example: kernel-5.10.0-153.12.0.92.oe2203sp2-ACC-1-1 >> kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1 -+ wait_to_remove_patch = re.sub(r'-(ACC|SGL)', r'/\1', hotpatch) -+ # Example of command execution result: -+ # Succeed: -+ # [root@openEuler ~]# dnf hotpatch --remove kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1 -+ # Last metadata expiration check: 3:24:16 ago on Wed 13 Sep 2023 08:16:17 AM CST. -+ # Gonna remove this hot patch: kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1 -+ # remove hot patch 'kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1' succeed -+ # Fail: -+ # [root@openEuler ~]# dnf hotpatch --accept kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1 -+ # Last metadata expiration check: 3:25:24 ago on Wed 13 Sep 2023 08:16:17 AM CST. -+ # Gonna accept this hot patch: kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1 -+ # accept hot patch 'kernel-5.10.0-153.12.0.92.oe2203sp2/ACC-1-1' failed, remain original status -+ code, stdout, stderr = execute_shell_command(f"dnf hotpatch --{operation} {wait_to_remove_patch}") -+ if code != CommandExitCode.SUCCEED or 'failed' in stdout: - LOGGER.error(f"hotpatch {hotpatch} set status failed!") -- return False, stderr -+ return False, stdout + stderr - -- return True, stdout -+ return True, stdout + stderr - - def cve_rollback(self, cves: List[dict]) -> Tuple[str, list]: - """ --- -2.33.0 - diff --git a/0002-add-file-sync-func.patch b/0002-add-file-sync-func.patch deleted file mode 100644 index f667757..0000000 --- a/0002-add-file-sync-func.patch +++ /dev/null @@ -1,155 +0,0 @@ -From b0f71927a3bdb3096757ca8cdedb233d2b886a4d Mon Sep 17 00:00:00 2001 -From: smjiao -Date: Thu, 7 Sep 2023 16:28:49 +0800 -Subject: [PATCH] add file sync func -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - ceres/__main__.py | 6 ++++ - ceres/function/command.py | 11 ++++++++ - ceres/function/schema.py | 12 ++++++++ - ceres/manages/sync_manage.py | 55 ++++++++++++++++++++++++++++++++++++ - 4 files changed, 84 insertions(+) - create mode 100644 ceres/manages/sync_manage.py - -diff --git a/ceres/__main__.py b/ceres/__main__.py -index d1bbee3..a93ec49 100644 ---- a/ceres/__main__.py -+++ b/ceres/__main__.py -@@ -17,6 +17,7 @@ from ceres.function.command import ( - cve_command_manage, - plugin_command_manage, - register_on_manager, -+ sync_conf_manage, - ) - from ceres.function.log import LOGGER - -@@ -55,6 +56,11 @@ def main(): - cve_group.add_argument("--rollback", type=str) - subparsers_cve.set_defaults(function=cve_command_manage) - -+ subparsers_sync = subparsers.add_parser("sync", help='sync conf file') -+ sync_group = subparsers_sync.add_mutually_exclusive_group(required=True) -+ sync_group.add_argument("--conf", type=str) -+ subparsers_sync.set_defaults(function=sync_conf_manage) -+ - args = parser.parse_args() - try: - args.function(args) -diff --git a/ceres/function/command.py b/ceres/function/command.py -index e4d367a..7324f23 100644 ---- a/ceres/function/command.py -+++ b/ceres/function/command.py -@@ -25,11 +25,13 @@ from ceres.function.schema import ( - HOST_INFO_SCHEMA, - REPO_SET_SCHEMA, - STRING_ARRAY, -+ CONF_SYNC_SCHEMA, - ) - from ceres.function.status import SUCCESS, StatusCode - from ceres.function.util import convert_string_to_json, get_dict_from_file, plugin_status_judge, validate_data - from ceres.manages import plugin_manage - from ceres.manages.collect_manage import Collect -+from ceres.manages.sync_manage import SyncManage - from ceres.manages.vulnerability_manage import VulnerabilityManage - - -@@ -191,3 +193,12 @@ def cve_command_manage(args): - else: - print("Please check the input parameters!") - exit(1) -+ -+ -+def sync_conf_manage(args): -+ if args.conf: -+ config = convert_string_to_json(args.conf) -+ if not validate_data(config, CONF_SYNC_SCHEMA): -+ exit(1) -+ res = StatusCode.make_response_body(SyncManage.sync_contents_to_conf(config)) -+ print(json.dumps(res)) -diff --git a/ceres/function/schema.py b/ceres/function/schema.py -index ada35c3..794152d 100644 ---- a/ceres/function/schema.py -+++ b/ceres/function/schema.py -@@ -113,3 +113,15 @@ CVE_ROLLBACK_SCHEMA = { - } - }, - } -+ -+CONF_SYNC_SCHEMA = { -+ "type": "object", -+ "required": [ -+ "file_path", -+ "content" -+ ], -+ "properties": { -+ "file_path": {"type": "string", "minLength": 1}, -+ "content": {"type": "string", "minLength": 1} -+ } -+} -diff --git a/ceres/manages/sync_manage.py b/ceres/manages/sync_manage.py -new file mode 100644 -index 0000000..9be2a47 ---- /dev/null -+++ b/ceres/manages/sync_manage.py -@@ -0,0 +1,55 @@ -+#!/usr/bin/python3 -+# ****************************************************************************** -+# Copyright (c) Huawei Technologies Co., Ltd. 2022-2022. All rights reserved. -+# licensed under the Mulan PSL v2. -+# You can use this software according to the terms and conditions of the Mulan PSL v2. -+# You may obtain a copy of Mulan PSL v2 at: -+# http://license.coscl.org.cn/MulanPSL2 -+# THIS SOFTWARE IS PROVIDED ON AN 'AS IS' BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR -+# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR -+# PURPOSE. -+# See the Mulan PSL v2 for more details. -+# ******************************************************************************/ -+# Author: Lay -+# Description: default -+# Date: 2023/6/14 16:31 -+import os -+from ceres.function.log import LOGGER -+from ceres.function.status import ( -+ FILE_NOT_FOUND, -+ UNKNOWN_ERROR, -+ SUCCESS -+) -+ -+ -+class SyncManage: -+ """ -+ Sync managed conf to the host -+ """ -+ -+ @staticmethod -+ def sync_contents_to_conf(config: dict) -> str: -+ """ -+ Write conf into file -+ Args: -+ config(dict): filepath and content for file sync, only. eg: -+ { -+ "file_path" = "/tmp/test" -+ "content" = "contents for this file" -+ } -+ Returns: -+ str: status code -+ """ -+ file_path = config.get('file_path') -+ -+ contents = config.get('content') -+ lines = contents.split('\n') -+ try: -+ with open(file_path, "w", encoding="utf-8") as file: -+ for line in lines: -+ file.write(line + "\n") -+ except Exception as e: -+ LOGGER.error("write sync content to conf failed, with msg{}".format(e)) -+ return UNKNOWN_ERROR -+ -+ return SUCCESS --- -Gitee - diff --git a/0003-update-method-of-querying-fixed-cves-by-dnf-plugin.patch b/0003-update-method-of-querying-fixed-cves-by-dnf-plugin.patch deleted file mode 100644 index 5675379..0000000 --- a/0003-update-method-of-querying-fixed-cves-by-dnf-plugin.patch +++ /dev/null @@ -1,153 +0,0 @@ -From f947f2b46c52bc453858bf4e030ec9388c29b52d Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Mon, 18 Sep 2023 17:31:06 +0800 -Subject: [PATCH 1/1] update method of querying fixed cves by dnf plugin - ---- - ceres/manages/vulnerability_manage.py | 80 ++++++++++++++++++++------- - 1 file changed, 60 insertions(+), 20 deletions(-) - -diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py -index ab4b41c..ab10381 100644 ---- a/ceres/manages/vulnerability_manage.py -+++ b/ceres/manages/vulnerability_manage.py -@@ -132,7 +132,7 @@ class VulnerabilityManage: - { - "check_items": items_check_log, - "unfixed_cves": self._query_unfixed_cves_by_dnf_plugin() or self._query_unfixed_cves_by_dnf(), -- "fixed_cves": self._query_fixed_cves(), -+ "fixed_cves": self._query_fixed_cves_by_dnf_plugin() or self._query_fixed_cves_by_dnf(), - } - ) - return SUCCESS, cve_scan_result -@@ -339,7 +339,7 @@ class VulnerabilityManage: - - return cve_info_list - -- def _query_fixed_cves(self) -> list: -+ def _query_fixed_cves_by_dnf(self) -> list: - """ - parse the fixed kernel vulnerability info by dnf - -@@ -348,7 +348,6 @@ class VulnerabilityManage: - list: cve info e.g - [ - {"cve_id": "CVE-XXXX-XXXX","installed_rpm": "kernel-version-release.arch", "fix_way":"coldpatch"}, -- {"cve_id": "CVE-XXXX-XXXX","installed_rpm": "xxxx", "fix_way": "hotpatch", "hp_status": "ACCEPTED"} - ] - - """ -@@ -380,17 +379,70 @@ class VulnerabilityManage: - fixed_cves.append( - {"cve_id": cve_id, "installed_rpm": self.installed_rpm_info.get(rpm_name), "fix_way": "coldpatch"} - ) -- fixed_cves.extend(self._query_applied_hotpatch()) - return fixed_cves - -- def _query_applied_hotpatch(self) -> list: -+ def _query_fixed_cves_by_dnf_plugin(self) -> list: - """ -- parse kernel hotpatch info which has been applied by dnf hotpatch plugin (hotpatch) -+ parse the fixed kernel vulnerability info by dnf plugin - - Return: - list: hotpatch info list. e.g - [{"cve_id": "CVE-XXXX-XXXX", "fix_way": "hotpatch", "hp_status": "ACCEPTED", "installed_rpm":"xxxx"}] - -+ """ -+ # Example of command execution result: -+ # Last metadata expiration check: 0:31:50 ago on Mon 07 Aug 2023 10:26:32 AM CST. -+ # CVE-2023-1981 Moderate/Sec. avahi-libs-0.8-9.oe1.x86_64 - -+ # CVE-2021-42574 Important/Sec. binutils-2.34-19.oe1.x86_64 - -+ # CVE-2023-1513 Important/Sec. kernel-4.19.90-2304.1.0.0196.oe1.x86_64 patch-kernel-4.19.90-2112... -+ -+ code, stdout, stderr = execute_shell_command("dnf hot-updateinfo list cves --installed") -+ if code != CommandExitCode.SUCCEED: -+ LOGGER.error("query unfixed cve info failed by dnf!") -+ LOGGER.error(stderr) -+ return [] -+ -+ # Example of regex matching result: -+ # [ -+ # ("CVE-2023-1513", "Important/Sec.", "kernel-4.19.90-2304.1.0.0196.oe1.x86_64", "patch-kernel-4.19.90-2112.."), -+ # ("CVE-2021-xxxx", "Important/Sec.", "-", "patch-redis-6.2.5-1-SGL_CVE_2023_1111_CVE_2023_1112-1-1.x86_64") -+ # ] -+ hotpatch_status = self._query_applied_hotpatch_status() -+ all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(kernel\S+|-)\s+(patch-kernel\S+|-)", stdout) -+ -+ cve_info_fixed_by_coldpatch, cve_info_fixed_by_hotpatch, hotpatch_dic = [], [], defaultdict(str) -+ for cve_id, _, coldpatch, hotpatch in all_cve_info: -+ if hotpatch == "-": -+ cve_info_fixed_by_coldpatch.append( -+ { -+ "cve_id": cve_id, -+ "installed_rpm": self.installed_rpm_info.get(coldpatch.rsplit("-", 2)[0]), -+ "fix_way": "coldpatch", -+ } -+ ) -+ else: -+ cve_info_fixed_by_hotpatch.append({"cve_id": cve_id, "fix_way": "hotpatch", "installed_rpm": hotpatch}) -+ -+ hotpatch_dic_key = hotpatch.rsplit("-", 2)[0] -+ if hotpatch_dic_key.endswith("ACC"): -+ hotpatch_dic[hotpatch_dic_key] = max(hotpatch, hotpatch_dic.get(hotpatch_dic_key, hotpatch)) -+ -+ for cve_info in cve_info_fixed_by_hotpatch: -+ hotpatch_dic_key = cve_info["installed_rpm"].rsplit("-", 2)[0] -+ -+ if hotpatch_dic_key in hotpatch_dic: -+ cve_info["installed_rpm"] = hotpatch_dic[hotpatch_dic_key] -+ cve_info["hp_status"] = hotpatch_status.get(cve_info["installed_rpm"].rsplit(".", 1)[0], "") -+ -+ return cve_info_fixed_by_coldpatch + cve_info_fixed_by_hotpatch -+ -+ def _query_applied_hotpatch_status(self) -> Dict[str, str]: -+ """ -+ query applied hotpatch with its status -+ -+ Return: -+ dict: key is hotpatch name, value is its status. e.g {"patch-redis-6.2.5-1-ACC-1-3": "ACTIVED"} -+ - """ - # Example of command execution result: - # Last metadata expiration check: 0:28:36 ago on Mon 07 Aug 2023 10:26:32 AM CST. -@@ -409,7 +461,7 @@ class VulnerabilityManage: - # CVE-2023-1112 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-cli NOT-APPLIED - # CVE-2023-1111 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server NOT-APPLIED - # CVE-2023-1112 redis-6.2.5-1/SGL_CVE_2023_1111_CVE_2023_1112-1-1/redis-server NOT-APPLIED -- result = [] -+ result = {} - code, stdout, stderr = execute_shell_command("dnf hotpatch --list cves") - if code != CommandExitCode.SUCCEED: - LOGGER.error("query applied hotpatch info failed!") -@@ -426,11 +478,6 @@ class VulnerabilityManage: - if not applied_hotpatch_info_list: - return result - -- code, arch, _ = execute_shell_command("uname -m") -- if code != CommandExitCode.SUCCEED: -- LOGGER.debug("Failed to query host arch info!") -- arch = "unknown_arch" -- - record_key_set = set() - for cve_id, patch_name, hotpatch_status in applied_hotpatch_info_list: - rpm = patch_name.split("-", 1)[0] -@@ -445,14 +492,7 @@ class VulnerabilityManage: - and (hotpatch_status in ("ACTIVED", "ACCEPTED")) - and record_key not in record_key_set - ): -- result.append( -- { -- "cve_id": cve_id, -- "installed_rpm": f"patch-{patch_name.rsplit('/',1)[0].replace('/','-')}.{arch}", -- "fix_way": "hotpatch", -- "hp_status": hotpatch_status, -- } -- ) -+ result[f"patch-{patch_name.rsplit('/',1)[0].replace('/','-')}"] = hotpatch_status - record_key_set.add(record_key) - return result - --- -2.33.1.windows.1 - diff --git a/0004-update-func-about-querying-applied-hotpatch-info.patch b/0004-update-func-about-querying-applied-hotpatch-info.patch deleted file mode 100644 index 9567cc2..0000000 --- a/0004-update-func-about-querying-applied-hotpatch-info.patch +++ /dev/null @@ -1,62 +0,0 @@ -From 3e8e26b0b1b4b18ab45048069fc2f6a89b852802 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Tue, 19 Sep 2023 20:02:44 +0800 -Subject: [PATCH 1/1] update func about querying applied hotpatch info - ---- - ceres/manages/vulnerability_manage.py | 33 +++++++++++++++------------ - 1 file changed, 18 insertions(+), 15 deletions(-) - -diff --git a/ceres/manages/vulnerability_manage.py b/ceres/manages/vulnerability_manage.py -index ab10381..1591d74 100644 ---- a/ceres/manages/vulnerability_manage.py -+++ b/ceres/manages/vulnerability_manage.py -@@ -806,27 +806,30 @@ class VulnerabilityManage: - "CVE-XXXX-XXX": {"patch 1", "patch 2"} - } - """ -- # Run the dnf command to query the hotpatch list,e.g -- # Last metadata expiration check: -- # CVE id base-pkg/hotpatch status -- # CVE-1 A-1.1-1/ACC-1-1/binary_file1 ACTIVED -- # CVE-2 A-1.1-1/ACC-1-1/binary_file2 ACTIVED -- code, hotpatch_list_output, _ = execute_shell_command(f"dnf hotpatch --list cve") -+ code, stdout, _ = execute_shell_command(f"dnf hot-updateinfo list cves --installed|grep patch") - if code != CommandExitCode.SUCCEED: - LOGGER.error(f"Failed to hotpatch list cve.") - return None - -- if not re.search("base-pkg/hotpatch", hotpatch_list_output): -+ all_cve_info = re.findall(r"(CVE-\d{4}-\d+)\s+([\w+/.]+)\s+(\S+|-)\s+(patch\S+)", stdout) -+ if not all_cve_info: -+ LOGGER.error(f"Failed to hotpatch list cve.") - return None -+ -+ applied_hotpatch_info = {} -+ hotpatch_dic = {} -+ for cve_id, _, _, hotpatch in all_cve_info: -+ applied_hotpatch_info[cve_id] = hotpatch -+ hotpatch_dic_key = hotpatch.rsplit("-", 2)[0] -+ if hotpatch_dic_key.endswith("ACC"): -+ hotpatch_dic[hotpatch_dic_key] = max(hotpatch, hotpatch_dic.get(hotpatch_dic_key, hotpatch)) -+ -+ for cve_id, cmd_output_hotpatch in applied_hotpatch_info.items(): -+ applied_hotpatch_info[cve_id] = hotpatch_dic.get(cmd_output_hotpatch.rsplit("-", 2)[0], cmd_output_hotpatch) -+ - hotpatch_list = defaultdict(set) -- for hotpatch_info in [line for line in hotpatch_list_output.split(os.linesep) if line]: -- if not hotpatch_info.startswith("CVE"): -- continue -- cve_id, base_pkg, status = [info.strip() for info in hotpatch_info.split()] -- if status != "ACTIVED" and status != "ACCEPTED": -- continue -- hotpatch_name = "patch-%s-%s" % tuple(base_pkg.rsplit("/", 2)[:2]) -- hotpatch_list[cve_id].add(hotpatch_name) -+ for cve_id, hotpatch in applied_hotpatch_info.items(): -+ hotpatch_list[cve_id].add(hotpatch) - - return hotpatch_list - --- -2.33.0 - diff --git a/aops-ceres-v1.3.1.tar.gz b/aops-ceres-v1.3.1.tar.gz deleted file mode 100644 index 5c66c47..0000000 Binary files a/aops-ceres-v1.3.1.tar.gz and /dev/null differ diff --git a/aops-ceres-v1.3.2.tar.gz b/aops-ceres-v1.3.2.tar.gz new file mode 100644 index 0000000..6039320 Binary files /dev/null and b/aops-ceres-v1.3.2.tar.gz differ diff --git a/aops-ceres.spec b/aops-ceres.spec index 6551fac..f7afbf2 100644 --- a/aops-ceres.spec +++ b/aops-ceres.spec @@ -1,14 +1,10 @@ Name: aops-ceres -Version: v1.3.1 -Release: 5 +Version: v1.3.2 +Release: 1 Summary: An agent which needs to be adopted in client, it managers some plugins, such as gala-gopher(kpi collection), fluentd(log collection) and so on. License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} Source0: %{name}-%{version}.tar.gz -Patch0001: 0001-update-func-named-set-hotpatch-status-by-dnf-plugin.patch -Patch0002: 0002-add-file-sync-func.patch -Patch0003: 0003-update-method-of-querying-fixed-cves-by-dnf-plugin.patch -Patch0004: 0004-update-func-about-querying-applied-hotpatch-info.patch BuildRequires: python3-setuptools @@ -23,7 +19,7 @@ An agent which needs to be adopted in client, it managers some plugins, such as %prep -%autosetup -n %{name}-%{version} -p1 +%autosetup -n %{name}-%{version} # build for aops-ceres @@ -44,6 +40,9 @@ An agent which needs to be adopted in client, it managers some plugins, such as %changelog +* Wed Sep 20 2023 wenxin - v1.3.2-1 +- fix query fixed cves info error by dnf + * Tue Sep 19 2023 wenxin - v1.3.1-5 - update func about querying applied hotpatch info