diff --git a/cmd/monfront/main.go b/cmd/monfront/main.go index eaf1d94..7d80c65 100644 --- a/cmd/monfront/main.go +++ b/cmd/monfront/main.go @@ -26,6 +26,29 @@ type ( DB string `json:"db"` Listen string `json:"listen"` } + + Context struct { + Mappings map[int]map[int]MapEntry + Checks []check + } + + MapEntry struct { + Title string + Color string + } + + check struct { + NodeName string + CommandName string + CheckID int64 + MappingId int + State int + Notify bool + Enabled bool + Notice sql.NullString + NextTime time.Time + Msg string + } ) func main() { @@ -149,21 +172,10 @@ func showChecks(w http.ResponseWriter, r *http.Request) { return } - type check struct { - NodeName string - CommandName string - CheckID int64 - State int - Notify bool - Enabled bool - Notice sql.NullString - NextTime time.Time - Msg string - } checks := []check{} for rows.Next() { c := check{} - err := rows.Scan(&c.CheckID, &c.NodeName, &c.CommandName, &c.State, &c.Notify, &c.Enabled, &c.Notice, &c.NextTime, &c.Msg) + err := rows.Scan(&c.CheckID, &c.NodeName, &c.CommandName, &c.MappingId, &c.State, &c.Notify, &c.Enabled, &c.Notice, &c.NextTime, &c.Msg) if err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("problems with the database")) @@ -181,8 +193,17 @@ func showChecks(w http.ResponseWriter, r *http.Request) { log.Printf("could not parse template: %s", err) return } + con := Context{ + Checks: checks, + } + if err := loadMappings(&con); err != nil { + w.WriteHeader(http.StatusInternalServerError) + w.Write([]byte("problem with the mappings")) + log.Printf("could not load mappings: %s", err) + return + } w.Header()["Content-Type"] = []string{"text/html"} - if err := tmpl.Execute(w, checks); err != nil { + if err := tmpl.Execute(w, con); err != nil { w.WriteHeader(http.StatusInternalServerError) w.Write([]byte("problem with a template")) log.Printf("could not execute template: %s", err) @@ -193,6 +214,7 @@ func showChecks(w http.ResponseWriter, r *http.Request) { func showUnhandledHosts(w http.ResponseWriter, r *http.Request) { } + func showUnhandledGroups(w http.ResponseWriter, r *http.Request) { rows, err := DB.Query(SQLShowUnhandledGroups) if err != nil { @@ -236,8 +258,40 @@ func showUnhandledGroups(w http.ResponseWriter, r *http.Request) { return } +func loadMappings(c *Context) error { + c.Mappings = map[int]map[int]MapEntry{} + rows, err := DB.Query(SQLShowMappings) + if err != nil { + return err + } + + for rows.Next() { + if rows.Err() != nil { + return rows.Err() + } + var ( + mapId int + target int + title string + color string + ) + if err := rows.Scan(&mapId, &target, &title, &color); err != nil { + return err + } + ma, found := c.Mappings[mapId] + if !found { + ma = map[int]MapEntry{} + c.Mappings[mapId] = ma + } + ma[target] = MapEntry{Title: title, Color: color} + } + return nil +} + var ( - SQLShowChecks = `select c.id, n.name, co.name, ac.states[1] as state, ac.notify, + SQLShowMappings = `select mapping_id, target, title, color + from mapping_level` + SQLShowChecks = `select c.id, n.name, co.name, ac.mapping_id, ac.states[1] as state, ac.notify, ac.enabled, ac.notice, ac.next_time, ac.msg from active_checks ac join checks c on ac.check_id = c.id @@ -280,10 +334,15 @@ var ( form nav { display: flex; flex-direction: column; } form nav > * { margin: 0.5em; } table td, table th { padding: 0.5em; } - td.state-0 { background: green; } + {{ range $mapId, $mapping := .Mappings }} + {{ range $target, $val := $mapping }} + td.state-{{ $mapId }}-{{ $target }} { background: {{ $val.Color }}; } + {{ end }} + {{ end }} + /* td.state-0 { background: green; } td.state-1 { background: orange; } td.state-2 { background: red; } - td.state-99 { background: gray; } + td.state-99 { background: gray; } */ @@ -321,11 +380,12 @@ var ( hoststatusnext checkmessage {{ $current := "" }} - {{ range . }} + {{ $mapping := .Mappings }} + {{ range .Checks }} {{ if ne $current .NodeName }}{{ $current = .NodeName }}{{ .NodeName }}{{ end }} - {{ .CommandName }} - {{ .State }} + {{ .CommandName }} - {{ (index $mapping .MappingId .State).Title }} {{ .NextTime.Format "2006.01.02 15:04:05" }}
{{ .Msg }}
diff --git a/cmd/monwork/main.go b/cmd/monwork/main.go index 5c71a60..13c4f39 100644 --- a/cmd/monwork/main.go +++ b/cmd/monwork/main.go @@ -218,11 +218,13 @@ var ( where c.last_refresh < c.updated or c.last_refresh is null limit 1 for update of c skip locked;` - SQLRefreshActiveCheck = `insert into active_checks(check_id, cmdline, intval, enabled, notify, msg) -select id, $2, c.intval, c.enabled, c.notify, case when ac.msg is null then '' else ac.msg end from checks c + SQLRefreshActiveCheck = `insert into active_checks(check_id, cmdline, intval, enabled, notify, msg, mapping_id) +select c.id, $2, c.intval, c.enabled, c.notify, case when ac.msg is null then '' else ac.msg end, case when c.mapping_id is not null then c.mapping_id when n.mapping_id is not null then n.mapping_id else 1 end +from checks c left join active_checks ac on c.id = ac.check_id -where id = $1 +left join nodes n on c.node_id = n.id +where c.id = $1 on conflict(check_id) -do update set cmdline = $2, intval = excluded.intval, enabled = excluded.enabled, notify = excluded.notify;` +do update set cmdline = $2, intval = excluded.intval, enabled = excluded.enabled, notify = excluded.notify, mapping_id = excluded.mapping_id;` SQLUpdateLastRefresh = `update checks set last_refresh = now() where id = $1;` ) diff --git a/schema/20181210.sql b/schema/20181210.sql index 757055d..05236ca 100644 --- a/schema/20181210.sql +++ b/schema/20181210.sql @@ -1,3 +1,18 @@ +create table public.mappings( + id serial primary key, + name text not null, + description text not null +); + +create table public.mapping_level( + mapping_id integer not null, + source int not null, + target int not null, + title text not null, + color text not null, + unique(mapping_id, source) +); + CREATE TABLE public.notifier ( id serial NOT NULL primary key, name text NOT NULL @@ -10,10 +25,11 @@ CREATE TABLE public.groups ( CREATE TABLE public.nodes ( id bigserial NOT NULL primary key, + mapping_id int references mappings(id), name text NOT NULL, updated timestamp with time zone DEFAULT now() NOT NULL, created timestamp with time zone DEFAULT now() NOT NULL, - message text NOT NULL + message text NOT NULL, ); CREATE TABLE public.nodes_groups ( @@ -28,13 +44,14 @@ CREATE TABLE public.commands ( command text NOT NULL, updated timestamp with time zone DEFAULT now() NOT NULL, created timestamp with time zone DEFAULT now() NOT NULL, - message text NOT NULL + message text NOT NULL, ); CREATE TABLE public.checks ( id bigserial NOT NULL primary key, node_id integer not null references nodes(id) on delete cascade, command_id integer not null references commands(id) on delete restrict, + mapping_id int references mappings(id), intval interval DEFAULT '00:05:00'::interval NOT NULL, options jsonb DEFAULT '{}'::jsonb NOT NULL, updated timestamp with time zone DEFAULT now() NOT NULL, @@ -48,6 +65,7 @@ CREATE TABLE public.checks ( CREATE TABLE public.active_checks ( check_id bigint NOT NULL references checks(id) on delete cascade, + mapping_id int not null references mappings(id), cmdline text[] NOT NULL, next_time timestamp with time zone DEFAULT now() NOT NULL, states integer[] DEFAULT ARRAY[0] NOT NULL,