Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"github.com/prometheus/alertmanager/notify/jira"
"github.com/prometheus/alertmanager/notify/mattermost"
"github.com/prometheus/alertmanager/notify/msteams"
"github.com/prometheus/alertmanager/notify/slack"
"github.com/prometheus/alertmanager/notify/webhook"
"github.com/prometheus/alertmanager/timeinterval"
"github.com/prometheus/alertmanager/tracing"
Expand Down Expand Up @@ -412,7 +413,7 @@ func (c *Config) UnmarshalYAML(unmarshal func(any) error) error {
}
for _, sc := range rcv.SlackConfigs {
if sc == nil {
sc = &SlackConfig{}
sc = &slack.Config{}
}
sc.AppURL = cmp.Or(sc.AppURL, c.Global.SlackAppURL)
if sc.AppURL == nil {
Expand Down Expand Up @@ -948,7 +949,7 @@ type Receiver struct {
EmailConfigs []*EmailConfig `yaml:"email_configs,omitempty" json:"email_configs,omitempty"`
IncidentioConfigs []*incidentio.IncidentioConfig `yaml:"incidentio_configs,omitempty" json:"incidentio_configs,omitempty"`
PagerdutyConfigs []*PagerdutyConfig `yaml:"pagerduty_configs,omitempty" json:"pagerduty_configs,omitempty"`
SlackConfigs []*SlackConfig `yaml:"slack_configs,omitempty" json:"slack_configs,omitempty"`
SlackConfigs []*slack.Config `yaml:"slack_configs,omitempty" json:"slack_configs,omitempty"`
WebhookConfigs []*webhook.WebhookConfig `yaml:"webhook_configs,omitempty" json:"webhook_configs,omitempty"`
OpsGenieConfigs []*OpsGenieConfig `yaml:"opsgenie_configs,omitempty" json:"opsgenie_configs,omitempty"`
WechatConfigs []*WechatConfig `yaml:"wechat_configs,omitempty" json:"wechat_configs,omitempty"`
Expand Down
171 changes: 0 additions & 171 deletions config/notifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,6 @@ var (
ClientURL: `{{ template "pagerduty.default.clientURL" . }}`,
}

// DefaultSlackConfig defines default values for Slack configurations.
DefaultSlackConfig = SlackConfig{
NotifierConfig: amcommoncfg.NotifierConfig{
VSendResolved: false,
},
Color: `{{ template "slack.default.color" . }}`,
Username: `{{ template "slack.default.username" . }}`,
Title: `{{ template "slack.default.title" . }}`,
TitleLink: `{{ template "slack.default.titlelink" . }}`,
IconEmoji: `{{ template "slack.default.iconemoji" . }}`,
IconURL: `{{ template "slack.default.iconurl" . }}`,
Pretext: `{{ template "slack.default.pretext" . }}`,
Text: `{{ template "slack.default.text" . }}`,
Fallback: `{{ template "slack.default.fallback" . }}`,
CallbackID: `{{ template "slack.default.callbackid" . }}`,
Footer: `{{ template "slack.default.footer" . }}`,
}
// DefaultRocketchatConfig defines default values for Rocketchat configurations.
DefaultRocketchatConfig = RocketchatConfig{
NotifierConfig: amcommoncfg.NotifierConfig{
Expand Down Expand Up @@ -343,160 +326,6 @@ func (c *PagerdutyConfig) UnmarshalYAML(unmarshal func(any) error) error {
return nil
}

// SlackAction configures a single Slack action that is sent with each notification.
// 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"`
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.
func (c *SlackAction) UnmarshalYAML(unmarshal func(any) error) error {
type plain SlackAction
if err := unmarshal((*plain)(c)); err != nil {
return err
}
if c.Type == "" {
return errors.New("missing type in Slack action configuration")
}
if c.Text == "" {
return errors.New("missing text in Slack action configuration")
}
if c.URL != "" {
// Clear all message action fields.
c.Name = ""
c.Value = ""
c.ConfirmField = nil
} else if c.Name != "" {
c.URL = ""
} else {
return errors.New("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(any) error) error {
type plain SlackConfirmationField
if err := unmarshal((*plain)(c)); err != nil {
return err
}
if c.Text == "" {
return errors.New("missing text in Slack confirmation configuration")
}
return nil
}

// SlackField configures a single Slack field that is sent with each notification.
// Each field must contain a title, value, and optionally, a boolean value to indicate if the field
// is short enough to be displayed next to other fields designated as short.
// See https://api.slack.com/docs/message-attachments#fields for more information.
type SlackField struct {
Title string `yaml:"title,omitempty" json:"title,omitempty"`
Value string `yaml:"value,omitempty" json:"value,omitempty"`
Short *bool `yaml:"short,omitempty" json:"short,omitempty"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface for SlackField.
func (c *SlackField) UnmarshalYAML(unmarshal func(any) error) error {
type plain SlackField
if err := unmarshal((*plain)(c)); err != nil {
return err
}
if c.Title == "" {
return errors.New("missing title in Slack field configuration")
}
if c.Value == "" {
return errors.New("missing value in Slack field configuration")
}
return nil
}

// SlackConfig configures notifications via Slack.
type SlackConfig struct {
amcommoncfg.NotifierConfig `yaml:",inline" json:",inline"`

HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"`

APIURL *amcommoncfg.SecretURL `yaml:"api_url,omitempty" json:"api_url,omitempty"`
APIURLFile string `yaml:"api_url_file,omitempty" json:"api_url_file,omitempty"`
AppToken commoncfg.Secret `yaml:"app_token,omitempty" json:"app_token,omitempty"`
AppTokenFile string `yaml:"app_token_file,omitempty" json:"app_token_file,omitempty"`
AppURL *amcommoncfg.URL `yaml:"app_url,omitempty" json:"app_url,omitempty"`

// Slack channel override, (like #other-channel or @username).
Channel string `yaml:"channel,omitempty" json:"channel,omitempty"`
Username string `yaml:"username,omitempty" json:"username,omitempty"`
Color string `yaml:"color,omitempty" json:"color,omitempty"`

Title string `yaml:"title,omitempty" json:"title,omitempty"`
TitleLink string `yaml:"title_link,omitempty" json:"title_link,omitempty"`
Pretext string `yaml:"pretext,omitempty" json:"pretext,omitempty"`
Text string `yaml:"text,omitempty" json:"text,omitempty"`
MessageText string `yaml:"message_text,omitempty" json:"message_text,omitempty"`
Fields []*SlackField `yaml:"fields,omitempty" json:"fields,omitempty"`
ShortFields bool `yaml:"short_fields" json:"short_fields,omitempty"`
Footer string `yaml:"footer,omitempty" json:"footer,omitempty"`
Fallback string `yaml:"fallback,omitempty" json:"fallback,omitempty"`
CallbackID string `yaml:"callback_id,omitempty" json:"callback_id,omitempty"`
IconEmoji string `yaml:"icon_emoji,omitempty" json:"icon_emoji,omitempty"`
IconURL string `yaml:"icon_url,omitempty" json:"icon_url,omitempty"`
ImageURL string `yaml:"image_url,omitempty" json:"image_url,omitempty"`
ThumbURL string `yaml:"thumb_url,omitempty" json:"thumb_url,omitempty"`
LinkNames bool `yaml:"link_names" json:"link_names,omitempty"`
MrkdwnIn []string `yaml:"mrkdwn_in,omitempty" json:"mrkdwn_in,omitempty"`
Actions []*SlackAction `yaml:"actions,omitempty" json:"actions,omitempty"`

// UpdateMessage enables updating existing Slack messages instead of creating new ones.
// Requires bot token with chat:write scope. Webhook URLs do not support updates.

UpdateMessage bool `yaml:"update_message" json:"update_message,omitempty"`
// Timeout is the maximum time allowed to invoke the slack. Setting this to 0
// does not impose a timeout.
Timeout time.Duration `yaml:"timeout" json:"timeout"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface.
func (c *SlackConfig) UnmarshalYAML(unmarshal func(any) error) error {
*c = DefaultSlackConfig
type plain SlackConfig
if err := unmarshal((*plain)(c)); err != nil {
return err
}

if c.APIURL != nil && len(c.APIURLFile) > 0 {
return errors.New("at most one of api_url & api_url_file must be configured")
}
if c.AppToken != "" && len(c.AppTokenFile) > 0 {
return errors.New("at most one of app_token & app_token_file must be configured")
}
if (c.APIURL != nil || len(c.APIURLFile) > 0) && (c.AppToken != "" || len(c.AppTokenFile) > 0) {
return errors.New("at most one of api_url/api_url_file & app_token/app_token_file must be configured")
}

if c.UpdateMessage && c.APIURL.String() != "https://slack.com/api/chat.postMessage" {
return errors.New("update_message can only be used with bot tokens. api_url must be set to https://slack.com/api/chat.postMessage")
}

return nil
}

// WechatConfig configures notifications via Wechat.
type WechatConfig struct {
amcommoncfg.NotifierConfig `yaml:",inline" json:",inline"`
Expand Down
Loading
Loading