1026 lines
40 KiB
Diff
1026 lines
40 KiB
Diff
|
|
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
|