1
0
mirror of https://github.com/prometheus/alertmanager.git synced 2026-02-05 06:45:45 +01:00

Support global Telegram bot token (#4823)

* Support global Telegram bot token

---------

Signed-off-by: Ali Afsharzadeh <afsharzadeh8@gmail.com>
Co-authored-by: Ben Kochie <superq@gmail.com>
This commit is contained in:
Ali Afsharzadeh
2026-01-30 19:03:36 +03:30
committed by GitHub
parent f94e947edf
commit 4e48a1c07b
9 changed files with 133 additions and 11 deletions

View File

@@ -488,6 +488,10 @@ func (c *Config) UnmarshalYAML(unmarshal func(any) error) error {
return errors.New("at most one of victorops_api_key & victorops_api_key_file must be configured")
}
if c.Global.TelegramBotToken != "" && len(c.Global.TelegramBotTokenFile) > 0 {
return errors.New("at most one of telegram_bot_token & telegram_bot_token_file must be configured")
}
if len(c.Global.SMTPAuthPassword) > 0 && len(c.Global.SMTPAuthPasswordFile) > 0 {
return errors.New("at most one of smtp_auth_password & smtp_auth_password_file must be configured")
}
@@ -652,6 +656,13 @@ func (c *Config) UnmarshalYAML(unmarshal func(any) error) error {
for _, telegram := range rcv.TelegramConfigs {
telegram.HTTPConfig = cmp.Or(telegram.HTTPConfig, c.Global.HTTPConfig)
telegram.APIUrl = cmp.Or(telegram.APIUrl, c.Global.TelegramAPIUrl)
if telegram.BotToken == "" && len(telegram.BotTokenFile) == 0 {
if c.Global.TelegramBotToken == "" && len(c.Global.TelegramBotTokenFile) == 0 {
return errors.New("missing bot_token or bot_token_file on telegram_config")
}
telegram.BotToken = c.Global.TelegramBotToken
telegram.BotTokenFile = c.Global.TelegramBotTokenFile
}
}
for _, discord := range rcv.DiscordConfigs {
discord.HTTPConfig = cmp.Or(discord.HTTPConfig, c.Global.HTTPConfig)
@@ -940,6 +951,8 @@ type GlobalConfig struct {
VictorOpsAPIKey Secret `yaml:"victorops_api_key,omitempty" json:"victorops_api_key,omitempty"`
VictorOpsAPIKeyFile string `yaml:"victorops_api_key_file,omitempty" json:"victorops_api_key_file,omitempty"`
TelegramAPIUrl *URL `yaml:"telegram_api_url,omitempty" json:"telegram_api_url,omitempty"`
TelegramBotToken Secret `yaml:"telegram_bot_token,omitempty" json:"telegram_bot_token,omitempty"`
TelegramBotTokenFile string `yaml:"telegram_bot_token_file,omitempty" json:"telegram_bot_token_file,omitempty"`
WebexAPIURL *URL `yaml:"webex_api_url,omitempty" json:"webex_api_url,omitempty"`
RocketchatAPIURL *URL `yaml:"rocketchat_api_url,omitempty" json:"rocketchat_api_url,omitempty"`
RocketchatToken *Secret `yaml:"rocketchat_token,omitempty" json:"rocketchat_token,omitempty"`

View File

@@ -1144,6 +1144,68 @@ func TestVictorOpsNoAPIKey(t *testing.T) {
}
}
func TestTelegramDefaultBotToken(t *testing.T) {
conf, err := LoadFile("testdata/conf.telegram-default-bot-token.yml")
if err != nil {
t.Fatalf("Error parsing %s: %s", "testdata/conf.telegram-default-bot-token.yml", err)
}
defaultBotToken := conf.Global.TelegramBotToken
overrideBotToken := Secret("qwe456")
if defaultBotToken != conf.Receivers[0].TelegramConfigs[0].BotToken {
t.Fatalf("Invalid telegram bot token: %s\nExpected: %s", conf.Receivers[0].TelegramConfigs[0].BotToken, defaultBotToken)
}
if overrideBotToken != conf.Receivers[1].TelegramConfigs[0].BotToken {
t.Errorf("Invalid telegram bot token: %s\nExpected: %s", conf.Receivers[0].TelegramConfigs[0].BotToken, string(overrideBotToken))
}
}
func TestTelegramDefaultBotTokenFile(t *testing.T) {
conf, err := LoadFile("testdata/conf.telegram-default-bot-token-file.yml")
if err != nil {
t.Fatalf("Error parsing %s: %s", "testdata/conf.telegram-default-bot-token-file.yml", err)
}
defaultBotToken := conf.Global.TelegramBotTokenFile
overrideBotToken := "/override_file"
if defaultBotToken != conf.Receivers[0].TelegramConfigs[0].BotTokenFile {
t.Fatalf("Invalid telegram bot token file: %s\nExpected: %s", conf.Receivers[0].TelegramConfigs[0].BotTokenFile, defaultBotToken)
}
if overrideBotToken != conf.Receivers[1].TelegramConfigs[0].BotTokenFile {
t.Errorf("Invalid telegram bot token file: %s\nExpected: %s", conf.Receivers[0].TelegramConfigs[0].BotTokenFile, overrideBotToken)
}
}
func TestTelegramBothBotTokenAndFile(t *testing.T) {
_, err := LoadFile("testdata/conf.telegram-both-bot-token-and-file.yml")
if err == nil {
t.Fatalf("Expected an error parsing %s: %s", "testdata/conf.telegram-both-bot-token-and-file.yml", err)
}
if err.Error() != "at most one of telegram_bot_token & telegram_bot_token_file must be configured" {
t.Errorf("Expected: %s\nGot: %s", "at most one of telegram_bot_token & telegram_bot_token_file must be configured", err.Error())
}
}
func TestTelegramValidReceiverBothBotTokenAndFile(t *testing.T) {
_, err := LoadFile("testdata/conf.telegram-valid-receiver-both-bot-token-and-file.yml")
if err == nil {
t.Fatalf("Expected an error parsing %s: %s", "testdata/conf.telegram-valid-receiver-both-bot-token-and-file.yml", err)
}
if err.Error() != "at most one of telegram_bot_token & telegram_bot_token_file must be configured" {
t.Errorf("Expected: %s\nGot: %s", "at most one of telegram_bot_token & telegram_bot_token_file must be configured", err.Error())
}
}
func TestTelegramNoBotToken(t *testing.T) {
_, err := LoadFile("testdata/conf.telegram-no-bot-token.yml")
if err == nil {
t.Fatalf("Expected an error parsing %s: %s", "testdata/conf.telegram-no-bot-token.yml", err)
}
if err.Error() != "missing bot_token or bot_token_file on telegram_config" {
t.Errorf("Expected: %s\nGot: %s", "missing bot_token or bot_token_file on telegram_config", err.Error())
}
}
func TestOpsGenieDefaultAPIKey(t *testing.T) {
conf, err := LoadFile("testdata/conf.opsgenie-default-apikey.yml")
if err != nil {

View File

@@ -938,9 +938,6 @@ func (c *TelegramConfig) UnmarshalYAML(unmarshal func(any) error) error {
if err := unmarshal((*plain)(c)); err != nil {
return err
}
if c.BotToken == "" && c.BotTokenFile == "" {
return errors.New("missing bot_token or bot_token_file on telegram_config")
}
if c.BotToken != "" && c.BotTokenFile != "" {
return errors.New("at most one of bot_token & bot_token_file must be configured")
}

View File

@@ -1099,14 +1099,6 @@ bot_token_file: /file
`,
expected: errors.New("at most one of bot_token & bot_token_file must be configured"),
},
{
name: "with no bot_token & bot_token_file - it fails",
in: `
bot_token: ''
bot_token_file: ''
`,
expected: errors.New("missing bot_token or bot_token_file on telegram_config"),
},
{
name: "with bot_token and chat_id set - it succeeds",
in: `

View File

@@ -0,0 +1,14 @@
global:
telegram_bot_token: asd132
telegram_bot_token_file: /global_file
route:
receiver: team-X-telegram
receivers:
- name: team-X-telegram
telegram_configs:
- chat_id: 123
- name: team-Y-telegram
telegram_configs:
- chat_id: 456
bot_token: qwe456

View File

@@ -0,0 +1,13 @@
global:
telegram_bot_token_file: /global_file
route:
receiver: team-X-telegram
receivers:
- name: team-X-telegram
telegram_configs:
- chat_id: 123
- name: team-Y-telegram
telegram_configs:
- chat_id: 456
bot_token_file: /override_file

View File

@@ -0,0 +1,13 @@
global:
telegram_bot_token: asd132
route:
receiver: team-X-telegram
receivers:
- name: team-X-telegram
telegram_configs:
- chat_id: 123
- name: team-Y-telegram
telegram_configs:
- chat_id: 456
bot_token: qwe456

View File

@@ -0,0 +1,7 @@
route:
receiver: team-X-telegram
receivers:
- name: team-X-telegram
telegram_configs:
- chat_id: 123

View File

@@ -0,0 +1,11 @@
global:
telegram_bot_token: asd132
telegram_bot_token_file: /global_file
route:
receiver: team-X-telegram
receivers:
- name: team-X-telegram
telegram_configs:
- chat_id: 123
bot_token_file: /override_file