Skip to content

Commit

Permalink
Add new Dispatcher PagerDuty (#296)
Browse files Browse the repository at this point in the history
* - Add a new dispatcher `PagerDuty`
- Update Configs include 'pagerDuty' Conf
* - Unify some switch & case phrases in the codes.
* - updated for comments on PR
  • Loading branch information
xellos00 authored Nov 8, 2022
1 parent 085cc34 commit c83b7cc
Show file tree
Hide file tree
Showing 8 changed files with 214 additions and 69 deletions.
2 changes: 2 additions & 0 deletions cmd/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ func createInitCommand() *cobra.Command {
dispatch_channels:
- channel: "discord"
secret: "Put your Discord Webhook"
- channel: "pagerduty"
secret: "Put your PagerDuty's Integration Key (Events API v2)"
- channel: "telegram"
secret: "Put Your Bot's Token"
chat_id: "Put Your Chat's chat_id"
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/dsrvlabs/vatz
go 1.18

require (
github.com/PagerDuty/go-pagerduty v1.6.0
github.com/dsrvlabs/vatz-proto v0.0.0-20220908182122-4c28400b195f
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3
github.com/jarcoal/httpmock v1.2.0
Expand All @@ -15,6 +16,7 @@ require (
)

require (
github.com/google/go-querystring v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.0.1 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
Expand Down
23 changes: 23 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,59 +1,81 @@
github.com/PagerDuty/go-pagerduty v1.6.0 h1:am81SzvG5Pw+s3JZ5yEy6kGvsXXklTNRrGr3d8WKpsU=
github.com/PagerDuty/go-pagerduty v1.6.0/go.mod h1:7eaBLzsDpK7VUvU0SJ5mohczQkoWrrr5CjDaw5gh1as=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dsrvlabs/vatz-proto v0.0.0-20220908182122-4c28400b195f h1:VUX+u+XbsRZOnmX4SzXaW6LFcBOF9IZlBVHdgu43EGc=
github.com/dsrvlabs/vatz-proto v0.0.0-20220908182122-4c28400b195f/go.mod h1:0ksXsnd9pZ860eMhnoNT6wq0hALJc6EM0JnFx6zQJHk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3 h1:lLT7ZLSzGLI08vc9cpd+tYmNWjdKDqyr/2L+f6U12Fk=
github.com/grpc-ecosystem/grpc-gateway/v2 v2.11.3/go.mod h1:o//XUCC/F+yRGJoPO/VU0GSB0f8Nhgmxx0VIRUvaC0w=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jarcoal/httpmock v1.2.0 h1:gSvTxxFR/MEMfsGrvRbdfpRUMBStovlSRLw0Ep1bwwc=
github.com/jarcoal/httpmock v1.2.0/go.mod h1:oCoTsnAz4+UoOUIf5lJOWV2QQIW5UoeUI6aM2YnWAZk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/maxatome/go-testdeep v1.11.0 h1:Tgh5efyCYyJFGUYiT0qxBSIDeXw0F5zSoatlou685kk=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
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/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU=
github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
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/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7 h1:1WGATo9HAhkWMbfyuVU0tEFP88OIkUvwaHFveQPvzCQ=
golang.org/x/net v0.0.0-20220907135653-1e95f45603a7/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220406155245-289d7a0edf71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -70,6 +92,7 @@ google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
74 changes: 34 additions & 40 deletions manager/dispatcher/discord.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,11 @@ import (
type DiscordColor int

const (
discordRed tp.DiscordColor = 15548997
discordYellow tp.DiscordColor = 16705372
discordGreen tp.DiscordColor = 65340
discordGray tp.DiscordColor = 9807270
discordBlue tp.DiscordColor = 4037805

discordWebhookFormat string = "https://discord.com/api/webhooks/"
discordRed tp.DiscordColor = 15548997
discordYellow tp.DiscordColor = 16705372
discordGreen tp.DiscordColor = 65340
discordGray tp.DiscordColor = 9807270
discordWebhookFormat string = "https://discord.com/api/webhooks/"
)

type discord struct {
Expand All @@ -46,9 +44,11 @@ func (d *discord) SetDispatcher(firstRunMsg bool, preStat tp.StateFlag, notifyIn

if reminderState == tp.ON {
newEntries := []cron.EntryID{}
//In case of reminder has to keep but stateFlag has changed,
//e.g.) CRITICAL -> WARNING
//e.g.) ERROR -> INFO -> ERROR
/*
In case of reminder has to keep but stateFlag has changed,
e.g.) CRITICAL -> WARNING
e.g.) ERROR -> INFO -> ERROR
*/
if entries, ok := d.entry.Load(methodName); ok {
for _, entry := range entries.([]cron.EntryID) {
d.reminderCron.Remove(entry)
Expand All @@ -63,7 +63,6 @@ func (d *discord) SetDispatcher(firstRunMsg bool, preStat tp.StateFlag, notifyIn
}
d.entry.Store(methodName, newEntries)
d.reminderCron.Start()

} else if reminderState == tp.OFF {
entries, _ := d.entry.Load(methodName)
for _, entity := range entries.([]cron.EntryID) {
Expand All @@ -78,43 +77,38 @@ func (d *discord) SetDispatcher(firstRunMsg bool, preStat tp.StateFlag, notifyIn
}

func (d *discord) SendNotification(msg tp.ReqMsg) error {
if msg.ResourceType == "" {
msg.ResourceType = "No Resource Type"
}
if msg.Msg == "" {
msg.Msg = "No Message"
}

// Check discord secret
if strings.Contains(d.secret, discordWebhookFormat) {
sMsg := tp.DiscordMsg{Embeds: make([]tp.Embed, 1)}
emoji := "🚨"
switch msg.Severity {
case pb.SEVERITY_CRITICAL:
sMsg.Embeds[0].Color = discordRed
case pb.SEVERITY_WARNING:
sMsg.Embeds[0].Color = discordYellow
case pb.SEVERITY_INFO:
sMsg.Embeds[0].Color = discordGreen
default:
sMsg.Embeds[0].Color = discordGray
sendingMsg := tp.DiscordMsg{Embeds: make([]tp.Embed, 1)}
sendingMsg.Embeds[0].Color = discordGray
emoji := emojiER

if msg.ResourceType == "" {
msg.ResourceType = "No Resource Type"
}

if msg.Msg == "" {
msg.Msg = "No Message"
}

if msg.State == pb.STATE_SUCCESS {
if msg.Severity == pb.SEVERITY_CRITICAL {
emoji = "‼️"
} else if msg.Severity == pb.SEVERITY_WARNING {
emoji = "❗"
} else if msg.Severity == pb.SEVERITY_INFO {
emoji = "✅"
switch {
case msg.Severity == pb.SEVERITY_CRITICAL:
sendingMsg.Embeds[0].Color = discordRed
emoji = emojiDoubleEX
case msg.Severity == pb.SEVERITY_WARNING:
sendingMsg.Embeds[0].Color = discordYellow
emoji = emojiSingleEx
case msg.Severity == pb.SEVERITY_INFO:
sendingMsg.Embeds[0].Color = discordGreen
emoji = emojiCheck
}
}

sMsg.Embeds[0].Title = fmt.Sprintf(`%s %s`, emoji, msg.Severity.String())
sMsg.Embeds[0].Fields = []tp.Field{{Name: "(" + d.host + ") " + msg.ResourceType, Value: msg.Msg, Inline: false}}
sMsg.Embeds[0].Timestamp = time.Now()
sendingMsg.Embeds[0].Title = fmt.Sprintf(`%s %s`, emoji, msg.Severity.String())
sendingMsg.Embeds[0].Fields = []tp.Field{{Name: "(" + d.host + ") " + msg.ResourceType, Value: msg.Msg, Inline: false}}
sendingMsg.Embeds[0].Timestamp = time.Now()

message, err := json.Marshal(sMsg)
message, err := json.Marshal(sendingMsg)
if err != nil {
return err
}
Expand Down
16 changes: 15 additions & 1 deletion manager/dispatcher/dispatcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ As I see this code, dispatcher itself is described is dispatcher
but dispatcher and dispatcher module should be splitted into two part.
*/

const (
emojiER string = "🚨"
emojiDoubleEX string = "‼️"
emojiSingleEx string = "❗"
emojiCheck string = "✅"
)

var (
dispatcherSingletons []Dispatcher
dispatcherOnce sync.Once
Expand All @@ -32,7 +39,7 @@ type Dispatcher interface {
func GetDispatchers(cfg config.NotificationInfo) []Dispatcher {
if len(cfg.DispatchChannels) == 0 {
dpError := errors.New("Error: No Dispatcher has set.")
log.Error().Str("module", "dispatcher").Msg("Please, Set at least a channel for dispatcher, e.g.) Discord or Telegram")
log.Error().Str("module", "dispatcher").Msg("Please, Set at least a single channel for dispatcher, e.g.) Discord or Telegram")
panic(dpError)
}

Expand Down Expand Up @@ -61,6 +68,13 @@ func GetDispatchers(cfg config.NotificationInfo) []Dispatcher {
reminderSchedule: chanInfo.ReminderSchedule,
entry: sync.Map{},
})
case strings.EqualFold(channel, string(tp.PagerDuty)):
dispatcherSingletons = append(dispatcherSingletons, &pagerduty{
host: cfg.HostName,
channel: tp.PagerDuty,
secret: chanInfo.Secret,
pagerEntry: sync.Map{},
})
}
}
})
Expand Down
110 changes: 110 additions & 0 deletions manager/dispatcher/pagerduty.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
package dispatcher

import (
"context"
"fmt"
pd "github.com/PagerDuty/go-pagerduty"
pb "github.com/dsrvlabs/vatz-proto/plugin/v1"
tp "github.com/dsrvlabs/vatz/manager/types"
"github.com/rs/zerolog/log"
"sync"
"time"
)

const SUCCESS = "success"

type pagerdutyMSGEvent struct {
flag string
deKey string
}

type pagerduty struct {
host string
channel tp.Channel
secret string
pagerEntry sync.Map
}

func (p *pagerduty) SetDispatcher(firstRunMsg bool, preStat tp.StateFlag, notifyInfo tp.NotifyInfo) error {
reqToNotify, _, deliverMessage := messageHandler(firstRunMsg, preStat, notifyInfo)
if reqToNotify {
p.SendNotification(deliverMessage)
}
return nil
}

func (p *pagerduty) SendNotification(msg tp.ReqMsg) error {

var (
pagerdutySeverity string
emoji string
methodName = msg.FuncName
)
/*
Pagerduty severity Allowed values:
- critical
- warning
- error
- info
*/
switch {
case msg.Severity == pb.SEVERITY_INFO:
pagerdutySeverity = "info"
emoji = emojiCheck
case msg.Severity == pb.SEVERITY_CRITICAL:
pagerdutySeverity = "critical"
emoji = "‼️"
case msg.Severity == pb.SEVERITY_WARNING:
pagerdutySeverity = "warning"
emoji = "❗"
default:
emoji = emojiER
pagerdutySeverity = "error"
}

v2EventPayload := &pd.V2Payload{
Source: fmt.Sprintf(`(%s)`, p.host),
Component: msg.ResourceType,
Severity: pagerdutySeverity,
Summary: fmt.Sprintf(`
%s %s %s
(%s)
Plugin Name: %s
%s`, emoji, msg.Severity.String(), emoji, p.host, msg.ResourceType, msg.Msg)}

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel()

if pb.STATE_SUCCESS != msg.State || pb.SEVERITY_INFO != msg.Severity {
resp, err := pd.ManageEventWithContext(ctx, pd.V2Event{RoutingKey: p.secret, Action: "trigger", Payload: v2EventPayload})
if err != nil {
log.Error().Str("module", "dispatcher").Msgf("Channel(Pagerduty): Connection failed due to Error: %s", err)
return err
}
if resp.Status == SUCCESS {
preps := make([]pagerdutyMSGEvent, 0)
if prepTriggers, ok := p.pagerEntry.Load(methodName); ok {
preps = prepTriggers.([]pagerdutyMSGEvent)
}
preps = append(preps, pagerdutyMSGEvent{flag: pagerdutySeverity, deKey: resp.DedupKey})
p.pagerEntry.Store(methodName, preps)
}
} else if pdResolver, ok := p.pagerEntry.Load(methodName); ok {
resolver := pdResolver.([]pagerdutyMSGEvent)
for _, prepFlags := range resolver {
_, err := pd.ManageEventWithContext(ctx, pd.V2Event{
RoutingKey: p.secret,
Action: "resolve",
DedupKey: prepFlags.deKey,
Payload: v2EventPayload,
})
if err != nil {
log.Error().Str("module", "dispatcher").Msgf("Channel(Pagerduty): Connection failed due to Error: %s", err)
return err
}
}
p.pagerEntry.Store(methodName, make([]pagerdutyMSGEvent, 0))
}

return nil
}
Loading

0 comments on commit c83b7cc

Please sign in to comment.