package h
import (
"bytes"
"html/template"
"io"
"net/url"
"gopkg.awl.red/cicada/config"
)
var tmplfuncs = template.FuncMap{
"Fst": func(x string) string {
if x == "" {
return x
}
return x[:1]
},
"Status": func(x string) string {
switch x {
case "ACKNOWLEDGED":
return "👀"
case "RESOLVED":
return "✅"
case "TRIGGERED":
return "❗"
default:
return ""
}
},
"Swatch": func(x string) template.HTML {
if x == "IMMEDIATE" {
return template.HTML(`<span class="swatch red"></span>`)
}
return template.HTML(`<span class="swatch yellow"></span>`)
},
"SwatchInactive": func(x string) template.HTML {
return template.HTML(`<span class="swatch inactive"></span>`)
},
}
var templateLogin = template.Must(template.New("template_login").Funcs(tmplfuncs).Parse(`<!doctype html><html><head>
<title>Cicada login</title>
<html lang="en"><head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{.StyleTag}}
</head><body>
</body>
<form action="/login" method="post">
<label for="pw">Put admin CICADA_KEY here</label>
<input id="pw" type="password" name="cicada_key"></input>
<input type="submit" value="log in"></input>
</form>
</html>`))
var templateAlerts = template.Must(template.New("template_alerts").Funcs(tmplfuncs).Parse(`<!doctype html>
<html lang="en"><head>
<title>Cicada alerts</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
{{.StyleTag}}
</head>
<body>
<a href="/logout">logout</a>
{{ if .Data.Alerts }}
<h2>Active alerts</h2>
<table>
<thead>
<td>Service</td> <td>Component</td> <td>Severity</td> <td>Status</td> <td>Time (UTC)</td> <td>Error</td> <td>Message</td> <td>Updater</td> <td>Alerter</td> <td class="actions">Actions</td>
</thead>
{{range .Data.Alerts}}
<tr><td>{{.Service}}</td><td>{{.Component}}</td><td>{{Swatch .Severity}}</td><td>{{Status .Status}}</td><td><div>{{.CreatedTime}} (started)</div><div>{{.StatusTime}} (status)</div></td><td>{{.Error}}</td><td>{{.Message}}</td><td>{{.Updater}}</td><td>{{.Alerter}}</td><td class="actions"><a href="/alerts/{{ .Id }}/newstatus/TRIGGERED">Trigger</a> <a href="/alerts/{{ .Id }}/newstatus/ACKNOWLEDGED">Acknowledge</a> <a href="/alerts/{{ .Id }}/newstatus/RESOLVED">Resolve</a></td></tr>
{{ end }}
</table>
{{end}}
{{ if .Data.Resolved }}
<h2>Recently resolved alerts</h2>
<table>
<thead>
<td>Service</td> <td>Component</td> <td>Severity</td> <td>Status</td> <td>Time (UTC)</td> <td>Error</td> <td>Message</td> <td>Updater</td> <td>Alerter</td> <td class="actions">Actions</td>
</thead>
{{range .Data.Resolved}}
<tr><td>{{.Service}}</td><td>{{.Component}}</td><td>{{SwatchInactive .Severity}}</td><td>{{Status .Status}}</td><td><div>{{.CreatedTime}} (started)</div><div>{{.StatusTime}} (status)</div></td><td>{{.Error}}</td><td>{{.Message}}</td><td>{{.Updater}}</td><td>{{.Alerter}}</td><td class="actions"><a href="/alerts/{{ .Id }}/newstatus/TRIGGERED">Trigger</a> <a href="/alerts/{{ .Id }}/delete">Delete</a></td></tr>
{{ end }}
</table>
{{ end }}
<h2>Create new alert</h2>
<form action="/alerts" method="POST">
<div>
<label for="service">Service</label>
<input id="service" name="service" type="text" required></input>
</div>
<div>
<label for="component">Component</label>
<input id="component" name="component" type="text"></input>
</div>
<div>
<label for="error">Error</label>
<input id="error" name="error" type="text"></input>
</div>
<div>
<label for="message">Message</label>
<input id="message" name="message" type="text" required></input>
</div>
<div>
<label for="severity">Severity</label>
<select id="severity" name="severity" value="IMMEDIATE">
<option value="IMMEDIATE">IMMEDIATE</option>
<option value="INVESTIGATE">INVESTIGATE</option>
</select>
</div>
<div>
<label for="status">Status</label>
<select id="status" name="status" value="TRIGGERED">
<option value="TRIGGERED">Trigger</option>
<option value="ACKNOWLEDGED">Acknowledge</option>
<option value="RESOLVED">Resolve</option>
</select>
</div>
<div>
<input type="submit" value="Create new alert"></input>
</div>
</form>
</body>
</html>`))
type ConfigTemplateData struct {
Config *config.Config `json:"config"`
Data any `json:"data"`
StyleTag template.HTML `json:"style_tag"`
}
func TAlerts(w io.Writer, u url.Values, c *config.Config, data map[string]any) error {
// _, didLogout := u["did_logout"]
// _, badLogin := u["bad_login"]
// data.DidLogout = didLogout
// data.BadLogin = badLogin
// data.Footer = template.HTML(footer(c))
var stylesheetBuf bytes.Buffer
templateBaseStylesheet.Execute(&stylesheetBuf, ConfigTemplateData{Config: c})
return templateAlerts.Execute(w, ConfigTemplateData{Config: c, StyleTag: template.HTML(stylesheetBuf.String()), Data: data})
}
func TLogin(w io.Writer, u url.Values, c *config.Config, data map[string]any) error {
var stylesheetBuf bytes.Buffer
templateBaseStylesheet.Execute(&stylesheetBuf, ConfigTemplateData{Config: c})
return templateLogin.Execute(w, ConfigTemplateData{Config: c, StyleTag: template.HTML(stylesheetBuf.String()), Data: data})
}