diff --git a/api/tasks/audit.go b/api/tasks/audit.go new file mode 100644 index 000000000..7d209837a --- /dev/null +++ b/api/tasks/audit.go @@ -0,0 +1,48 @@ +package tasks + +import ( + "bytes" + "encoding/json" + "github.com/ansible-semaphore/semaphore/util" + "net/http" + "strconv" + "time" +) + +func (t *task) sendAuditLog() { + if !util.Config.AuditLog { + return + } + url := util.Config.AuditLogURL + method := "POST" + payload, err := json.Marshal(map[string]interface{}{ + "project_id": t.projectID, + "template_id": t.task.TemplateID, + "task_id": t.task.ID, + "playbook": t.task.Playbook, + "environment": t.task.Environment, + "start": t.task.Start, + "end": t.task.End, + "status": t.task.Status, + "task_url": util.Config.WebHost + "/project/" + strconv.Itoa(t.template.ProjectID) + "/history/?t=" + strconv.Itoa(t.task.ID), + }) + requestBody := bytes.NewBuffer(payload) + if err != nil { + util.LogError(err) + return + } + client := &http.Client{Timeout: 5 * time.Second} + req, err := http.NewRequest(method, url, requestBody) + + if err != nil { + util.LogError(err) + return + } + req.Header.Add("Content-Type", "application/json") + + _, err = client.Do(req) + if err != nil { + util.LogError(err) + return + } +} diff --git a/api/tasks/runner.go b/api/tasks/runner.go index 7980c788e..646893f0d 100644 --- a/api/tasks/runner.go +++ b/api/tasks/runner.go @@ -99,7 +99,7 @@ func (t *task) updateStatus() { sockets.Message(user, b) } - + t.sendAuditLog() if err := t.store.UpdateTask(t.task); err != nil { t.panicOnError(err, "Failed to update task status") } diff --git a/cli/setup/setup.go b/cli/setup/setup.go index 18e951e31..0082a8326 100644 --- a/cli/setup/setup.go +++ b/cli/setup/setup.go @@ -78,6 +78,12 @@ func InteractiveSetup(conf *util.ConfigType) { askValue("LDAP mapping for full name field", "cn", &conf.LdapMappings.CN) askValue("LDAP mapping for email field", "mail", &conf.LdapMappings.Mail) } + + askConfirmation("Enable audit logs?", false, &conf.AuditLog) + if conf.AuditLog { + askValue("URL to send POST audit logs to(it should start with http:// or https://)", "http://127.0.0.1:6666/", &conf.AuditLogURL) + } + } func scanBoltDb(conf *util.ConfigType) { diff --git a/util/config.go b/util/config.go index 7a016a4de..d7b1cb208 100644 --- a/util/config.go +++ b/util/config.go @@ -85,6 +85,9 @@ type ConfigType struct { EmailUsername string `json:"email_username"` EmailPassword string `json:"email_password"` + // Audit Log + AuditLogURL string `json:"audit_log_url"` + // web host WebHost string `json:"web_host"` @@ -113,6 +116,7 @@ type ConfigType struct { TelegramAlert bool `json:"telegram_alert"` LdapEnable bool `json:"ldap_enable"` LdapNeedTLS bool `json:"ldap_needtls"` + AuditLog bool `json:"audit_log"` SshConfigPath string `json:"ssh_config_path"`