diff --git a/ui/src/kapacitor/components/EndpointInput.js b/ui/src/kapacitor/components/EndpointInput.js index 31cba6d3f9..d0f64f204d 100644 --- a/ui/src/kapacitor/components/EndpointInput.js +++ b/ui/src/kapacitor/components/EndpointInput.js @@ -19,7 +19,7 @@ const EndpointInput = ({ type="text" placeholder={placeholder} onChange={handleModifyEndpoint(selectedEndpoint, fieldName)} - value={selectedEndpoint.options[fieldName]} + value={selectedEndpoint[fieldName]} autoComplete="off" spellCheck="false" /> diff --git a/ui/src/kapacitor/components/EndpointOptions.js b/ui/src/kapacitor/components/EndpointOptions.js index c426900176..ca6bac1a4f 100644 --- a/ui/src/kapacitor/components/EndpointOptions.js +++ b/ui/src/kapacitor/components/EndpointOptions.js @@ -1,6 +1,6 @@ import React, {Component, PropTypes} from 'react' import { - HttpConfig, + PostConfig, TcpConfig, ExecConfig, LogConfig, @@ -25,9 +25,9 @@ class EndpointOptions extends Component { render() { const {selectedEndpoint, handleModifyEndpoint} = this.props switch (selectedEndpoint && selectedEndpoint.type) { - case 'http': + case 'post': return ( - diff --git a/ui/src/kapacitor/components/RuleMessage.js b/ui/src/kapacitor/components/RuleMessage.js index 728c9c4898..5d0f8fa2a6 100644 --- a/ui/src/kapacitor/components/RuleMessage.js +++ b/ui/src/kapacitor/components/RuleMessage.js @@ -16,9 +16,11 @@ const alertNodesToEndpoints = rule => { const count = _.get(endpointsOfKind, an.name, 0) + 1 endpointsOfKind[an.name] = count const ep = { + ...an.properties, + ...an.args, + ...an, alias: an.name + count, type: an.name, - options: {...an.properties, args: an.args || {}}, } endpointsOnThisAlert.push(ep) }) @@ -101,15 +103,15 @@ class RuleMessage extends Component { handleUpdateAllAlerts = () => { const {rule, actions} = this.props const {endpointsOnThisAlert} = this.state + actions.updateAlertNodes(rule.id, endpointsOnThisAlert) - actions.updateAlerts(rule.id, endpointsOnThisAlert) } handleModifyEndpoint = (selectedEndpoint, fieldName) => e => { const {endpointsOnThisAlert} = this.state const modifiedEP = { ...selectedEndpoint, - options: {...selectedEndpoint.options, [fieldName]: e.target.value}, + [fieldName]: e.target.value, } const remainingEndpoints = _.reject(endpointsOnThisAlert, [ 'alias', diff --git a/ui/src/kapacitor/components/configEP/AlertaConfig.js b/ui/src/kapacitor/components/configEP/AlertaConfig.js index 62c56e6f6b..d100e955eb 100644 --- a/ui/src/kapacitor/components/configEP/AlertaConfig.js +++ b/ui/src/kapacitor/components/configEP/AlertaConfig.js @@ -9,9 +9,65 @@ const AlertaConfig = ({selectedEndpoint, handleModifyEndpoint}) => { + + + + + + + + diff --git a/ui/src/kapacitor/components/configEP/ExecConfig.js b/ui/src/kapacitor/components/configEP/ExecConfig.js index c89155f5c8..d2c95cd5a8 100644 --- a/ui/src/kapacitor/components/configEP/ExecConfig.js +++ b/ui/src/kapacitor/components/configEP/ExecConfig.js @@ -11,7 +11,7 @@ const ExecConfig = ({selectedEndpoint, handleModifyEndpoint}) => { handleModifyEndpoint={handleModifyEndpoint} fieldName="command" fieldDisplay="Command (arguments separated by spaces):" - placeholder="Ex: woogie boogie" + placeholder="Ex: command argument" /> diff --git a/ui/src/kapacitor/components/configEP/LogConfig.js b/ui/src/kapacitor/components/configEP/LogConfig.js index b2cf5644e4..50daa9dafb 100644 --- a/ui/src/kapacitor/components/configEP/LogConfig.js +++ b/ui/src/kapacitor/components/configEP/LogConfig.js @@ -9,8 +9,8 @@ const LogConfig = ({selectedEndpoint, handleModifyEndpoint}) => { diff --git a/ui/src/kapacitor/components/configEP/OpsGenieConfig.js b/ui/src/kapacitor/components/configEP/OpsGenieConfig.js index ac264c2203..f1a6e33324 100644 --- a/ui/src/kapacitor/components/configEP/OpsGenieConfig.js +++ b/ui/src/kapacitor/components/configEP/OpsGenieConfig.js @@ -1,9 +1,35 @@ import React, {PropTypes} from 'react' +import EndpointInput from 'src/kapacitor/components/EndpointInput' -const OpsgenieConfig = () => { - return
this is OpsgenieConfig
+const OpsgenieConfig = ({selectedEndpoint, handleModifyEndpoint}) => { + return ( +
+

Alert Parameters:

+
+ + +
+
+ ) } -OpsgenieConfig.propTypes = {} +const {func, shape} = PropTypes + +OpsgenieConfig.propTypes = { + selectedEndpoint: shape({}).isRequired, + handleModifyEndpoint: func.isRequired, +} export default OpsgenieConfig diff --git a/ui/src/kapacitor/components/configEP/PagerDutyConfig.js b/ui/src/kapacitor/components/configEP/PagerDutyConfig.js index f24d8fa673..0991b77e24 100644 --- a/ui/src/kapacitor/components/configEP/PagerDutyConfig.js +++ b/ui/src/kapacitor/components/configEP/PagerDutyConfig.js @@ -10,8 +10,8 @@ const PagerdutyConfig = ({selectedEndpoint, handleModifyEndpoint}) => { selectedEndpoint={selectedEndpoint} handleModifyEndpoint={handleModifyEndpoint} fieldName="serviceKey" - fieldDisplay="Servive Key:" - placeholder="Ex: a_key" + fieldDisplay="Service Key:" + placeholder="Ex: service_key" /> diff --git a/ui/src/kapacitor/components/configEP/HttpConfig.js b/ui/src/kapacitor/components/configEP/PostConfig.js similarity index 73% rename from ui/src/kapacitor/components/configEP/HttpConfig.js rename to ui/src/kapacitor/components/configEP/PostConfig.js index be38234e6b..4a5774810d 100644 --- a/ui/src/kapacitor/components/configEP/HttpConfig.js +++ b/ui/src/kapacitor/components/configEP/PostConfig.js @@ -10,14 +10,7 @@ const HttpConfig = ({selectedEndpoint, handleModifyEndpoint}) => { selectedEndpoint={selectedEndpoint} handleModifyEndpoint={handleModifyEndpoint} fieldName="url" - fieldDisplay="URL" - placeholder="Ex: http://example.com/api/alert" - /> - diff --git a/ui/src/kapacitor/components/configEP/PushoverConfig.js b/ui/src/kapacitor/components/configEP/PushoverConfig.js index cf9fdb399d..d0e83bd84f 100644 --- a/ui/src/kapacitor/components/configEP/PushoverConfig.js +++ b/ui/src/kapacitor/components/configEP/PushoverConfig.js @@ -6,12 +6,19 @@ const PushoverConfig = ({selectedEndpoint, handleModifyEndpoint}) => {

Alert Parameters:

+ { diff --git a/ui/src/kapacitor/components/configEP/SMTPConfig.js b/ui/src/kapacitor/components/configEP/SMTPConfig.js index 9e93aa7d59..0bbd1771a9 100644 --- a/ui/src/kapacitor/components/configEP/SMTPConfig.js +++ b/ui/src/kapacitor/components/configEP/SMTPConfig.js @@ -9,7 +9,7 @@ const SmtpConfig = ({selectedEndpoint, handleModifyEndpoint}) => { diff --git a/ui/src/kapacitor/components/configEP/SensuConfig.js b/ui/src/kapacitor/components/configEP/SensuConfig.js index 2159bce993..530c0dacc1 100644 --- a/ui/src/kapacitor/components/configEP/SensuConfig.js +++ b/ui/src/kapacitor/components/configEP/SensuConfig.js @@ -1,9 +1,35 @@ import React, {PropTypes} from 'react' +import EndpointInput from 'src/kapacitor/components/EndpointInput' -const SensuConfig = () => { - return
this is SensuConfig
+const SensuConfig = ({selectedEndpoint, handleModifyEndpoint}) => { + return ( +
+

Alert Parameters:

+
+ + +
+
+ ) } -SensuConfig.propTypes = {} +const {func, shape} = PropTypes + +SensuConfig.propTypes = { + selectedEndpoint: shape({}).isRequired, + handleModifyEndpoint: func.isRequired, +} export default SensuConfig diff --git a/ui/src/kapacitor/components/configEP/SlackConfig.js b/ui/src/kapacitor/components/configEP/SlackConfig.js index 1ce9a460c4..ad2f76378b 100644 --- a/ui/src/kapacitor/components/configEP/SlackConfig.js +++ b/ui/src/kapacitor/components/configEP/SlackConfig.js @@ -11,7 +11,14 @@ const SlackConfig = ({selectedEndpoint, handleModifyEndpoint}) => { handleModifyEndpoint={handleModifyEndpoint} fieldName="channel" fieldDisplay="Channel:" - placeholder="Ex: #My_favorite_channel" + placeholder="Ex: #my_favorite_channel" + /> + { fieldDisplay="Emoji:" placeholder="Ex: :thumbsup:" /> -
) diff --git a/ui/src/kapacitor/components/configEP/TalkConfig.js b/ui/src/kapacitor/components/configEP/TalkConfig.js index 76c9e393ee..fad6f4720e 100644 --- a/ui/src/kapacitor/components/configEP/TalkConfig.js +++ b/ui/src/kapacitor/components/configEP/TalkConfig.js @@ -1,9 +1,18 @@ import React, {PropTypes} from 'react' const TalkConfig = () => { - return
this is TalkConfig
+ return ( +
+

Talk requires no additional alert parameters.

+
+ ) } -TalkConfig.propTypes = {} +const {func, shape} = PropTypes + +TalkConfig.propTypes = { + selectedEndpoint: shape({}).isRequired, + handleModifyEndpoint: func.isRequired, +} export default TalkConfig diff --git a/ui/src/kapacitor/components/configEP/TelegramConfig.js b/ui/src/kapacitor/components/configEP/TelegramConfig.js index 75b2edaf4c..8b36293675 100644 --- a/ui/src/kapacitor/components/configEP/TelegramConfig.js +++ b/ui/src/kapacitor/components/configEP/TelegramConfig.js @@ -1,7 +1,7 @@ import React, {PropTypes} from 'react' import EndpointInput from 'src/kapacitor/components/EndpointInput' -const HttpConfig = ({selectedEndpoint, handleModifyEndpoint}) => { +const TelegramConfig = ({selectedEndpoint, handleModifyEndpoint}) => { return (

Alert Parameters:

@@ -27,9 +27,9 @@ const HttpConfig = ({selectedEndpoint, handleModifyEndpoint}) => { const {func, shape} = PropTypes -HttpConfig.propTypes = { +TelegramConfig.propTypes = { selectedEndpoint: shape({}).isRequired, handleModifyEndpoint: func.isRequired, } -export default HttpConfig +export default TelegramConfig diff --git a/ui/src/kapacitor/components/configEP/VictorOpsConfig.js b/ui/src/kapacitor/components/configEP/VictorOpsConfig.js index 84443e5fca..5fcbb89db5 100644 --- a/ui/src/kapacitor/components/configEP/VictorOpsConfig.js +++ b/ui/src/kapacitor/components/configEP/VictorOpsConfig.js @@ -10,8 +10,8 @@ const VictoropsConfig = ({selectedEndpoint, handleModifyEndpoint}) => { selectedEndpoint={selectedEndpoint} handleModifyEndpoint={handleModifyEndpoint} fieldName="routingKey" - fieldDisplay="Channel:" - placeholder="Ex: team_rocket" + fieldDisplay="Routing Key:" + placeholder="Ex: routing_key" />
diff --git a/ui/src/kapacitor/components/configEP/index.js b/ui/src/kapacitor/components/configEP/index.js index b17c621044..211b7bcb96 100644 --- a/ui/src/kapacitor/components/configEP/index.js +++ b/ui/src/kapacitor/components/configEP/index.js @@ -1,4 +1,4 @@ -import HttpConfig from './HttpConfig' +import PostConfig from './PostConfig' import TcpConfig from './TcpConfig' import ExecConfig from './ExecConfig' import LogConfig from './LogConfig' @@ -15,7 +15,7 @@ import TelegramConfig from './TelegramConfig' import VictoropsConfig from './VictoropsConfig' export { - HttpConfig, + PostConfig, TcpConfig, ExecConfig, LogConfig, diff --git a/ui/src/kapacitor/constants/index.js b/ui/src/kapacitor/constants/index.js index 1b86417610..47c204711c 100644 --- a/ui/src/kapacitor/constants/index.js +++ b/ui/src/kapacitor/constants/index.js @@ -87,14 +87,84 @@ export const RULE_MESSAGE_TEMPLATES = { text: 'The time of the point that triggered the event', }, } - +// DEFAULT_ALERTS provides a template for alerts that don't exist in the kapacitor config export const DEFAULT_ALERTS = [ - {type: 'http', options: {url: ''}}, - {type: 'tcp', options: {address: ''}}, - {type: 'exec', options: {command: ''}}, - {type: 'log', options: {file: ''}}, + {type: 'post', url: '', headers: '', captureResponse: '', timeout: ''}, // is actually called 'post'?? + {type: 'tcp', address: ''}, + {type: 'exec', command: ''}, + {type: 'log', filePath: ''}, ] +// ALERT_FIELDS_FROM_CONFIG returns an array of fields to accept from the Kapacitor Config +// I WILL NEED TO ADD MORE TO DISPLAY FIELDS WHICH COME FROM THE CONFIG WHICH WILL JUST BE DISPLAYED NOT EDITABLE> +// I need to check what happens when one of these fields does not exist- the value in the input will fail at first. ?? add a default val? +export const ALERT_FIELDS_FROM_CONFIG = { + alerta: [ + 'token', + 'resource', + 'event', + 'environment', + 'group', + 'value', + 'origin', + 'service', + 'timeout', + ], + hipchat: ['room', 'token'], + opsgenie: ['teams', 'recipients'], + pagerduty: ['serviceKey'], + pushover: ['userKey', 'device', 'title', 'url', 'urlTitle', 'sound'], + sensu: ['source', 'handlers'], + slack: ['channel', 'username', 'iconEmoji'], + smtp: ['to'], + snmpTrap: ['trapOid', 'data'], // [oid/type/value] + talk: [], + telegram: [ + 'chatId', + 'parseMode', + 'disableWebPagePreview', + 'disableNotification', + ], + victorOps: ['routingKey'], + influxdb: [], +} + +// ALERTS_TO_RULE returns array of fields that may be updated for each alert on rule. +export const ALERT_FIELDS_TO_RULE = { + alerta: [ + 'token', + 'resource', + 'event', + 'environment', + 'group', + 'value', + 'origin', + 'service', + 'timeout', + ], + hipchat: ['room', 'token'], + opsgenie: ['teams', 'recipients'], + pagerduty: ['serviceKey'], + pushover: ['userKey', 'device', 'title', 'url', 'urlTitle', 'sound'], + sensu: ['source', 'handlers'], + slack: ['channel', 'username', 'iconEmoji'], + email: ['to'], + snmpTrap: ['trapOid', 'data'], // [oid/type/value] + talk: [], + telegram: [ + 'chatId', + 'parseMode', + 'disableWebPagePreview', + 'disableNotification', + ], + victorOps: ['routingKey'], + influxdb: [], // ????? + post: ['url', 'headers', 'captureResponse', 'timeout'], + tcp: ['address'], + exec: ['command'], + log: ['filePath'], +} + export const RULE_ALERT_OPTIONS = { http: { args: { diff --git a/ui/src/kapacitor/containers/KapacitorRulePage.js b/ui/src/kapacitor/containers/KapacitorRulePage.js index d32ac81617..f7d826953d 100644 --- a/ui/src/kapacitor/containers/KapacitorRulePage.js +++ b/ui/src/kapacitor/containers/KapacitorRulePage.js @@ -7,18 +7,24 @@ import * as kapacitorQueryConfigActionCreators from 'src/kapacitor/actions/query import {bindActionCreators} from 'redux' import {getActiveKapacitor, getKapacitorConfig} from 'shared/apis/index' -import {DEFAULT_RULE_ID} from 'src/kapacitor/constants' +import { + DEFAULT_RULE_ID, + ALERT_FIELDS_FROM_CONFIG, +} from 'src/kapacitor/constants' import KapacitorRule from 'src/kapacitor/components/KapacitorRule' const getEnabled = config => { const {data: {sections}} = config const allAlerts = _.map(sections, (v, k) => { - return {type: k, options: _.get(v, ['elements', '0', 'options'], {})} + const fromConfig = _.get(v, ['elements', '0', 'options'], {}) + const pickedFromConfig = _.pick(fromConfig, [ + ALERT_FIELDS_FROM_CONFIG[k], + 'enabled', + ]) + return {type: k, ...pickedFromConfig} }) - let enabledAlerts = _.filter(allAlerts, v => - _.get(v, ['options', 'enabled'], false) - ) - enabledAlerts = _.reject(enabledAlerts, v => v.type === 'influxdb') // TODO: should I be whitelisting here?? + let enabledAlerts = _.filter(allAlerts, v => _.get(v, ['enabled'], false)) + enabledAlerts = _.reject(enabledAlerts, v => v.type === 'influxdb') // TODO: remove this. return enabledAlerts } diff --git a/ui/src/kapacitor/reducers/rules.js b/ui/src/kapacitor/reducers/rules.js index 5b0f7d2253..2f25b46ac9 100644 --- a/ui/src/kapacitor/reducers/rules.js +++ b/ui/src/kapacitor/reducers/rules.js @@ -1,6 +1,9 @@ -import {defaultRuleConfigs, DEFAULT_RULE_ID} from 'src/kapacitor/constants' +import { + defaultRuleConfigs, + DEFAULT_RULE_ID, + ALERT_FIELDS_TO_RULE, +} from 'src/kapacitor/constants' import _ from 'lodash' -import {parseAlerta} from 'shared/parsing/parseAlerta' export default function rules(state = {}, action) { switch (action.type) { @@ -86,46 +89,13 @@ export default function rules(state = {}, action) { case 'UPDATE_RULE_ALERT_NODES': { const {ruleID, alerts} = action.payload - const alertNodesByType = alerts.map(alert => { - const {type, alias} = alert - switch (type) { - case 'http': - case 'tcp': - case 'log': - return { - name: type, - args: [alias], - properties: [], - } - case 'exec': - case 'smtp': - return [ - { - name: type, - args: alias.split(' '), - properties: [], - }, - ] - case 'alerta': - return { - name: type, - args: [], - properties: parseAlerta(alias), - } - case 'hipchat': - case 'opsgenie': - case 'pagerduty': - case 'slack': - case 'telegram': - case 'victorops': - case 'pushover': - default: - return { - name: type, - args: [], - properties: [], - } - } + const alertNodesByType = {} + _.forEach(alerts, ep => { + const existing = _.get(alertNodesByType, ep.type, []) + alertNodesByType[ep.type] = [ + ...existing, + _.pick(ep, ALERT_FIELDS_TO_RULE[ep.type]), + ] }) return Object.assign({}, state, { [ruleID]: Object.assign({}, state[ruleID], { diff --git a/ui/src/style/unsorted.scss b/ui/src/style/unsorted.scss index 3a601d6754..781fd65024 100644 --- a/ui/src/style/unsorted.scss +++ b/ui/src/style/unsorted.scss @@ -451,7 +451,7 @@ $dash-editable-header-padding: 7px; } } } - +} /* Add borders between items in .nav-tablist ----------------------------------------------------------------------------- TODO: Add these styles into the theme