Merge branch 'master' into bugfix/data-explorer-error
commit
921ded2959
|
@ -38,6 +38,7 @@
|
|||
1. [#3412](https://github.com/influxdata/chronograf/pull/3412): Limit max-width of TICKScript editor.
|
||||
1. [#3166](https://github.com/influxdata/chronograf/pull/3166): Fixes naming of new TICKScripts
|
||||
1. [#3449](https://github.com/influxdata/chronograf/pull/3449): Fixes data explorer query error reporting regression
|
||||
1. [#3453](https://github.com/influxdata/chronograf/pull/3453): Fix Kapacitor Logs fetch regression
|
||||
|
||||
## v1.4.4.1 [2018-04-16]
|
||||
|
||||
|
|
|
@ -5,6 +5,8 @@ import _ from 'lodash'
|
|||
import classnames from 'classnames'
|
||||
import OnClickOutside from 'shared/components/OnClickOutside'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
import FancyScrollbar from 'src/shared/components/FancyScrollbar'
|
||||
import {DROPDOWN_MENU_MAX_HEIGHT} from 'src/shared/constants/index'
|
||||
|
||||
@ErrorHandling
|
||||
class DashboardSwitcher extends Component {
|
||||
|
@ -29,9 +31,8 @@ class DashboardSwitcher extends Component {
|
|||
}
|
||||
|
||||
render() {
|
||||
const {activeDashboard, names} = this.props
|
||||
const {activeDashboard} = this.props
|
||||
const {isOpen} = this.state
|
||||
const sorted = _.sortBy(names, ({name}) => name.toLowerCase())
|
||||
|
||||
return (
|
||||
<div
|
||||
|
@ -44,19 +45,29 @@ class DashboardSwitcher extends Component {
|
|||
<span className="icon dash-f" />
|
||||
</button>
|
||||
<ul className="dropdown-menu">
|
||||
{sorted.map(({name, link}) => (
|
||||
<NameLink
|
||||
key={link}
|
||||
name={name}
|
||||
link={link}
|
||||
activeName={activeDashboard}
|
||||
onClose={this.handleCloseMenu}
|
||||
/>
|
||||
))}
|
||||
<FancyScrollbar
|
||||
autoHeight={true}
|
||||
maxHeight={DROPDOWN_MENU_MAX_HEIGHT}
|
||||
>
|
||||
{this.sortedList.map(({name, link}) => (
|
||||
<NameLink
|
||||
key={link}
|
||||
name={name}
|
||||
link={link}
|
||||
activeName={activeDashboard}
|
||||
onClose={this.handleCloseMenu}
|
||||
/>
|
||||
))}
|
||||
</FancyScrollbar>
|
||||
</ul>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
get sortedList() {
|
||||
const {names} = this.props
|
||||
return _.sortBy(names, ({name}) => name.toLowerCase())
|
||||
}
|
||||
}
|
||||
|
||||
const NameLink = ({name, link, activeName, onClose}) => (
|
||||
|
|
|
@ -107,22 +107,23 @@ const kapacitorLogHeaders = {
|
|||
}
|
||||
|
||||
export const getLogStream = kapacitor =>
|
||||
AJAX({
|
||||
url: `${kapacitor.links.proxy}?path=/kapacitor/v1preview/logs`,
|
||||
// fetch required for kapacitors log querying
|
||||
fetch(`${kapacitor.links.proxy}?path=/kapacitor/v1preview/logs`, {
|
||||
method: 'GET',
|
||||
headers: kapacitorLogHeaders,
|
||||
credentials: 'include',
|
||||
})
|
||||
|
||||
export const getLogStreamByRuleID = (kapacitor, ruleID) =>
|
||||
AJAX({
|
||||
url: `${
|
||||
kapacitor.links.proxy
|
||||
}?path=/kapacitor/v1preview/logs?task=${ruleID}`,
|
||||
method: 'GET',
|
||||
headers: kapacitorLogHeaders,
|
||||
credentials: 'include',
|
||||
})
|
||||
// fetch required for kapacitors log querying
|
||||
fetch(
|
||||
`${kapacitor.links.proxy}?path=/kapacitor/v1preview/logs?task=${ruleID}`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: kapacitorLogHeaders,
|
||||
credentials: 'include',
|
||||
}
|
||||
)
|
||||
|
||||
export const pingKapacitorVersion = async kapacitor => {
|
||||
try {
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
KafkaConfig,
|
||||
OpsGenieConfig,
|
||||
PagerDutyConfig,
|
||||
PagerDuty2Config,
|
||||
PushoverConfig,
|
||||
SensuConfig,
|
||||
SlackConfig,
|
||||
|
@ -280,7 +281,7 @@ class AlertTabs extends PureComponent<Props, State> {
|
|||
type: 'PagerDuty2',
|
||||
enabled: this.getEnabled(configSections, 'pagerduty2'),
|
||||
renderComponent: () => (
|
||||
<PagerDutyConfig
|
||||
<PagerDuty2Config
|
||||
onSave={this.handleSaveConfig('pagerduty2')}
|
||||
config={this.getSection(configSections, 'pagerduty2')}
|
||||
onTest={this.handleTestConfig('pagerduty2')}
|
||||
|
|
|
@ -11,6 +11,7 @@ import {
|
|||
KafkaHandler,
|
||||
OpsgenieHandler,
|
||||
PagerdutyHandler,
|
||||
Pagerduty2Handler,
|
||||
PushoverHandler,
|
||||
SensuHandler,
|
||||
SlackHandler,
|
||||
|
@ -131,7 +132,7 @@ class HandlerOptions extends Component {
|
|||
)
|
||||
case 'pagerDuty2':
|
||||
return (
|
||||
<PagerdutyHandler
|
||||
<Pagerduty2Handler
|
||||
selectedHandler={selectedHandler}
|
||||
handleModifyHandler={handleModifyHandler}
|
||||
onGoToConfig={onGoToConfig('pagerduty2')}
|
||||
|
|
|
@ -56,18 +56,6 @@ const TasksTable: SFC<TasksTableProps> = ({
|
|||
)
|
||||
|
||||
export class TaskRow extends PureComponent<TaskRowProps> {
|
||||
public handleClickRuleStatusEnabled(task: AlertRule) {
|
||||
return () => {
|
||||
this.props.onChangeRuleStatus(task)
|
||||
}
|
||||
}
|
||||
|
||||
public handleDelete(task: AlertRule) {
|
||||
return () => {
|
||||
this.props.onDelete(task)
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {task, source} = this.props
|
||||
|
||||
|
@ -91,9 +79,9 @@ export class TaskRow extends PureComponent<TaskRowProps> {
|
|||
className="form-control-static"
|
||||
type="checkbox"
|
||||
checked={task.status === 'enabled'}
|
||||
onChange={this.handleClickRuleStatusEnabled(task)}
|
||||
onChange={this.handleClickRuleStatusEnabled}
|
||||
/>
|
||||
<label htmlFor={`kapacitor-task-row-task-enabled ${task.name}`} />
|
||||
<label htmlFor={`kapacitor-task-row-task-enabled ${task.id}`} />
|
||||
</div>
|
||||
</td>
|
||||
<td style={{width: colActions}} className="text-right">
|
||||
|
@ -102,12 +90,24 @@ export class TaskRow extends PureComponent<TaskRowProps> {
|
|||
type="btn-danger"
|
||||
size="btn-xs"
|
||||
customClass="table--show-on-row-hover"
|
||||
confirmAction={this.handleDelete(task)}
|
||||
confirmAction={this.handleDelete}
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
)
|
||||
}
|
||||
|
||||
private handleDelete = () => {
|
||||
const {onDelete, task} = this.props
|
||||
|
||||
onDelete(task)
|
||||
}
|
||||
|
||||
private handleClickRuleStatusEnabled = () => {
|
||||
const {onChangeRuleStatus, task} = this.props
|
||||
|
||||
onChangeRuleStatus(task)
|
||||
}
|
||||
}
|
||||
|
||||
export default TasksTable
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
import _ from 'lodash'
|
||||
import React, {PureComponent, ChangeEvent} from 'react'
|
||||
import RedactedInput from 'src/kapacitor/components/config/RedactedInput'
|
||||
import {ErrorHandling} from 'src/shared/decorators/errors'
|
||||
|
||||
interface Properties {
|
||||
'routing-key': string
|
||||
url: string
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
interface Config {
|
||||
options: {
|
||||
'routing-key': boolean
|
||||
url: string
|
||||
enabled: boolean
|
||||
}
|
||||
}
|
||||
|
||||
interface Props {
|
||||
config: Config
|
||||
onSave: (properties: Properties) => void
|
||||
onTest: (event: React.MouseEvent<HTMLButtonElement>) => void
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
interface State {
|
||||
testEnabled: boolean
|
||||
enabled: boolean
|
||||
}
|
||||
|
||||
@ErrorHandling
|
||||
class PagerDuty2Config extends PureComponent<Props, State> {
|
||||
private routingKey: HTMLInputElement
|
||||
private url: HTMLInputElement
|
||||
|
||||
constructor(props: Props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
testEnabled: this.props.enabled,
|
||||
enabled: _.get(this.props, 'config.options.enabled', false),
|
||||
}
|
||||
}
|
||||
|
||||
public render() {
|
||||
const {options} = this.props.config
|
||||
const {url} = options
|
||||
const routingKey = options['routing-key']
|
||||
const {testEnabled, enabled} = this.state
|
||||
|
||||
return (
|
||||
<form onSubmit={this.handleSubmit}>
|
||||
<div className="form-group col-xs-12">
|
||||
<label htmlFor="routing-key">Routing Key</label>
|
||||
<RedactedInput
|
||||
defaultValue={routingKey}
|
||||
id="routing-key"
|
||||
refFunc={this.handleRoutingKeyRef}
|
||||
disableTest={this.disableTest}
|
||||
isFormEditing={!testEnabled}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<label htmlFor="url">PagerDuty URL</label>
|
||||
<input
|
||||
className="form-control"
|
||||
id="url"
|
||||
type="text"
|
||||
ref={r => (this.url = r)}
|
||||
defaultValue={url || ''}
|
||||
onChange={this.disableTest}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="form-group col-xs-12">
|
||||
<div className="form-control-static">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="disabled"
|
||||
checked={enabled}
|
||||
onChange={this.handleEnabledChange}
|
||||
/>
|
||||
<label htmlFor="disabled">Configuration Enabled</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="form-group form-group-submit col-xs-12 text-center">
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
type="submit"
|
||||
disabled={this.state.testEnabled}
|
||||
>
|
||||
<span className="icon checkmark" />
|
||||
Save Changes
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary"
|
||||
disabled={!this.state.testEnabled || !enabled}
|
||||
onClick={this.props.onTest}
|
||||
>
|
||||
<span className="icon pulse-c" />
|
||||
Send Test Alert
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
)
|
||||
}
|
||||
|
||||
private handleRoutingKeyRef = (r: HTMLInputElement): HTMLInputElement =>
|
||||
(this.routingKey = r)
|
||||
|
||||
private handleEnabledChange = (e: ChangeEvent<HTMLInputElement>): void => {
|
||||
this.setState({enabled: e.target.checked})
|
||||
this.disableTest()
|
||||
}
|
||||
|
||||
private handleSubmit = async (
|
||||
e: React.FormEvent<HTMLFormElement>
|
||||
): Promise<void> => {
|
||||
e.preventDefault()
|
||||
|
||||
const properties: Properties = {
|
||||
'routing-key': this.routingKey.value,
|
||||
url: this.url.value,
|
||||
enabled: this.state.enabled,
|
||||
}
|
||||
|
||||
const success = await this.props.onSave(properties)
|
||||
if (success) {
|
||||
this.setState({testEnabled: true})
|
||||
}
|
||||
}
|
||||
|
||||
private disableTest = (): void => {
|
||||
this.setState({testEnabled: false})
|
||||
}
|
||||
}
|
||||
|
||||
export default PagerDuty2Config
|
|
@ -3,6 +3,7 @@ import HipChatConfig from './HipChatConfig'
|
|||
import KafkaConfig from './KafkaConfig'
|
||||
import OpsGenieConfig from './OpsGenieConfig'
|
||||
import PagerDutyConfig from './PagerDutyConfig'
|
||||
import PagerDuty2Config from './PagerDuty2Config'
|
||||
import PushoverConfig from './PushoverConfig'
|
||||
import SensuConfig from './SensuConfig'
|
||||
import SlackConfig from './SlackConfig'
|
||||
|
@ -17,6 +18,7 @@ export {
|
|||
KafkaConfig,
|
||||
OpsGenieConfig,
|
||||
PagerDutyConfig,
|
||||
PagerDuty2Config,
|
||||
PushoverConfig,
|
||||
SensuConfig,
|
||||
SlackConfig,
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
import React, {SFC} from 'react'
|
||||
import HandlerInput from 'src/kapacitor/components/HandlerInput'
|
||||
import HandlerEmpty from 'src/kapacitor/components/HandlerEmpty'
|
||||
|
||||
interface Props {
|
||||
selectedHandler: {
|
||||
enabled: boolean
|
||||
}
|
||||
handleModifyHandler: () => void
|
||||
onGoToConfig: () => void
|
||||
validationError: string
|
||||
}
|
||||
|
||||
const Pagerduty2Handler: SFC<Props> = ({
|
||||
selectedHandler,
|
||||
handleModifyHandler,
|
||||
onGoToConfig,
|
||||
validationError,
|
||||
}) => {
|
||||
if (selectedHandler.enabled) {
|
||||
let goToConfigText
|
||||
if (validationError) {
|
||||
goToConfigText = 'Exit this Rule and Edit Configuration'
|
||||
} else {
|
||||
goToConfigText = 'Save this Rule and Edit Configuration'
|
||||
}
|
||||
return (
|
||||
<div className="endpoint-tab-contents">
|
||||
<div className="endpoint-tab--parameters">
|
||||
<h4 className="u-flex u-jc-space-between">
|
||||
Parameters from Kapacitor Configuration
|
||||
<div className="btn btn-default btn-sm" onClick={onGoToConfig}>
|
||||
<span className="icon cog-thick" />
|
||||
{goToConfigText}
|
||||
</div>
|
||||
</h4>
|
||||
<HandlerInput
|
||||
selectedHandler={selectedHandler}
|
||||
handleModifyHandler={handleModifyHandler}
|
||||
fieldName="routingKey"
|
||||
fieldDisplay="Routing Key:"
|
||||
placeholder="ex: routing_key"
|
||||
redacted={true}
|
||||
fieldColumns="col-md-12"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<HandlerEmpty
|
||||
onGoToConfig={onGoToConfig}
|
||||
validationError={validationError}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
export default Pagerduty2Handler
|
|
@ -7,6 +7,7 @@ import HipchatHandler from './HipchatHandler'
|
|||
import KafkaHandler from './KafkaHandler'
|
||||
import OpsgenieHandler from './OpsgenieHandler'
|
||||
import PagerdutyHandler from './PagerdutyHandler'
|
||||
import Pagerduty2Handler from './Pagerduty2Handler'
|
||||
import PushoverHandler from './PushoverHandler'
|
||||
import SensuHandler from './SensuHandler'
|
||||
import SlackHandler from './SlackHandler'
|
||||
|
@ -26,6 +27,7 @@ export {
|
|||
KafkaHandler,
|
||||
OpsgenieHandler,
|
||||
PagerdutyHandler,
|
||||
Pagerduty2Handler,
|
||||
PushoverHandler,
|
||||
SensuHandler,
|
||||
SlackHandler,
|
||||
|
|
|
@ -118,7 +118,7 @@ export const ALERTS_FROM_CONFIG = {
|
|||
opsGenie: ['api-key', 'teams', 'recipients'], // api-key = bool
|
||||
opsGenie2: ['api-key', 'teams', 'recipients'], // api-key = bool
|
||||
pagerDuty: ['service-key'], // service-key = bool
|
||||
pagerDuty2: ['service-key'], // service-key = bool
|
||||
pagerDuty2: ['routing-key'], // routing-key = bool
|
||||
pushover: ['token', 'user-key'], // token = bool, user-key = bool
|
||||
sensu: ['addr', 'source'],
|
||||
slack: ['url', 'channel'], // url = bool
|
||||
|
@ -143,7 +143,7 @@ export const MAP_FIELD_KEYS_FROM_CONFIG = {
|
|||
opsGenie: {},
|
||||
opsGenie2: {},
|
||||
pagerDuty: {'service-key': 'serviceKey'},
|
||||
pagerDuty2: {'service-key': 'serviceKey'},
|
||||
pagerDuty2: {'routing-key': 'routingKey'},
|
||||
pushover: {'user-key': 'userKey'},
|
||||
sensu: {},
|
||||
slack: {},
|
||||
|
|
|
@ -56,7 +56,7 @@ interface AlertNodes {
|
|||
log: Log[]
|
||||
victorOps: VictorOps[]
|
||||
pagerDuty: PagerDuty[]
|
||||
pagerDuty2?: PagerDuty[]
|
||||
pagerDuty2?: PagerDuty2[]
|
||||
pushover: Pushover[]
|
||||
sensu: Sensu[]
|
||||
slack: Slack[]
|
||||
|
@ -120,6 +120,11 @@ interface PagerDuty {
|
|||
serviceKey: string
|
||||
}
|
||||
|
||||
// PagerDuty2 sends alerts to the pagerduty.com service
|
||||
interface PagerDuty2 {
|
||||
routingKey: string
|
||||
}
|
||||
|
||||
// HipChat sends alerts to stride.com
|
||||
interface HipChat {
|
||||
room: string
|
||||
|
|
Loading…
Reference in New Issue