wormhole-explorer/common/client/alert/opsgenie.go

97 lines
2.5 KiB
Go

package alert
import (
"context"
"errors"
opsgenieAlert "github.com/opsgenie/opsgenie-go-sdk-v2/alert"
"github.com/opsgenie/opsgenie-go-sdk-v2/client"
)
// RegisterAlertsFunc is the function that loads the alerts from the corresponding component.
type RegisterAlertsFunc func(cfg AlertConfig) map[string]Alert
type AlertClient interface {
CreateAlert(key string, alertCtx AlertContext) (Alert, error)
Send(ctx context.Context, alert Alert) error
CreateAndSend(ctx context.Context, key string, alertCtx AlertContext) error
}
type AlertConfig struct {
Environment string
ApiKey string
Enabled bool
}
// OpsgenieClient is the alert client.
type OpsgenieClient struct {
enabled bool
client *opsgenieAlert.Client
alerts map[string]Alert
}
// NewAlertService creates a new alert service
func NewAlertService(cfg AlertConfig, registerAlertsFunc RegisterAlertsFunc) (*OpsgenieClient, error) {
// load the alert templates from the corresponding component
alerts := registerAlertsFunc(cfg)
// create the opsgenie alert client
alertClient, err := opsgenieAlert.NewClient(&client.Config{ApiKey: cfg.ApiKey})
if err != nil {
return nil, err
}
return &OpsgenieClient{
client: alertClient,
alerts: alerts,
enabled: cfg.Enabled}, nil
}
// CreateAlert creates an alert by key and alert context.
// The key is the alert name, and with it we can get the alert from the registerd alerts.
// The alert context contains the alert execution data
func (s *OpsgenieClient) CreateAlert(key string, alertCtx AlertContext) (Alert, error) {
if !s.enabled {
return Alert{}, errors.New("alert not enabled")
}
// check alert exists.
alert, ok := s.alerts[key]
if !ok {
return Alert{}, errors.New("alert not found")
}
alert.context = alertCtx
return alert, nil
}
// Send sends an alert to opsgenie.
func (s *OpsgenieClient) Send(ctx context.Context, alert Alert) error {
if !s.enabled {
return errors.New("alert not enabled")
}
// check alert exists
if alert.Message == "" {
return errors.New("message can not be empty")
}
// convert alert to an opsgenie alerte request.
alertRequest := alert.toOpsgenieRequest()
// create the request
_, err := s.client.Create(ctx, &alertRequest)
if err != nil {
return err
}
return nil
}
// CreateAndSend creates an alert by key and alert context and sends it to opsgenie.
func (s *OpsgenieClient) CreateAndSend(ctx context.Context, key string, alertCtx AlertContext) error {
alert, err := s.CreateAlert(key, alertCtx)
if err != nil {
return err
}
return s.Send(ctx, alert)
}