Merge pull request #758 from influxdata/unsafe-ssl

Unsafe ssl
pull/10616/head
Chris Goller 2017-01-12 17:08:12 -06:00 committed by GitHub
commit 5e78dda63d
6 changed files with 152 additions and 95 deletions

View File

@ -12,7 +12,7 @@ import {Login} from 'src/auth';
import {KapacitorPage, KapacitorRulePage, KapacitorRulesPage, KapacitorTasksPage} from 'src/kapacitor';
import DataExplorer from 'src/data_explorer';
import {DashboardsPage} from 'src/dashboards';
import {CreateSource, SourceForm, ManageSources} from 'src/sources';
import {CreateSource, SourcePage, ManageSources} from 'src/sources';
import NotFound from 'src/shared/components/NotFound';
import configureStore from 'src/store/configureStore';
import {getMe, getSources} from 'shared/apis';
@ -95,8 +95,8 @@ const Root = React.createClass({
<Route path="/sources/:sourceID" component={App}>
<Route component={CheckSources}>
<Route path="manage-sources" component={ManageSources} />
<Route path="manage-sources/new" component={SourceForm} />
<Route path="manage-sources/:id/edit" component={SourceForm} />
<Route path="manage-sources/new" component={SourcePage} />
<Route path="manage-sources/:id/edit" component={SourcePage} />
<Route path="chronograf/data-explorer" component={DataExplorer} />
<Route path="chronograf/data-explorer/:base64ExplorerID" component={DataExplorer} />
<Route path="hosts" component={HostsPage} />

View File

@ -1,10 +0,0 @@
{
noData: {
head: `Unable to find a data node!`,
body: `Make sure your cluster is configured correctly by verifying that at least one valid data node is part of your cluster.`,
},
noCluster: {
head: `Unable to communicate with cluster!`,
body: `Make sure your cluster is configured correctly by verifying that at least one valid meta and data node is part of your cluster.`,
},
}

View File

@ -0,0 +1,2 @@
export const insecureSkipVerifyText = `Unsafe SSL controls whether a client verifies the server's certificate chain and host name. \n
If checked, TLS accepts any certificate presented by the server and any host name in that certificate.`;

View File

@ -1,90 +1,40 @@
import React, {PropTypes} from 'react';
import {withRouter} from 'react-router';
import {getSource, createSource, updateSource} from 'shared/apis';
import {
addSource as addSourceAction,
updateSource as updateSourceAction,
} from 'shared/actions/sources';
import classNames from 'classnames';
import {connect} from 'react-redux';
import {insecureSkipVerifyText} from 'src/shared/copy/tooltipText';
const {
bool,
func,
shape,
} = PropTypes;
export const SourceForm = React.createClass({
propTypes: {
params: PropTypes.shape({
id: PropTypes.string,
}),
router: PropTypes.shape({
push: PropTypes.func.isRequired,
}).isRequired,
location: PropTypes.shape({
query: PropTypes.shape({
redirectPath: PropTypes.string,
}).isRequired,
}).isRequired,
addFlashMessage: PropTypes.func.isRequired,
addSourceAction: PropTypes.func,
updateSourceAction: PropTypes.func,
addFlashMessage: func.isRequired,
addSourceAction: func,
updateSourceAction: func,
source: shape({}).isRequired,
editMode: bool.isRequired,
onInputChange: func.isRequired,
onSubmit: func.isRequired,
},
getInitialState() {
return {
source: {},
editMode: this.props.params.id !== undefined,
};
},
componentDidMount() {
if (!this.state.editMode) {
return;
}
getSource(this.props.params.id).then(({data: source}) => {
this.setState({source});
});
},
handleSubmit(e) {
handleSubmitForm(e) {
e.preventDefault();
const {router, params, addFlashMessage} = this.props;
const newSource = Object.assign({}, this.state.source, {
const newSource = Object.assign({}, this.props.source, {
url: this.sourceURL.value.trim(),
name: this.sourceName.value,
username: this.sourceUsername.value,
password: this.sourcePassword.value,
'default': this.sourceDefault.checked,
telegraf: this.sourceTelegraf.value,
insecureSkipVerify: this.sourceInsecureSkipVerify ? this.sourceInsecureSkipVerify.checked : false,
});
if (this.state.editMode) {
updateSource(newSource).then(({data: sourceFromServer}) => {
this.props.updateSourceAction(sourceFromServer);
router.push(`/sources/${params.sourceID}/manage-sources`);
addFlashMessage({type: 'success', text: 'The source was successfully updated'});
}).catch(() => {
addFlashMessage({type: 'error', text: 'There was a problem updating the source. Check the settings'});
});
} else {
createSource(newSource).then(({data: sourceFromServer}) => {
this.props.addSourceAction(sourceFromServer);
router.push(`/sources/${params.sourceID}/manage-sources`);
addFlashMessage({type: 'success', text: 'The source was successfully created'});
}).catch(() => {
addFlashMessage({type: 'error', text: 'There was a problem creating the source. Check the settings'});
});
}
},
onInputChange(e) {
const val = e.target.value;
const name = e.target.name;
this.setState((prevState) => {
const newSource = Object.assign({}, prevState.source, {
[name]: val,
});
return Object.assign({}, prevState, {source: newSource});
});
this.props.onSubmit(newSource);
},
render() {
const {source, editMode} = this.state;
const {source, editMode, onInputChange} = this.props;
if (editMode && !source.id) {
return <div className="page-spinner"></div>;
@ -110,26 +60,26 @@ export const SourceForm = React.createClass({
<h4 className="text-center">Connection Details</h4>
<br/>
<form onSubmit={this.handleSubmit}>
<form onSubmit={this.handleSubmitForm}>
<div className="form-group col-xs-12 col-sm-6">
<label htmlFor="connect-string">Connection String</label>
<input type="text" name="url" ref={(r) => this.sourceURL = r} className="form-control" id="connect-string" placeholder="http://localhost:8086" onChange={this.onInputChange} value={source.url || ''}></input>
<input type="text" name="url" ref={(r) => this.sourceURL = r} className="form-control" id="connect-string" placeholder="http://localhost:8086" onChange={onInputChange} value={source.url || ''}></input>
</div>
<div className="form-group col-xs-12 col-sm-6">
<label htmlFor="name">Name</label>
<input type="text" name="name" ref={(r) => this.sourceName = r} className="form-control" id="name" placeholder="Influx 1" onChange={this.onInputChange} value={source.name || ''}></input>
<input type="text" name="name" ref={(r) => this.sourceName = r} className="form-control" id="name" placeholder="Influx 1" onChange={onInputChange} value={source.name || ''}></input>
</div>
<div className="form-group col-xs-12 col-sm-6">
<label htmlFor="username">Username</label>
<input type="text" name="username" ref={(r) => this.sourceUsername = r} className="form-control" id="username" onChange={this.onInputChange} value={source.username || ''}></input>
<input type="text" name="username" ref={(r) => this.sourceUsername = r} className="form-control" id="username" onChange={onInputChange} value={source.username || ''}></input>
</div>
<div className="form-group col-xs-12 col-sm-6">
<label htmlFor="password">Password</label>
<input type="password" name="password" ref={(r) => this.sourcePassword = r} className="form-control" id="password" onChange={this.onInputChange} value={source.password || ''}></input>
<input type="password" name="password" ref={(r) => this.sourcePassword = r} className="form-control" id="password" onChange={onInputChange} value={source.password || ''}></input>
</div>
<div className="form-group col-xs-12">
<label htmlFor="telegraf">Telegraf database</label>
<input type="text" name="telegraf" ref={(r) => this.sourceTelegraf = r} className="form-control" id="telegraf" onChange={this.onInputChange} value={source.telegraf || 'telegraf'}></input>
<input type="text" name="telegraf" ref={(r) => this.sourceTelegraf = r} className="form-control" id="telegraf" onChange={onInputChange} value={source.telegraf || 'telegraf'}></input>
</div>
<div className="form-group col-xs-12">
<div className="form-control-static">
@ -137,6 +87,14 @@ export const SourceForm = React.createClass({
<label htmlFor="defaultSourceCheckbox">Make this the default source</label>
</div>
</div>
{source.url.startsWith("https") ?
<div className="form-group col-xs-12">
<div className="form-control-static">
<input type="checkbox" id="insecureSkipVerifyCheckbox" defaultChecked={source.insecureSkipVerify} ref={(r) => this.sourceInsecureSkipVerify = r} />
<label htmlFor="insecureSkipVerifyCheckbox">Unsafe SSL</label>
</div>
<label className="form-helper">{insecureSkipVerifyText}</label>
</div> : null}
<div className="form-group form-group-submit col-xs-12 col-sm-6 col-sm-offset-3">
<button className={classNames('btn btn-block', {'btn-primary': editMode, 'btn-success': !editMode})} type="submit">{editMode ? "Save Changes" : "Add Source"}</button>
</div>
@ -152,8 +110,4 @@ export const SourceForm = React.createClass({
},
});
function mapStateToProps(_) {
return {};
}
export default connect(mapStateToProps, {addSourceAction, updateSourceAction})(withRouter(SourceForm));
export default SourceForm;

View File

@ -0,0 +1,111 @@
import React, {PropTypes} from 'react';
import {withRouter} from 'react-router';
import {getSource} from 'shared/apis';
import {createSource, updateSource} from 'shared/apis';
import {
addSource as addSourceAction,
updateSource as updateSourceAction,
} from 'shared/actions/sources';
import {connect} from 'react-redux';
import SourceForm from 'src/sources/components/SourceForm';
const {
func,
shape,
string,
} = PropTypes;
export const SourcePage = React.createClass({
propTypes: {
params: shape({
id: string,
sourceID: string,
}),
router: shape({
push: func.isRequired,
}).isRequired,
location: shape({
query: shape({
redirectPath: string,
}).isRequired,
}).isRequired,
addFlashMessage: func.isRequired,
addSourceAction: func,
updateSourceAction: func,
},
getInitialState() {
return {
source: {},
editMode: this.props.params.id !== undefined,
};
},
componentDidMount() {
if (!this.state.editMode) {
return;
}
getSource(this.props.params.id).then(({data: source}) => {
this.setState({source});
});
},
handleInputChange(e) {
const val = e.target.value;
const name = e.target.name;
this.setState((prevState) => {
const newSource = Object.assign({}, prevState.source, {
[name]: val,
});
return Object.assign({}, prevState, {source: newSource});
});
},
handleSubmit(newSource) {
const {router, params, addFlashMessage} = this.props;
if (this.state.editMode) {
updateSource(newSource).then(({data: sourceFromServer}) => {
this.props.updateSourceAction(sourceFromServer);
router.push(`/sources/${params.sourceID}/manage-sources`);
addFlashMessage({type: 'success', text: 'The source was successfully updated'});
}).catch(() => {
addFlashMessage({type: 'error', text: 'There was a problem updating the source. Check the settings'});
});
} else {
createSource(newSource).then(({data: sourceFromServer}) => {
this.props.addSourceAction(sourceFromServer);
router.push(`/sources/${params.sourceID}/manage-sources`);
addFlashMessage({type: 'success', text: 'The source was successfully created'});
}).catch(() => {
addFlashMessage({type: 'error', text: 'There was a problem creating the source. Check the settings'});
});
}
},
render() {
const {source, editMode} = this.state;
const {addFlashMessage, router, location, params} = this.props;
return (
<SourceForm
sourceID={params.sourceID}
router={router}
location={location}
source={source}
editMode={editMode}
addFlashMessage={addFlashMessage}
addSourceAction={addSourceAction}
updateSourceAction={updateSourceAction}
onInputChange={this.handleInputChange}
onSubmit={this.handleSubmit}
/>
);
},
});
function mapStateToProps(_) {
return {};
}
export default connect(mapStateToProps, {addSourceAction, updateSourceAction})(withRouter(SourcePage));

View File

@ -1,4 +1,4 @@
import CreateSource from './containers/CreateSource';
import SourceForm from './containers/SourceForm';
import SourcePage from './containers/SourcePage';
import ManageSources from './containers/ManageSources';
export {CreateSource, SourceForm, ManageSources};
export {CreateSource, SourcePage, ManageSources};