add cluster register page
This commit is contained in:
parent
82a1c63233
commit
3aeef79fe0
|
@ -20,11 +20,9 @@ type APIHandler struct {
|
|||
func (h *APIHandler) HandleCreateClusterAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params){
|
||||
var conf = &model.ClusterConfig{}
|
||||
resBody := map[string] interface{}{
|
||||
"status": true,
|
||||
}
|
||||
err := h.DecodeJSON(req, conf)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
|
@ -34,7 +32,6 @@ func (h *APIHandler) HandleCreateClusterAction(w http.ResponseWriter, req *http.
|
|||
id := util.GetUUID()
|
||||
ir, err := esClient.Index(orm.GetIndexName(model.ClusterConfig{}), "", id, conf)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
|
@ -46,11 +43,9 @@ func (h *APIHandler) HandleCreateClusterAction(w http.ResponseWriter, req *http.
|
|||
func (h *APIHandler) HandleUpdateClusterAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params){
|
||||
var conf = map[string]interface{}{}
|
||||
resBody := map[string] interface{}{
|
||||
"status": true,
|
||||
}
|
||||
err := h.DecodeJSON(req, conf)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
|
@ -60,7 +55,6 @@ func (h *APIHandler) HandleUpdateClusterAction(w http.ResponseWriter, req *http.
|
|||
indexName := orm.GetIndexName(model.ClusterConfig{})
|
||||
originConf, err := esClient.Get(indexName, "", id)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
|
@ -74,36 +68,33 @@ func (h *APIHandler) HandleUpdateClusterAction(w http.ResponseWriter, req *http.
|
|||
}
|
||||
ir, err := esClient.Index(indexName, "", id, source)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
resBody["acknowledged"] = true
|
||||
resBody["payload"] = ir
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *APIHandler) HandleDeleteClusterAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params){
|
||||
resBody := map[string] interface{}{
|
||||
"status": true,
|
||||
}
|
||||
id := ps.ByName("id")
|
||||
esClient := elastic.GetClient(h.Config.Elasticsearch)
|
||||
_, err := esClient.Delete(orm.GetIndexName(model.ClusterConfig{}), "", id)
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
resBody["payload"] = true
|
||||
resBody["acknowledged"] = true
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *APIHandler) HandleSearchClusterAction(w http.ResponseWriter, req *http.Request, ps httprouter.Params){
|
||||
resBody := map[string] interface{}{
|
||||
"status": true,
|
||||
}
|
||||
var (
|
||||
name = h.GetParameterOrDefault(req, "name", "")
|
||||
|
@ -123,12 +114,10 @@ func (h *APIHandler) HandleSearchClusterAction(w http.ResponseWriter, req *http.
|
|||
esClient := elastic.GetClient(h.Config.Elasticsearch)
|
||||
res, err := esClient.SearchWithRawQueryDSL(orm.GetIndexName(model.ClusterConfig{}), []byte(queryDSL))
|
||||
if err != nil {
|
||||
resBody["status"] = false
|
||||
resBody["error"] = err
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
return
|
||||
}
|
||||
|
||||
resBody["payload"] = res
|
||||
h.WriteJSON(w, resBody, http.StatusOK)
|
||||
h.WriteJSON(w, res, http.StatusOK)
|
||||
}
|
|
@ -39,6 +39,10 @@ export default [
|
|||
name: 'monitoring',
|
||||
component: './Cluster/ClusterList',
|
||||
}, {
|
||||
path: '/cluster/logging',
|
||||
name: 'logging',
|
||||
component: './Cluster/SearchMonitor',
|
||||
},{
|
||||
path: '/cluster/settings',
|
||||
name: 'settings',
|
||||
component: './Cluster/Settings/Base',
|
||||
|
@ -52,12 +56,7 @@ export default [
|
|||
component: './Cluster/Settings/Repository',
|
||||
}
|
||||
]
|
||||
}, {
|
||||
path: '/cluster/logging',
|
||||
name: 'logging',
|
||||
component: './Cluster/SearchMonitor',
|
||||
},
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
|
@ -89,11 +88,11 @@ export default [
|
|||
{
|
||||
path: '/data/overview',
|
||||
name: 'overview',
|
||||
component: './DataManagement/Indices',
|
||||
component: './DataManagement/IndexSummary',
|
||||
}, {
|
||||
path: '/data/index',
|
||||
name: 'index',
|
||||
component: './DataManagement/Indices',
|
||||
component: './DataManagement/Index',
|
||||
},{
|
||||
path: '/data/document',
|
||||
name: 'document',
|
||||
|
@ -101,18 +100,12 @@ export default [
|
|||
}, {
|
||||
path: '/data/template',
|
||||
name: 'template',
|
||||
component: './DataManagement/Indices',
|
||||
component: './DataManagement/IndexTemplate',
|
||||
},
|
||||
// {
|
||||
// path: '/data/rebuild/new',
|
||||
// name: 'rebuild',
|
||||
// component: './DataManagement/Rebuild',
|
||||
// hideInMenu: true,
|
||||
// },
|
||||
{
|
||||
path: '/data/lifecycle',
|
||||
name: 'lifecycle',
|
||||
component: './DataManagement/Indices',
|
||||
component: './DataManagement/IndexLifeCycle',
|
||||
},
|
||||
]
|
||||
},
|
||||
|
@ -249,7 +242,7 @@ export default [
|
|||
routes: [
|
||||
{
|
||||
path: '/sync/pipeline',
|
||||
redirect: '/sync/pipeline',
|
||||
redirect: '/sync/pipeline/logstash',
|
||||
},
|
||||
{
|
||||
path: '/sync/pipeline/ingestpipeline',
|
||||
|
@ -262,6 +255,11 @@ export default [
|
|||
path: '/sync/rebuild',
|
||||
name: 'rebuild',
|
||||
component: './Synchronize/RebuildList',
|
||||
},
|
||||
{
|
||||
path: '/sync/rebuild/new',
|
||||
component: './Synchronize/Rebuild',
|
||||
hideInMenu: true,
|
||||
},{
|
||||
path: '/sync/inout',
|
||||
name: 'inout',
|
||||
|
@ -302,7 +300,13 @@ export default [
|
|||
{
|
||||
path: '/system/cluster',
|
||||
name: 'cluster',
|
||||
component: './System/Settings/Base',
|
||||
component: './System/Cluster/Index',
|
||||
},
|
||||
{
|
||||
path: '/system/cluster/new',
|
||||
name: 'new-cluster',
|
||||
component: './System/Cluster/Form',
|
||||
hideInMenu: true
|
||||
},
|
||||
{
|
||||
path: '/system/settings',
|
||||
|
|
|
@ -93,7 +93,7 @@ export default {
|
|||
'menu.home': '首页',
|
||||
|
||||
'menu.cluster': '集群管理',
|
||||
'menu.cluster.overview': '集群概览',
|
||||
'menu.cluster.overview': '概览',
|
||||
'menu.cluster.monitoring': '集群监控',
|
||||
'menu.cluster.settings': '集群设置',
|
||||
'menu.cluster.logging': '集群日志',
|
||||
|
@ -103,8 +103,8 @@ export default {
|
|||
'menu.data.overview': '概览',
|
||||
'menu.data.index': '索引管理',
|
||||
'menu.data.document': '文档管理',
|
||||
'menu.data.template': '索引模版管理',
|
||||
'menu.data.lifecycle': '索引生命周期管理',
|
||||
'menu.data.template': '模版管理',
|
||||
'menu.data.lifecycle': '周期管理',
|
||||
|
||||
'menu.search': '搜索管理',
|
||||
'menu.search.overview': '概览',
|
||||
|
|
|
@ -153,7 +153,7 @@ class RebuildList extends React.Component {
|
|||
<Divider style={{marginBottom:0}} />
|
||||
<Card
|
||||
bodyStyle={{padding:0}}
|
||||
extra={<div><Button onClick={this.handleRefreshClick} icon="redo">Refresh</Button><Link to="/data/rebuild/new"> <Button type="primary" icon="plus">New</Button></Link></div>}
|
||||
extra={<div><Button onClick={this.handleRefreshClick} icon="redo">Refresh</Button><Link to="/sync/rebuild/new"> <Button type="primary" icon="plus">New</Button></Link></div>}
|
||||
bordered={false}>
|
||||
<Table columns={this.columns}
|
||||
loading={rebuildlist.isLoading}
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
import React from 'react';
|
||||
import {Card, Form, Icon, Input, InputNumber, Button, Switch} from 'antd';
|
||||
|
||||
@Form.create()
|
||||
class ClusterForm extends React.Component{
|
||||
state = {
|
||||
confirmDirty: false,
|
||||
}
|
||||
compareToFirstPassword = (rule, value, callback) => {
|
||||
const { form } = this.props;
|
||||
if (value && value !== form.getFieldValue('password')) {
|
||||
callback('Two passwords that you enter is inconsistent!');
|
||||
} else {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
|
||||
validateToNextPassword = (rule, value, callback) => {
|
||||
const { form } = this.props;
|
||||
if (value && this.state.confirmDirty) {
|
||||
form.validateFields(['confirm'], { force: true });
|
||||
}
|
||||
callback();
|
||||
};
|
||||
render() {
|
||||
const {getFieldDecorator} = this.props.form;
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 6 },
|
||||
},
|
||||
wrapperCol: {
|
||||
xs: { span: 24 },
|
||||
sm: { span: 16 },
|
||||
},
|
||||
};
|
||||
const tailFormItemLayout = {
|
||||
wrapperCol: {
|
||||
xs: {
|
||||
span: 24,
|
||||
offset: 0,
|
||||
},
|
||||
sm: {
|
||||
span: 16,
|
||||
offset: 6,
|
||||
},
|
||||
},
|
||||
};
|
||||
return (
|
||||
<Card>
|
||||
<Form {...formItemLayout} onSubmit={this.handleSubmit}>
|
||||
<Form.Item label="集群名称">
|
||||
{getFieldDecorator('name', {
|
||||
rules: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input cluster name!',
|
||||
},
|
||||
],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="集群 URL">
|
||||
{getFieldDecorator('endpoint', {
|
||||
rules: [
|
||||
{
|
||||
type: 'url', //https://github.com/yiminghe/async-validator#type
|
||||
message: 'The input is not valid url!',
|
||||
},
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input cluster name!',
|
||||
},
|
||||
],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="ES 用户名">
|
||||
{getFieldDecorator('username', {
|
||||
rules: [
|
||||
],
|
||||
})(<Input />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="ES 密码" hasFeedback>
|
||||
{getFieldDecorator('password', {
|
||||
rules: [
|
||||
{
|
||||
validator: this.validateToNextPassword,
|
||||
},
|
||||
],
|
||||
})(<Input.Password />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="ES 确认密码" hasFeedback>
|
||||
{getFieldDecorator('confirm', {
|
||||
rules: [
|
||||
{
|
||||
validator: this.compareToFirstPassword,
|
||||
},
|
||||
],
|
||||
})(<Input.Password onBlur={this.handleConfirmBlur} />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="排序权重">
|
||||
{getFieldDecorator('order', {
|
||||
initialValue: 0
|
||||
})(<InputNumber />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="描述">
|
||||
{getFieldDecorator('order', {
|
||||
})(<Input.TextArea />)}
|
||||
</Form.Item>
|
||||
<Form.Item label="是否启用">
|
||||
{getFieldDecorator('enabled', {
|
||||
valuePropName: 'checked',
|
||||
initialValue: true
|
||||
})(<Switch
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
/>)}
|
||||
</Form.Item>
|
||||
<Form.Item {...tailFormItemLayout}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
Register
|
||||
</Button>
|
||||
</Form.Item>
|
||||
</Form>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default ClusterForm;
|
|
@ -0,0 +1,87 @@
|
|||
import React from 'react';
|
||||
import {Button, Card, Col, Divider, Form, Input, Row, Table,Switch, Icon} from "antd";
|
||||
import Link from "_umi@2.13.16@umi/link";
|
||||
|
||||
@Form.create()
|
||||
class Index extends React.Component {
|
||||
columns = [{
|
||||
title: '集群名称',
|
||||
dataIndex: 'name',
|
||||
key: 'name',
|
||||
},{
|
||||
title: '集群访问URL',
|
||||
dataIndex: 'endpoint',
|
||||
key: 'endpoint',
|
||||
},{
|
||||
title: '用户名',
|
||||
dataIndex: 'username',
|
||||
key: 'username',
|
||||
},{
|
||||
title: '密码',
|
||||
dataIndex: 'password',
|
||||
key: 'password',
|
||||
},{
|
||||
title: '排序权重',
|
||||
dataIndex: 'order',
|
||||
key: 'order',
|
||||
},{
|
||||
title: '描述',
|
||||
dataIndex: 'description',
|
||||
key: 'description',
|
||||
},{
|
||||
title: '是否启用',
|
||||
dataIndex: 'enabled',
|
||||
key: 'enabled',
|
||||
}]
|
||||
|
||||
render() {
|
||||
const {getFieldDecorator} = this.props.form;
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 10 },
|
||||
wrapperCol: { span: 14 },
|
||||
style: {marginBottom: 0}
|
||||
};
|
||||
return (
|
||||
<Card>
|
||||
<Form>
|
||||
<Row gutter={{md:16, sm:8}}>
|
||||
<Col md={8} sm={10}>
|
||||
<Form.Item {...formItemLayout} label="集群名称">
|
||||
{getFieldDecorator('name')(<Input placeholder="please input cluster name" />)}
|
||||
</Form.Item>
|
||||
</Col>
|
||||
<Col md={8} sm={8}>
|
||||
<div style={{paddingTop:4}}>
|
||||
<Button type="primary" icon="search" onClick={this.handleSearch}>
|
||||
Search
|
||||
</Button>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Form>
|
||||
<Divider style={{marginBottom:0}} />
|
||||
<Card
|
||||
bodyStyle={{padding:0}}
|
||||
extra={<div>
|
||||
<span style={{marginRight:24}}><Switch
|
||||
checkedChildren={<Icon type="check" />}
|
||||
unCheckedChildren={<Icon type="close" />}
|
||||
defaultChecked
|
||||
/>是否启用</span>
|
||||
<Link to='/system/cluster/new'> <Button type="primary" icon="plus">New</Button></Link>
|
||||
</div>}
|
||||
bordered={false}>
|
||||
<Table
|
||||
bordered
|
||||
columns={this.columns}
|
||||
dataSource={[]}
|
||||
rowKey='id'
|
||||
/>
|
||||
</Card>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default Index;
|
Loading…
Reference in New Issue