package notifier import ( "bytes" "context" "fmt" "io/ioutil" "net/http" "strings" ) // AlertManager represents integration provider with Prometheus alert manager // https://github.com/prometheus/alertmanager type AlertManager struct { addr string alertURL string basicAuthUser string basicAuthPass string argFunc AlertURLGenerator client *http.Client } // Addr returns address where alerts are sent. func (am AlertManager) Addr() string { return am.addr } // Send an alert or resolve message func (am *AlertManager) Send(ctx context.Context, alerts []Alert) error { b := &bytes.Buffer{} writeamRequest(b, alerts, am.argFunc) req, err := http.NewRequest("POST", am.alertURL, b) if err != nil { return err } req.Header.Set("Content-Type", "application/json") req = req.WithContext(ctx) if am.basicAuthPass != "" { req.SetBasicAuth(am.basicAuthUser, am.basicAuthPass) } resp, err := am.client.Do(req) if err != nil { return err } defer func() { _ = resp.Body.Close() }() if resp.StatusCode != http.StatusOK { body, err := ioutil.ReadAll(resp.Body) if err != nil { return fmt.Errorf("failed to read response from %q: %w", am.alertURL, err) } return fmt.Errorf("invalid SC %d from %q; response body: %s", resp.StatusCode, am.alertURL, string(body)) } return nil } // AlertURLGenerator returns URL to single alert by given name type AlertURLGenerator func(Alert) string const alertManagerPath = "/api/v2/alerts" // NewAlertManager is a constructor for AlertManager func NewAlertManager(alertManagerURL, user, pass string, fn AlertURLGenerator, c *http.Client) *AlertManager { url := strings.TrimSuffix(alertManagerURL, "/") + alertManagerPath return &AlertManager{ addr: alertManagerURL, alertURL: url, argFunc: fn, client: c, basicAuthUser: user, basicAuthPass: pass, } }