Skip to content
Open
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
13 changes: 13 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ func resolveFilepaths(baseDir string, cfg *Config) {
for _, cfg := range receiver.RocketchatConfigs {
cfg.HTTPConfig.SetDirectory(baseDir)
}
for _, cfg := range receiver.ExecConfigs {
cfg.SetDirectory(baseDir)
}
}
}

Expand Down Expand Up @@ -412,6 +415,14 @@ func (c *Config) UnmarshalYAML(unmarshal func(any) error) error {
wh.HTTPConfig = c.Global.HTTPConfig
}
}
for _, ec := range rcv.ExecConfigs {
if ec.ExecFile == "" {
if c.Global.ExecFile == "" {
return errors.New("no global executable file set")
}
ec.ExecFile = c.Global.ExecFile
}
}
for _, ec := range rcv.EmailConfigs {
if ec.TLSConfig == nil {
ec.TLSConfig = c.Global.SMTPTLSConfig
Expand Down Expand Up @@ -867,6 +878,7 @@ type GlobalConfig struct {
RocketchatTokenFile string `yaml:"rocketchat_token_file,omitempty" json:"rocketchat_token_file,omitempty"`
RocketchatTokenID *Secret `yaml:"rocketchat_token_id,omitempty" json:"rocketchat_token_id,omitempty"`
RocketchatTokenIDFile string `yaml:"rocketchat_token_id_file,omitempty" json:"rocketchat_token_id_file,omitempty"`
ExecFile string `yaml:"exec_file,omitempty" json:"exec_file,omitempty"`
}

// UnmarshalYAML implements the yaml.Unmarshaler interface for GlobalConfig.
Expand Down Expand Up @@ -1010,6 +1022,7 @@ type Receiver struct {
PagerdutyConfigs []*PagerdutyConfig `yaml:"pagerduty_configs,omitempty" json:"pagerduty_configs,omitempty"`
SlackConfigs []*SlackConfig `yaml:"slack_configs,omitempty" json:"slack_configs,omitempty"`
WebhookConfigs []*WebhookConfig `yaml:"webhook_configs,omitempty" json:"webhook_configs,omitempty"`
ExecConfigs []*ExecConfig `yaml:"exec_configs,omitempty" json:"exec_configs,omitempty"`
OpsGenieConfigs []*OpsGenieConfig `yaml:"opsgenie_configs,omitempty" json:"opsgenie_configs,omitempty"`
WechatConfigs []*WechatConfig `yaml:"wechat_configs,omitempty" json:"wechat_configs,omitempty"`
PushoverConfigs []*PushoverConfig `yaml:"pushover_configs,omitempty" json:"pushover_configs,omitempty"`
Expand Down
52 changes: 52 additions & 0 deletions config/notifiers.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ var (
},
}

// DefaultExecConfig defines default values for Exec configurations.
DefaultExecConfig = ExecConfig{
NotifierConfig: NotifierConfig{
VSendResolved: true,
},
}

// DefaultWebexConfig defines default values for Webex configurations.
DefaultWebexConfig = WebexConfig{
NotifierConfig: NotifierConfig{
Expand Down Expand Up @@ -557,6 +564,51 @@ func (c *WebhookConfig) UnmarshalYAML(unmarshal func(any) error) error {
return nil
}

// ExecConfig configures notifications via a generic exec.
type ExecConfig struct {
NotifierConfig `yaml:",inline" json:",inline"`

// WorkingDir specifies the working directory of the command.
// If Dir is the empty string, the command is run in
// the current directory of Alertmanager.
WorkingDir string `yaml:"working_dir" json:"working_dir"`
// ExecFile is the path of the command to run. Relative values
// will be resolved against WorkingDir prior to execution.
ExecFile string `yaml:"exec_file" json:"exec_file"`
// Arguments is the list of additional command line arguments
// to pass to the executable.
Arguments []string `yaml:"arguments,omitempty" json:"arguments,omitempty"`
// Environment specifies the environment of the process.
Environment map[string]string `yaml:"environment,omitempty" json:"environment,omitempty"`
// Environment specifies environment variables with values read from files.
EnvironmentFiles map[string]string `yaml:"environment_files,omitempty" json:"environment_files,omitempty"`

// Timeout is the maximum time allowed to invoke the command. Setting this to 0
// does not impose a timeout.
Timeout time.Duration `yaml:"timeout" json:"timeout"`
}

// SetDirectory uses [config.JoinDir] to resolver internal
// path properties to absolute values.
func (c *ExecConfig) SetDirectory(s string) {
c.WorkingDir = commoncfg.JoinDir(s, c.WorkingDir)
c.ExecFile = commoncfg.JoinDir(s, c.ExecFile)

for k, f := range c.EnvironmentFiles {
c.EnvironmentFiles[k] = commoncfg.JoinDir(s, f)
}
}

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

// WechatConfig configures notifications via Wechat.
type WechatConfig struct {
NotifierConfig `yaml:",inline" json:",inline"`
Expand Down
4 changes: 4 additions & 0 deletions config/receiver/receiver.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/prometheus/alertmanager/notify"
"github.com/prometheus/alertmanager/notify/discord"
"github.com/prometheus/alertmanager/notify/email"
"github.com/prometheus/alertmanager/notify/exec"
"github.com/prometheus/alertmanager/notify/jira"
"github.com/prometheus/alertmanager/notify/msteams"
"github.com/prometheus/alertmanager/notify/msteamsv2"
Expand Down Expand Up @@ -64,6 +65,9 @@ func BuildReceiverIntegrations(nc config.Receiver, tmpl *template.Template, logg
for i, c := range nc.WebhookConfigs {
add("webhook", i, c, func(l *slog.Logger) (notify.Notifier, error) { return webhook.New(c, tmpl, l, httpOpts...) })
}
for i, c := range nc.ExecConfigs {
add("exec", i, c, func(l *slog.Logger) (notify.Notifier, error) { return exec.New(c, tmpl, l) })
}
for i, c := range nc.EmailConfigs {
add("email", i, c, func(l *slog.Logger) (notify.Notifier, error) { return email.New(c, tmpl, l), nil })
}
Expand Down
8 changes: 8 additions & 0 deletions config/testdata/conf.good.yml
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,11 @@ receivers:
slack_configs:
- channel: '#my-channel'
image_url: 'http://some.img.com/img.png'
- name: exec-receiver
exec_configs:
- exec_file: /bin/cat
working_dir: /tmp
arguments: [ "-A" ]
environment:
LANG: C
timeout: 5s
47 changes: 47 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,8 @@ discord_configs:
[ - <discord_config>, ... ]
email_configs:
[ - <email_config>, ... ]
exec_configs:
[ - <exec_config>, ... ]
msteams_configs:
[ - <msteams_config>, ... ]
msteamsv2_configs:
Expand Down Expand Up @@ -986,6 +988,51 @@ tls_config:
[ headers: { <string>: <tmpl_string>, ... } ]
```

### `<exec_config>`

The exec receiver allows configuring a generic receiver
using executables for processing.

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

# Directory to change into before running the executable.
[ working_dir: <filepath> ]

# Script/Binary to invoke for data processing.
exec_file: <filepath>

# Commandline arguments to pass to the executable.
arguments:
[ - <string> ... ]

# Environment variables to expose to the process in addition to
# the variables the Alertmanager process already inherited.
environment:
[ <string>: <string> ... ]

# Environment variables to expose to the process in addition to
# the variables the Alertmanager process already inherited.
# The actual values are read from the specified files.
environment_files:
[ <string>: <filepath> ... ]

# The maximum time to wait for the call to complete, before interrupting the
# process and allowing it to be retried. The default value of 0s indicates that
# no timeout should be applied.
# NOTE: This will have no effect if set higher than the group_interval.
[ timeout: <duration> | default = 0s ]
```

The executable will receive data via STDIN formatted in a similar fashion as the
[webhook](#webhook_config`. The exit code is used to determine the result of the
processing:

* Success (0)
* Error but retryable (3)
* Unrecoverable error (all other status codes)

### `<msteams_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.
Expand Down
34 changes: 34 additions & 0 deletions examples/exec/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2018 Prometheus Team
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"encoding/json"
"log"
"os"

"github.com/prometheus/alertmanager/notify/exec"
)

func main() {
var msg exec.Message
err := json.NewDecoder(os.Stdin).Decode(&msg)
if err != nil {
log.Fatal(err)
}

log.Printf("version=%q, group_key=%s\n", msg.Version, msg.GroupKey)

os.Exit(exec.ExitSuccess)
}
Loading