diff --git a/prober/notification.go b/prober/notification.go deleted file mode 100644 index c62580f98..000000000 --- a/prober/notification.go +++ /dev/null @@ -1,139 +0,0 @@ -// Copyright (c) Tailscale Inc & AUTHORS -// SPDX-License-Identifier: BSD-3-Clause - -package prober - -import ( - "bytes" - "encoding/json" - "errors" - "expvar" - "fmt" - "io" - "net/http" - "os" - "strings" - "time" - - "github.com/google/uuid" - "tailscale.com/util/httpm" -) - -var ( - alertGenerated = expvar.NewInt("alert_generated") - alertFailed = expvar.NewInt("alert_failed") - warningGenerated = expvar.NewInt("warning_generated") - warningFailed = expvar.NewInt("warning_failed") -) - -// SendAlert sends an alert to the incident response system, to -// page a human responder immediately. -// summary should be short and state the nature of the emergency. -// details can be longer, up to 29 KBytes. -func SendAlert(summary, details string) error { - type squadcastAlert struct { - Message string `json:"message"` - Description string `json:"description"` - Tags map[string]string `json:"tags,omitempty"` - Status string `json:"status"` - EventId string `json:"event_id"` - } - - sqa := squadcastAlert{ - Message: summary, - Description: details, - Tags: map[string]string{"severity": "critical"}, - Status: "trigger", - EventId: uuid.New().String(), - } - - sqBody, err := json.Marshal(sqa) - if err != nil { - alertFailed.Add(1) - return fmt.Errorf("encoding alert payload: %w", err) - } - - webhookUrl := os.Getenv("SQUADCAST_WEBHOOK") - if webhookUrl == "" { - warningFailed.Add(1) - return errors.New("no SQUADCAST_WEBHOOK configured") - } - - req, err := http.NewRequest(httpm.POST, webhookUrl, bytes.NewBuffer(sqBody)) - if err != nil { - alertFailed.Add(1) - return err - } - - req.Header.Set("Content-Type", "application/json") - - client := &http.Client{Timeout: 10 * time.Second} - resp, err := client.Do(req) - if err != nil { - alertFailed.Add(1) - return err - } - defer resp.Body.Close() - - if resp.StatusCode != 200 { - alertFailed.Add(1) - return errors.New(resp.Status) - } - - body, _ := io.ReadAll(resp.Body) - if string(body) != "ok" { - alertFailed.Add(1) - return errors.New("non-ok response returned from Squadcast") - } - - alertGenerated.Add(1) - return nil -} - -// SendWarning will post a message to Slack. -// details should be a description of the issue. -func SendWarning(details string) error { - webhookUrl := os.Getenv("SLACK_WEBHOOK") - if webhookUrl == "" { - warningFailed.Add(1) - return errors.New("no SLACK_WEBHOOK configured") - } - - type slackRequestBody struct { - Text string `json:"text"` - } - - slackBody, err := json.Marshal(slackRequestBody{Text: details}) - if err != nil { - warningFailed.Add(1) - return err - } - - req, err := http.NewRequest("POST", webhookUrl, bytes.NewReader(slackBody)) - if err != nil { - warningFailed.Add(1) - return err - } - req.Header.Set("Content-Type", "application/json") - - client := &http.Client{Timeout: 10 * time.Second} - resp, err := client.Do(req) - if err != nil { - warningFailed.Add(1) - return err - } - defer resp.Body.Close() - - if resp.StatusCode != http.StatusOK { - warningFailed.Add(1) - return errors.New(resp.Status) - } - - body, _ := io.ReadAll(resp.Body) - if s := strings.TrimSpace(string(body)); s != "ok" { - warningFailed.Add(1) - return errors.New("non-ok response returned from Slack") - } - warningGenerated.Add(1) - return nil -}