package slack import ( "bytes" "encoding/json" "fmt" "net/http" "strings" "time" "github.com/porter-dev/porter/api/types" "github.com/porter-dev/porter/internal/models/integrations" ) type IncidentNotifier struct { slackInts []*integrations.SlackIntegration } func NewIncidentNotifier(slackInts ...*integrations.SlackIntegration) *IncidentNotifier { return &IncidentNotifier{ slackInts: slackInts, } } func (s *IncidentNotifier) NotifyNew(incident *types.Incident, url string) error { res := []*SlackBlock{} resourceKind := "application" if strings.ToLower(string(incident.InvolvedObjectKind)) == "job" { resourceKind = "job" } topSectionMarkdwn := fmt.Sprintf( ":warning: Your %s %s crashed on Porter. <%s|View the incident.>", resourceKind, "`"+incident.ReleaseName+"`", url, ) createdAt := incident.CreatedAt res = append( res, getMarkdownBlock(topSectionMarkdwn), getDividerBlock(), getMarkdownBlock(fmt.Sprintf("*Namespace:* %s", "`"+incident.ReleaseNamespace+"`")), getMarkdownBlock(fmt.Sprintf("*Name:* %s", "`"+incident.ReleaseName+"`")), getMarkdownBlock(fmt.Sprintf( "*Created at:* ", createdAt.Unix(), createdAt.Format("2006-01-02 15:04:05 UTC"), )), getMarkdownBlock(fmt.Sprintf("```\n%s\n```", incident.Summary)), ) slackPayload := &SlackPayload{ Blocks: res, } payload, err := json.Marshal(slackPayload) if err != nil { return err } reqBody := bytes.NewReader(payload) client := &http.Client{ Timeout: time.Second * 5, } for _, slackInt := range s.slackInts { _, err := client.Post(string(slackInt.Webhook), "application/json", reqBody) if err != nil { return err } } return nil } func (s *IncidentNotifier) NotifyResolved(incident *types.Incident, url string) error { res := []*SlackBlock{} createdAt := incident.CreatedAt resolvedAt := incident.UpdatedAt topSectionMarkdwn := fmt.Sprintf( ":white_check_mark: The incident for application %s has been resolved. <%s|View the incident.>", "`"+incident.ReleaseName+"`", url, ) res = append( res, getMarkdownBlock(topSectionMarkdwn), getDividerBlock(), getMarkdownBlock(fmt.Sprintf("*Namespace:* %s", "`"+incident.ReleaseNamespace+"`")), getMarkdownBlock(fmt.Sprintf("*Name:* %s", "`"+incident.ReleaseName+"`")), getMarkdownBlock(fmt.Sprintf( "*Created at:* ", createdAt.Unix(), createdAt.Format("2006-01-02 15:04:05 UTC"), )), getMarkdownBlock(fmt.Sprintf( "*Resolved at:* ", resolvedAt.Unix(), resolvedAt.Format("2006-01-02 15:04:05 UTC"), )), getMarkdownBlock(fmt.Sprintf("*Incident Summary:*")), getMarkdownBlock(fmt.Sprintf("```\n%s\n```", incident.Summary)), ) slackPayload := &SlackPayload{ Blocks: res, } payload, err := json.Marshal(slackPayload) if err != nil { return err } reqBody := bytes.NewReader(payload) client := &http.Client{ Timeout: time.Second * 5, } for _, slackInt := range s.slackInts { _, err := client.Post(string(slackInt.Webhook), "application/json", reqBody) if err != nil { return err } } return nil }