From 24ea849db3e600a92718bc8318226f838646a687 Mon Sep 17 00:00:00 2001 From: Hu gang <18768366022@163.com> Date: Mon, 18 Dec 2023 09:30:17 +0800 Subject: [PATCH] fix adapt rollback tasks and fix some bug (cherry picked from commit 64fc4858726c896d6d5064d59c1ea9370b182ded) --- 001-bugfix-and-adapt-rollback-tasks.patch | 1025 +++++++++++++++++++++ 002-fix-hotpatch-remove-filter.patch | 24 + 003-change-search-placeholder.patch | 24 + 004-modify-search-key-for-hostlist.patch | 38 + aops-hermes-v1.4.0.tar.gz | Bin 883781 -> 765190 bytes aops-hermes.spec | 18 +- 6 files changed, 1126 insertions(+), 3 deletions(-) create mode 100644 001-bugfix-and-adapt-rollback-tasks.patch create mode 100644 002-fix-hotpatch-remove-filter.patch create mode 100644 003-change-search-placeholder.patch create mode 100644 004-modify-search-key-for-hostlist.patch diff --git a/001-bugfix-and-adapt-rollback-tasks.patch b/001-bugfix-and-adapt-rollback-tasks.patch new file mode 100644 index 0000000..a389f0b --- /dev/null +++ b/001-bugfix-and-adapt-rollback-tasks.patch @@ -0,0 +1,1025 @@ +From bba113a5899bb0b17916b2179e1f5594756dc58e Mon Sep 17 00:00:00 2001 +From: Hu gang <18768366022@163.com> +Date: Wed, 13 Dec 2023 15:15:59 +0800 +Subject: [PATCH] feat: add host management status, adaptation rollback tsak + +--- + src/api/assest.js | 1 + + src/api/leaks.js | 24 +-- + src/config/router.config.js | 4 + + src/vendor/ant-design-pro/utils/request.js | 14 +- + src/views/assests/HostDetail.vue | 39 ++-- + src/views/assests/HostManagement.vue | 82 ++++--- + src/views/leaks/LeakTaskDetail.vue | 203 ++++++++++-------- + src/views/leaks/LeakTaskList.vue | 4 + + src/views/leaks/TaskResultReport.vue | 76 +++++-- + .../components/CreateRepairTaskDrawer.vue | 36 ++-- + 10 files changed, 277 insertions(+), 206 deletions(-) + +diff --git a/src/api/assest.js b/src/api/assest.js +index a0f70ec..94015d3 100644 +--- a/src/api/assest.js ++++ b/src/api/assest.js +@@ -55,6 +55,7 @@ export function hostList({tableInfo, ...parameter}) { + ...parameter, + host_group_list: tableInfo.filters.host_group_name || [], + management, ++ search_key: tableInfo.filters.searchKey, + sort: tableInfo.sorter.field, + direction: directionMap[tableInfo.sorter.order], + page: tableInfo.pagination.current, +diff --git a/src/api/leaks.js b/src/api/leaks.js +index 8daf70d..c6f704b 100644 +--- a/src/api/leaks.js ++++ b/src/api/leaks.js +@@ -44,15 +44,15 @@ const api = { + getRpmUnderCve: '/vulnerability/cve/packages/host/get', // 查询cve影响的rpm包的主机列表 + getCvefixLeakRpm: '/vulnerability/task/cve/rpm/get', // 修复任务详情中cve列表的二级package + getCveRpmHostUnderLeak: '/vulnerability/task/cve/rpm/host/get', // 查询修复任务下的cve影响的rpm包的主机列表 +- getCveListInFixDetail: '/vulnerability/task/cve-fix/info/get', // 新接口取代api.getCveUnderCveTask 获取修复任务详情下的cve列表 + getRpmListInFixDetail: '/vulnerability/task/cve-fix/rpm/get', // 新接口取代api.getCvefixLeakRpm,获取修复任务详情下指定主机和任务下的rpm列表 + getCveFixReport: '/vulnerability/task/cve-fix/result/get', // 新接口取代api.getCveTaskResult ,获取修复任务的报告 +- getCveRollvackReport: ' /vulnerability/task/rollback/result/get', // 获取回滚任务报告 ++ getCveRollvackReport: '/vulnerability/task/cve-rollback/result/get', // 获取回滚任务报告 + generateHotPathRemoveTask: '/vulnerability/task/hotpatch-remove/generate', // 新接口取代api.generateRollbackTask ,生成热补丁移除任务 +- getRpmListInRollbackDetail: '/vulnerability/task/rollback/rpm/get', // 获取回滚任务详情列表下的rpm信息 +- getCveListInRollbackDetail: '/vulnerability/task/rollback/cve-info/get', // 获取回滚任务详情下的列表信息 ++ getRpmListInRollbackDetail: '/vulnerability/task/cve-rollback/rpm/get', // 获取回滚任务详情列表下的rpm信息 + generateRollbackTask: '/vulnerability/task/cve-rollback/generate', // 生成回滚任务 ++ getCveListInRollbackDetail: '/vulnerability/task/cve-rollback/info/get', // 获取回滚任务详情下的列表信息 + getCveHotpatchRemoveDetail: '/vulnerability/task/hotpatch-remove/info/get', // 获取热补丁移除任务详情 ++ getCveListInFixDetail: '/vulnerability/task/cve-fix/info/get', // 新接口取代api.getCveUnderCveTask 获取修复任务详情下的cve列表 + getHotpatchRemoveTaskReport: '/vulnerability/task/hotpatch-remove/result/get', // 获取热补丁移除任务报告 + getAllHostInDetail: '/vulnerability/task/host/get' // 获取详情页面下所有的hostid + }; +@@ -132,6 +132,7 @@ export function getCveListInRollbackDetail({tableInfo, ...params}) { + task_id: params.taskId, + direction: sorterMap[tableInfo.sorter.order], + filter: { ++ search_key: tableInfo.filters.searchKey, + status: tableInfo.filters.status + }, + page: tableInfo.pagination.current, +@@ -140,7 +141,7 @@ export function getCveListInRollbackDetail({tableInfo, ...params}) { + }); + } + +-// 创建热补丁回退任务 ++// 创建热补丁移除任务 + export function generateHotPatchRemoveTask(params) { + return request({ + url: api.generateHotPathRemoveTask, +@@ -196,6 +197,7 @@ export function getCveListInFixDetail({tableInfo, ...params}) { + task_id: params.taskId, + direction: sorterMap[tableInfo.sorter.order], + filter: { ++ search_key: tableInfo.filters.searchKey, + status: tableInfo.filters.status + }, + page: tableInfo.pagination.current, +@@ -267,18 +269,6 @@ export function getCveFixRpm(parameters) { + }); + } + +-// export function generateRollbackTask(parameters) { +-// return request({ +-// url: api.generateRollbackTask, +-// method: 'post', +-// data: { +-// task_name: parameters.task_name, +-// description: parameters.description, +-// info: parameters.info || [] +-// } +-// }); +-// } +- + export function getCveExport(parameter) { + return request({ + url: api.getCveExport, +diff --git a/src/config/router.config.js b/src/config/router.config.js +index b92011f..5f1d4df 100644 +--- a/src/config/router.config.js ++++ b/src/config/router.config.js +@@ -575,6 +575,10 @@ export const asyncRouterMap = [ + breadcrumbName: routeMap.leaks.children.leakTaskView.children.leakTaskList.title, + path: routeMap.leaks.children.leakTaskView.children.leakTaskList.path + }, ++ { ++ breadcrumbName: routeMap.leaks.children.leakTaskView.children.leakTaskDetail.title, ++ path: routeMap.leaks.children.leakTaskView.children.leakTaskDetail.path ++ }, + { + breadcrumbName: routeMap.leaks.children.leakTaskView.children.taskResultReport.title, + path: routeMap.leaks.children.leakTaskView.children.taskResultReport.path +diff --git a/src/vendor/ant-design-pro/utils/request.js b/src/vendor/ant-design-pro/utils/request.js +index d9320d8..661bfd0 100644 +--- a/src/vendor/ant-design-pro/utils/request.js ++++ b/src/vendor/ant-design-pro/utils/request.js +@@ -101,7 +101,7 @@ request.interceptors.response.use((response) => { + const code = response.data.code || response.status; + // 不处理所有2xx的状态码 + if (!code.toString().match(/^2[0-9]{2,2}$/)) { +- let err = null; ++ // let err = null; + switch (code) { + case '1201': + if (!timestamp1 || timestamp1 + 1632252465 < new Date().getTime()) { +@@ -166,10 +166,14 @@ request.interceptors.response.use((response) => { + }); + return retryRequest; + default: +- err = new Error(response.data.message); +- err.data = response.data.data; +- err.response = response.data; +- throw err; ++ notification.error({ ++ message: response.data.label, ++ description: response.data.message ++ }); ++ // err = new Error(response.data.message); ++ // err.data = response.data.data; ++ // err.response = response.data; ++ // throw err; + } + } + if (response.headers['content-type'] === 'application/octet-stream') { +diff --git a/src/views/assests/HostDetail.vue b/src/views/assests/HostDetail.vue +index 8286caf..6eadb05 100644 +--- a/src/views/assests/HostDetail.vue ++++ b/src/views/assests/HostDetail.vue +@@ -49,38 +49,37 @@ export default { + }; + }, + methods: { +- fetchHostInfo(This) { +- const _this = This; +- This.basicHostInfoIsLoading = true; +- getHostDetail(This.hostId, true) +- .then(function (res) { +- _this.basicHostInfo = res.data.host_infos[0]; +- _this.scene = This.basicHostInfo.scene; ++ fetchHostInfo() { ++ this.basicHostInfoIsLoading = true; ++ getHostDetail(Number(this.hostId), true) ++ .then((res) => { ++ this.basicHostInfo = res.data.host_infos[0]; ++ this.scene = this.basicHostInfo.scene; + }) +- .catch(function (err) { +- _this.$message.error(err.response.message); ++ .catch((err) => { ++ this.$message.error(err.response.message); + }) + .finally(() => { +- _this.basicHostInfoIsLoading = false; ++ this.basicHostInfoIsLoading = false; + }); +- This.basicInfoIsLoading = true; +- getHostDetail(This.hostId, false) +- .then(function (res) { +- _this.basicInfo = res.data.host_infos[0]; ++ this.basicInfoIsLoading = true; ++ getHostDetail(Number(this.hostId), false) ++ .then((res) => { ++ this.basicInfo = res.data.host_infos[0]; + }) +- .catch(function (err) { +- _this.$message.error(err.response.message); ++ .catch((err) => { ++ this.$message.error(err.response.message); + }) + .finally(() => { +- _this.basicInfoIsLoading = false; ++ this.basicInfoIsLoading = false; + }); + }, + reFetchHostInfo() { +- this.$options.methods.fetchHostInfo(this); ++ this.fetchHostInfo(); + } + }, +- mounted: function () { +- this.$options.methods.fetchHostInfo(this); ++ mounted() { ++ this.fetchHostInfo(); + } + }; + +diff --git a/src/views/assests/HostManagement.vue b/src/views/assests/HostManagement.vue +index aaa86a8..77e0ed8 100644 +--- a/src/views/assests/HostManagement.vue ++++ b/src/views/assests/HostManagement.vue +@@ -17,7 +17,8 @@ + + + +- 重置条件 ++ ++ + + + +@@ -59,26 +60,19 @@ + >{{ hostName }} + {{ isMana ? '是' : '否' }} +- {{ hostStatusMap[status] }} ++ ++ ++ {{ hostStatusMap[status] }} ++ + {{ scene ? (scene === 'normal' ? '通用' : scene) : '暂无' }} + +- + 编辑 +- | +- 删除 ++ >编辑 ++ ++ 删除 + +- + + + +@@ -94,7 +88,7 @@ import MyPageHeaderWrapper from '@/views/utils/MyPageHeaderWrapper'; + import {getSelectedRow} from '@/views/utils/getSelectedRow'; + import HostDetailDrawer from './components/HostDetailDrawer'; + // import HostTerminal from '@/views/assests/components/HostTerminal'; +-import {hostList, deleteHost, hostGroupList} from '@/api/assest'; ++import {hostList, deleteHost, hostGroupList, getHostListWithStatus} from '@/api/assest'; + + const hostStatusMap = { + 0: '在线', +@@ -214,6 +208,9 @@ export default { + } + }, + methods: { ++ async getAllHostStatus() { ++ const res = await getHostListWithStatus(); ++ }, + handleTableChange(pagination, filters, sorter) { + // 存储翻页状态 + this.pagination = pagination; +@@ -230,14 +227,13 @@ export default { + this.selectedRowsAll = getSelectedRow(selectedRowKeys, this.selectedRowsAll, this.tableData, 'host_id'); + }, + // 获取列表数据 +- getHostList() { +- const _this = this; ++ async getHostList() { + this.tableIsLoading = true; + const pagination = this.pagination || {}; + const filters = this.filters || {}; + const sorter = this.sorter || {}; + +- hostList({ ++ const hostListRes = await hostList({ + tableInfo: { + pagination: { + current: pagination.current, +@@ -249,22 +245,28 @@ export default { + order: sorter.order + } + } +- }) +- .then(function (res) { +- _this.tableData = res.data.host_infos || []; +- _this.pagination = { +- ..._this.pagination, +- current: pagination.current, +- pageSize: pagination.pageSize, +- total: res.data.total_count || (res.data.total_count === 0 ? 0 : pagination.total) +- }; +- }) +- .catch(function (err) { +- _this.$message.error(err.response.message); +- }) +- .finally(function () { +- _this.tableIsLoading = false; +- }); ++ }); ++ if (hostListRes) { ++ this.tableData = hostListRes.data.host_infos || []; ++ this.pagination = { ++ ...this.pagination, ++ current: pagination.current, ++ pageSize: pagination.pageSize, ++ total: hostListRes.data.total_count || (hostListRes.data.total_count === 0 ? 0 : pagination.total) ++ }; ++ const hostIdList = this.tableData.map((item) => item.host_id); ++ this.tableIsLoading = false; ++ const res = await getHostListWithStatus(hostIdList); ++ if (res) { ++ this.tableData.forEach((item) => { ++ const s = res.data.find((s) => item.host_id === s.host_id); ++ if (s) { ++ item.status = s.status; ++ } ++ }); ++ this.tableData = JSON.parse(JSON.stringify(this.tableData)); ++ } ++ } + }, + editHost(record) { + this.$message.success('连接到主机' + record.host_ip); +@@ -384,6 +386,16 @@ export default { + duration: 5 + }); + }, ++ handleSearch(text = '') { ++ this.pagination = defaultPagination; ++ this.sorter = null; ++ if (!this.filters) { ++ this.filters = {}; ++ } ++ this.selectedRowKeys = []; ++ this.filters.searchKey = text !== '' ? text : undefined; ++ this.getHostList(); ++ }, + handleReset() { + this.pagination = defaultPagination; + this.sorter = null; +diff --git a/src/views/leaks/LeakTaskDetail.vue b/src/views/leaks/LeakTaskDetail.vue +index 27e919e..f7f7438 100644 +--- a/src/views/leaks/LeakTaskDetail.vue ++++ b/src/views/leaks/LeakTaskDetail.vue +@@ -111,7 +111,9 @@ + + + +- 生成回滚任务 ++ 生成回滚任务 + + + +@@ -236,12 +238,13 @@ import { + getTaskProgress, + generateRollbackTask, + getCveProgressUnderCveTask, +- getAllHostInDetail ++ getAllHostInDetail, ++ getHostScanStatus + } from '@/api/leaks'; + import configs from '@/config/defaultSettings'; + + const taskTypeMap = { +- 'cve fix': '漏洞修复', ++ 'cve fix': 'cve修复', + 'repo set': 'REPO设置', + 'cve rollback': 'cve回滚', + 'hotpatch remove': '热补丁移除' +@@ -307,6 +310,8 @@ export default { + }, + data() { + return { ++ // 生成回滚任务按钮是否loading ++ isRollBackButtonLoading: false, + expandedRowKeys: [], + rpmrecord: {}, + propType: '', +@@ -379,7 +384,7 @@ export default { + { + dataIndex: 'host_name', + key: 'host_name', +- title: '主机', ++ title: '主机名', + scopedSlots: {customRender: 'hostName'} + }, + { +@@ -391,7 +396,7 @@ export default { + { + dataIndex: 'cve_num', + key: 'cve_num', +- title: '修复的CVE', ++ title: 'CVE数量', + scopedSlots: {customRender: 'cveNum'} + }, + { +@@ -405,26 +410,27 @@ export default { + {text: '修复成功', value: 'succeed'}, + {text: '待修复', value: 'fail'}, + {text: '运行中', value: 'running'}, +- {text: '未知', value: 'None'} ++ {text: '未知', value: 'unknown'} + ] + : [ + {text: '回滚成功', value: 'succeed'}, + {text: '待回滚', value: 'fail'}, + {text: '运行中', value: 'running'}, +- {text: '未知', value: 'None'} ++ {text: '未知', value: 'unknown'} + ], + filteredValue: filters.status || null, + onFilter: (value, record) => record.status.includes(value) + } + ]; + }, ++ + repoColumns() { + let {filters} = this; + filters = filters || {}; + return [ + { + dataIndex: 'host_name', +- title: '主机名称', ++ title: '主机名', + scopedSlots: {customRender: 'host_name'} + }, + { +@@ -452,27 +458,28 @@ export default { + }, + // 展开后的列表列号 + innerColumns() { ++ const {taskType} = this; + return [ + { + dataIndex: 'installed_rpm', + key: 'installed_rpm', +- title: '受影响rpm' ++ title: taskType === 'cve fix' ? '受影响rpm' : '已安装rpm' + }, + { +- dataIndex: 'available_rpm', +- key: 'available_rpm', +- title: '待安装rpm', +- scopedSlots: {customRender: 'available_rpm'} ++ dataIndex: taskType === 'cve fix' ? 'available_rpm' : 'target_rpm', ++ key: taskType === 'cve fix' ? 'available_rpm' : 'target_rpm', ++ title: taskType === 'cve fix' ? '待安装rpm' : '目标rpm', ++ scopedSlots: {customRender: 'rpm'} + }, + { + dataIndex: 'cves', + key: 'cves', +- title: '修复cve' ++ title: 'CVE' + }, + { + dataIndex: 'status', + key: 'rpm_status', +- title: '状态', ++ title: this.taskType === 'cve fix' ? '修复状态' : '回滚状态', + scopedSlots: {customRender: 'status'}, + filter: + this.taskType === 'cve fix' +@@ -480,13 +487,13 @@ export default { + {text: '修复成功', value: 'succeed'}, + {text: '待修复', value: 'fail'}, + {text: '运行中', value: 'running'}, +- {text: '未知', value: 'None'} ++ {text: '未知', value: 'unknown'} + ] + : [ + {text: '回滚成功', value: 'succeed'}, + {text: '待回滚', value: 'fail'}, + {text: '运行中', value: 'running'}, +- {text: '未知', value: 'None'} ++ {text: '未知', value: 'unknown'} + ] + } + ]; +@@ -563,50 +570,43 @@ export default { + clearInterval(this.jumpModalInterval); + this.isRollbackModelvisible = false; + this.$router.push({ +- path: `/leaks/task/${this.taskType}/${this.rollbackTaskId}`, ++ path: `/leaks/task/cve rollback/${this.rollbackTaskId}`, + query: { + task_id: this.rollbackTaskId + } + }); ++ this.expandedRowKeys = []; ++ this.taskType = 'cve rollback'; + this.taskId = this.rollbackTaskId; + localStorage.setItem('taskId', this.taskId); + this.getInitalData(); + }, + async generateRollbackTask() { ++ this.isRollBackButtonLoading = true; + if (this.detail.statuses['running'] > 0) { + this.$warning({ + title: '有任务正在运行,不能回滚。' + }); ++ this.isRollBackButtonLoading = false; + return; + } +- this.$confirm({ +- title: ( +-

+- 回滚后无法恢复 +-
+- 请确认回滚CVE修复任务: +-

+- ), +- icon: () => , +- onOk: async () => { +- const res = await generateRollbackTask(this.taskId); +- if (res) { +- this.rollbackTaskId = res.data.task_id; +- this.countDown = 5; +- this.isRollbackModelvisible = true; +- this.jumpModalInterval = setInterval(() => { +- this.countDown = this.countDown - 1; +- if (this.countDown === 0) { +- clearInterval(this.jumpModalInterval); +- this.isRollbackModelvisible = false; +- } +- }, 1000); ++ const res = await generateRollbackTask(this.taskId); ++ if (res) { ++ this.rollbackTaskId = res.data.task_id; ++ this.countDown = 5; ++ this.isRollbackModelvisible = true; ++ this.jumpModalInterval = setInterval(() => { ++ this.countDown = this.countDown - 1; ++ if (this.countDown === 0) { ++ clearInterval(this.jumpModalInterval); ++ this.isRollbackModelvisible = false; + } +- } +- }); ++ }, 1000); ++ this.isRollBackButtonLoading = false; ++ } else { ++ } + }, + dateFormat, +- + jumptoResult(value) { + this.$router.push({ + path: `/leaks/task-report/${this.taskType}/${this.taskId}`, +@@ -633,7 +633,6 @@ export default { + }); + return res || null; + }, +- + // 展开详情列表 + async expand(expanded, record) { + if (!expanded) return; +@@ -739,7 +738,7 @@ export default { + current: pagination.current, + pageSize: pagination.pageSize + }, +- filters: filters, ++ filters, + sorter: { + field: sorter.field, + order: sorter.order +@@ -770,7 +769,7 @@ export default { + return res || null; + }, + // 获取热补丁回退列表 +- async getCveListWithHotpathRemove() { ++ async getCveListWithHotpathRemove(needScan = false) { + this.tableIsLoading = true; + const pagination = this.pagination || {}; + const filters = this.filters || {}; +@@ -800,12 +799,13 @@ export default { + this.tableIsLoading = false; + await this.updateCveProgress( + this.taskId, +- res.data.result.map((cve) => cve.cve_id) ++ res.data.result.map((cve) => cve.cve_id), ++ needScan + ); + } + }, +- // for cve task +- async getCveList() { ++ // 获取cve列表(修复,回滚) ++ async getCveList(needScan = false) { + this.tableIsLoading = true; + const res = this.taskType === 'cve fix' ? await this.getCveListWithFix() : await this.getCveListWithRollback(); + if (res) { +@@ -814,34 +814,67 @@ export default { + rpms: [] + })); + this.reportvisible = this.getReportVisible(res.data.result); +- this.expandedRowKeys = []; ++ // this.expandedRowKeys = []; + this.pagination = { + ...this.pagination, + total: res.data.total_count || (res.data.total_count === 0 ? 0 : this.pagination.total) + }; +- await this.updateHostProgress(); ++ !this.reportvisible && (await this.updateHostProgress(needScan)); + this.tableIsLoading = false; + } + }, + // 修复,回滚任务running时刷新列表状态 +- async updateHostProgress() { ++ async updateHostProgress(needScan = false) { + clearTimeout(this.CveScanStatueTimeout); + const res = this.taskType === 'cve fix' ? await this.getCveListWithFix() : await this.getCveListWithRollback(); + const progressRes = res.data.result; +- this.tableData = progressRes.map((item) => ({ +- ...item, +- rpms: [] +- })); ++ progressRes.forEach((item) => { ++ const i = this.tableData.findIndex((t) => t.host_id === item.host_id); ++ if (i > -1 && this.tableData[i].status !== item.status) { ++ this.tableData[i].status = item.status; ++ if (this.expandedRowKeys.includes(this.tableData[i].host_id)) this.expand(true, this.tableData[i]); ++ } ++ }); ++ + const list = progressRes.filter((item) => item.status === 'running'); + this.reportvisible = list.length === 0; + if (list.length > 0) { + this.CveScanStatueTimeout = setTimeout(() => { +- this.updateHostProgress(); ++ this.updateHostProgress(needScan); + }, configs.taskProgressUpdateInterval); ++ } else { ++ needScan && (await this.sacnHostAfterExcute()); + } + }, +- // 更新热补丁回退的执行进度 +- async updateCveProgress(taskId, cveList) { ++ ++ // 在任务执行完成之后进行主机扫描 ++ async sacnHostAfterExcute() { ++ const hostList = await this.getAllHostId(); ++ const res = await getHostScanStatus({hostList}); ++ if (!res) return; ++ const hostStatusList = res.data.result; ++ const needScanList = Object.keys(hostStatusList).map((h) => { ++ if (hostStatusList[h] !== 3 && hostList.includes(Number(h))) return Number(h); ++ }); ++ this.scanLeakAfterExecuteTask(needScanList); ++ }, ++ // 返回扫描状态的主机 ++ getScanningHost(scanMap, hostList) { ++ const arr = []; ++ hostList.forEach((host) => { ++ if (scanMap[host.host_id] === 3) { ++ arr.push(host); ++ } ++ }); ++ return arr; ++ }, ++ /** ++ * 更新热补丁回退的执行进度 ++ * @param {*} taskId 任务id ++ * @param {*} cveList cve 列表 ++ * @param {*} needScan 是否需要扫描主机 ++ */ ++ async updateCveProgress(taskId, cveList, needScan = false) { + clearTimeout(this.CveScanStatueTimeout); + const processRes = await getCveProgressUnderCveTask({ + taskId, +@@ -852,8 +885,10 @@ export default { + this.runningCveIds = this.getRunningCve(processRes.data.result); + if (this.runningCveIds.length > 0) { + this.CveScanStatueTimeout = setTimeout(() => { +- this.updateCveProgress(taskId, cveList); ++ this.updateCveProgress(taskId, cveList, needScan); + }, configs.taskProgressUpdateInterval); ++ } else { ++ needScan && (await this.sacnHostAfterExcute()); + } + }, + // 将查询到的cve进度更新到表格数据中,用于数据展示 +@@ -954,26 +989,23 @@ export default { + title: `确定执行任务${this.detail.task_name}?`, + icon: () => , + okText: '执行', +- onOk: () => { +- return executeTask(this.taskId) +- .then((res) => { +- this.$message.success(res.message); +- this.scanLeakAfterExecuteTask(); +- // 执行任务成功后刷新 +- setTimeout(() => { +- this.getInitalData(); +- this.expandedRowKeys = []; +- }, 3000); +- }) +- .catch((err) => { +- this.$message.error(err.response.message); +- }); ++ onOk: async () => { ++ const excuteRes = await executeTask(this.taskId); ++ if (excuteRes) { ++ // 获取详情任务所有处理的hostid列表 ++ this.$message.success(excuteRes.message); ++ // 执行任务成功后刷新 ++ setTimeout(() => { ++ this.getInitalData(true); ++ this.expandedRowKeys = []; ++ }, 3000); ++ } + } + }); + }, +- async scanLeakAfterExecuteTask() { ++ async scanLeakAfterExecuteTask(hostList) { + await scanHost({ +- hostList: this.hostList, ++ hostList, + filter: null + }); + }, +@@ -981,7 +1013,7 @@ export default { + async getAllHostId() { + const res = await getAllHostInDetail(this.taskId); + if (res) { +- this.hostList = res.data; ++ return res.data; + } + }, + showHostListUnderCve(type, record) { +@@ -992,16 +1024,17 @@ export default { + closeHostListUnderCve() { + this.hostListUnderCveVisible = false; + }, +- getInitalData() { ++ /** ++ * isFresh 是第一次初始化还是后续的刷新数据 ++ */ ++ getInitalData(isFresh = false) { + this.getInfo(); +- // 获取详情任务所有处理的hostid列表 +- this.getAllHostId(); + if (this.taskType === 'repo set') { + this.getHostList(); + } else if (this.taskType === 'hotpatch remove') { +- this.getCveListWithHotpathRemove(); ++ this.getCveListWithHotpathRemove(isFresh); + } else { +- this.getCveList(); ++ this.getCveList(isFresh); + } + }, + +@@ -1023,9 +1056,9 @@ export default { + } + if (this.taskType === 'cve fix' || this.taskType === 'cve rollback') { + if (text !== '') { +- this.filters.host_name = text; ++ this.filters.searchKey = text; + } else { +- this.filters.host_name = undefined; ++ this.filters.searchKey = undefined; + } + this.getCveList(); + } else { +@@ -1065,7 +1098,7 @@ export default { + localStorage.setItem('taskId', this.taskId); + }, + mounted() { +- this.getInitalData(); ++ this.getInitalData(false); + }, + beforeDestroy() { + // 离开页面前,若当前存在轮询,清除轮询 +diff --git a/src/views/leaks/LeakTaskList.vue b/src/views/leaks/LeakTaskList.vue +index be0ce82..08cb5e4 100644 +--- a/src/views/leaks/LeakTaskList.vue ++++ b/src/views/leaks/LeakTaskList.vue +@@ -193,6 +193,10 @@ export default { + { + text: 'cve rollback', + value: 'cve rollback' ++ }, ++ { ++ text: 'hotpatch remove', ++ value: 'hotpatch remove' + } + ] + }, +diff --git a/src/views/leaks/TaskResultReport.vue b/src/views/leaks/TaskResultReport.vue +index ca8d031..e702b06 100644 +--- a/src/views/leaks/TaskResultReport.vue ++++ b/src/views/leaks/TaskResultReport.vue +@@ -1,4 +1,3 @@ +- +