aboutsummaryrefslogtreecommitdiff
path: root/cmd/monfront/checks.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/monfront/checks.go')
-rw-r--r--cmd/monfront/checks.go226
1 files changed, 226 insertions, 0 deletions
diff --git a/cmd/monfront/checks.go b/cmd/monfront/checks.go
new file mode 100644
index 0000000..d61d337
--- /dev/null
+++ b/cmd/monfront/checks.go
@@ -0,0 +1,226 @@
+package main
+
+import (
+ "database/sql"
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/lib/pq"
+)
+
+type (
+ check struct {
+ NodeId int
+ NodeName string
+ CommandName string
+ CheckID int64
+ CheckName string
+ MappingId int
+ State int
+ Enabled bool
+ Notify bool
+ Notice sql.NullString
+ NextTime time.Time
+ Msg string
+ StateSince time.Time
+ }
+
+ checkDetails struct {
+ Id int64
+ Name string
+ Message string
+ Enabled bool
+ Updated time.Time
+ LastRefresh time.Time
+ NextTime time.Time
+ MappingId int
+ MappingName string
+ NodeId int
+ NodeName string
+ NodeMessage string
+ CommandId int
+ CommandName string
+ CommandLine []string
+ CommandMessage string
+ States []int64
+ Notice sql.NullString
+ Notifiers []notifier
+ Notifications []notification
+ CheckerID int
+ CheckerName string
+ CheckerMsg string
+ }
+
+ notifier struct {
+ Id int
+ Name string
+ Enabled bool
+ }
+
+ notification struct {
+ Id int64
+ State int
+ Output string
+ Inserted time.Time
+ Sent pq.NullTime
+ NotifierName string
+ MappingId int
+ }
+)
+
+// showCheck loads shows the notifications for a specific check.
+func showCheck(con *Context) {
+ cd := checkDetails{}
+ con.CheckDetails = &cd
+ id, found := con.r.URL.Query()["check_id"]
+ if !found {
+ con.Error = "no check given to view"
+ returnError(http.StatusNotFound, con, con.w)
+ return
+ }
+ query := `select c.id, c.name, c.message, c.enabled, c.updated, c.last_refresh,
+ m.id, m.name, n.id, n.name, n.message, co.id, co.Name, co.message,
+ ac.cmdline, ac.states, ac.msg, ac.next_time, ch.id, ch.name, ch.description
+ from checks c
+ join active_checks ac on c.id = ac.check_id
+ join nodes n on c.node_id = n.id
+ join commands co on c.command_id = co.id
+ join mappings m on ac.mapping_id = m.id
+ join checkers ch on c.checker_id = ch.id
+ where c.id = $1::bigint`
+ err := DB.QueryRow(query, id[0]).Scan(&cd.Id, &cd.Name, &cd.Message, &cd.Enabled,
+ &cd.Updated, &cd.LastRefresh, &cd.MappingId, &cd.MappingName, &cd.NodeId,
+ &cd.NodeName, &cd.NodeMessage, &cd.CommandId, &cd.CommandName, &cd.CommandMessage,
+ pq.Array(&cd.CommandLine), pq.Array(&cd.States), &cd.Notice, &cd.NextTime,
+ &cd.CheckerID, &cd.CheckerName, &cd.CheckerMsg)
+ if err != nil && err == sql.ErrNoRows {
+ con.w.Header()["Location"] = []string{"/"}
+ con.w.WriteHeader(http.StatusSeeOther)
+ return
+ } else if err != nil {
+ con.w.WriteHeader(http.StatusInternalServerError)
+ con.w.Write([]byte("problems with the database"))
+ log.Printf("could not get check details for check id %s: %s", id[0], err)
+ return
+ }
+
+ query = `select n.id, states[1], output, inserted, sent, no.name, n.mapping_id
+ from notifications n
+ join notifier no on n.notifier_id = no.id
+ where check_id = $1::bigint
+ order by inserted desc
+ limit 500`
+ rows, err := DB.Query(query, cd.Id)
+ defer rows.Close()
+ if err != nil {
+ log.Printf("could not load notifications: %s", err)
+ con.Error = "could not load notification information"
+ returnError(http.StatusInternalServerError, con, con.w)
+ return
+ }
+ cd.Notifications = []notification{}
+ for rows.Next() {
+ if err := rows.Err(); err != nil {
+ log.Printf("could not load notifications: %s", err)
+ con.Error = "could not load notification information"
+ returnError(http.StatusInternalServerError, con, con.w)
+ return
+ }
+ no := notification{}
+ if err := rows.Scan(&no.Id, &no.State, &no.Output, &no.Inserted,
+ &no.Sent, &no.NotifierName, &no.MappingId); err != nil {
+ log.Printf("could not scan notifications: %s", err)
+ con.Error = "could not load notification information"
+ returnError(http.StatusInternalServerError, con, con.w)
+ return
+ }
+ cd.Notifications = append(cd.Notifications, no)
+ }
+
+ if err := con.loadMappings(); err != nil {
+ con.w.WriteHeader(http.StatusInternalServerError)
+ con.w.Write([]byte("problem with the mappings"))
+ log.Printf("could not load mappings: %s", err)
+ return
+ }
+
+ con.w.Header()["Content-Type"] = []string{"text/html"}
+ con.Render("check")
+}
+
+func showChecks(con *Context) {
+ query := `select c.id, c.name, n.id, n.name, co.name, ac.mapping_id, ac.states[1] as state,
+ ac.enabled, ac.notice, ac.next_time, ac.msg,
+ case when cn.check_id is null then false else true end as notify_enabled,
+ state_since
+ from active_checks ac
+ join checks c on ac.check_id = c.id
+ join nodes n on c.node_id = n.id
+ join commands co on c.command_id = co.id
+ left join ( select distinct check_id from checks_notify where enabled = true) cn on c.id = cn.check_id`
+ filter := newFilter()
+ con.Filter = filter
+ if id, found := con.r.URL.Query()["group_id"]; found {
+ query += ` join nodes_groups ng on n.id = ng.node_id`
+ filter.Add("ng.group_id", "=", id[0], "int")
+ }
+ filter.filterChecks(con)
+ if search, found := con.r.URL.Query()["search"]; found {
+ filter.AddSpecial(
+ `to_tsvector('english', regexp_replace(n.name, '[.-/]', ' ', 'g'))`,
+ `@@`,
+ `to_tsquery('english', regexp_replace($%d, '[.-/]', ' & ', 'g') || ':*')`,
+ search[0])
+ }
+ if id, found := con.r.URL.Query()["node_id"]; found {
+ filter.Add("n.id", "=", id[0], "int")
+ }
+ if id, found := con.r.URL.Query()["check_id"]; found {
+ filter.Add("c.id", "=", id[0], "int")
+ }
+ where, params := filter.Join()
+ if len(where) > 0 {
+ query += " where " + where
+ }
+ query += ` order by n.name, c.name, co.name`
+ rows, err := DB.Query(query, params...)
+ if err != nil {
+ con.w.WriteHeader(http.StatusInternalServerError)
+ con.w.Write([]byte("problems with the database"))
+ log.Printf("could not get check list: %s", err)
+ return
+ }
+ defer rows.Close()
+
+ checks := []check{}
+ for rows.Next() {
+ c := check{}
+ err := rows.Scan(&c.CheckID, &c.CheckName, &c.NodeId, &c.NodeName, &c.CommandName, &c.MappingId,
+ &c.State, &c.Enabled, &c.Notice, &c.NextTime, &c.Msg, &c.Notify, &c.StateSince)
+ if err != nil {
+ con.w.WriteHeader(http.StatusInternalServerError)
+ returnError(http.StatusInternalServerError, con, con.w)
+ log.Printf("could not get check list: %s", err)
+ return
+ }
+ checks = append(checks, c)
+ }
+ con.Checks = checks
+ if err := con.loadCommands(); err != nil {
+ con.Error = "could not load commands"
+ returnError(http.StatusInternalServerError, con, con.w)
+ log.Printf("could not get commands: %s", err)
+ return
+ }
+ if err := con.loadMappings(); err != nil {
+ con.Error = "could not load mapping data"
+ con.w.WriteHeader(http.StatusInternalServerError)
+ con.w.Write([]byte("problem with the mappings"))
+ log.Printf("could not load mappings: %s", err)
+ return
+ }
+ con.w.Header()["Content-Type"] = []string{"text/html"}
+ con.Render("checklist")
+ return
+}