Provide better feedback on unhappy paths for Kapacitor configuration

pull/546/head
Will Piers 2016-11-14 14:23:13 -08:00
parent 485bd4f637
commit dc5f41b5e7
3 changed files with 52 additions and 26 deletions

View File

@ -16,6 +16,7 @@ const AlertOutputs = React.createClass({
id: PropTypes.string.isRequired,
}).isRequired,
kapacitor: PropTypes.shape({
url: PropTypes.string.isRequired,
links: PropTypes.shape({
proxy: PropTypes.string.isRequired,
}).isRequired,
@ -31,14 +32,21 @@ const AlertOutputs = React.createClass({
},
componentDidMount() {
this.refreshKapacitorConfig();
this.refreshKapacitorConfig(this.props.kapacitor);
},
refreshKapacitorConfig() {
getKapacitorConfig(this.props.kapacitor).then(({data: {sections}}) => {
componentWillReceiveProps(nextProps) {
if (this.props.kapacitor.url !== nextProps.kapacitor.url) {
this.refreshKapacitorConfig(nextProps.kapacitor);
}
},
refreshKapacitorConfig(kapacitor) {
getKapacitorConfig(kapacitor).then(({data: {sections}}) => {
this.setState({configSections: sections});
}).catch(() => {
this.props.addFlashMessage({type: 'error', text: `There was an error getting the kapacitor config`});
this.setState({configSections: null});
this.props.addFlashMessage({type: 'error', text: `There was an error getting the Kapacitor config`});
});
},
@ -50,7 +58,7 @@ const AlertOutputs = React.createClass({
if (section !== '') {
const propsToSend = this.sanitizeProperties(section, properties);
updateKapacitorConfigSection(this.props.kapacitor, section, propsToSend).then(() => {
this.refreshKapacitorConfig();
this.refreshKapacitorConfig(this.props.kapacitor);
this.props.addFlashMessage({type: 'success', text: `Alert for ${section} successfully saved`});
}).catch(() => {
this.props.addFlashMessage({type: 'error', text: `There was an error saving the kapacitor config`});
@ -87,6 +95,11 @@ const AlertOutputs = React.createClass({
},
render() {
const {configSections, selectedEndpoint} = this.state;
if (!configSections) { // could use this state to conditionally render spinner or error message
return null;
}
return (
<div className="panel-body">
<h4 className="text-center">Alert Endpoints</h4>
@ -107,7 +120,7 @@ const AlertOutputs = React.createClass({
</div>
</div>
<div className="row">
{this.renderAlertConfig(this.state.selectedEndpoint)}
{this.renderAlertConfig(selectedEndpoint)}
</div>
</div>
</div>
@ -115,6 +128,7 @@ const AlertOutputs = React.createClass({
},
renderAlertConfig(endpoint) {
const {configSections} = this.state;
const save = (properties) => {
this.handleSaveConfig(endpoint, properties);
};
@ -122,11 +136,6 @@ const AlertOutputs = React.createClass({
this.handleTest(endpoint, properties);
};
const {configSections} = this.state;
if (!configSections) { // could use this state to conditionally render spinner or error message
return null;
}
switch (endpoint) {
case 'alerta': {
return <AlertaConfig onSave={save} config={this.getSection(configSections, endpoint)} />;

View File

@ -1,5 +1,5 @@
import React, {PropTypes} from 'react';
import {getKapacitor, createKapacitor, updateKapacitor, pingKapacitor} from 'shared/apis';
import {getKapacitor, getKapacitorConfigSection, createKapacitor, updateKapacitor, pingKapacitor} from 'shared/apis';
import AlertOutputs from '../components/AlertOutputs';
export const KapacitorPage = React.createClass({
@ -35,6 +35,27 @@ export const KapacitorPage = React.createClass({
});
},
componentDidUpdate(prevProps, prevState) {
if (!prevState.kapacitor || !this.state.kapacitor) {
return;
}
if (prevState.kapacitor.url !== this.state.kapacitor.url) {
this.checkKapacitorSetup();
}
},
checkKapacitorSetup() {
const {addFlashMessage, source} = this.props;
getKapacitorConfigSection(this.state.kapacitor, 'influxdb').then(({data: {elements}}) => {
const sourceMatch = elements[0].options.urls.some((url) => url === source.url);
if (!sourceMatch) {
addFlashMessage({type: 'warning', text: `Warning: Kapacitor is configured to use an instance of InfluxDB which does not match the URL of your current source. Please ensure your InfluxDB source and Kapacitor's InfluxDB configuration point to the same server.`});
}
}).catch(() => {
addFlashMessage({type: 'error', text: `Could not connect to Kapacitor. Check connection settings.`});
});
},
handleKapacitorUpdate(e) {
e.preventDefault();
if (this.state.kapacitor) {
@ -45,7 +66,7 @@ export const KapacitorPage = React.createClass({
},
handleCreateKapacitor() {
const {source} = this.props;
const {addFlashMessage, source} = this.props;
const {newURL, newName, newUsername} = this.state;
createKapacitor(source, {
url: newURL.trim(),
@ -53,7 +74,7 @@ export const KapacitorPage = React.createClass({
username: newUsername,
password: this.kapacitorPassword.value,
}).then(({data: createdKapacitor}) => {
this.props.addFlashMessage({type: 'success', text: 'Kapacitor Created!'});
addFlashMessage({type: 'success', text: 'Kapacitor Created!'});
this.setState({kapacitor: createdKapacitor});
}).catch(() => {
this.props.addFlashMessage({type: 'error', text: 'There was a problem creating the Kapacitor record'});
@ -61,7 +82,7 @@ export const KapacitorPage = React.createClass({
},
handleUpdateKapacitor() {
const {addFlashMessage, source} = this.props;
const {addFlashMessage} = this.props;
const {kapacitor, newURL, newName, newUsername} = this.state;
updateKapacitor(kapacitor, {
url: (newURL || kapacitor.url).trim(),
@ -69,16 +90,8 @@ export const KapacitorPage = React.createClass({
username: newUsername || kapacitor.username,
password: this.kapacitorPassword.value,
}).then(({data: newKapacitor}) => {
pingKapacitor(kapacitor).then(({data: {elements}}) => {
this.setState({kapacitor: newKapacitor});
const sourceMatch = elements[0].options.urls.some((url) => url === source.url);
if (!sourceMatch && kapacitor.url !== newKapacitor.url) {
addFlashMessage({type: 'warning', text: `Warning: Kapacitor is configured to use an instance of InfluxDB which does not match the URL of your current source. Please ensure your InfluxDB source and Kapacitor's InfluxDB configuration point to the same server.`});
}
addFlashMessage({type: 'success', text: 'Kapacitor Saved!'});
}).catch(() => {
this.props.addFlashMessage({type: 'error', text: 'Kapacitor Saved, but cannot connect. Check settings.'});
});
addFlashMessage({type: 'success', text: 'Kapacitor Updated!'});
this.setState({kapacitor: newKapacitor});
}).catch(() => {
addFlashMessage({type: 'error', text: 'There was a problem updating the Kapacitor record'});
});

View File

@ -38,7 +38,7 @@ export function deleteSource(source) {
export function pingKapacitor(kapacitor) {
return AJAX({
method: 'GET',
url: `${kapacitor.links.proxy}?path=/kapacitor/v1/config/influxdb`,
url: `${kapacitor.links.proxy}?path=/kapacitor/v1/ping`,
});
}
@ -81,6 +81,10 @@ export function getKapacitorConfig(kapacitor) {
return kapacitorProxy(kapacitor, 'GET', '/kapacitor/v1/config', '');
}
export function getKapacitorConfigSection(kapacitor, section) {
return kapacitorProxy(kapacitor, 'GET', `/kapacitor/v1/config/${section}`, '');
}
export function updateKapacitorConfigSection(kapacitor, section, properties) {
return AJAX({
method: 'POST',