Merge pull request #914 from KalvadTech/slack-alerts

Slack alerts
This commit is contained in:
Denis Gukov 2022-07-14 14:16:34 +05:00 committed by GitHub
commit d25afd8c49
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 99 additions and 2 deletions

View File

@ -65,6 +65,11 @@ func InteractiveSetup(conf *util.ConfigType) {
askValue("Telegram chat ID", "", &conf.TelegramChat)
}
askConfirmation("Enable slack alerts?", false, &conf.SlackAlert)
if conf.SlackAlert {
askValue("Slack Webhook URL", "", &conf.SlackUrl)
}
askConfirmation("Enable LDAP authentication?", false, &conf.LdapEnable)
if conf.LdapEnable {
askValue("LDAP server host", "localhost:389", &conf.LdapServer)

View File

@ -81,6 +81,7 @@ ${SEMAPHORE_TMP_PATH}
${SEMAPHORE_WEB_ROOT}
no
no
no
${SEMAPHORE_LDAP_ACTIVATED}
EOF

View File

@ -3,12 +3,11 @@ package tasks
import (
"bytes"
"github.com/ansible-semaphore/semaphore/db"
"github.com/ansible-semaphore/semaphore/util"
"html/template"
"net/http"
"strconv"
"strings"
"github.com/ansible-semaphore/semaphore/util"
)
const emailTemplate = `Subject: Task '{{ .Name }}' failed
@ -18,6 +17,8 @@ Task log: <a href='{{ .TaskURL }}'>{{ .TaskURL }}</a>`
const telegramTemplate = `{"chat_id": "{{ .ChatID }}","parse_mode":"HTML","text":"<code>{{ .Name }}</code>\n#{{ .TaskID }} <b>{{ .TaskResult }}</b> <code>{{ .TaskVersion }}</code> {{ .TaskDescription }}\nby {{ .Author }}\n{{ .TaskURL }}"}`
const slackTemplate = `{ "attachments": [ { "title": "Task: {{ .Name }}", "title_link": "{{ .TaskURL }}", "text": "execution ID #{{ .TaskID }}, status: {{ .TaskResult }}!", "color": "{{ .Color }}", "mrkdwn_in": ["text"], "fields": [ { "title": "Author", "value": "{{ .Author }}", "short": true }] } ]}`
// Alert represents an alert that will be templated and sent to the appropriate service
type Alert struct {
TaskID string
@ -28,6 +29,7 @@ type Alert struct {
TaskDescription string
TaskVersion string
Author string
Color string
}
func (t *TaskRunner) sendMailAlert() {
@ -139,3 +141,86 @@ func (t *TaskRunner) sendTelegramAlert() {
t.Log("Can't send telegram alert! Response code not 200!")
}
}
func (t *TaskRunner) sendSlackAlert() {
if !util.Config.SlackAlert || !t.alert {
return
}
if t.template.SuppressSuccessAlerts && t.task.Status == db.TaskSuccessStatus {
return
}
slackUrl := util.Config.SlackUrl
var slackBuffer bytes.Buffer
var version string
if t.task.Version != nil {
version = *t.task.Version
} else if t.task.BuildTaskID != nil {
version = "build " + strconv.Itoa(*t.task.BuildTaskID)
} else {
version = ""
}
var message string
if t.task.Message != "" {
message = "- " + t.task.Message
}
var author string
if t.task.UserID != nil {
user, err := t.pool.store.GetUser(*t.task.UserID)
if err != nil {
panic(err)
}
author = user.Name
}
var color string
if t.task.Status == db.TaskSuccessStatus {
color = "good"
} else if t.task.Status == db.TaskFailStatus {
color = "bad"
} else if t.task.Status == db.TaskRunningStatus {
color = "#333CFF"
} else if t.task.Status == db.TaskWaitingStatus {
color = "#FFFC33"
} else if t.task.Status == db.TaskStoppingStatus {
color = "#BEBEBE"
} else if t.task.Status == db.TaskStoppedStatus {
color = "#5B5B5B"
}
alert := Alert{
TaskID: strconv.Itoa(t.task.ID),
Name: t.template.Name,
TaskURL: util.Config.WebHost + "/project/" + strconv.Itoa(t.template.ProjectID) + "/templates/" + strconv.Itoa(t.template.ID) + "?t=" + strconv.Itoa(t.task.ID),
TaskResult: strings.ToUpper(string(t.task.Status)),
TaskVersion: version,
TaskDescription: message,
Author: author,
Color: color,
}
tpl := template.New("slack body template")
tpl, err := tpl.Parse(slackTemplate)
if err != nil {
t.Log("Can't parse slack template!")
panic(err)
}
err = tpl.Execute(&slackBuffer, alert)
if err != nil {
t.Log("Can't generate alert template!")
panic(err)
}
resp, err := http.Post(slackUrl, "application/json", &slackBuffer)
if err != nil {
t.Log("Can't send slack alert! Response code not 200!")
} else if resp.StatusCode != 200 {
t.Log("Can't send slack alert! Response code not 200!")
}
}

View File

@ -72,6 +72,8 @@ func (t *TaskRunner) setStatus(status db.TaskStatus) {
t.updateStatus()
t.sendSlackAlert()
if status == db.TaskFailStatus {
t.sendMailAlert()
}

View File

@ -98,6 +98,9 @@ type ConfigType struct {
TelegramChat string `json:"telegram_chat"`
TelegramToken string `json:"telegram_token"`
// slack alerting
SlackUrl string `json:"slack_url"`
// task concurrency
MaxParallelTasks int `json:"max_parallel_tasks"`
@ -108,6 +111,7 @@ type ConfigType struct {
EmailAlert bool `json:"email_alert"`
EmailSecure bool `json:"email_secure"`
TelegramAlert bool `json:"telegram_alert"`
SlackAlert bool `json:"slack_alert"`
LdapEnable bool `json:"ldap_enable"`
LdapNeedTLS bool `json:"ldap_needtls"`