[notify/slack] Add name, value, SlackConfirmationField to slack action (#1557)

Signed-off-by: Arno Uhlig <arno.uhlig@sap.com>
This commit is contained in:
Arno Uhlig 2018-10-29 15:55:43 +01:00 committed by Max Inden
parent 0d94ec2268
commit b63b560074
3 changed files with 138 additions and 10 deletions

View File

@ -247,13 +247,16 @@ func (c *PagerdutyConfig) UnmarshalYAML(unmarshal func(interface{}) error) error
}
// SlackAction configures a single Slack action that is sent with each notification.
// Each action must contain a type, text, and url.
// See https://api.slack.com/docs/message-attachments#action_fields for more information.
// See https://api.slack.com/docs/message-attachments#action_fields and https://api.slack.com/docs/message-buttons
// for more information.
type SlackAction struct {
Type string `yaml:"type,omitempty" json:"type,omitempty"`
Text string `yaml:"text,omitempty" json:"text,omitempty"`
URL string `yaml:"url,omitempty" json:"url,omitempty"`
Style string `yaml:"style,omitempty" json:"style,omitempty"`
Type string `yaml:"type,omitempty" json:"type,omitempty"`
Text string `yaml:"text,omitempty" json:"text,omitempty"`
URL string `yaml:"url,omitempty" json:"url,omitempty"`
Style string `yaml:"style,omitempty" json:"style,omitempty"`
Name string `yaml:"name,omitempty" json:"name,omitempty"`
Value string `yaml:"value,omitempty" json:"value,omitempty"`
ConfirmField *SlackConfirmationField `yaml:"confirm,omitempty" json:"confirm,omitempty"`
}
// UnmarshalYAML implements the yaml.Unmarshaler interface for SlackAction.
@ -266,10 +269,39 @@ func (c *SlackAction) UnmarshalYAML(unmarshal func(interface{}) error) error {
return fmt.Errorf("missing type in Slack action configuration")
}
if c.Text == "" {
return fmt.Errorf("missing value in Slack text configuration")
return fmt.Errorf("missing text in Slack action configuration")
}
if c.URL == "" {
return fmt.Errorf("missing value in Slack url configuration")
if c.URL != "" {
// Clear all message action fields.
c.Name = ""
c.Value = ""
c.ConfirmField = nil
} else if c.Name != "" {
c.URL = ""
} else {
return fmt.Errorf("missing name or url in Slack action configuration")
}
return nil
}
// SlackConfirmationField protect users from destructive actions or particularly distinguished decisions
// by asking them to confirm their button click one more time.
// See https://api.slack.com/docs/interactive-message-field-guide#confirmation_fields for more information.
type SlackConfirmationField struct {
Text string `yaml:"text,omitempty" json:"text,omitempty"`
Title string `yaml:"title,omitempty" json:"title,omitempty"`
OkText string `yaml:"ok_text,omitempty" json:"ok_text,omitempty"`
DismissText string `yaml:"dismiss_text,omitempty" json:"dismiss_text,omitempty"`
}
// UnmarshalYAML implements the yaml.Unmarshaler interface for SlackConfirmationField.
func (c *SlackConfirmationField) UnmarshalYAML(unmarshal func(interface{}) error) error {
type plain SlackConfirmationField
if err := unmarshal((*plain)(c)); err != nil {
return err
}
if c.Text == "" {
return fmt.Errorf("missing text in Slack confirmation configuration")
}
return nil
}

View File

@ -435,6 +435,89 @@ fields:
}
}
func TestSlackActionsValidation(t *testing.T) {
in := `
actions:
- type: button
text: hello
url: https://localhost
style: danger
- type: button
text: hello
name: something
style: default
confirm:
title: please confirm
text: are you sure?
ok_text: yes
dismiss_text: no
`
expected := []*SlackAction{
{
Type: "button",
Text: "hello",
URL: "https://localhost",
Style: "danger",
},
{
Type: "button",
Text: "hello",
Name: "something",
Style: "default",
ConfirmField: &SlackConfirmationField{
Title: "please confirm",
Text: "are you sure?",
OkText: "yes",
DismissText: "no",
},
},
}
var cfg SlackConfig
err := yaml.UnmarshalStrict([]byte(in), &cfg)
if err != nil {
t.Fatalf("\nerror returned when none expected, error:\n%v", err)
}
for index, action := range cfg.Actions {
exp := expected[index]
if action.Type != exp.Type {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.Type, action.Type)
}
if action.Text != exp.Text {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.Text, action.Text)
}
if action.URL != exp.URL {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.URL, action.URL)
}
if action.Style != exp.Style {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.Style, action.Style)
}
if action.Name != exp.Name {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.Name, action.Name)
}
if action.Value != exp.Value {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.Value, action.Value)
}
if action.ConfirmField != nil && exp.ConfirmField == nil || action.ConfirmField == nil && exp.ConfirmField != nil {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.ConfirmField, action.ConfirmField)
} else if action.ConfirmField != nil && exp.ConfirmField != nil {
if action.ConfirmField.Title != exp.ConfirmField.Title {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.ConfirmField.Title, action.ConfirmField.Title)
}
if action.ConfirmField.Text != exp.ConfirmField.Text {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.ConfirmField.Text, action.ConfirmField.Text)
}
if action.ConfirmField.OkText != exp.ConfirmField.OkText {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.ConfirmField.OkText, action.ConfirmField.OkText)
}
if action.ConfirmField.DismissText != exp.ConfirmField.DismissText {
t.Errorf("\nexpected:\n%v\ngot:\n%v", exp.ConfirmField.DismissText, action.ConfirmField.DismissText)
}
}
}
}
func newBoolPointer(b bool) *bool {
return &b
}

View File

@ -770,12 +770,25 @@ func (n *Slack) Notify(ctx context.Context, as ...*types.Alert) (bool, error) {
if numActions > 0 {
var actions = make([]config.SlackAction, numActions)
for index, action := range n.conf.Actions {
actions[index] = config.SlackAction{
slackAction := config.SlackAction{
Type: tmplText(action.Type),
Text: tmplText(action.Text),
URL: tmplText(action.URL),
Style: tmplText(action.Style),
Name: tmplText(action.Name),
Value: tmplText(action.Value),
}
if action.ConfirmField != nil {
slackAction.ConfirmField = &config.SlackConfirmationField{
Title: tmplText(action.ConfirmField.Title),
Text: tmplText(action.ConfirmField.Text),
OkText: tmplText(action.ConfirmField.OkText),
DismissText: tmplText(action.ConfirmField.DismissText),
}
}
actions[index] = slackAction
}
attachment.Actions = actions
}