diff --git a/spug_api/apps/host/views.py b/spug_api/apps/host/views.py index c17df42..dd93512 100644 --- a/spug_api/apps/host/views.py +++ b/spug_api/apps/host/views.py @@ -14,7 +14,6 @@ from libs.ssh import SSH, AuthenticationException from paramiko.ssh_exception import BadAuthenticationType from libs import AttrDict from openpyxl import load_workbook -import socket class HostView(View): @@ -90,7 +89,7 @@ class HostView(View): 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'), addr=form.id).first() + 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() @@ -99,6 +98,7 @@ class HostView(View): def post_import(request): password = request.POST.get('password') + group_id = request.POST.get('group_id') file = request.FILES['file'] ws = load_workbook(file, read_only=True)['Sheet1'] summary = {'invalid': [], 'skip': [], 'repeat': [], 'success': []} @@ -109,13 +109,12 @@ def post_import(request): summary['invalid'].append(i) continue data = AttrDict( - zone=row[0].value, - name=row[1].value, - hostname=row[2].value, - port=row[3].value, - username=row[4].value, - password=row[5].value, - desc=row[6].value + name=row[0].value, + hostname=row[1].value, + port=row[2].value, + username=row[3].value, + password=row[4].value, + desc=row[5].value ) if Host.objects.filter(hostname=data.hostname, port=data.port, username=data.username).exists(): summary['skip'].append(i) @@ -130,6 +129,7 @@ def post_import(request): except Exception: pass host = Host.objects.create(created_by=request.user, **data) + host.groups.add(group_id) if request.user.role: request.user.role.add_host_perm(host.id) summary['success'].append(i) diff --git a/spug_web/src/pages/host/Import.js b/spug_web/src/pages/host/Import.js index 5f3ddef..0c7657f 100644 --- a/spug_web/src/pages/host/Import.js +++ b/spug_web/src/pages/host/Import.js @@ -6,7 +6,7 @@ import React, { useState } from 'react'; import { observer } from 'mobx-react'; import { UploadOutlined } from '@ant-design/icons'; -import { Modal, Form, Input, Upload, Button, Tooltip, Alert } from 'antd'; +import { Modal, Form, Input, Upload, Button, Tooltip, Alert, Cascader, message } from 'antd'; import http from 'libs/http'; import store from './store'; @@ -14,11 +14,14 @@ export default observer(function () { const [loading, setLoading] = useState(false); const [password, setPassword] = useState(''); const [fileList, setFileList] = useState([]); + const [groupId, setGroupId] = useState([]); function handleSubmit() { + if (groupId.length === 0) return message.error('请选择要导入的分组'); setLoading(true); const formData = new FormData(); formData.append('file', fileList[0]); + formData.append('group_id', groupId[groupId.length - 1]); if (password) formData.append('password', password); http.post('/api/host/import/', formData, {timeout: 120000}) .then(res => { @@ -35,7 +38,11 @@ export default observer(function () { {res['repeat'].length > 0 && {res['repeat'].length} } - + , + onOk: () => { + store.fetchRecords(); + store.importVisible = false + } }) }) .finally(() => setLoading(false)) @@ -52,7 +59,6 @@ export default observer(function () { return ( - +
主机导入模板.xlsx + + + - false} - onChange={handleUpload}> - + false} + onChange={handleUpload}> + {fileList.length === 0 && ( + + )}
diff --git a/spug_web/src/pages/host/store.js b/spug_web/src/pages/host/store.js index bbc4f7f..48e881f 100644 --- a/spug_web/src/pages/host/store.js +++ b/spug_web/src/pages/host/store.js @@ -6,6 +6,7 @@ import { observable, computed } from 'mobx'; import { message } from 'antd'; import http from 'libs/http'; +import lds from 'lodash'; class Store { counter = {}; @@ -87,10 +88,11 @@ class Store { refreshCounter = () => { if (this.treeData.length && this.records.length) { - for (let item of this.treeData) { + const treeData = lds.cloneDeep(this.treeData); + for (let item of treeData) { this._refreshCounter(item) } - this.treeData = [...this.treeData] + this.treeData = treeData } } @@ -101,6 +103,7 @@ class Store { item.all_host_ids = item.all_host_ids.concat(ids) } item.all_host_ids = Array.from(new Set(item.all_host_ids)); + if (this.group.key === item.key) this.group = item; return item.all_host_ids }