- GetComponentStatus fix - get main url from api definition for slack post - fix run send slack
170 lines
4.0 KiB
Go
170 lines
4.0 KiB
Go
package cachet
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// Incident Cachet data model
|
|
type Incident struct {
|
|
ID int `json:"id"`
|
|
Name string `json:"name"`
|
|
Message string `json:"message"`
|
|
Status int `json:"status"`
|
|
Visible int `json:"visible"`
|
|
Notify bool `json:"notify"`
|
|
|
|
ComponentID int `json:"component_id"`
|
|
ComponentStatus int `json:"component_status"`
|
|
}
|
|
|
|
//Get the last still open incident
|
|
func (mon *AbstractMonitor) Get(cfg *CachetMonitor) (*Incident, error) {
|
|
requestType := "GET"
|
|
requestURL := fmt.Sprintf("/incidents?component_id=%d", mon.ComponentID)
|
|
_, body, err := cfg.API.NewRequest(requestType, requestURL, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
data := make([]Incident, 0)
|
|
if err := json.Unmarshal(body.Data, &data); err != nil {
|
|
return nil, fmt.Errorf("Cannot parse incident body: %v, %v", err, string(body.Data))
|
|
}
|
|
//filter out resolved incidents
|
|
openIncidents := make([]Incident, 0)
|
|
for _, i := range data {
|
|
if i.Status < 4 {
|
|
openIncidents = append(openIncidents, i)
|
|
}
|
|
}
|
|
if len(openIncidents) == 0 {
|
|
return nil, nil
|
|
}
|
|
return &openIncidents[0], nil
|
|
|
|
}
|
|
|
|
// Send - Create or Update incident
|
|
func (incident *Incident) Send(cfg *CachetMonitor) error {
|
|
switch incident.Status {
|
|
case 1, 2, 3:
|
|
// partial outage
|
|
incident.ComponentStatus = 3
|
|
|
|
componentStatus, err := incident.GetComponentStatus(cfg)
|
|
if componentStatus == 3 {
|
|
// major outage
|
|
incident.ComponentStatus = 4
|
|
}
|
|
|
|
if err != nil {
|
|
logrus.Warnf("cannot fetch component: %v", err)
|
|
}
|
|
case 4:
|
|
// fixed
|
|
incident.ComponentStatus = 1
|
|
}
|
|
|
|
requestType := "POST"
|
|
requestURL := "/incidents"
|
|
if incident.ID > 0 {
|
|
requestType = "PUT"
|
|
requestURL += "/" + strconv.Itoa(incident.ID)
|
|
}
|
|
|
|
jsonBytes, _ := json.Marshal(incident)
|
|
|
|
resp, body, err := cfg.API.NewRequest(requestType, requestURL, jsonBytes)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var data struct {
|
|
ID int `json:"id"`
|
|
}
|
|
if err := json.Unmarshal(body.Data, &data); err != nil {
|
|
return fmt.Errorf("Cannot parse incident body: %v, %v", err, string(body.Data))
|
|
}
|
|
|
|
incident.ID = data.ID
|
|
if resp.StatusCode != 200 {
|
|
return fmt.Errorf("Could not create/update incident")
|
|
}
|
|
// send slack message
|
|
if cfg.SlackWebhook != "" {
|
|
incident.sendSlack(cfg)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (incident *Incident) GetComponentStatus(cfg *CachetMonitor) (int, error) {
|
|
resp, body, err := cfg.API.NewRequest("GET", "/components/"+strconv.Itoa(incident.ComponentID), nil)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
if resp.StatusCode != 200 {
|
|
return 0, fmt.Errorf("Invalid status code. Received %d", resp.StatusCode)
|
|
}
|
|
|
|
var data struct {
|
|
Status int `json:"status"`
|
|
}
|
|
if err := json.Unmarshal(body.Data, &data); err != nil {
|
|
return 0, fmt.Errorf("Cannot parse component body: %v. Err = %v", string(body.Data), err)
|
|
}
|
|
|
|
return data.Status, nil
|
|
}
|
|
|
|
// SetInvestigating sets status to Investigating
|
|
func (incident *Incident) SetInvestigating() {
|
|
incident.Status = 1
|
|
}
|
|
|
|
// SetIdentified sets status to Identified
|
|
func (incident *Incident) SetIdentified() {
|
|
incident.Status = 2
|
|
}
|
|
|
|
// SetWatching sets status to Watching
|
|
func (incident *Incident) SetWatching() {
|
|
incident.Status = 3
|
|
}
|
|
|
|
// SetFixed sets status to Fixed
|
|
func (incident *Incident) SetFixed() {
|
|
incident.Status = 4
|
|
}
|
|
|
|
// Send slack message
|
|
func (incident *Incident) sendSlack(cfg *CachetMonitor) {
|
|
color := "#bf1932" //red
|
|
if incident.ComponentStatus == 1 {
|
|
color = "#36a64f" //green
|
|
}
|
|
titleLink := MainUrl(cfg) + "/dashboard/incidents/" + strconv.Itoa(incident.ID)
|
|
slack := Slack{
|
|
WebhookURL: cfg.SlackWebhook,
|
|
Attachments: []Attachments{
|
|
Attachments{
|
|
Fallback: incident.Name,
|
|
Color: color,
|
|
Title: incident.Name,
|
|
TitleLink: titleLink,
|
|
Text: incident.Message,
|
|
Footer: "Cachet Monitor",
|
|
FooterIcon: "https://i.imgur.com/spck1w6.png",
|
|
Ts: time.Now().Unix(),
|
|
},
|
|
}}
|
|
err := slack.SendSlackNotification()
|
|
if err != nil {
|
|
fmt.Errorf("Cannot send slack message. Err = %v", err)
|
|
}
|
|
}
|