diff --git a/0001-add-file-sync-func.patch b/0001-add-file-sync-func.patch deleted file mode 100644 index a5d1b6abf548110e716082e93327983945eee224..0000000000000000000000000000000000000000 --- a/0001-add-file-sync-func.patch +++ /dev/null @@ -1,141 +0,0 @@ -From 0e2ad3cc141390e26d7a20bccf5ccc0660f7c172 Mon Sep 17 00:00:00 2001 -From: smjiao -Date: Thu, 7 Sep 2023 16:24:42 +0800 -Subject: [PATCH] add file sync func -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - zeus/conf/constant.py | 2 ++ - zeus/config_manager/view.py | 45 ++++++++++++++++++++++++++++++++-- - zeus/function/verify/config.py | 9 +++++++ - zeus/url.py | 6 ++++- - 4 files changed, 59 insertions(+), 3 deletions(-) - -diff --git a/zeus/conf/constant.py b/zeus/conf/constant.py -index 2fbf1be..3175c65 100644 ---- a/zeus/conf/constant.py -+++ b/zeus/conf/constant.py -@@ -33,6 +33,7 @@ CERES_CVE_REPO_SET = "aops-ceres apollo --set-repo '%s'" - CERES_CVE_SCAN = "aops-ceres apollo --scan '%s'" - CERES_CVE_FIX = "aops-ceres apollo --fix '%s'" - CERES_CVE_ROLLBACK = "aops-ceres apollo --rollback '%s'" -+CERES_SYNC_CONF = "aops-ceres sync --conf '%s'" - - # zeus route - ADD_HOST = "/manage/host/add" -@@ -54,6 +55,7 @@ DELETE_GROUP = "/manage/host/group/delete" - GET_GROUP = "/manage/host/group/get" - - COLLECT_CONFIG = '/manage/config/collect' -+SYNC_CONFIG = '/manage/config/sync' - - USER_LOGIN = "/manage/account/login" - LOGOUT = "/manage/account/logout" -diff --git a/zeus/config_manager/view.py b/zeus/config_manager/view.py -index cd83e35..baeef7e 100644 ---- a/zeus/config_manager/view.py -+++ b/zeus/config_manager/view.py -@@ -21,10 +21,11 @@ from typing import List, Dict - from vulcanus.multi_thread_handler import MultiThreadHandler - from vulcanus.restful.resp import state - from vulcanus.restful.response import BaseResponse --from zeus.conf.constant import CERES_COLLECT_FILE -+from zeus.conf import configuration -+from zeus.conf.constant import CERES_COLLECT_FILE, CERES_SYNC_CONF - from zeus.database.proxy.host import HostProxy - from zeus.function.model import ClientConnectArgs --from zeus.function.verify.config import CollectConfigSchema -+from zeus.function.verify.config import CollectConfigSchema, SyncConfigSchema - from zeus.host_manager.ssh import execute_command_and_parse_its_result - - -@@ -218,3 +219,43 @@ class CollectConfig(BaseResponse): - return self.response( - state.SUCCEED, None, self.generate_target_data_format(multi_thread.get_result(), host_id_with_config_file) - ) -+ -+ -+class SyncConfig(BaseResponse): -+ -+ @staticmethod -+ def sync_config_content(host_info: Dict, sync_config_info: Dict): -+ command = CERES_SYNC_CONF % json.dumps(sync_config_info) -+ status, content = execute_command_and_parse_its_result( -+ ClientConnectArgs(host_info.get("host_ip"), host_info.get("ssh_port"), -+ host_info.get("ssh_user"), host_info.get("pkey")), command) -+ return status -+ -+ @BaseResponse.handle(schema=SyncConfigSchema, token=False) -+ def put(self, **params): -+ -+ sync_config_info = dict() -+ sync_config_info['file_path'] = params.get('file_path') -+ sync_config_info['content'] = params.get('content') -+ -+ sync_result = { -+ "file_path": sync_config_info['file_path'], -+ "sync_result": False -+ } -+ -+ # Query host address from database -+ proxy = HostProxy(configuration) -+ if not proxy.connect(): -+ return self.response(code=state.DATABASE_CONNECT_ERROR, data={"resp": sync_result}) -+ -+ status, host_list = proxy.get_host_info( -+ {"username": "admin", "host_list": [params.get('host_id')]}, True) -+ if status != state.SUCCEED or len(host_list) == 1: -+ return self.response(code=status, data={"resp": sync_result}) -+ -+ host_info = host_list[0] -+ status = self.sync_config_content(host_info, sync_config_info) -+ if status == state.SUCCEED: -+ sync_result['sync_result'] = True -+ return self.response(code=state.SUCCEED, data={"resp": sync_result}) -+ return self.response(code=state.UNKNOWN_ERROR, data={"resp": sync_result}) -diff --git a/zeus/function/verify/config.py b/zeus/function/verify/config.py -index 230b65d..6e5bf64 100644 ---- a/zeus/function/verify/config.py -+++ b/zeus/function/verify/config.py -@@ -36,3 +36,12 @@ class CollectConfigSchema(Schema): - """ - - infos = fields.List(fields.Nested(ConfigSchema(), required=True), required=True, validate=lambda s: len(s) > 0) -+ -+ -+class SyncConfigSchema(Schema): -+ """ -+ validators for SyncConfigSchema -+ """ -+ host_id = fields.Integer(required=True, validate=lambda s: s > 0) -+ file_path = fields.String(required=True, validate=lambda s: len(s) > 0) -+ content = fields.String(required=True, validate=lambda s: len(s) > 0) -diff --git a/zeus/url.py b/zeus/url.py -index e0cf1de..597dcc7 100644 ---- a/zeus/url.py -+++ b/zeus/url.py -@@ -49,6 +49,7 @@ from zeus.conf.constant import ( - REFRESH_TOKEN, - UPDATE_HOST, - USER_LOGIN, -+ SYNC_CONFIG, - ) - from zeus.config_manager import view as config_view - from zeus.host_manager import view as host_view -@@ -83,7 +84,10 @@ SPECIFIC_URLS = { - (host_view.DeleteHostGroup, DELETE_GROUP), - (host_view.GetHostGroup, GET_GROUP), - ], -- "CONFIG_URLS": [(config_view.CollectConfig, COLLECT_CONFIG)], -+ "CONFIG_URLS": [ -+ (config_view.CollectConfig, COLLECT_CONFIG), -+ (config_view.SyncConfig, SYNC_CONFIG) -+ ], - 'AGENT_URLS': [ - (agent_view.AgentPluginInfo, AGENT_PLUGIN_INFO), - (agent_view.SetAgentPluginStatus, AGENT_PLUGIN_SET), --- -Gitee - diff --git a/0002-update-callback-request-headers.patch b/0002-update-callback-request-headers.patch deleted file mode 100644 index b73eacad00bb12804535cede8129f1ca5f4cb84b..0000000000000000000000000000000000000000 --- a/0002-update-callback-request-headers.patch +++ /dev/null @@ -1,68 +0,0 @@ -From 51be015c84619925873ff377a72827b7c9770632 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Mon, 18 Sep 2023 12:18:52 +0800 -Subject: [PATCH 1/1] update callback request headers -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - zeus/vulnerability_manage/view.py | 14 +++++--------- - 1 file changed, 5 insertions(+), 9 deletions(-) - -diff --git a/zeus/vulnerability_manage/view.py b/zeus/vulnerability_manage/view.py -index 1bfed63..b5360e2 100644 ---- a/zeus/vulnerability_manage/view.py -+++ b/zeus/vulnerability_manage/view.py -@@ -119,7 +119,7 @@ def generate_tasks(tasks: list, host_infos: dict, **kwargs: dict) -> list: - - class BaseExcuteTask: - def __init__(self) -> None: -- self._header = {'content-type': 'application/json', 'access_token': request.headers.get('access_token')} -+ self._header = {"exempt_authentication": configuration.individuation.get("EXEMPT_AUTHENTICATION")} - - - class ExecuteRepoSetTask(BaseResponse, BaseExcuteTask): -@@ -234,7 +234,7 @@ class ExecuteRepoSetTask(BaseResponse, BaseExcuteTask): - return self.response(code=status_code) - - self._callback_url = params.get('callback') -- self._header = {'content-type': 'application/json', 'access_token': request.headers.get('access_token')} -+ self._header["local_account"] = params.get("username") - self._task_id = params.get("task_id") - self._task_name = params.get("task_name") - self._task_type = params.get("task_type") -@@ -337,13 +337,7 @@ class ExecuteCveScanTask(BaseResponse, BaseExcuteTask): - return self.response(code=status_code) - # parse args - self._callback_url = params.get('callback') -- if params.get("timed"): -- self._header.update( -- { -- "exempt_authentication": configuration.individuation.get("EXEMPT_AUTHENTICATION"), -- "local_account": params.get("username"), -- } -- ) -+ self._header["local_account"] = params.get("username") - self._task_id = params.get("task_id") - self._check_items = params.get('check_items') - # Execute task -@@ -465,6 +459,7 @@ class ExecuteCveFixTask(BaseResponse, BaseExcuteTask): - self._task_id = params.get("task_id") - self._task_name = params.get("task_name") - self._task_type = params.get("task_type") -+ self._header["local_account"] = params.get("username") - self._accepted = params.get('accepted') - self._takeover = params.get('takeover') - self._check_items = params.get('check_items') -@@ -582,6 +577,7 @@ class ExecuteCveRollbackTask(BaseResponse, BaseExcuteTask): - # Generate tasks - self._callback_url = params.get('callback') - self._task_id = params.get("task_id") -+ self._header["local_account"] = params.get("username") - self._task_name = params.get("task_name") - self._task_type = params.get("task_type") - --- -2.33.1.windows.1 - diff --git a/0003-fix-bash-file-sync-error.patch b/0003-fix-bash-file-sync-error.patch deleted file mode 100644 index 7a6837404fcbccba14f955d6a06b24d3a5740caf..0000000000000000000000000000000000000000 --- a/0003-fix-bash-file-sync-error.patch +++ /dev/null @@ -1,220 +0,0 @@ -From 80272352b3067ebb2cb3011cfbeeef5e9d464fa6 Mon Sep 17 00:00:00 2001 -From: smjiao -Date: Mon, 18 Sep 2023 20:37:50 +0800 -Subject: [PATCH 1/1] fix bash file sync error -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - ---- - zeus/config_manager/view.py | 48 ++++++++++++++++++++----- - zeus/host_manager/ssh.py | 72 +++++++++++++++++++++++++++++++------ - 2 files changed, 102 insertions(+), 18 deletions(-) - -diff --git a/zeus/config_manager/view.py b/zeus/config_manager/view.py -index baeef7e..6779153 100644 ---- a/zeus/config_manager/view.py -+++ b/zeus/config_manager/view.py -@@ -16,6 +16,7 @@ Author: - Description: Restful APIs for host - """ - import json -+import os - from typing import List, Dict - - from vulcanus.multi_thread_handler import MultiThreadHandler -@@ -26,7 +27,7 @@ from zeus.conf.constant import CERES_COLLECT_FILE, CERES_SYNC_CONF - from zeus.database.proxy.host import HostProxy - from zeus.function.model import ClientConnectArgs - from zeus.function.verify.config import CollectConfigSchema, SyncConfigSchema --from zeus.host_manager.ssh import execute_command_and_parse_its_result -+from zeus.host_manager.ssh import execute_command_and_parse_its_result, execute_command_sftp_result - - - class CollectConfig(BaseResponse): -@@ -222,15 +223,46 @@ class CollectConfig(BaseResponse): - - - class SyncConfig(BaseResponse): -- - @staticmethod -- def sync_config_content(host_info: Dict, sync_config_info: Dict): -- command = CERES_SYNC_CONF % json.dumps(sync_config_info) -- status, content = execute_command_and_parse_its_result( -+ def sync_config_by_execute_command_sftp(host_info: Dict, sync_config_info: Dict, local_path: str, -+ remote_path: str): -+ content = sync_config_info.get("content") -+ with open(local_path, "w", encoding="UTF-8") as f: -+ f.write(content) -+ status = execute_command_sftp_result( - ClientConnectArgs(host_info.get("host_ip"), host_info.get("ssh_port"), -- host_info.get("ssh_user"), host_info.get("pkey")), command) -+ host_info.get("ssh_user"), host_info.get("pkey")), local_path, remote_path) - return status - -+ @staticmethod -+ def sync_config_content(host_info: Dict, sync_config_info: Dict): -+ join_path = "/tmp" -+ if sync_config_info.get("file_path") == "/etc/profile": -+ local_path = os.path.join(join_path, "profile") -+ remote_path = "/etc/profile" -+ status = SyncConfig.sync_config_by_execute_command_sftp(host_info, sync_config_info, local_path, -+ remote_path) -+ return status -+ elif sync_config_info.get("file_path") == "/etc/rc.local": -+ local_path = os.path.join(join_path, "rc.local") -+ remote_path = "/etc/rc.local" -+ status = SyncConfig.sync_config_by_execute_command_sftp(host_info, sync_config_info, local_path, -+ remote_path) -+ return status -+ elif sync_config_info.get("file_path") == "/etc/bashrc": -+ local_path = os.path.join(join_path, "bashrc") -+ remote_path = "/etc/bashrc" -+ status = SyncConfig.sync_config_by_execute_command_sftp(host_info, sync_config_info, local_path, -+ remote_path) -+ return status -+ else: -+ command = CERES_SYNC_CONF % json.dumps(sync_config_info) -+ -+ status, content = execute_command_and_parse_its_result( -+ ClientConnectArgs(host_info.get("host_ip"), host_info.get("ssh_port"), -+ host_info.get("ssh_user"), host_info.get("pkey")), command) -+ return status -+ - @BaseResponse.handle(schema=SyncConfigSchema, token=False) - def put(self, **params): - -@@ -244,13 +276,13 @@ class SyncConfig(BaseResponse): - } - - # Query host address from database -- proxy = HostProxy(configuration) -+ proxy = HostProxy() - if not proxy.connect(): - return self.response(code=state.DATABASE_CONNECT_ERROR, data={"resp": sync_result}) - - status, host_list = proxy.get_host_info( - {"username": "admin", "host_list": [params.get('host_id')]}, True) -- if status != state.SUCCEED or len(host_list) == 1: -+ if status != state.SUCCEED: - return self.response(code=status, data={"resp": sync_result}) - - host_info = host_list[0] -diff --git a/zeus/host_manager/ssh.py b/zeus/host_manager/ssh.py -index 4c3a259..11f6383 100644 ---- a/zeus/host_manager/ssh.py -+++ b/zeus/host_manager/ssh.py -@@ -15,6 +15,7 @@ from io import StringIO - from typing import Tuple - - import paramiko -+from paramiko import sftp - - from vulcanus.log.log import LOGGER - from vulcanus.restful.resp import state -@@ -57,7 +58,13 @@ class SSH: - """ - - def __init__(self, ip, username, port, password=None, pkey=None): -- self._client_args = {'hostname': ip, 'username': username, 'port': port, "password": password, "pkey": pkey} -+ self._client_args = { -+ 'hostname': ip, -+ 'username': username, -+ 'port': port, -+ "password": password, -+ "pkey": pkey -+ } - self._client = self.client() - - def client(self): -@@ -71,15 +78,15 @@ class SSH: - - def execute_command(self, command: str, timeout: float = None) -> tuple: - """ -- create a ssh client, execute command and parse result -+ create a ssh client, execute command and parse result - -- Args: -- command(str): shell command -- timeout(float): the maximum time to wait for the result of command execution -+ Args: -+ command(str): shell command -+ timeout(float): the maximum time to wait for the result of command execution - -- Returns: -- tuple: -- status, result, error message -+ Returns: -+ tuple: -+ status, result, error message - """ - open_channel = self._client.get_transport().open_session(timeout=timeout) - open_channel.set_combine_stderr(False) -@@ -110,13 +117,14 @@ def execute_command_and_parse_its_result(connect_args: ClientConnectArgs, comman - status, result - """ - if not connect_args.pkey: -- return state.SSH_AUTHENTICATION_ERROR, f"ssh authentication failed when connect host " f"{connect_args.host_ip}" -+ return state.SSH_AUTHENTICATION_ERROR, f"ssh authentication failed when connect host " \ -+ f"{connect_args.host_ip}" - try: - client = SSH( - ip=connect_args.host_ip, - username=connect_args.ssh_user, - port=connect_args.ssh_port, -- pkey=paramiko.RSAKey.from_private_key(StringIO(connect_args.pkey)), -+ pkey=paramiko.RSAKey.from_private_key(StringIO(connect_args.pkey)) - ) - exit_status, stdout, stderr = client.execute_command(command, connect_args.timeout) - except socket.error as error: -@@ -131,3 +139,47 @@ def execute_command_and_parse_its_result(connect_args: ClientConnectArgs, comman - return state.SUCCEED, stdout - LOGGER.error(stderr) - return state.EXECUTE_COMMAND_ERROR, stderr -+ -+ -+def execute_command_sftp_result(connect_args: ClientConnectArgs, local_path=None, remote_path=None): -+ """ -+ create a ssh client, execute command and parse result -+ -+ Args: -+ connect_args(ClientConnectArgs): e.g -+ ClientArgs(host_ip='127.0.0.1', ssh_port=22, ssh_user='root', pkey=RSAKey string) -+ command(str): shell command -+ -+ Returns: -+ tuple: -+ status, result -+ """ -+ global sftp_client, client -+ if not connect_args.pkey: -+ return state.SSH_AUTHENTICATION_ERROR, f"ssh authentication failed when connect host " \ -+ f"{connect_args.host_ip}" -+ try: -+ client = SSH( -+ ip=connect_args.host_ip, -+ username=connect_args.ssh_user, -+ port=connect_args.ssh_port, -+ pkey=paramiko.RSAKey.from_private_key(StringIO(connect_args.pkey)) -+ ) -+ sftp_client = client.client().open_sftp() -+ -+ # Specifies the path to the local file and the remote file -+ # Upload files to a remote server -+ sftp_client.put(local_path, remote_path) -+ return state.SUCCEED -+ except socket.error as error: -+ LOGGER.error(error) -+ return state.SSH_CONNECTION_ERROR, "SSH.Connection.Error" -+ except paramiko.ssh_exception.SSHException as error: -+ LOGGER.error(error) -+ return state.SSH_AUTHENTICATION_ERROR, "SSH.Authentication.Error" -+ except Exception as error: -+ LOGGER.error(error) -+ return state.SSH_AUTHENTICATION_ERROR, "SSH.Authentication.Error" -+ finally: -+ sftp_client.close() -+ client.close() --- -2.33.1.windows.1 - diff --git a/0004-bugfix-cve-fix-result-parsing-error.patch b/0004-bugfix-cve-fix-result-parsing-error.patch deleted file mode 100644 index 40248bef7e5b75672ee4d8ce69ab609dfa6c7702..0000000000000000000000000000000000000000 --- a/0004-bugfix-cve-fix-result-parsing-error.patch +++ /dev/null @@ -1,29 +0,0 @@ -From 21a8a9db54175547675bda5214d98ffa5a654d03 Mon Sep 17 00:00:00 2001 -From: rabbitali -Date: Tue, 19 Sep 2023 16:58:56 +0800 -Subject: [PATCH 1/1] bugfix: cve fix result parsing error - ---- - zeus/vulnerability_manage/view.py | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - -diff --git a/zeus/vulnerability_manage/view.py b/zeus/vulnerability_manage/view.py -index b5360e2..345978f 100644 ---- a/zeus/vulnerability_manage/view.py -+++ b/zeus/vulnerability_manage/view.py -@@ -416,10 +416,11 @@ class ExecuteCveFixTask(BaseResponse, BaseExcuteTask): - cve_fix_result_json = json.loads(cve_fix_result) - if cve_fix_result_json.pop("code") != state.SUCCEED: - request_body["status"] = CveTaskStatus.FAIL -+ else: -+ request_body["status"] = CveTaskStatus.SUCCEED - - request_body.update( - { -- "status": CveTaskStatus.SUCCEED, - "check_items": cve_fix_result_json.get("check_items"), - "cves": cve_fix_result_json.get("cves"), - } --- -2.33.0 - diff --git a/aops-zeus-v1.3.0.tar.gz b/aops-zeus-v1.3.1.tar.gz similarity index 52% rename from aops-zeus-v1.3.0.tar.gz rename to aops-zeus-v1.3.1.tar.gz index 6882ff18ce1c90f986aea04bb1c1bd31f9061dd4..da95fe85b025d16ed980909ec8644da992876a23 100644 Binary files a/aops-zeus-v1.3.0.tar.gz and b/aops-zeus-v1.3.1.tar.gz differ diff --git a/aops-zeus.spec b/aops-zeus.spec index 00f2c2eb984d988d40a9d45409a5d24e0b523fd3..6da50b1e1b73f84f948328a644adc251beaad898 100644 --- a/aops-zeus.spec +++ b/aops-zeus.spec @@ -1,18 +1,14 @@ Name: aops-zeus -Version: v1.3.0 -Release: 4 +Version: v1.3.1 +Release: 1 Summary: A host and user manager service which is the foundation of aops. License: MulanPSL2 URL: https://gitee.com/openeuler/%{name} Source0: %{name}-%{version}.tar.gz -Patch0001: 0001-add-file-sync-func.patch -Patch0002: 0002-update-callback-request-headers.patch -Patch0003: 0003-fix-bash-file-sync-error.patch -Patch0004: 0004-bugfix-cve-fix-result-parsing-error.patch BuildRequires: python3-setuptools -Requires: aops-vulcanus >= v1.2.0 +Requires: aops-vulcanus >= v1.3.0 Requires: python3-marshmallow >= 3.13.0 python3-flask python3-flask-restful python3-gevent Requires: python3-requests python3-uWSGI python3-sqlalchemy python3-werkzeug python3-PyMySQL Requires: python3-paramiko >= 2.11.0 python3-redis python3-prometheus-api-client @@ -49,6 +45,10 @@ cp -r database %{buildroot}/opt/aops/ %changelog +* Thu Sep 21 2023 wenxin - v1.3.1-1 +- update spec requires +- update version info in setup.py file + * Tue Sep 19 2023 wenxin - v1.3.0-4 - bugfix: cve fix result parsing error