-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add opsgenie client + error saving vaa alert in fly component (#442)
- Loading branch information
Showing
14 changed files
with
434 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
package alert | ||
|
||
import ( | ||
"fmt" | ||
|
||
opsgenieAlert "github.com/opsgenie/opsgenie-go-sdk-v2/alert" | ||
) | ||
|
||
// Respoder struct to define alert routing notifications. | ||
type Responder struct { | ||
Id string | ||
Type string | ||
Name string | ||
Username string | ||
} | ||
|
||
// Priority is the alert priority. | ||
type Priority string | ||
|
||
const ( | ||
CRITICAL Priority = "CRITICAL" | ||
HIGH Priority = "HIGH" | ||
MODERATE Priority = "MODERATE" | ||
LOW Priority = "LOW" | ||
INFORMATIONAL Priority = "INFORMATIONAL" | ||
) | ||
|
||
// Alert is the alert struct. | ||
type Alert struct { | ||
Message string | ||
Alias string | ||
Description string | ||
Actions []string | ||
Tags []string | ||
Entity string | ||
Priority Priority | ||
Responder []Responder | ||
VisibleTo []Responder | ||
context AlertContext | ||
} | ||
|
||
// AlertContext contains the alert execution context. | ||
type AlertContext struct { | ||
Details map[string]string | ||
Error error | ||
Note string | ||
} | ||
|
||
// toOpsgenieResponder converts a Responder to an Opsgenie Responder. | ||
func (a *Responder) toOpsgenieResponder() opsgenieAlert.Responder { | ||
|
||
var responderType opsgenieAlert.ResponderType | ||
switch a.Type { | ||
case "user": | ||
responderType = opsgenieAlert.UserResponder | ||
case "team": | ||
responderType = opsgenieAlert.TeamResponder | ||
case "escalation": | ||
responderType = opsgenieAlert.EscalationResponder | ||
case "schedule": | ||
responderType = opsgenieAlert.ScheduleResponder | ||
} | ||
|
||
opsgenieResponder := opsgenieAlert.Responder{ | ||
Id: a.Id, | ||
Type: responderType, | ||
Name: a.Name, | ||
Username: a.Username, | ||
} | ||
return opsgenieResponder | ||
} | ||
|
||
// toOpsgeniePriority converts a Priority to an Opsgenie Priority. | ||
func (p Priority) toOpsgeniePriority() opsgenieAlert.Priority { | ||
switch p { | ||
case CRITICAL: | ||
return opsgenieAlert.P1 | ||
case HIGH: | ||
return opsgenieAlert.P2 | ||
case MODERATE: | ||
return opsgenieAlert.P3 | ||
case LOW: | ||
return opsgenieAlert.P4 | ||
case INFORMATIONAL: | ||
return opsgenieAlert.P5 | ||
default: | ||
return opsgenieAlert.P5 | ||
} | ||
} | ||
|
||
// toOpsgenieRequest converts an Alert to an Opsgenie CreateAlertRequest. | ||
func (a Alert) toOpsgenieRequest() opsgenieAlert.CreateAlertRequest { | ||
// convert priority to opsgenie priority. | ||
priotity := a.Priority.toOpsgeniePriority() | ||
|
||
// convert responders to opsgenie responders. | ||
var responders []opsgenieAlert.Responder | ||
for _, responder := range a.Responder { | ||
responders = append(responders, responder.toOpsgenieResponder()) | ||
} | ||
|
||
// convert visibleTo to opsgenie responders. | ||
var visibleTo []opsgenieAlert.Responder | ||
for _, responder := range a.VisibleTo { | ||
visibleTo = append(visibleTo, responder.toOpsgenieResponder()) | ||
} | ||
|
||
// add error details to opsgenie alert details data. | ||
description := a.Description | ||
if a.context.Error != nil { | ||
description = fmt.Sprintf("%s\n%s", a.Description, a.context.Error.Error()) | ||
} | ||
|
||
return opsgenieAlert.CreateAlertRequest{ | ||
Message: a.Message, | ||
Alias: a.Alias, | ||
Description: description, | ||
Actions: a.Actions, | ||
Tags: a.Tags, | ||
Details: a.context.Details, | ||
Entity: a.Entity, | ||
Priority: priotity, | ||
Note: a.context.Note, | ||
Responders: responders, | ||
VisibleTo: visibleTo, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package alert | ||
|
||
import "context" | ||
|
||
// DummyClient is a dummy alert client. | ||
type DummyClient struct{} | ||
|
||
// NewDummyClient creates a new dummy alert client. | ||
func NewDummyClient() *DummyClient { | ||
return &DummyClient{} | ||
} | ||
|
||
// NewDummyClient creates a new dummy alert client. | ||
func (d *DummyClient) CreateAlert(key string, alertCtx AlertContext) (Alert, error) { | ||
return Alert{}, nil | ||
} | ||
|
||
// Send sends an alert to opsgenie. | ||
func (d *DummyClient) Send(ctx context.Context, alert Alert) error { | ||
return nil | ||
} | ||
|
||
// CreateAndSend creates an alert by key and alert context and sends it to opsgenie. | ||
func (d *DummyClient) CreateAndSend(ctx context.Context, key string, alertCtx AlertContext) error { | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
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 { | ||
Enviroment string | ||
P2PNetwork string | ||
ApiKey string | ||
Enabled bool | ||
Responder []Responder | ||
VisibleTo []Responder | ||
} | ||
|
||
// 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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.