From 824cf39c4341a918ec04dab5dbfb1e38f0513ef8 Mon Sep 17 00:00:00 2001 From: vapao Date: Thu, 17 Feb 2022 20:24:49 +0800 Subject: [PATCH] =?UTF-8?q?U=20=E6=89=B9=E9=87=8F=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=E7=9A=84=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=EF=BC=8C=E5=A6=82?= =?UTF-8?q?=E6=9E=9C=E6=9D=A5=E8=87=AA=E6=A8=A1=E7=89=88=E6=89=A7=E8=A1=8C?= =?UTF-8?q?=EF=BC=8C=E5=88=99=E6=98=BE=E7=A4=BA=E6=A8=A1=E7=89=88=E5=90=8D?= =?UTF-8?q?=E7=A7=B0=20#430?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- spug_api/apps/exec/models.py | 3 +++ spug_api/apps/exec/views.py | 12 +++++++++-- .../src/pages/exec/task/TemplateSelector.js | 13 +++--------- spug_web/src/pages/exec/task/index.js | 21 ++++++++++++------- .../src/pages/exec/task/index.module.less | 13 ++++++++++++ spug_web/src/pages/exec/template/Table.js | 9 +------- spug_web/src/pages/exec/template/store.js | 9 +++++++- spug_web/src/pages/monitor/Step1.js | 2 +- spug_web/src/pages/schedule/Step1.js | 2 +- 9 files changed, 54 insertions(+), 30 deletions(-) diff --git a/spug_api/apps/exec/models.py b/spug_api/apps/exec/models.py index 9fff4da..f3cb77d 100644 --- a/spug_api/apps/exec/models.py +++ b/spug_api/apps/exec/models.py @@ -35,6 +35,7 @@ class ExecTemplate(models.Model, ModelMixin): class ExecHistory(models.Model, ModelMixin): user = models.ForeignKey(User, on_delete=models.CASCADE) + template = models.ForeignKey(ExecTemplate, on_delete=models.SET_NULL, null=True) digest = models.CharField(max_length=32, db_index=True) interpreter = models.CharField(max_length=20) command = models.TextField() @@ -44,6 +45,8 @@ class ExecHistory(models.Model, ModelMixin): def to_view(self): tmp = self.to_dict() tmp['host_ids'] = json.loads(self.host_ids) + if hasattr(self, 'template_name'): + tmp['template_name'] = self.template_name return tmp class Meta: diff --git a/spug_api/apps/exec/views.py b/spug_api/apps/exec/views.py index f3fd11b..ba16175 100644 --- a/spug_api/apps/exec/views.py +++ b/spug_api/apps/exec/views.py @@ -4,6 +4,7 @@ from django.views.generic import View from django_redis import get_redis_connection from django.conf import settings +from django.db.models import F from libs import json_response, JsonParser, Argument, human_datetime, auth from apps.exec.models import ExecTemplate, ExecHistory from apps.host.models import Host @@ -57,7 +58,8 @@ def do_task(request): form, error = JsonParser( Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择执行主机'), Argument('command', help='请输入执行命令内容'), - Argument('interpreter', default='sh') + Argument('interpreter', default='sh'), + Argument('template_id', type=int, required=False) ).parse(request.body) if error is None: if not has_host_perm(request.user, form.host_ids): @@ -81,7 +83,12 @@ def do_task(request): tmp_str = f'{form.interpreter},{host_ids},{form.command}' digest = hashlib.md5(tmp_str.encode()).hexdigest() record = ExecHistory.objects.filter(user=request.user, digest=digest).first() + if form.template_id: + template = ExecTemplate.objects.filter(pk=form.template_id).first() + if not template or template.body != form.command: + form.template_id = None if record: + record.template_id = form.template_id record.updated_at = human_datetime() record.save() else: @@ -89,6 +96,7 @@ def do_task(request): user=request.user, digest=digest, interpreter=form.interpreter, + template_id=form.template_id, command=form.command, host_ids=json.dumps(form.host_ids), ) @@ -98,5 +106,5 @@ def do_task(request): @auth('exec.task.do') def get_histories(request): - records = ExecHistory.objects.filter(user=request.user) + records = ExecHistory.objects.filter(user=request.user).annotate(template_name=F('template__name')) return json_response([x.to_view() for x in records]) diff --git a/spug_web/src/pages/exec/task/TemplateSelector.js b/spug_web/src/pages/exec/task/TemplateSelector.js index 82d69ad..b5dee03 100644 --- a/spug_web/src/pages/exec/task/TemplateSelector.js +++ b/spug_web/src/pages/exec/task/TemplateSelector.js @@ -32,8 +32,8 @@ class TemplateSelector extends React.Component { handleSubmit = () => { if (this.state.selectedRows.length > 0) { - const {host_ids, body, interpreter} = this.state.selectedRows[0] - this.props.onOk(host_ids, body, interpreter) + const tpl = this.state.selectedRows[0] + this.props.onOk(tpl) } this.props.onCancel() }; @@ -62,13 +62,6 @@ class TemplateSelector extends React.Component { render() { const {selectedRows} = this.state; - let data = store.records; - if (store.f_name) { - data = data.filter(item => item['name'].toLowerCase().includes(store.f_name.toLowerCase())) - } - if (store.f_type) { - data = data.filter(item => item['type'].toLowerCase().includes(store.f_type.toLowerCase())) - } return ( this.setState({selectedRows}) }} - dataSource={data} + dataSource={store.dataSource} loading={store.isFetching} onRow={record => { return { diff --git a/spug_web/src/pages/exec/task/index.js b/spug_web/src/pages/exec/task/index.js index c9e665d..b49ec96 100644 --- a/spug_web/src/pages/exec/task/index.js +++ b/spug_web/src/pages/exec/task/index.js @@ -20,6 +20,7 @@ function TaskIndex() { const [loading, setLoading] = useState(false) const [interpreter, setInterpreter] = useState('sh') const [command, setCommand] = useState('') + const [template_id, setTemplateId] = useState() const [histories, setHistories] = useState([]) useEffect(() => { @@ -40,19 +41,21 @@ function TaskIndex() { function handleSubmit() { setLoading(true) - const host_ids = store.host_ids; - http.post('/api/exec/do/', {host_ids, interpreter, command: cleanCommand(command)}) + const formData = {interpreter, template_id, host_ids: store.host_ids, command: cleanCommand(command)} + http.post('/api/exec/do/', formData) .then(store.switchConsole) .finally(() => setLoading(false)) } - function handleTemplate(host_ids, command, interpreter) { - if (host_ids.length > 0) store.host_ids = host_ids - setInterpreter(interpreter) - setCommand(command) + function handleTemplate(tpl) { + if (tpl.host_ids.length > 0) store.host_ids = tpl.host_ids + setTemplateId(tpl.id) + setInterpreter(tpl.interpreter) + setCommand(tpl.body) } function handleClick(item) { + setTemplateId(item.template_id) setInterpreter(item.interpreter) setCommand(item.command) store.host_ids = item.host_ids @@ -110,7 +113,11 @@ function TaskIndex() {
handleClick(item)}>
{item.interpreter.substr(0, 2)}
{item.host_ids.length}
-
{item.command}
+ {item.template_name ? ( +
{item.template_name}
+ ) : ( +
{item.command}
+ )}
{moment(item.updated_at).format('MM.DD HH:mm')}
))} diff --git a/spug_web/src/pages/exec/task/index.module.less b/spug_web/src/pages/exec/task/index.module.less index 83e76f5..13c820e 100644 --- a/spug_web/src/pages/exec/task/index.module.less +++ b/spug_web/src/pages/exec/task/index.module.less @@ -1,6 +1,7 @@ .index { display: flex; height: calc(100vh - 218px); + min-height: 420px; background-color: #fff; overflow: hidden; @@ -27,6 +28,7 @@ .editor { height: calc(100vh - 482px) !important; + min-height: 152px; } } @@ -95,6 +97,17 @@ margin: 0 12px; } + .tpl { + flex: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + margin: 0 12px; + background-color: #d2e7fd; + padding: 0 8px; + border-radius: 2px; + } + .desc { color: #999; } diff --git a/spug_web/src/pages/exec/template/Table.js b/spug_web/src/pages/exec/template/Table.js index b5cbda9..49a2156 100644 --- a/spug_web/src/pages/exec/template/Table.js +++ b/spug_web/src/pages/exec/template/Table.js @@ -32,20 +32,13 @@ class ComTable extends React.Component { }; render() { - let data = store.records; - if (store.f_name) { - data = data.filter(item => item['name'].toLowerCase().includes(store.f_name.toLowerCase())) - } - if (store.f_type) { - data = data.filter(item => item['type'].toLowerCase().includes(store.f_type.toLowerCase())) - } return ( includes(x.name, this.f_name)) + if (this.f_type) data = data.filter(x => includes(x.type, this.f_type)) + return data + } + fetchRecords = () => { this.isFetching = true; http.get('/api/exec/template/') diff --git a/spug_web/src/pages/monitor/Step1.js b/spug_web/src/pages/monitor/Step1.js index 9c61f01..41290af 100644 --- a/spug_web/src/pages/monitor/Step1.js +++ b/spug_web/src/pages/monitor/Step1.js @@ -167,7 +167,7 @@ export default observer(function () { Tips: 仅测试第一个监控地址 - {showTmp && store.record.extra = v} onCancel={() => setShowTmp(false)}/>} + {showTmp && store.record.extra = body} onCancel={() => setShowTmp(false)}/>} {() => } - {showTmp && setCommand(v)} onCancel={() => setShowTmp(false)}/>} + {showTmp && setCommand(body)} onCancel={() => setShowTmp(false)}/>} ) }) \ No newline at end of file