aops-hermes/001-bugfix-and-adapt-rollback-tasks.patch
Hu gang 24ea849db3 fix adapt rollback tasks and fix some bug
(cherry picked from commit 64fc4858726c896d6d5064d59c1ea9370b182ded)
2023-12-18 16:43:02 +08:00

1026 lines
40 KiB
Diff
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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();
}
};
</script>
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 @@
</a-alert>
</a-col>
<a-col>
- <a-button @click="handleReset">重置条件</a-button>
+ <!-- <a-button @click="handleReset">重置条件</a-button> -->
+ <a-input-search placeholder="按主机名或主机ip搜索" style="width: 200px" @search="handleSearch" />
</a-col>
</a-row>
</a-col>
@@ -59,26 +60,19 @@
>{{ hostName }}</router-link
>
<span slot="isManagement" slot-scope="isMana">{{ isMana ? '是' : '否' }}</span>
- <span slot="statusItem" slot-scope="status">{{ hostStatusMap[status] }}</span>
+ <span slot="statusItem" slot-scope="status">
+ <a-spin v-if="!status && status !== 0"></a-spin>
+ <span v-else>{{ hostStatusMap[status] }}</span>
+ </span>
<span slot="scene" slot-scope="scene">{{ scene ? (scene === 'normal' ? '通用' : scene) : '暂无' }}</span>
<span slot="action" slot-scope="record">
- <!-- <a @click="openDetail(record.host_id)">查看</a>
- ----后续增加-----
- <a-divider type="vertical" />
- <span>编辑</span>
- ----------------
- <a-divider type="vertical" /> -->
<router-link
:to="{path: `hosts-management/host-edit`, query: {hostId: record.host_id, pageType: 'edit'}}"
@click="editHost(record)"
- >编辑</router-link
- >
- <span> | </span>
- <a @click="deleteHost(record)">删除</a>
+ >编辑
+ </router-link>
+ <a @click="deleteHost(record)" class="delete-button"> 删除</a>
</span>
- <!-- <div slot="expandedRowRender" style="margin: 0">
- <host-terminal />
- </div> -->
</a-table>
</div>
</a-card>
@@ -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 @@
</a-row>
</a-col>
<a-col v-if="taskType === 'cve fix'">
- <a-button type="primary" @click="generateRollbackTask">生成回滚任务</a-button>
+ <a-button type="primary" @click="generateRollbackTask" :loading="isRollBackButtonLoading"
+ >生成回滚任务</a-button
+ >
</a-col>
</a-row>
<!-- 热补丁移除任务 -->
@@ -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: (
- <p>
- 回滚后无法恢复
- <br />
- 请确认回滚CVE修复任务
- </p>
- ),
- icon: () => <a-icon type="exclamation-circle" />,
- 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: () => <a-icon type="exclamation-circle" />,
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 @@
-<!-- eslint-disable vue/max-attributes-per-line -->
<template>
<page-header-wrapper :breadcrumb="breadcrumb">
<a-card :bordered="false" class="aops-theme">
@@ -30,7 +29,7 @@
{{ cveStatusTextMap[resultItem.status] }}
</a-descriptions-item>
<a-descriptions-item label="状态" v-if="resultItem.task_type === 'cve rollback'">
- {{ rollStatusTextMap[resultItem.status] }}
+ {{ rollStatusTextMap[resultItem.task_result.result] }}
</a-descriptions-item>
<a-descriptions-item label="状态" v-if="resultItem.task_type === 'repo set'">
{{ repoStatusTextMap[resultItem.task_result.status] }}
@@ -39,8 +38,13 @@
{{ resultItem.task_result.repo }}
</a-descriptions-item>
</a-descriptions>
- <p class="reuslt-item-title">检查项:</p>
- <a-row>
+ <span class="reuslt-item-title">检查项:</span>
+ <span
+ v-if="resultItem.task_result.check_items && resultItem.task_result.check_items.length === 0"
+ style="margin-left: 10px"
+ >无</span
+ >
+ <a-row v-else>
<a-col span="8">
<a-descriptions :column="{sm: 1}" bordered size="small">
<a-descriptions-item
@@ -79,33 +83,31 @@
</div>
</div>
<!-- 回滚任务 -->
- <div v-if="taskType === 'cve rollback'" style="margin-left: 50px">
- <p class="reuslt-item-title" style="margin-top: 12px">RPM回滚情况:</p>
+ <div v-if="taskType === 'cve rollback'">
+ <p class="reuslt-item-title" style="margin-top: 12px">RPM回滚详情:</p>
<a-collapse v-if="resultItem.task_result.rpms.length !== 0" :bordered="false">
<a-collapse-panel
v-for="(rpm, rkidx) in resultItem.task_result.rpms"
:key="rkidx"
- :header="`${rpm.installed_rpm}`"
+ :header="`${rpm.cves}`"
>
- <div class="cve-item">
- <p class="reuslt-item-title">结果:</p>
- {{ rollStatusTextMap[rpm.result] }}
- </div>
- <div class="cve-item">
- <p class="reuslt-item-title" style="margin-top: 12px">Log:</p>
- <p class="result-log" v-html="logFormat(rpm.log)"></p>
- </div>
- <a-badge :status="statusResultValueMap[rpm.result]" slot="extra" />
+ <p>
+ <span class="title">已安装rpm:</span>
+ <span> {{ rpm.installed_rpm }}</span>
+ </p>
+ <p>
+ <span class="title">目标rpm:</span>
+ <span> {{ rpm.target_rpm }}</span>
+ </p>
+ <a-badge :status="statusResultValueMap[resultItem.task_result.result]" slot="extra" />
</a-collapse-panel>
</a-collapse>
- <div v-else class="cve-item">
- <p class="reuslt-item-title" style="margin-top: 12px">Log:</p>
- <p class="result-log">{{ resultItem.log }}</p>
- </div>
+ <p class="reuslt-item-title" style="margin-top: 16px">Log:</p>
+ <p class="result-log" v-html="logFormat(resultItem.task_result.log)"></p>
</div>
<!-- 热补丁移除任务 -->
<div v-if="taskType === 'hotpatch remove'" style="margin-left: 50px">
- <p class="reuslt-item-title" style="margin-top: 12px">CVE修复情况:</p>
+ <p class="reuslt-item-title" style="margin-top: 12px">热补丁移除情况:</p>
<a-collapse v-if="resultItem.task_result.cves.length !== 0" :bordered="false">
<a-collapse-panel
v-for="(cve, rkidx) in resultItem.task_result.cves"
@@ -113,7 +115,7 @@
:header="`${cve.cve_id}`"
>
<div class="cve-item">
- <p class="reuslt-item-title">结果: {{ statusResultTextMap[cve.result] }}</p>
+ <p class="reuslt-item-title">结果: {{ removeStatusResult[cve.result] }}</p>
</div>
<div class="cve-item">
<p class="reuslt-item-title" style="margin-top: 12px">Log:</p>
@@ -132,7 +134,16 @@
<p class="reuslt-item-title" style="margin-top: 16px">Log:</p>
<p class="result-log">{{ resultItem.task_result.log }}</p>
</div>
- <a-badge :status="statusValueMap[resultItem.status]" slot="extra" />
+ <a-badge
+ :status="
+ taskType === 'repo set'
+ ? statusValueMap[resultItem.task_result.status]
+ : taskType === 'cve fix' || taskType === 'hotpatch remove'
+ ? statusValueMap[resultItem.status]
+ : statusValueMap[resultItem.task_result.result]
+ "
+ slot="extra"
+ />
</a-collapse-panel>
</a-collapse>
</div>
@@ -188,6 +199,13 @@ const statusResultTextMap = {
unknown: '未知'
};
+const removeStatusResult = {
+ succeed: '移除成功',
+ fail: '待移除',
+ running: '运行中',
+ unknown: '未知'
+};
+
const statusResultValueMap = {
succeed: 'success',
unfixed: 'error',
@@ -210,6 +228,13 @@ export default {
props: {
routes,
itemRender: ({route, params, routes, paths, h}) => {
+ if (route.path === '/leaks/task/:taskType/:taskId') {
+ const path = {
+ path: `/leaks/task/${this.$route.query.taskType}/${this.$route.query.taskId}`,
+ query: {taskId: this.$route.query.taskId}
+ };
+ return <router-link to={path}>{route.breadcrumbName}</router-link>;
+ }
return <router-link to={route.path}>{route.breadcrumbName}</router-link>;
}
}
@@ -218,6 +243,7 @@ export default {
},
data() {
return {
+ removeStatusResult,
taskId: this.$route.query.taskId,
taskType: this.$route.query.taskType,
latestExecuteTime: this.$route.query.latestExecuteTime,
@@ -293,6 +319,10 @@ export default {
font-weight: 500;
color: rgba(0, 0, 0, 0.85);
}
+.title {
+ font-weight: bold;
+ margin-right: 5px;
+}
/deep/ .ant-descriptions-item {
.ant-descriptions-item-label {
font-weight: 500;
diff --git a/src/views/leaks/components/CreateRepairTaskDrawer.vue b/src/views/leaks/components/CreateRepairTaskDrawer.vue
index 5977bfb..b302439 100644
--- a/src/views/leaks/components/CreateRepairTaskDrawer.vue
+++ b/src/views/leaks/components/CreateRepairTaskDrawer.vue
@@ -4,7 +4,7 @@
{{ taskTypsbutton[taskType] }}
</a-button>
<a-drawer
- :title="`生成任务${taskType === 'repo set' ? ' 设置REPO' : ''}`"
+ :title="taskTypsbutton[taskType]"
closable
@close="handleCancel"
:get-container="false"
@@ -227,7 +227,7 @@ const taskTypsbutton = {
'cve fix': '生成修复任务',
'repo set': '设置REPO',
'cve rollback': '生成回滚任务',
- 'hotpatch remove': '热补丁移除'
+ 'hotpatch remove': '热补丁移除任务'
};
const taskTypsEnum = {
'cve fix': 'cve修复',
@@ -814,25 +814,19 @@ export default {
break;
} else {
// make request
- generateTask(params)
- .then((res) => {
- this.$message.success(res.message);
- if (excuteASAP) {
- const task = res.data.filter((item) => item.fix_way === 'hotpatch');
- this.handleExcuteASAP(task[0].task_id, res.data);
- } else {
- this.visible = false;
- this.handleGenerateSuccess(res.data, 'CVE修复', 'normal');
- }
- })
- .catch((err) => {
- this.$message.error(err.response.message);
- })
- .finally(() => {
- if (!excuteASAP) {
- this.submitLoading = false;
- }
- });
+ generateTask(params).then((res) => {
+ this.$message.success(res.message);
+ if (excuteASAP) {
+ // 如果同时存在冷热补丁两种任务,则选择热补丁任务立即执行,如果只有单个任务,则执行该任务
+ const task =
+ res.data.length > 1 ? res.data.filter((item) => item.fix_way === 'hotpatch') : res.data;
+ this.handleExcuteASAP(task[0].task_id, res.data);
+ } else {
+ this.visible = false;
+ this.handleGenerateSuccess(res.data, 'CVE修复', 'normal');
+ }
+ });
+ this.submitLoading = false;
break;
}
case 'repo set':
--
Gitee