Merge pull request #303 from influxdata/feature/kapacitor-alert-settings
Feature/kapacitor alert settingspull/10616/head
commit
c65491c4e8
|
@ -1,10 +1,14 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
import _ from 'lodash';
|
||||
import {getKapacitorConfig, updateKapacitorConfigSection, testAlertOutput} from 'shared/apis';
|
||||
import AlertaConfig from './AlertaConfig';
|
||||
import HipchatConfig from './HipchatConfig';
|
||||
import PagerdutyConfig from './PagerdutyConfig';
|
||||
import SensuConfig from './SensuConfig';
|
||||
import SlackConfig from './SlackConfig';
|
||||
import SMTPConfig from './SMTPConfig';
|
||||
import TelegramConfig from './TelegramConfig';
|
||||
import VictoropsConfig from './VictoropsConfig';
|
||||
import AlertaConfig from './AlertaConfig';
|
||||
|
||||
const AlertOutputs = React.createClass({
|
||||
propTypes: {
|
||||
|
@ -22,9 +26,12 @@ const AlertOutputs = React.createClass({
|
|||
getInitialState() {
|
||||
return {
|
||||
selectedEndpoint: 'alerta',
|
||||
alertaConfig: null,
|
||||
smtpConfig: null,
|
||||
slackConfig: null,
|
||||
alertaConfig: null,
|
||||
telegramConfig: null,
|
||||
hipchatConfig: null,
|
||||
sensuConfig: null,
|
||||
};
|
||||
},
|
||||
|
||||
|
@ -35,14 +42,22 @@ const AlertOutputs = React.createClass({
|
|||
refreshKapacitorConfig() {
|
||||
getKapacitorConfig(this.props.kapacitor).then(({data: {sections}}) => {
|
||||
this.setState({
|
||||
alertaConfig: _.get(sections, ['alerta', 'elements', '0'], null),
|
||||
slackConfig: _.get(sections, ['slack', 'elements', '0'], null),
|
||||
smtpConfig: _.get(sections, ['smtp', 'elements', '0'], null),
|
||||
victoropsConfig: _.get(sections, ['victorops', 'elements', '0'], null),
|
||||
alertaConfig: this.getSection(sections, 'alerta'),
|
||||
hipchatConfig: this.getSection(sections, 'hipchat'),
|
||||
pagerdutyConfig: this.getSection(sections, 'pagerduty'),
|
||||
slackConfig: this.getSection(sections, 'slack'),
|
||||
smtpConfig: this.getSection(sections, 'smtp'),
|
||||
telegramConfig: this.getSection(sections, 'telegram'),
|
||||
victoropsConfig: this.getSection(sections, 'victorops'),
|
||||
sensuConfig: this.getSection(sections, 'sensu'),
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
getSection(sections, section) {
|
||||
return _.get(sections, [section, 'elements', '0'], null);
|
||||
},
|
||||
|
||||
handleSaveConfig(section, properties) {
|
||||
if (section !== '') {
|
||||
updateKapacitorConfigSection(this.props.kapacitor, section, Object.assign({}, properties, {enabled: true})).then(() => {
|
||||
|
@ -85,8 +100,12 @@ const AlertOutputs = React.createClass({
|
|||
<label htmlFor="alert-endpoint" className="sr-only">Alert Enpoint</label>
|
||||
<select className="form-control" id="source" onChange={this.changeSelectedEndpoint}>
|
||||
<option value="alerta">Alerta</option>
|
||||
<option value="hipchat">HipChat</option>
|
||||
<option value="pagerduty">PagerDuty</option>
|
||||
<option value="sensu">Sensu</option>
|
||||
<option value="slack">Slack</option>
|
||||
<option value="smtp">SMTP</option>
|
||||
<option value="telegram">Telegram</option>
|
||||
<option value="victorops">VictorOps</option>
|
||||
</select>
|
||||
</div>
|
||||
|
@ -119,7 +138,23 @@ const AlertOutputs = React.createClass({
|
|||
return <VictoropsConfig onSave={save} config={this.state.victoropsConfig} />;
|
||||
}
|
||||
|
||||
return <div>This endpoint is not supported yet!</div>;
|
||||
if (endpoint === 'telegram' && this.state.telegramConfig) {
|
||||
return <TelegramConfig onSave={save} config={this.state.telegramConfig} />;
|
||||
}
|
||||
|
||||
if (endpoint === 'pagerduty' && this.state.pagerdutyConfig) {
|
||||
return <PagerdutyConfig onSave={save} config={this.state.pagerdutyConfig} />;
|
||||
}
|
||||
|
||||
if (endpoint === 'hipchat' && this.state.hipchatConfig) {
|
||||
return <HipchatConfig onSave={save} config={this.state.hipchatConfig} />;
|
||||
}
|
||||
|
||||
if (endpoint === 'sensu' && this.state.sensuConfig) {
|
||||
return <SensuConfig onSave={save} config={this.state.sensuConfig} />;
|
||||
}
|
||||
|
||||
return <div></div>;
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
|
||||
const HipchatConfig = React.createClass({
|
||||
propTypes: {
|
||||
config: PropTypes.shape({
|
||||
options: PropTypes.shape({
|
||||
global: PropTypes.bool.isRequired,
|
||||
room: PropTypes.string.isRequired,
|
||||
'state-changes-only': PropTypes.bool.isRequired,
|
||||
token: PropTypes.bool.isRequired,
|
||||
url: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
onSave: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
handleSaveAlert(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const properties = {
|
||||
room: this.room.value,
|
||||
url: this.url.value,
|
||||
token: this.token.value,
|
||||
'state-changes-only': this.stateChangesOnly.checked,
|
||||
global: this.global.checked,
|
||||
};
|
||||
|
||||
this.props.onSave(properties);
|
||||
},
|
||||
|
||||
render() {
|
||||
const {options} = this.props.config;
|
||||
const stateChangesOnly = options['state-changes-only'];
|
||||
const {url, global, room, token} = options;
|
||||
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<h4 className="text-center">VictorOps Alert</h4>
|
||||
<br/>
|
||||
<form onSubmit={this.handleSaveAlert}>
|
||||
<div className="row">
|
||||
<div className="col-xs-7 col-sm-8 col-sm-offset-2">
|
||||
<p>
|
||||
Have alerts sent to HipChat
|
||||
</p>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="url">HipChat URL</label>
|
||||
<input className="form-control" id="url" type="text" ref={(r) => this.url = r} defaultValue={url || ''}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="room">Room</label>
|
||||
<input className="form-control" id="room" type="text" ref={(r) => this.room = r} defaultValue={room || ''}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="token">Token</label>
|
||||
<input className="form-control" id="token" type="text" ref={(r) => this.token = r} defaultValue={token || ''}></input>
|
||||
<span>Note: a value of <code>true</code> indicates the HipChat token has been set</span>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" defaultChecked={global} ref={(r) => this.global = r} />
|
||||
Send all alerts without marking them explicitly in TICKscript
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" defaultChecked={stateChangesOnly} ref={(r) => this.stateChangesOnly = r} />
|
||||
Send alerts on state change only
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<div className="row">
|
||||
<div className="form-group col-xs-5 col-sm-3 col-sm-offset-2">
|
||||
<button className="btn btn-block btn-primary" type="submit">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default HipchatConfig;
|
|
@ -0,0 +1,78 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
|
||||
const PagerdutyConfig = React.createClass({
|
||||
propTypes: {
|
||||
config: PropTypes.shape({
|
||||
options: PropTypes.shape({
|
||||
global: PropTypes.bool.isRequired,
|
||||
'service-key': PropTypes.bool.isRequired,
|
||||
url: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
onSave: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
handleSaveAlert(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const properties = {
|
||||
global: this.global.checked,
|
||||
serviceKey: this.serviceKey.value,
|
||||
url: this.url.value,
|
||||
};
|
||||
|
||||
this.props.onSave(properties);
|
||||
},
|
||||
|
||||
render() {
|
||||
const {options} = this.props.config;
|
||||
const {global, url} = options;
|
||||
const serviceKey = options['service-key'];
|
||||
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<h4 className="text-center">PagerDuty Alert</h4>
|
||||
<br/>
|
||||
<form onSubmit={this.handleSaveAlert}>
|
||||
<div className="row">
|
||||
<div className="col-xs-7 col-sm-8 col-sm-offset-2">
|
||||
<p>
|
||||
You can have alerts sent to PagerDuty by entering info below.
|
||||
</p>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="service-key">Service Key</label>
|
||||
<input className="form-control" id="service-key" type="text" ref={(r) => this.serviceKey = r} defaultValue={serviceKey || ''}></input>
|
||||
<span>Note: a value of <code>true</code> indicates the PagerDuty service key has been set</span>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="url">PagerDuty URL</label>
|
||||
<input className="form-control" id="url" type="text" ref={(r) => this.url = r} defaultValue={url || ''}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" defaultChecked={global} ref={(r) => this.global = r} />
|
||||
Send all alerts without marking them explicitly in TICKscript
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<div className="row">
|
||||
<div className="form-group col-xs-5 col-sm-3 col-sm-offset-2">
|
||||
<button className="btn btn-block btn-primary" type="submit">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default PagerdutyConfig;
|
|
@ -0,0 +1,63 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
|
||||
const SensuConfig = React.createClass({
|
||||
propTypes: {
|
||||
config: PropTypes.shape({
|
||||
options: PropTypes.shape({
|
||||
source: PropTypes.string.isRequired,
|
||||
addr: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
onSave: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
handleSaveAlert(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const properties = {
|
||||
source: this.source.value,
|
||||
addr: this.addr.value,
|
||||
};
|
||||
|
||||
this.props.onSave(properties);
|
||||
},
|
||||
|
||||
render() {
|
||||
const {source, addr} = this.props.config.options;
|
||||
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<h4 className="text-center">Alerta Alert</h4>
|
||||
<br/>
|
||||
<form onSubmit={this.handleSaveAlert}>
|
||||
<div className="row">
|
||||
<div className="col-xs-7 col-sm-8 col-sm-offset-2">
|
||||
<p>
|
||||
Have alerts sent to Sensu
|
||||
</p>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="source">Source</label>
|
||||
<input className="form-control" id="source" type="text" ref={(r) => this.source = r} defaultValue={source || ''}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="address">Address</label>
|
||||
<input className="form-control" id="address" type="text" ref={(r) => this.addr = r} defaultValue={addr || ''}></input>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<div className="row">
|
||||
<div className="form-group col-xs-5 col-sm-3 col-sm-offset-2">
|
||||
<button className="btn btn-block btn-primary" type="submit">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default SensuConfig;
|
|
@ -0,0 +1,133 @@
|
|||
import React, {PropTypes} from 'react';
|
||||
|
||||
const TelegramConfig = React.createClass({
|
||||
propTypes: {
|
||||
config: PropTypes.shape({
|
||||
options: PropTypes.shape({
|
||||
'chat-id': PropTypes.string.isRequired,
|
||||
'disable-notification': PropTypes.bool.isRequired,
|
||||
'disable-web-page-preview': PropTypes.bool.isRequired,
|
||||
global: PropTypes.bool.isRequired,
|
||||
'parse-mode': PropTypes.string.isRequired,
|
||||
'state-changes-only': PropTypes.bool.isRequired,
|
||||
token: PropTypes.bool.isRequired,
|
||||
url: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
}).isRequired,
|
||||
onSave: PropTypes.func.isRequired,
|
||||
},
|
||||
|
||||
handleSaveAlert(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const properties = {
|
||||
chatID: this.chatID.value,
|
||||
disableNotification: this.disableNotification.checked,
|
||||
disableWebPagePreview: this.disableWebPagePreview.checked,
|
||||
global: this.global.checked,
|
||||
parseMode: this.parseMode.checked,
|
||||
stateChangesOnly: this.stateChangesOnly.checked,
|
||||
token: this.token.value,
|
||||
url: this.url.value,
|
||||
};
|
||||
|
||||
this.props.onSave(properties);
|
||||
},
|
||||
|
||||
render() {
|
||||
const {options} = this.props.config;
|
||||
const {global, url, token} = options;
|
||||
const chatID = options['chat-id'];
|
||||
const disableNotification = options['chat-id'];
|
||||
const disableWebPagePreview = options['disable-web-page-preview'];
|
||||
const parseMode = options['parse-mode'];
|
||||
const stateChangesOnly = options['state-changes-only'];
|
||||
|
||||
return (
|
||||
<div className="panel-body">
|
||||
<h4 className="text-center">Telegram Alert</h4>
|
||||
<br/>
|
||||
<form onSubmit={this.handleSaveAlert}>
|
||||
<div className="row">
|
||||
<div className="col-xs-7 col-sm-8 col-sm-offset-2">
|
||||
<p>
|
||||
You can have alerts sent to Telegram by entering info below.
|
||||
</p>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="url">Telegram URL</label>
|
||||
<input className="form-control" id="url" type="text" ref={(r) => this.url = r} defaultValue={url || ''}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="token">Token</label>
|
||||
<input className="form-control" id="token" type="text" ref={(r) => this.token = r} defaultValue={token || ''}></input>
|
||||
<span>Note: a value of <code>true</code> indicates the Telegram token has been set</span>
|
||||
</div>
|
||||
|
||||
<div className="form-group">
|
||||
<label htmlFor="chat-id">Chat ID</label>
|
||||
<input className="form-control" id="chat-id" type="text" ref={(r) => this.chatID = r} defaultValue={chatID || ''}></input>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" defaultChecked={parseMode} ref={(r) => this.parseMode = r} />
|
||||
Enable Parse Mode
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" defaultChecked={disableWebPagePreview} ref={(r) => this.disableWebPagePreview = r} />
|
||||
Disable Web Page Preview
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" defaultChecked={disableNotification} ref={(r) => this.disableNotification = r} />
|
||||
Disable Notification
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" defaultChecked={global} ref={(r) => this.global = r} />
|
||||
Send all alerts without marking them explicitly in TICKscript
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" defaultChecked={stateChangesOnly} ref={(r) => this.stateChangesOnly = r} />
|
||||
Send alerts on state change only
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
<div className="row">
|
||||
<div className="form-group col-xs-5 col-sm-3 col-sm-offset-2">
|
||||
<button className="btn btn-block btn-primary" type="submit">Save</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export default TelegramConfig;
|
Loading…
Reference in New Issue