mirror of https://github.com/openspug/spug
add batch delete hosts
parent
ce69718202
commit
b64342a192
|
@ -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)
|
||||
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue