diff --git a/0002-update-callback-request-headers.patch b/0002-update-callback-request-headers.patch new file mode 100644 index 0000000000000000000000000000000000000000..b73eacad00bb12804535cede8129f1ca5f4cb84b --- /dev/null +++ b/0002-update-callback-request-headers.patch @@ -0,0 +1,68 @@ +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 new file mode 100644 index 0000000000000000000000000000000000000000..7a6837404fcbccba14f955d6a06b24d3a5740caf --- /dev/null +++ b/0003-fix-bash-file-sync-error.patch @@ -0,0 +1,220 @@ +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/aops-zeus.spec b/aops-zeus.spec index de10a14d8192c6c46cc3f2f5cf571a5841193216..d84b046891889477018469218027e13c7aa60db9 100644 --- a/aops-zeus.spec +++ b/aops-zeus.spec @@ -1,11 +1,14 @@ Name: aops-zeus Version: v1.3.0 -Release: 2 +Release: 3 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 + BuildRequires: python3-setuptools Requires: aops-vulcanus >= v1.2.0 @@ -45,6 +48,10 @@ cp -r database %{buildroot}/opt/aops/ %changelog +* Tue Sep 19 2023 wenxin - v1.3.0-3 +- update callback request headers +- fix bash file sync error + * Wed Sep 13 2023 wenxin - v1.3.0-2 - add file sync func