Commit 5137a280 authored by George Goldberg's avatar George Goldberg Committed by Christopher Speller
Browse files

PLT-6474 Basic Elasticsearch System Console Page (#6825)

* PLT-6474: Basic System Console Elasticsearch Config.

* Fix review comments.

* More review fixes.

* Review comments.
parent a21c5f14
......@@ -383,3 +383,16 @@ export function getPostsPerDayAnalytics(teamId) {
export function getUsersPerDayAnalytics(teamId) {
AdminActions.getUsersPerDayAnalytics(teamId)(dispatch, getState);
}
export function elasticsearchTest(config, success, error) {
AdminActions.testElasticsearch(config)(dispatch, getState).then(
(data) => {
if (data && success) {
success(data);
} else if (data == null && error) {
const serverError = getState().requests.admin.testElasticsearch.error;
error({id: serverError.server_error_id, ...serverError});
}
}
);
}
......@@ -258,6 +258,21 @@ export default class AdminSidebar extends React.Component {
/>
);
let elasticSearchSettings = null;
if (window.mm_license.IsLicensed === 'true') {
elasticSearchSettings = (
<AdminSidebarSection
name='elasticsearch'
title={
<FormattedMessage
id='admin.sidebar.elasticsearch'
defaultMessage='Elasticsearch'
/>
}
/>
);
}
return (
<div className='admin-sidebar'>
<AdminSidebarHeader/>
......@@ -618,6 +633,7 @@ export default class AdminSidebar extends React.Component {
/>
}
/>
{elasticSearchSettings}
<AdminSidebarSection
name='developer'
title={
......
// Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved.
// See License.txt for license information.
import React from 'react';
import * as Utils from 'utils/utils.jsx';
import AdminSettings from './admin_settings.jsx';
import {elasticsearchTest} from 'actions/admin_actions.jsx';
import BooleanSetting from './boolean_setting.jsx';
import {FormattedMessage} from 'react-intl';
import SettingsGroup from './settings_group.jsx';
import TextSetting from './text_setting.jsx';
import RequestButton from './request_button/request_button.jsx';
export default class ElasticsearchSettings extends AdminSettings {
constructor(props) {
super(props);
this.getConfigFromState = this.getConfigFromState.bind(this);
this.doTestConfig = this.doTestConfig.bind(this);
this.handleChange = this.handleChange.bind(this);
this.renderSettings = this.renderSettings.bind(this);
}
getConfigFromState(config) {
config.ElasticSearchSettings.ConnectionUrl = this.state.connectionUrl;
config.ElasticSearchSettings.Username = this.state.username;
config.ElasticSearchSettings.Password = this.state.password;
config.ElasticSearchSettings.Sniff = this.state.sniff;
config.ElasticSearchSettings.EnableIndexing = this.state.enableIndexing;
config.ElasticSearchSettings.EnableSearching = this.state.enableSearching;
return config;
}
getStateFromConfig(config) {
return {
connectionUrl: config.ElasticSearchSettings.ConnectionUrl,
username: config.ElasticSearchSettings.Username,
password: config.ElasticSearchSettings.Password,
sniff: config.ElasticSearchSettings.Sniff,
enableIndexing: config.ElasticSearchSettings.EnableIndexing,
enableSearching: config.ElasticSearchSettings.EnableSearching,
configTested: true,
canSave: true
};
}
handleChange(id, value) {
if (id === 'enableIndexing') {
if (value === false) {
this.setState({
enableSearching: false
});
} else {
this.setState({
canSave: false,
configTested: false
});
}
}
if (id === 'connectionUrl' || id === 'username' || id === 'password' || id === 'sniff') {
this.setState({
configTested: false,
canSave: false
});
}
super.handleChange(id, value);
}
canSave() {
return this.state.canSave;
}
doTestConfig(success, error) {
const config = JSON.parse(JSON.stringify(this.props.config));
this.getConfigFromState(config);
elasticsearchTest(
config,
() => {
this.setState({
configTested: true,
canSave: true
});
success();
},
(err) => {
this.setState({
configTested: false,
canSave: false
});
error(err);
}
);
}
renderTitle() {
return (
<FormattedMessage
id='admin.elasticsearch.title'
defaultMessage='Elasticsearch Settings'
/>
);
}
renderSettings() {
return (
<SettingsGroup>
<div className='banner'>
<div className='banner__content'>
<FormattedMessage
id='admin.elasticsearch.noteDescription'
defaultMessage='Changing properties in this section will require a server restart before taking effect.'
/>
</div>
</div>
<BooleanSetting
id='enableIndexing'
label={
<FormattedMessage
id='admin.elasticsearch.enableIndexingTitle'
defaultMessage='Enable Elasticsearch Indexing:'
/>
}
helpText={
<FormattedMessage
id='admin.elasticsearch.enableIndexingDescription'
defaultMessage='When true, indexing of new posts occurs automatically. Search queries will use database search until "Enable Elasticsearch for search queries" is enabled. {documentationLink}'
values={{
documentationLink: (
<a
href='http://www.mattermost.com'
rel='noopener noreferrer'
target='_blank'
>
<FormattedMessage
id='admin.elasticsearch.enableIndexingDescription.documentationLinkText'
defaultMessage='Learn more about Elasticsearch in our documentation.'
/>
</a>
)
}}
/>
}
value={this.state.enableIndexing}
onChange={this.handleChange}
/>
<TextSetting
id='connectionUrl'
label={
<FormattedMessage
id='admin.elasticsearch.connectionUrlTitle'
defaultMessage='Server Connection Address:'
/>
}
placeholder={Utils.localizeMessage('admin.elasticsearch.connectionUrlExample', 'E.g.: "https://elasticsearch.example.org:9200"')}
helpText={
<FormattedMessage
id='admin.elasticsearch.connectionUrlDescription'
defaultMessage='The address of the Elasticsearch server. {documentationLink}'
values={{
documentationLink: (
<a
href='http://www.mattermost.com'
rel='noopener noreferrer'
target='_blank'
>
<FormattedMessage
id='admin.elasticsearch.connectionUrlExample.documentationLinkText'
defaultMessage='Please see documentation with server setup instructions.'
/>
</a>
)
}}
/>
}
value={this.state.connectionUrl}
disabled={!this.state.enableIndexing}
onChange={this.handleChange}
/>
<TextSetting
id='username'
label={
<FormattedMessage
id='admin.elasticsearch.usernameTitle'
defaultMessage='Server Username:'
/>
}
placeholder={Utils.localizeMessage('admin.elasticsearch.usernameExample', 'E.g.: "elastic"')}
helpText={
<FormattedMessage
id='admin.elasticsearch.usernameDescription'
defaultMessage='(Optional) The username to authenticate to the Elasticsearch server.'
/>
}
value={this.state.username}
disabled={!this.state.enableIndexing}
onChange={this.handleChange}
/>
<TextSetting
id='password'
label={
<FormattedMessage
id='admin.elasticsearch.passwordTitle'
defaultMessage='Server Password:'
/>
}
placeholder={Utils.localizeMessage('admin.elasticsearch.password', 'E.g.: "yourpassword"')}
helpText={
<FormattedMessage
id='admin.elasticsearch.passwordDescription'
defaultMessage='(Optional) The password to authenticate to the Elasticsearch server.'
/>
}
value={this.state.password}
disabled={!this.state.enableIndexing}
onChange={this.handleChange}
/>
<BooleanSetting
id='sniff'
label={
<FormattedMessage
id='admin.elasticsearch.sniffTitle'
defaultMessage='Enable Cluster Sniffing:'
/>
}
helpText={
<FormattedMessage
id='admin.elasticsearch.sniffDescription'
defaultMessage='When true, sniffing finds and connects to all data nodes in your cluster automatically.'
/>
}
value={this.state.sniff}
disabled={!this.state.enableIndexing}
onChange={this.handleChange}
/>
<RequestButton
requestAction={this.doTestConfig}
helpText={
<FormattedMessage
id='admin.elasticsearch.testHelpText'
defaultMessage='Tests if the Mattermost server can connect to the Elasticsearch server specified. Testing the connection does not save the configuration. See log file for more detailed error messages.'
/>
}
buttonText={
<FormattedMessage
id='admin.elasticsearch.elasticsearch_test_button'
defaultMessage='Test Connection'
/>
}
disabled={!this.state.enableIndexing}
/>
<BooleanSetting
id='enableSearching'
label={
<FormattedMessage
id='admin.elasticsearch.enableSearchingTitle'
defaultMessage='Enable Elasticsearch for search queries:'
/>
}
helpText={
<FormattedMessage
id='admin.elasticsearch.enableSearchingDescription'
defaultMessage='Requires a successful connection to the Elasticsearch server. When true, Elasticsearch will be used for all search queries using the latest index. Search results may be incomplete until a bulk index of the existing post database is finished. When false, database search is used.'
/>
}
value={this.state.enableSearching}
disabled={!this.state.enableIndexing || !this.state.configTested}
onChange={this.handleChange}
/>
</SettingsGroup>
);
}
}
......@@ -235,6 +235,27 @@
"admin.customization.support": "Legal and Support",
"admin.database.title": "Database Settings",
"admin.developer.title": "Developer Settings",
"admin.elasticsearch.title": "Elasticsearch Settings",
"admin.elasticsearch.noteDescription": "Changing properties in this section will require a server restart before taking effect.",
"admin.elasticsearch.enableIndexingTitle": "Enable Elasticsearch Indexing:",
"admin.elasticsearch.enableIndexingDescription": "When true, indexing of new posts occurs automatically. Search queries will use database search until \"Enable Elasticsearch for search queries\" is enabled. {documentationLink}",
"admin.elasticsearch.enableIndexingDescription.documentationLinkText": "Learn more about Elasticsearch in our documentation.",
"admin.elasticsearch.connectionUrlTitle": "Server Connection Address:",
"admin.elasticsearch.connectionUrlDescription": "The address of the Elasticsearch server. {documentationLink}",
"admin.elasticsearch.connectionUrlExample.documentationLinkText": "Please see documentation with server setup instructions.",
"admin.elasticsearch.usernameTitle": "Server Username:",
"admin.elasticsearch.usernameDescription": "(Optional) The username to authenticate to the Elasticsearch server.",
"admin.elasticsearch.passwordTitle": "Server Password:",
"admin.elasticsearch.passwordDescription": "(Optional) The password to authenticate to the Elasticsearch server.",
"admin.elasticsearch.sniffTitle": "Enable Cluster Sniffing:",
"admin.elasticsearch.sniffDescription": "When true, sniffing finds and connects to all data nodes in your cluster automatically.",
"admin.elasticsearch.enableSearchingTitle": "Enable Elasticsearch for search queries:",
"admin.elasticsearch.enableSearchingDescription": "Requires a successful connection to the Elasticsearch server. When true, Elasticsearch will be used for all search queries using the latest index. Search results may be incomplete until a bulk index of the existing post database is finished. When false, database search is used.",
"admin.elasticsearch.connectionUrlExample": "E.g.: \"https://elasticsearch.example.org:9200\"",
"admin.elasticsearch.usernameExample": "E.g.: \"elastic\"",
"admin.elasticsearch.password": "E.g.: \"yourpassword\"",
"admin.elasticsearch.testHelpText": "Tests if the Mattermost server can connect to the Elasticsearch server specified. Testing the connection does not save the configuration. See log file for more detailed error messages.",
"admin.elasticsearch.elasticsearch_test_button": "Test Connection",
"admin.email.agreeHPNS": " I understand and accept the Mattermost Hosted Push Notification Service <a href=\"https://about.mattermost.com/hpns-terms/\" target='_blank'>Terms of Service</a> and <a href=\"https://about.mattermost.com/hpns-privacy/\" target='_blank'>Privacy Policy</a>.",
"admin.email.allowEmailSignInDescription": "When true, Mattermost allows users to sign in using their email and password.",
"admin.email.allowEmailSignInTitle": "Enable sign-in with email: ",
......
......@@ -45,6 +45,7 @@ import TeamAnalytics from 'components/analytics/team_analytics';
import LicenseSettings from 'components/admin_console/license_settings.jsx';
import Audits from 'components/admin_console/audits';
import Logs from 'components/admin_console/server_logs';
import ElasticsearchSettings from 'components/admin_console/elasticsearch_settings.jsx';
export default (
<Route>
......@@ -199,6 +200,10 @@ export default (
path='database'
component={DatabaseSettings}
/>
<Route
path='elasticsearch'
component={ElasticsearchSettings}
/>
<Route
path='developer'
component={DeveloperSettings}
......
......@@ -5047,7 +5047,7 @@ math-expression-evaluator@^1.2.14:
mattermost-redux@mattermost/mattermost-redux#webapp-master:
version "0.0.1"
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/dd48556075c8be41aa5ac4a0165bbe830d496875"
resolved "https://codeload.github.com/mattermost/mattermost-redux/tar.gz/a850fc2696c7083a068f7852c1d4b8bce0ec72ba"
dependencies:
deep-equal "1.0.1"
harmony-reflect "1.5.1"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment