Provide better feedback on unhappy paths for Kapacitor configuration
parent
485bd4f637
commit
dc5f41b5e7
|
@ -16,6 +16,7 @@ const AlertOutputs = React.createClass({
|
||||||
id: PropTypes.string.isRequired,
|
id: PropTypes.string.isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
kapacitor: PropTypes.shape({
|
kapacitor: PropTypes.shape({
|
||||||
|
url: PropTypes.string.isRequired,
|
||||||
links: PropTypes.shape({
|
links: PropTypes.shape({
|
||||||
proxy: PropTypes.string.isRequired,
|
proxy: PropTypes.string.isRequired,
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
|
@ -31,14 +32,21 @@ const AlertOutputs = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.refreshKapacitorConfig();
|
this.refreshKapacitorConfig(this.props.kapacitor);
|
||||||
},
|
},
|
||||||
|
|
||||||
refreshKapacitorConfig() {
|
componentWillReceiveProps(nextProps) {
|
||||||
getKapacitorConfig(this.props.kapacitor).then(({data: {sections}}) => {
|
if (this.props.kapacitor.url !== nextProps.kapacitor.url) {
|
||||||
|
this.refreshKapacitorConfig(nextProps.kapacitor);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
refreshKapacitorConfig(kapacitor) {
|
||||||
|
getKapacitorConfig(kapacitor).then(({data: {sections}}) => {
|
||||||
this.setState({configSections: sections});
|
this.setState({configSections: sections});
|
||||||
}).catch(() => {
|
}).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 !== '') {
|
if (section !== '') {
|
||||||
const propsToSend = this.sanitizeProperties(section, properties);
|
const propsToSend = this.sanitizeProperties(section, properties);
|
||||||
updateKapacitorConfigSection(this.props.kapacitor, section, propsToSend).then(() => {
|
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`});
|
this.props.addFlashMessage({type: 'success', text: `Alert for ${section} successfully saved`});
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.props.addFlashMessage({type: 'error', text: `There was an error saving the kapacitor config`});
|
this.props.addFlashMessage({type: 'error', text: `There was an error saving the kapacitor config`});
|
||||||
|
@ -87,6 +95,11 @@ const AlertOutputs = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const {configSections, selectedEndpoint} = this.state;
|
||||||
|
if (!configSections) { // could use this state to conditionally render spinner or error message
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="panel-body">
|
<div className="panel-body">
|
||||||
<h4 className="text-center">Alert Endpoints</h4>
|
<h4 className="text-center">Alert Endpoints</h4>
|
||||||
|
@ -107,7 +120,7 @@ const AlertOutputs = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{this.renderAlertConfig(this.state.selectedEndpoint)}
|
{this.renderAlertConfig(selectedEndpoint)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -115,6 +128,7 @@ const AlertOutputs = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
renderAlertConfig(endpoint) {
|
renderAlertConfig(endpoint) {
|
||||||
|
const {configSections} = this.state;
|
||||||
const save = (properties) => {
|
const save = (properties) => {
|
||||||
this.handleSaveConfig(endpoint, properties);
|
this.handleSaveConfig(endpoint, properties);
|
||||||
};
|
};
|
||||||
|
@ -122,11 +136,6 @@ const AlertOutputs = React.createClass({
|
||||||
this.handleTest(endpoint, properties);
|
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) {
|
switch (endpoint) {
|
||||||
case 'alerta': {
|
case 'alerta': {
|
||||||
return <AlertaConfig onSave={save} config={this.getSection(configSections, endpoint)} />;
|
return <AlertaConfig onSave={save} config={this.getSection(configSections, endpoint)} />;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import React, {PropTypes} from 'react';
|
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';
|
import AlertOutputs from '../components/AlertOutputs';
|
||||||
|
|
||||||
export const KapacitorPage = React.createClass({
|
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) {
|
handleKapacitorUpdate(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (this.state.kapacitor) {
|
if (this.state.kapacitor) {
|
||||||
|
@ -45,7 +66,7 @@ export const KapacitorPage = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
handleCreateKapacitor() {
|
handleCreateKapacitor() {
|
||||||
const {source} = this.props;
|
const {addFlashMessage, source} = this.props;
|
||||||
const {newURL, newName, newUsername} = this.state;
|
const {newURL, newName, newUsername} = this.state;
|
||||||
createKapacitor(source, {
|
createKapacitor(source, {
|
||||||
url: newURL.trim(),
|
url: newURL.trim(),
|
||||||
|
@ -53,7 +74,7 @@ export const KapacitorPage = React.createClass({
|
||||||
username: newUsername,
|
username: newUsername,
|
||||||
password: this.kapacitorPassword.value,
|
password: this.kapacitorPassword.value,
|
||||||
}).then(({data: createdKapacitor}) => {
|
}).then(({data: createdKapacitor}) => {
|
||||||
this.props.addFlashMessage({type: 'success', text: 'Kapacitor Created!'});
|
addFlashMessage({type: 'success', text: 'Kapacitor Created!'});
|
||||||
this.setState({kapacitor: createdKapacitor});
|
this.setState({kapacitor: createdKapacitor});
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
this.props.addFlashMessage({type: 'error', text: 'There was a problem creating the Kapacitor record'});
|
this.props.addFlashMessage({type: 'error', text: 'There was a problem creating the Kapacitor record'});
|
||||||
|
@ -61,7 +82,7 @@ export const KapacitorPage = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
handleUpdateKapacitor() {
|
handleUpdateKapacitor() {
|
||||||
const {addFlashMessage, source} = this.props;
|
const {addFlashMessage} = this.props;
|
||||||
const {kapacitor, newURL, newName, newUsername} = this.state;
|
const {kapacitor, newURL, newName, newUsername} = this.state;
|
||||||
updateKapacitor(kapacitor, {
|
updateKapacitor(kapacitor, {
|
||||||
url: (newURL || kapacitor.url).trim(),
|
url: (newURL || kapacitor.url).trim(),
|
||||||
|
@ -69,16 +90,8 @@ export const KapacitorPage = React.createClass({
|
||||||
username: newUsername || kapacitor.username,
|
username: newUsername || kapacitor.username,
|
||||||
password: this.kapacitorPassword.value,
|
password: this.kapacitorPassword.value,
|
||||||
}).then(({data: newKapacitor}) => {
|
}).then(({data: newKapacitor}) => {
|
||||||
pingKapacitor(kapacitor).then(({data: {elements}}) => {
|
addFlashMessage({type: 'success', text: 'Kapacitor Updated!'});
|
||||||
this.setState({kapacitor: newKapacitor});
|
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.'});
|
|
||||||
});
|
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
addFlashMessage({type: 'error', text: 'There was a problem updating the Kapacitor record'});
|
addFlashMessage({type: 'error', text: 'There was a problem updating the Kapacitor record'});
|
||||||
});
|
});
|
||||||
|
|
|
@ -38,7 +38,7 @@ export function deleteSource(source) {
|
||||||
export function pingKapacitor(kapacitor) {
|
export function pingKapacitor(kapacitor) {
|
||||||
return AJAX({
|
return AJAX({
|
||||||
method: 'GET',
|
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', '');
|
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) {
|
export function updateKapacitorConfigSection(kapacitor, section, properties) {
|
||||||
return AJAX({
|
return AJAX({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
Loading…
Reference in New Issue