Skip to content

Commit

Permalink
Add opsgenie client + error saving vaa alert in fly component (#442)
Browse files Browse the repository at this point in the history
  • Loading branch information
walker-16 authored Jun 22, 2023
1 parent 8b58196 commit 25b891f
Show file tree
Hide file tree
Showing 14 changed files with 434 additions and 5 deletions.
127 changes: 127 additions & 0 deletions common/client/alert/alert.go
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,
}
}
26 changes: 26 additions & 0 deletions common/client/alert/dummy.go
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
}
99 changes: 99 additions & 0 deletions common/client/alert/opsgenie.go
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)
}
8 changes: 8 additions & 0 deletions common/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ require (
github.com/go-redis/redis/v8 v8.11.5
github.com/influxdata/influxdb-client-go/v2 v2.12.2
github.com/mr-tron/base58 v1.2.0
github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.19
github.com/pkg/errors v0.9.1
github.com/shopspring/decimal v1.3.1
github.com/test-go/testify v1.1.4
github.com/wormhole-foundation/wormhole/sdk v0.0.0-20230426150516-e695fad0bed8
go.mongodb.org/mongo-driver v1.11.2
go.uber.org/zap v1.24.0
Expand All @@ -22,15 +24,21 @@ require (
github.com/aws/smithy-go v1.13.5 // indirect
github.com/btcsuite/btcd/btcec/v2 v2.2.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect
github.com/deepmap/oapi-codegen v1.8.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/ethereum/go-ethereum v1.10.21 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/hashicorp/go-cleanhttp v0.5.0 // indirect
github.com/hashicorp/go-retryablehttp v0.5.1 // indirect
github.com/holiman/uint256 v1.2.1 // indirect
github.com/influxdata/line-protocol v0.0.0-20210311194329-9aa0e372d097 // indirect
github.com/klauspost/compress v1.13.6 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.1 // indirect
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.4.2 // indirect
github.com/xdg-go/pbkdf2 v1.0.0 // indirect
github.com/xdg-go/scram v1.1.1 // indirect
github.com/xdg-go/stringprep v1.0.3 // indirect
Expand Down
16 changes: 16 additions & 0 deletions common/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/hashicorp/go-cleanhttp v0.5.0 h1:wvCrVc9TjDls6+YGAF2hAifE1E5U1+b4tH6KdvN3Gig=
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
github.com/hashicorp/go-retryablehttp v0.5.1 h1:Vsx5XKPqPs3M6sM4U4GWyUqFS8aBiL9U5gkgvpkg4SE=
github.com/hashicorp/go-retryablehttp v0.5.1/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs=
github.com/holiman/uint256 v1.2.1 h1:XRtyuda/zw2l+Bq/38n5XUoEF72aSOu/77Thd9pPp2o=
github.com/holiman/uint256 v1.2.1/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw=
github.com/influxdata/influxdb-client-go/v2 v2.12.2 h1:uYABKdrEKlYm+++qfKdbgaHKBPmoWR5wpbmj6MBB/2g=
Expand All @@ -57,6 +61,8 @@ github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHW
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
Expand All @@ -80,19 +86,27 @@ github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjW
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.19 h1:JernwK3Bgd5x+UJPV6S2LPYoBF+DFOYBoQ5JeJPVBNc=
github.com/opsgenie/opsgenie-go-sdk-v2 v1.2.19/go.mod h1:4OjcxgwdXzezqytxN534MooNmrxRD50geWZxTD7845s=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=
github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
Expand Down Expand Up @@ -126,6 +140,7 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220607020251-c690dde0001d h1:4SFsTMi4UahlKoloni7L4eYzhFRifURQLw+yv0QDCx8=
Expand All @@ -136,6 +151,7 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
3 changes: 2 additions & 1 deletion fly/cmd/backfiller/txhash_encoding_strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/hex"

"github.com/wormhole-foundation/wormhole-explorer/common/client/alert"
"github.com/wormhole-foundation/wormhole-explorer/common/domain"
"github.com/wormhole-foundation/wormhole-explorer/common/logger"
"github.com/wormhole-foundation/wormhole-explorer/fly/storage"
Expand All @@ -28,7 +29,7 @@ func RunTxHashEncoding(cfg TxHashEncondingConfig) {
logger.Fatal("could not connect to DB", zap.Error(err))
}

repository := storage.NewRepository(db, logger)
repository := storage.NewRepository(alert.NewDummyClient(), db, logger)

workerTxHashEncoding(ctx, logger, repository, vaa.ChainID(cfg.ChainID), cfg.PageSize)
}
Expand Down
3 changes: 2 additions & 1 deletion fly/cmd/backfiller/workpool.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"sync"

"github.com/schollz/progressbar/v3"
"github.com/wormhole-foundation/wormhole-explorer/common/client/alert"
"github.com/wormhole-foundation/wormhole-explorer/fly/storage"
"go.mongodb.org/mongo-driver/mongo"
"go.uber.org/zap"
Expand Down Expand Up @@ -57,7 +58,7 @@ func NewWorkpool(ctx context.Context, cfg WorkerConfiguration, workerFunc Generi
}

func (w *Workpool) Process(ctx context.Context) error {
repo := storage.NewRepository(w.DB, w.Log)
repo := storage.NewRepository(alert.NewDummyClient(), w.DB, w.Log)
var err error

for {
Expand Down
Loading

0 comments on commit 25b891f

Please sign in to comment.