feat(notification/telegram): specify channel as a telegram endpoint property

pull/18218/head
Pavel Zavora 2020-07-09 17:31:26 +02:00
parent 3f2ccfa9e1
commit 078bd8db09
12 changed files with 69 additions and 73 deletions

View File

@ -11616,9 +11616,6 @@ components:
messageTemplate: messageTemplate:
description: The message template as a flux interpolated string. description: The message template as a flux interpolated string.
type: string type: string
channel:
description: Id of the telegram channel.
type: string
parseMode: parseMode:
description: Parse mode of the message text per https://core.telegram.org/bots/api#formatting-options . Defaults to "MarkdownV2" . description: Parse mode of the message text per https://core.telegram.org/bots/api#formatting-options . Defaults to "MarkdownV2" .
type: string type: string
@ -11778,10 +11775,14 @@ components:
allOf: allOf:
- $ref: "#/components/schemas/NotificationEndpointBase" - $ref: "#/components/schemas/NotificationEndpointBase"
- type: object - type: object
required: [token, channel]
properties: properties:
token: token:
description: Specifies the Telegram bot token. See https://core.telegram.org/bots#creating-a-new-bot . description: Specifies the Telegram bot token. See https://core.telegram.org/bots#creating-a-new-bot .
type: string type: string
channel:
description: ID of the telegram channel, a chat_id in https://core.telegram.org/bots/api#sendmessage .
type: string
NotificationEndpointType: NotificationEndpointType:
type: string type: string
enum: ["slack", "pagerduty", "http", "telegram"] enum: ["slack", "pagerduty", "http", "telegram"]

View File

@ -62,7 +62,8 @@ func TestValidEndpoint(t *testing.T) {
OrgID: influxTesting.MustIDBase16Ptr(id3), OrgID: influxTesting.MustIDBase16Ptr(id3),
Status: influxdb.Active, Status: influxdb.Active,
}, },
Token: influxdb.SecretField{Key: id1 + "-token"}, Token: influxdb.SecretField{Key: id1 + "-token"},
Channel: "-1001406363649",
}, },
err: &influxdb.Error{ err: &influxdb.Error{
Code: influxdb.EInvalid, Code: influxdb.EInvalid,
@ -146,11 +147,23 @@ func TestValidEndpoint(t *testing.T) {
}, },
}, },
{ {
name: "valid telegram token", name: "empty telegram channel",
src: &endpoint.Telegram{ src: &endpoint.Telegram{
Base: goodBase, Base: goodBase,
Token: influxdb.SecretField{Key: id1 + "-token"}, Token: influxdb.SecretField{Key: id1 + "-token"},
}, },
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "empty telegram channel",
},
},
{
name: "valid telegram token",
src: &endpoint.Telegram{
Base: goodBase,
Token: influxdb.SecretField{Key: id1 + "-token"},
Channel: "-1001406363649",
},
err: nil, err: nil,
}, },
} }

View File

@ -15,6 +15,8 @@ type Telegram struct {
Base Base
// Token is the telegram bot token, see https://core.telegram.org/bots#creating-a-new-bot // Token is the telegram bot token, see https://core.telegram.org/bots#creating-a-new-bot
Token influxdb.SecretField `json:"token"` Token influxdb.SecretField `json:"token"`
// Channel is an ID of the telegram channel, see https://core.telegram.org/bots/api#sendmessage
Channel string `json:"channel"`
} }
// BackfillSecretKeys fill back the secret field key during the unmarshalling // BackfillSecretKeys fill back the secret field key during the unmarshalling
@ -45,6 +47,12 @@ func (s Telegram) Valid() error {
Msg: "empty telegram bot token", Msg: "empty telegram bot token",
} }
} }
if s.Channel == "" {
return &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "empty telegram channel",
}
}
return nil return nil
} }

View File

@ -353,7 +353,6 @@ func TestJSON(t *testing.T) {
UpdatedAt: timeGen2.Now(), UpdatedAt: timeGen2.Now(),
}, },
}, },
Channel: "channel1",
MessageTemplate: "blah", MessageTemplate: "blah",
}, },
}, },

View File

@ -14,7 +14,6 @@ import (
type Telegram struct { type Telegram struct {
Base Base
MessageTemplate string `json:"messageTemplate"` MessageTemplate string `json:"messageTemplate"`
Channel string `json:"channel"`
ParseMode string `json:"parseMode"` ParseMode string `json:"parseMode"`
DisableWebPagePreview bool `json:"disableWebPagePreview"` DisableWebPagePreview bool `json:"disableWebPagePreview"`
} }
@ -52,7 +51,7 @@ func (s *Telegram) generateFluxASTBody(e *endpoint.Telegram) []ast.Statement {
statements = append(statements, s.generateFluxASTNotificationDefinition(e)) statements = append(statements, s.generateFluxASTNotificationDefinition(e))
statements = append(statements, s.generateFluxASTStatuses()) statements = append(statements, s.generateFluxASTStatuses())
statements = append(statements, s.generateLevelChecks()...) statements = append(statements, s.generateLevelChecks()...)
statements = append(statements, s.generateFluxASTNotifyPipe()) statements = append(statements, s.generateFluxASTNotifyPipe(e))
return statements return statements
} }
@ -77,9 +76,9 @@ func (s *Telegram) generateFluxASTEndpoint(e *endpoint.Telegram) ast.Statement {
return flux.DefineVariable("telegram_endpoint", call) return flux.DefineVariable("telegram_endpoint", call)
} }
func (s *Telegram) generateFluxASTNotifyPipe() ast.Statement { func (s *Telegram) generateFluxASTNotifyPipe(e *endpoint.Telegram) ast.Statement {
endpointProps := []*ast.Property{} endpointProps := []*ast.Property{}
endpointProps = append(endpointProps, flux.Property("channel", flux.String(s.Channel))) endpointProps = append(endpointProps, flux.Property("channel", flux.String(e.Channel)))
endpointProps = append(endpointProps, flux.Property("text", flux.String(s.MessageTemplate))) endpointProps = append(endpointProps, flux.Property("text", flux.String(s.MessageTemplate)))
endpointProps = append(endpointProps, flux.Property("silent", s.generateSilent())) endpointProps = append(endpointProps, flux.Property("silent", s.generateSilent()))
endpointFn := flux.Function(flux.FunctionParams("r"), flux.Object(endpointProps...)) endpointFn := flux.Function(flux.FunctionParams("r"), flux.Object(endpointProps...))
@ -132,12 +131,6 @@ func (s Telegram) Valid() error {
Msg: "Telegram MessageTemplate is invalid", Msg: "Telegram MessageTemplate is invalid",
} }
} }
if s.Channel == "" {
return &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "Telegram Channel is invalid",
}
}
return nil return nil
} }

View File

@ -31,7 +31,6 @@ func TestTelegram_GenerateFlux(t *testing.T) {
}, },
rule: &rule.Telegram{ rule: &rule.Telegram{
MessageTemplate: "blah", MessageTemplate: "blah",
Channel: "-12345",
Base: rule.Base{ Base: rule.Base{
ID: 1, ID: 1,
EndpointID: 3, EndpointID: 3,
@ -69,11 +68,11 @@ func TestTelegram_GenerateFlux(t *testing.T) {
ID: idPtr(3), ID: idPtr(3),
Name: "foo", Name: "foo",
}, },
Token: influxdb.SecretField{Key: "3-key"}, Token: influxdb.SecretField{Key: "3-key"},
Channel: "-12345",
}, },
rule: &rule.Telegram{ rule: &rule.Telegram{
MessageTemplate: "blah", MessageTemplate: "blah",
Channel: "-12345",
Base: rule.Base{ Base: rule.Base{
ID: 1, ID: 1,
EndpointID: 3, EndpointID: 3,
@ -139,11 +138,11 @@ all_statuses
ID: idPtr(3), ID: idPtr(3),
Name: "foo", Name: "foo",
}, },
Token: influxdb.SecretField{Key: "3-key"}, Token: influxdb.SecretField{Key: "3-key"},
Channel: "-12345",
}, },
rule: &rule.Telegram{ rule: &rule.Telegram{
MessageTemplate: "blah", MessageTemplate: "blah",
Channel: "-12345",
DisableWebPagePreview: true, DisableWebPagePreview: true,
ParseMode: "HTML", ParseMode: "HTML",
Base: rule.Base{ Base: rule.Base{
@ -233,7 +232,6 @@ func TestTelegram_Valid(t *testing.T) {
name: "valid template", name: "valid template",
rule: &rule.Telegram{ rule: &rule.Telegram{
MessageTemplate: "blah", MessageTemplate: "blah",
Channel: "-12345",
Base: rule.Base{ Base: rule.Base{
ID: 1, ID: 1,
EndpointID: 3, EndpointID: 3,
@ -255,7 +253,6 @@ func TestTelegram_Valid(t *testing.T) {
name: "missing MessageTemplate", name: "missing MessageTemplate",
rule: &rule.Telegram{ rule: &rule.Telegram{
MessageTemplate: "", MessageTemplate: "",
Channel: "-12345",
Base: rule.Base{ Base: rule.Base{
ID: 1, ID: 1,
EndpointID: 3, EndpointID: 3,
@ -280,7 +277,6 @@ func TestTelegram_Valid(t *testing.T) {
name: "missing EndpointID", name: "missing EndpointID",
rule: &rule.Telegram{ rule: &rule.Telegram{
MessageTemplate: "", MessageTemplate: "",
Channel: "-12345",
Base: rule.Base{ Base: rule.Base{
ID: 1, ID: 1,
// EndpointID: 3, // EndpointID: 3,
@ -301,30 +297,6 @@ func TestTelegram_Valid(t *testing.T) {
Msg: "Notification Rule EndpointID is invalid", Msg: "Notification Rule EndpointID is invalid",
}, },
}, },
{
name: "missing Channel",
rule: &rule.Telegram{
MessageTemplate: "blah",
Base: rule.Base{
ID: 1,
EndpointID: 3,
OwnerID: 4,
OrgID: 5,
Name: "foo",
Every: mustDuration("1h"),
StatusRules: []notification.StatusRule{
{
CurrentLevel: notification.Critical,
},
},
TagRules: []notification.TagRule{},
},
},
err: &influxdb.Error{
Code: influxdb.EInvalid,
Msg: "Telegram Channel is invalid",
},
},
} }
for _, c := range cases { for _, c := range cases {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {

View File

@ -43,8 +43,14 @@ const EndpointOptions: FC<Props> = ({
) )
} }
case 'telegram': { case 'telegram': {
const {token} = endpoint as TelegramNotificationEndpoint const {token, channel} = endpoint as TelegramNotificationEndpoint
return <EndpointOptionsTelegram token={token} onChange={onChange} /> return (
<EndpointOptionsTelegram
token={token}
channel={channel}
onChange={onChange}
/>
)
} }
case 'http': { case 'http': {
const { const {

View File

@ -13,10 +13,11 @@ import {
interface Props { interface Props {
token: string token: string
channel: string
onChange: (e: ChangeEvent<HTMLInputElement>) => void onChange: (e: ChangeEvent<HTMLInputElement>) => void
} }
const EndpointOptionsTelegram: FC<Props> = ({token, onChange}) => { const EndpointOptionsTelegram: FC<Props> = ({token, channel, onChange}) => {
return ( return (
<Panel> <Panel>
<Panel.Header> <Panel.Header>
@ -35,6 +36,15 @@ const EndpointOptionsTelegram: FC<Props> = ({token, onChange}) => {
type={InputType.Password} type={InputType.Password}
/> />
</FormElement> </FormElement>
<FormElement label="Chat ID">
<Input
name="channel"
value={channel}
testID="channel"
onChange={onChange}
type={InputType.Text}
/>
</FormElement>
</Grid.Column> </Grid.Column>
</Grid.Row> </Grid.Row>
</Grid> </Grid>

View File

@ -64,6 +64,7 @@ export const reducer = (
...baseProps, ...baseProps,
type: 'telegram', type: 'telegram',
token: '', token: '',
channel: '',
} }
} }
} }

View File

@ -63,11 +63,10 @@ const RuleMessageContents: FC<Props> = ({rule}) => {
) )
} }
case 'telegram': { case 'telegram': {
const {messageTemplate, channel} = rule const {messageTemplate} = rule
return ( return (
<TelegramMessage <TelegramMessage
messageTemplate={messageTemplate} messageTemplate={messageTemplate}
channel={channel}
onChange={onChange} onChange={onChange}
/> />
) )

View File

@ -2,7 +2,7 @@
import React, {FC, ChangeEvent} from 'react' import React, {FC, ChangeEvent} from 'react'
// Components // Components
import {Form, TextArea, Input} from '@influxdata/clockface' import {Form, TextArea} from '@influxdata/clockface'
import {TelegramNotificationRuleBase} from 'src/types/alerting' import {TelegramNotificationRuleBase} from 'src/types/alerting'
interface EventHandlers { interface EventHandlers {
@ -10,23 +10,19 @@ interface EventHandlers {
} }
type Props = Omit<TelegramNotificationRuleBase, 'type'> & EventHandlers type Props = Omit<TelegramNotificationRuleBase, 'type'> & EventHandlers
const TelegramMessage: FC<Props> = ({messageTemplate, channel, onChange}) => { const TelegramMessage: FC<Props> = ({messageTemplate, onChange}) => {
return ( return (
<> <Form.Element label="Message Template">
<Form.Element label="Channel ID"> <TextArea
<Input value={channel} name="channel" onChange={onChange} /> name="messageTemplate"
</Form.Element> testID="slack-message-template--textarea"
<Form.Element label="Message Template"> value={messageTemplate}
<TextArea onChange={onChange}
name="messageTemplate" rows={3}
testID="slack-message-template--textarea" />
value={messageTemplate} </Form.Element>
onChange={onChange} /*
rows={3} // keep it simple, the following elements are possible, but too advanced
/>
</Form.Element>
{/*
// keep it simple, these following elements are possible, but too advanced
<Form.Element label="Parse Mode"> <Form.Element label="Parse Mode">
<Input value={parseMode} name="parseMode" onChange={onChange} /> <Input value={parseMode} name="parseMode" onChange={onChange} />
</Form.Element> </Form.Element>
@ -38,8 +34,7 @@ const TelegramMessage: FC<Props> = ({messageTemplate, channel, onChange}) => {
type={InputType.Checkbox} type={InputType.Checkbox}
/> />
</Form.Element> </Form.Element>
*/} */
</>
) )
} }

View File

@ -55,7 +55,6 @@ export const getRuleVariantDefaults = (
) )
return { return {
messageTemplate: messageTemplate, messageTemplate: messageTemplate,
channel: '',
parseMode: 'MarkdownV2', parseMode: 'MarkdownV2',
disableWebPagePreview: false, disableWebPagePreview: false,
type: 'telegram', type: 'telegram',