U 自动移除命令中换行包含的\r

pull/31/head
vapao 2020-03-12 22:21:43 +08:00
parent e285faf080
commit 17dfe2618d
7 changed files with 25 additions and 18 deletions

View File

@ -26,6 +26,11 @@ export function hasPermission(strCode) {
return false return false
} }
// 清理输入的命令中包含的\r符号
export function cleanCommand(text) {
return text ? text.replace(/\r\n/g, '\n') : ''
}
// 数组包含关系判断 // 数组包含关系判断
export function isSubArray(parent, child) { export function isSubArray(parent, child) {
for (let item of child) { for (let item of child) {

View File

@ -14,6 +14,7 @@ import 'ace-builds/src-noconflict/theme-tomorrow';
import store from './store'; import store from './store';
import http from 'libs/http'; import http from 'libs/http';
import styles from './index.module.css'; import styles from './index.module.css';
import { cleanCommand } from "../../../libs";
@observer @observer
class Ext1Setup3 extends React.Component { class Ext1Setup3 extends React.Component {
@ -86,7 +87,7 @@ class Ext1Setup3 extends React.Component {
height={full === '1' ? '100vh' : '100px'} height={full === '1' ? '100vh' : '100px'}
placeholder="每行一条规则" placeholder="每行一条规则"
value={info['filter_rule']['data']} value={info['filter_rule']['data']}
onChange={v => info['filter_rule']['data'] = v} onChange={v => info['filter_rule']['data'] = cleanCommand(v)}
style={{border: '1px solid #e8e8e8'}}/> style={{border: '1px solid #e8e8e8'}}/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
@ -100,7 +101,7 @@ class Ext1Setup3 extends React.Component {
height={full === '3' ? '100vh' : '100px'} height={full === '3' ? '100vh' : '100px'}
placeholder="输入要执行的命令" placeholder="输入要执行的命令"
value={info['hook_pre_server']} value={info['hook_pre_server']}
onChange={v => info['hook_pre_server'] = v} onChange={v => info['hook_pre_server'] = cleanCommand(v)}
style={{border: '1px solid #e8e8e8'}}/> style={{border: '1px solid #e8e8e8'}}/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
@ -114,7 +115,7 @@ class Ext1Setup3 extends React.Component {
height={full === '5' ? '100vh' : '100px'} height={full === '5' ? '100vh' : '100px'}
placeholder="输入要执行的命令" placeholder="输入要执行的命令"
value={info['hook_pre_host']} value={info['hook_pre_host']}
onChange={v => info['hook_pre_host'] = v} onChange={v => info['hook_pre_host'] = cleanCommand(v)}
style={{border: '1px solid #e8e8e8'}}/> style={{border: '1px solid #e8e8e8'}}/>
</Form.Item> </Form.Item>
</Col> </Col>
@ -144,7 +145,7 @@ class Ext1Setup3 extends React.Component {
height={full === '2' ? '100vh' : '100px'} height={full === '2' ? '100vh' : '100px'}
placeholder="每行一个例如HOME=/data/spug" placeholder="每行一个例如HOME=/data/spug"
value={info['custom_envs']} value={info['custom_envs']}
onChange={v => info['custom_envs'] = v} onChange={v => info['custom_envs'] = cleanCommand(v)}
style={{border: '1px solid #e8e8e8'}}/> style={{border: '1px solid #e8e8e8'}}/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
@ -158,7 +159,7 @@ class Ext1Setup3 extends React.Component {
height={full === '4' ? '100vh' : '100px'} height={full === '4' ? '100vh' : '100px'}
placeholder="输入要执行的命令" placeholder="输入要执行的命令"
value={info['hook_post_server']} value={info['hook_post_server']}
onChange={v => info['hook_post_server'] = v} onChange={v => info['hook_post_server'] = cleanCommand(v)}
style={{border: '1px solid #e8e8e8'}}/> style={{border: '1px solid #e8e8e8'}}/>
</Form.Item> </Form.Item>
<Form.Item <Form.Item
@ -172,7 +173,7 @@ class Ext1Setup3 extends React.Component {
height={full === '6' ? '100vh' : '100px'} height={full === '6' ? '100vh' : '100px'}
placeholder="输入要执行的命令" placeholder="输入要执行的命令"
value={info['hook_post_host']} value={info['hook_post_host']}
onChange={v => info['hook_post_host'] = v} onChange={v => info['hook_post_host'] = cleanCommand(v)}
style={{border: '1px solid #e8e8e8'}}/> style={{border: '1px solid #e8e8e8'}}/>
</Form.Item> </Form.Item>
</Col> </Col>

View File

@ -10,7 +10,7 @@ import Editor from 'react-ace';
import 'ace-builds/src-noconflict/mode-sh'; import 'ace-builds/src-noconflict/mode-sh';
import 'ace-builds/src-noconflict/theme-tomorrow'; import 'ace-builds/src-noconflict/theme-tomorrow';
import styles from './index.module.css'; import styles from './index.module.css';
import http from 'libs/http'; import { http, cleanCommand } from 'libs';
import store from './store'; import store from './store';
@observer @observer
@ -51,7 +51,8 @@ class Ext2Setup3 extends React.Component {
style={{margin: '0 80px 20px'}} style={{margin: '0 80px 20px'}}
description={[ description={[
<p key={1}>Spug 将遵循先本地后目标主机的原则按照顺序依次执行添加的动作例如本地动作1 -> 本地动作2 -> 目标主机动作1 -> 目标主机动作2 ...</p>, <p key={1}>Spug 将遵循先本地后目标主机的原则按照顺序依次执行添加的动作例如本地动作1 -> 本地动作2 -> 目标主机动作1 -> 目标主机动作2 ...</p>,
<p key={2}>执行的命令内可以使用发布申请中设置的环境变量 SPUG_RELEASE一般可用于标记一次发布的版本号或提交ID等在执行的脚本内通过使用 $SPUG_RELEASE 获取其值来执行相应操作</p> <p key={2}>执行的命令内可以使用发布申请中设置的环境变量 SPUG_RELEASE一般可用于标记一次发布的版本号或提交ID等在执行的脚本内通过使用 $SPUG_RELEASE
获取其值来执行相应操作</p>
]}/> ]}/>
)} )}
{server_actions.map((item, index) => ( {server_actions.map((item, index) => (
@ -67,7 +68,7 @@ class Ext2Setup3 extends React.Component {
width="100%" width="100%"
height="100px" height="100px"
value={item['data']} value={item['data']}
onChange={v => item['data'] = v} onChange={v => item['data'] = cleanCommand(v)}
placeholder="请输入要执行的动作"/> placeholder="请输入要执行的动作"/>
</Form.Item> </Form.Item>
<div className={styles.delAction} onClick={() => server_actions.splice(index, 1)}> <div className={styles.delAction} onClick={() => server_actions.splice(index, 1)}>
@ -94,7 +95,7 @@ class Ext2Setup3 extends React.Component {
width="100%" width="100%"
height="100px" height="100px"
value={item['data']} value={item['data']}
onChange={v => item['data'] = v} onChange={v => item['data'] = cleanCommand(v)}
placeholder="请输入要执行的动作"/> placeholder="请输入要执行的动作"/>
</Form.Item> </Form.Item>
<div className={styles.delAction} onClick={() => host_actions.splice(index, 1)}> <div className={styles.delAction} onClick={() => host_actions.splice(index, 1)}>

View File

@ -10,8 +10,8 @@ import { ACEditor, AuthCard } from 'components';
import HostSelector from './HostSelector'; import HostSelector from './HostSelector';
import TemplateSelector from './TemplateSelector'; import TemplateSelector from './TemplateSelector';
import ExecConsole from './ExecConsole'; import ExecConsole from './ExecConsole';
import { http, cleanCommand } from 'libs';
import store from './store'; import store from './store';
import http from 'libs/http';
@observer @observer
class TaskIndex extends React.Component { class TaskIndex extends React.Component {
@ -26,7 +26,7 @@ class TaskIndex extends React.Component {
handleSubmit = () => { handleSubmit = () => {
this.setState({loading: true}); this.setState({loading: true});
const host_ids = store.hosts.map(item => item.id); const host_ids = store.hosts.map(item => item.id);
http.post('/api/exec/do/', {host_ids, command: this.state.body}) http.post('/api/exec/do/', {host_ids, command: cleanCommand(this.state.body)})
.then(store.switchConsole) .then(store.switchConsole)
.finally(() => this.setState({loading: false})) .finally(() => this.setState({loading: false}))
}; };

View File

@ -7,7 +7,7 @@ import React from 'react';
import { observer } from 'mobx-react'; import { observer } from 'mobx-react';
import { Modal, Form, Input, Select, Col, Button, message } from 'antd'; import { Modal, Form, Input, Select, Col, Button, message } from 'antd';
import { ACEditor } from 'components'; import { ACEditor } from 'components';
import http from 'libs/http'; import { http, cleanCommand } from 'libs';
import store from './store'; import store from './store';
@observer @observer
@ -25,7 +25,7 @@ class ComForm extends React.Component {
this.setState({loading: true}); this.setState({loading: true});
const formData = this.props.form.getFieldsValue(); const formData = this.props.form.getFieldsValue();
formData['id'] = store.record.id; formData['id'] = store.record.id;
formData['body'] = this.state.body; formData['body'] = cleanCommand(this.state.body);
http.post('/api/exec/template/', formData) http.post('/api/exec/template/', formData)
.then(res => { .then(res => {
message.success('操作成功'); message.success('操作成功');

View File

@ -8,7 +8,7 @@ import { observer } from 'mobx-react';
import { Modal, Form, Input, Select, Radio, message, Steps, Button, Transfer, Checkbox } from 'antd'; import { Modal, Form, Input, Select, Radio, message, Steps, Button, Transfer, Checkbox } from 'antd';
import TemplateSelector from '../exec/task/TemplateSelector'; import TemplateSelector from '../exec/task/TemplateSelector';
import { LinkButton, ACEditor } from 'components'; import { LinkButton, ACEditor } from 'components';
import http from 'libs/http'; import { http, cleanCommand } from 'libs';
import store from './store'; import store from './store';
import hostStore from '../host/store'; import hostStore from '../host/store';
import groupStore from '../alarm/group/store'; import groupStore from '../alarm/group/store';
@ -158,7 +158,7 @@ class ComForm extends React.Component {
</Form.Item> </Form.Item>
<Form.Item required label="脚本内容" style={this.getStyle('4')} <Form.Item required label="脚本内容" style={this.getStyle('4')}
extra={<LinkButton onClick={() => this.setState({showTmp: true})}>从模板添加</LinkButton>}> extra={<LinkButton onClick={() => this.setState({showTmp: true})}>从模板添加</LinkButton>}>
<ACEditor mode="sh" value={extra['4']} height="200px" onChange={e => this.handleExtra('4', e)}/> <ACEditor mode="sh" value={extra['4']} height="200px" onChange={e => this.handleExtra('4', cleanCommand(e))}/>
</Form.Item> </Form.Item>
<Form.Item label="备注信息"> <Form.Item label="备注信息">
{getFieldDecorator('desc', {initialValue: info['desc']})( {getFieldDecorator('desc', {initialValue: info['desc']})(

View File

@ -8,7 +8,7 @@ import { observer } from 'mobx-react';
import { Modal, Form, Input, Select, Col, Button, Steps, Tabs, InputNumber, DatePicker, Icon, message } from 'antd'; import { Modal, Form, Input, Select, Col, Button, Steps, Tabs, InputNumber, DatePicker, Icon, message } from 'antd';
import { LinkButton, ACEditor } from 'components'; import { LinkButton, ACEditor } from 'components';
import TemplateSelector from '../exec/task/TemplateSelector'; import TemplateSelector from '../exec/task/TemplateSelector';
import http from 'libs/http'; import { http, cleanCommand } from 'libs';
import store from './store'; import store from './store';
import hostStore from '../host/store'; import hostStore from '../host/store';
import styles from './index.module.css'; import styles from './index.module.css';
@ -51,7 +51,7 @@ class ComForm extends React.Component {
} }
this.setState({loading: true}); this.setState({loading: true});
formData['id'] = store.record.id; formData['id'] = store.record.id;
formData['command'] = this.state.command; formData['command'] = cleanCommand(this.state.command);
formData['targets'] = store.targets.filter(x => x); formData['targets'] = store.targets.filter(x => x);
formData['trigger_args'] = this._parse_args(formData['trigger']); formData['trigger_args'] = this._parse_args(formData['trigger']);
http.post('/api/schedule/', formData) http.post('/api/schedule/', formData)