Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(3920): add msteamsv2 receiver #4024

Merged
merged 7 commits into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 2 additions & 2 deletions asset/assets_vfsdata.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,9 @@ func resolveFilepaths(baseDir string, cfg *Config) {
for _, cfg := range receiver.MSTeamsConfigs {
cfg.HTTPConfig.SetDirectory(baseDir)
}
for _, cfg := range receiver.MSTeamsV2Configs {
cfg.HTTPConfig.SetDirectory(baseDir)
}
for _, cfg := range receiver.JiraConfigs {
cfg.HTTPConfig.SetDirectory(baseDir)
}
Expand Down Expand Up @@ -551,6 +554,14 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
return fmt.Errorf("no msteams webhook URL or URLFile provided")
}
}
for _, msteamsv2 := range rcv.MSTeamsV2Configs {
if msteamsv2.HTTPConfig == nil {
msteamsv2.HTTPConfig = c.Global.HTTPConfig
}
if msteamsv2.WebhookURL == nil && len(msteamsv2.WebhookURLFile) == 0 {
return fmt.Errorf("no msteamsv2 webhook URL or URLFile provided")
gotjosh marked this conversation as resolved.
Show resolved Hide resolved
}
}
for _, jira := range rcv.JiraConfigs {
if jira.HTTPConfig == nil {
jira.HTTPConfig = c.Global.HTTPConfig
Expand Down Expand Up @@ -935,6 +946,7 @@ type Receiver struct {
TelegramConfigs []*TelegramConfig `yaml:"telegram_configs,omitempty" json:"telegram_configs,omitempty"`
WebexConfigs []*WebexConfig `yaml:"webex_configs,omitempty" json:"webex_configs,omitempty"`
MSTeamsConfigs []*MSTeamsConfig `yaml:"msteams_configs,omitempty" json:"msteams_configs,omitempty"`
MSTeamsV2Configs []*MSTeamsV2Config `yaml:"msteamsv2_configs,omitempty" json:"msteamsv2_configs,omitempty"`
JiraConfigs []*JiraConfig `yaml:"jira_configs,omitempty" json:"jira_configs,omitempty"`
}

Expand Down
36 changes: 36 additions & 0 deletions config/notifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,14 @@ var (
Text: `{{ template "msteams.default.text" . }}`,
}

DefaultMSTeamsV2Config = MSTeamsV2Config{
NotifierConfig: NotifierConfig{
VSendResolved: true,
},
Title: `{{ template "msteamsv2.default.title" . }}`,
Text: `{{ template "msteamsv2.default.text" . }}`,
}

DefaultJiraConfig = JiraConfig{
NotifierConfig: NotifierConfig{
VSendResolved: true,
Expand Down Expand Up @@ -836,6 +844,34 @@ func (c *MSTeamsConfig) UnmarshalYAML(unmarshal func(interface{}) error) error {
return nil
}

type MSTeamsV2Config struct {
NotifierConfig `yaml:",inline" json:",inline"`
HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"`
WebhookURL *SecretURL `yaml:"webhook_url,omitempty" json:"webhook_url,omitempty"`
WebhookURLFile string `yaml:"webhook_url_file,omitempty" json:"webhook_url_file,omitempty"`

Title string `yaml:"title,omitempty" json:"title,omitempty"`
Text string `yaml:"text,omitempty" json:"text,omitempty"`
}

func (c *MSTeamsV2Config) UnmarshalYAML(unmarshal func(interface{}) error) error {
*c = DefaultMSTeamsV2Config
type plain MSTeamsV2Config
if err := unmarshal((*plain)(c)); err != nil {
return err
}

if c.WebhookURL == nil && c.WebhookURLFile == "" {
return fmt.Errorf("one of webhook_url or webhook_url_file must be configured")
gotjosh marked this conversation as resolved.
Show resolved Hide resolved
}

if c.WebhookURL != nil && len(c.WebhookURLFile) > 0 {
return fmt.Errorf("at most one of webhook_url & webhook_url_file must be configured")
gotjosh marked this conversation as resolved.
Show resolved Hide resolved
}

return nil
}

type JiraConfig struct {
NotifierConfig `yaml:",inline" json:",inline"`
HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions config/receiver/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/prometheus/alertmanager/notify/email"
"github.com/prometheus/alertmanager/notify/jira"
"github.com/prometheus/alertmanager/notify/msteams"
"github.com/prometheus/alertmanager/notify/msteamsv2"
"github.com/prometheus/alertmanager/notify/opsgenie"
"github.com/prometheus/alertmanager/notify/pagerduty"
"github.com/prometheus/alertmanager/notify/pushover"
Expand Down Expand Up @@ -93,6 +94,9 @@ func BuildReceiverIntegrations(nc config.Receiver, tmpl *template.Template, logg
for i, c := range nc.MSTeamsConfigs {
add("msteams", i, c, func(l log.Logger) (notify.Notifier, error) { return msteams.New(c, tmpl, l, httpOpts...) })
}
for i, c := range nc.MSTeamsV2Configs {
add("msteamsv2", i, c, func(l log.Logger) (notify.Notifier, error) { return msteamsv2.New(c, tmpl, l, httpOpts...) })
}
for i, c := range nc.JiraConfigs {
add("jira", i, c, func(l log.Logger) (notify.Notifier, error) { return jira.New(c, tmpl, l, httpOpts...) })
}
Expand Down
38 changes: 38 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -700,6 +700,8 @@ email_configs:
[ - <email_config>, ... ]
msteams_configs:
[ - <msteams_config>, ... ]
msteamsv2_configs:
[ - <msteamsv2_config>, ... ]
jira_configs:
[ - <jira_config>, ... ]
opsgenie_configs:
Expand Down Expand Up @@ -927,6 +929,8 @@ tls_config:

Microsoft Teams notifications are sent via the [Incoming Webhooks](https://learn.microsoft.com/en-us/microsoftteams/platform/webhooks-and-connectors/what-are-webhooks-and-connectors) API endpoint.

DEPRECATION NOTICE: Microsoft is deprecating the creation and usage of [Microsoft 365 connectors via Microsoft Teams](https://devblogs.microsoft.com/microsoft365dev/retirement-of-office-365-connectors-within-microsoft-teams/). Consider migrating to using [Workflows](https://learn.microsoft.com/en-us/power-automate/teams/send-a-message-in-teams) with the msteamsv2 config.

```yaml
# Whether to notify about resolved alerts.
[ send_resolved: <boolean> | default = true ]
Expand All @@ -949,6 +953,40 @@ Microsoft Teams notifications are sent via the [Incoming Webhooks](https://learn
[ http_config: <http_config> | default = global.http_config ]
```

### `<msteamsv2_config>`

Microsoft Teams v2 notifications using the new message format with adaptive cards as required by [Workflow](https://support.microsoft.com/en-us/office/creating-a-workflow-from-a-channel-in-teams-242eb8f2-f328-45be-b81f-9817b51a5f0e).

#### How to create a workflow

1. Select the workflow template, `Post to a channel when a webhook request is received`
gotjosh marked this conversation as resolved.
Show resolved Hide resolved
2. Select `Microsoft Teams Team` you want to receive the notification
3. Select `Microsoft Teams Channel` you want to receive the notification

After that, you can get the webhook URL.

A Power Automate license is required to use this feature. You can get details
gotjosh marked this conversation as resolved.
Show resolved Hide resolved
from [Types of Power Automate licenses](https://learn.microsoft.com/en-us/power-platform/admin/power-automate-licensing/types) and [Office 365 licenses](https://learn.microsoft.com/en-us/power-platform/admin/power-automate-licensing/faqs#what-power-automate-capabilities-are-included-in-office-365-licenses).

```yaml
# Whether to notify about resolved alerts.
[ send_resolved: <boolean> | default = true ]

# The incoming webhook URL.
# webhook_url and webhook_url_file are mutually exclusive.
[ webhook_url: <secret> ]
[ webhook_url_file: <filepath> ]

# Message title template.
[ title: <tmpl_string> | default = '{{ template "msteamsv2.default.title" . }}' ]

# Message body template.
[ text: <tmpl_string> | default = '{{ template "msteamsv2.default.text" . }}' ]

# The HTTP client's configuration.
[ http_config: <http_config> | default = global.http_config ]
```

### `<jira_config>`

JIRA notifications are sent via [JIRA Rest API v2](https://developer.atlassian.com/cloud/jira/platform/rest/v2/intro/)
Expand Down
Loading
Loading