add batch delete hosts

pull/410/head
vapao 2021-09-17 23:14:31 +08:00
parent ce69718202
commit b64342a192
2 changed files with 46 additions and 31 deletions

View File

@ -98,22 +98,30 @@ class HostView(View):
def delete(self, request):
form, error = JsonParser(
Argument('id', type=int, help='请指定操作对象')
Argument('id', type=int, required=False),
Argument('group_id', type=int, required=False),
).parse(request.GET)
if error is None:
deploy = Deploy.objects.filter(host_ids__regex=fr'[^0-9]{form.id}[^0-9]').annotate(
app_name=F('app__name'),
env_name=F('env__name')
).first()
if deploy:
return json_response(error=f'应用【{deploy.app_name}】在【{deploy.env_name}】的发布配置关联了该主机,请解除关联后再尝试删除该主机')
task = Task.objects.filter(targets__regex=fr'[^0-9]{form.id}[^0-9]').first()
if task:
return json_response(error=f'任务计划中的任务【{task.name}】关联了该主机,请解除关联后再尝试删除该主机')
detection = Detection.objects.filter(type__in=('3', '4'), targets__regex=fr'[^0-9]{form.id}[^0-9]').first()
if detection:
return json_response(error=f'监控中心的任务【{detection.name}】关联了该主机,请解除关联后再尝试删除该主机')
Host.objects.filter(pk=form.id).delete()
if form.id:
host_ids = [form.id]
elif form.group_id:
group = Group.objects.get(pk=form.group_id)
host_ids = [x.id for x in group.hosts.all()]
else:
return json_response(error='参数错误')
for host_id in host_ids:
regex = fr'[^0-9]{host_id}[^0-9]'
deploy = Deploy.objects.filter(host_ids__regex=regex) \
.annotate(app_name=F('app__name'), env_name=F('env__name')).first()
if deploy:
return json_response(error=f'应用【{deploy.app_name}】在【{deploy.env_name}】的发布配置关联了该主机,请解除关联后再尝试删除该主机')
task = Task.objects.filter(targets__regex=fr'[^0-9]{form.id}[^0-9]').first()
if task:
return json_response(error=f'任务计划中的任务【{task.name}】关联了该主机,请解除关联后再尝试删除该主机')
detection = Detection.objects.filter(type__in=('3', '4'), targets__regex=regex).first()
if detection:
return json_response(error=f'监控中心的任务【{detection.name}】关联了该主机,请解除关联后再尝试删除该主机')
Host.objects.filter(id__in=host_ids).delete()
return json_response(error=error)

View File

@ -5,13 +5,14 @@
*/
import React, { useState, useEffect } from 'react';
import { observer } from 'mobx-react';
import { Input, Card, Tree, Dropdown, Menu, Switch, Tooltip, message } from 'antd';
import { Input, Card, Tree, Dropdown, Menu, Switch, Tooltip, Modal } from 'antd';
import {
FolderOutlined,
FolderAddOutlined,
EditOutlined,
DeleteOutlined,
CopyOutlined,
CloseOutlined,
ScissorOutlined,
LoadingOutlined,
QuestionCircleOutlined
@ -50,19 +51,32 @@ export default observer(function () {
<Menu.Item key="3" icon={<CopyOutlined/>} onClick={() => store.showSelector(true)}>添加至分组</Menu.Item>
<Menu.Item key="4" icon={<ScissorOutlined/>} onClick={() => store.showSelector(false)}>移动至分组</Menu.Item>
<Menu.Divider/>
<Menu.Item key="5" icon={<DeleteOutlined/>} danger onClick={handleRemove}>删除此分组</Menu.Item>
<Menu.Item key="5" icon={<CloseOutlined/>} danger onClick={handleRemoveHosts}>删除主机</Menu.Item>
<Menu.Item key="6" icon={<DeleteOutlined/>} danger onClick={handleRemove}>删除此分组</Menu.Item>
</Menu>
)
function handleSubmit() {
if (!store.group.title) {
return message.error('请输入分组名称')
if (store.group.title) {
setLoading(true);
const {key, parent_id, title} = store.group;
http.post('/api/host/group/', {id: key || undefined, parent_id, name: title})
.then(() => setAction(''))
.finally(() => setLoading(false))
} else {
if (store.group.key === 0) store.treeData = bakTreeData
setAction('')
}
setLoading(true);
const {key, parent_id, title} = store.group;
http.post('/api/host/group/', {id: key || undefined, parent_id, name: title})
.then(() => setAction(''))
.finally(() => setLoading(false))
}
function handleRemoveHosts() {
const group = store.group;
Modal.confirm({
title: '操作确认',
content: `批量删除【${group.title}】分组内的 ${group.all_host_ids.length} 个主机?`,
onOk: () => http.delete('/api/host/', {params: {group_id: group.key}})
.then(store.initial)
})
}
function handleRemove() {
@ -102,13 +116,6 @@ export default observer(function () {
.then(() => setLoading(false))
}
function handleBlur() {
if (store.group.key === 0) {
store.treeData = bakTreeData
}
setAction('')
}
function handleRightClick(v) {
if (hasPermission('admin')) {
store.group = v.node;
@ -131,7 +138,7 @@ export default observer(function () {
defaultValue={nodeData.title}
suffix={loading ? <LoadingOutlined/> : <span/>}
onClick={e => e.stopPropagation()}
onBlur={handleBlur}
onBlur={handleSubmit}
onChange={e => store.group.title = e.target.value}
onPressEnter={handleSubmit}/>
} else if (action === 'del' && nodeData.key === store.group.key) {