Skip to content

Commit

Permalink
New 'hosts' page, listing all hosts simply; updated 'time since' text…
Browse files Browse the repository at this point in the history
… to make it less precise / verbose; created a footer function.
  • Loading branch information
vaughany committed Sep 7, 2021
1 parent 80ec070 commit 87f9df7
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 8 deletions.
8 changes: 8 additions & 0 deletions cmd/receiver/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"net/http"
"os"
"os/signal"
"runtime"
"syscall"
"time"
vcms "vcms/internal"
Expand Down Expand Up @@ -41,6 +42,7 @@ type HTMLData struct {
Subtitle string
Footer template.HTML
Rows []rowData
RowCount int
}

type rowData struct {
Expand Down Expand Up @@ -117,6 +119,7 @@ func main() {
http.HandleFunc("/", rootHandler)
http.HandleFunc("/dashboard", dashboardHandler)
http.HandleFunc("/dashboard/full", dashboardHandler)
http.HandleFunc("/hosts", hostsHandler)
http.HandleFunc("/host/", hostHandler) // Note the trailing '/'.
http.HandleFunc("/api/announce", apiAnnounceHandler)
http.HandleFunc("/api/ping", apiPingHandler)
Expand Down Expand Up @@ -163,3 +166,8 @@ func shutdownHandler() {
os.Exit(0)
}()
}

func makeHTMLFooter() string {
return fmt.Sprintf("<strong>%s</strong> v%s (%s), built with %s, %s/%s. See <a href=\"https://%s\" target=\"_blank\">%s</a> for more info.",
vcms.AppTitle, vcms.AppVersion, vcms.AppDate, runtime.Version(), runtime.GOOS, runtime.GOARCH, vcms.ProjectURL, vcms.ProjectURL)
}
2 changes: 1 addition & 1 deletion cmd/receiver/templates/dashboard_full.gohtml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{{ define "content" }}
<div class="container-flex">

<h3 class="is-size-3">Nodes</h3>
<h3 class="is-size-3">Nodes ({{ .RowCount }})</h3>

{{ if .Rows }}
<table class="table is-striped is-hoverable is-fullwidth">
Expand Down
2 changes: 1 addition & 1 deletion cmd/receiver/templates/dashboard_light.gohtml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{{ define "content" }}
<div class="container-flex">

<h3 class="is-size-3">Nodes</h3>
<h3 class="is-size-3">Nodes ({{ .RowCount }})</h3>

{{ if .Rows }}
<table class="table is-striped is-hoverable is-fullwidth">
Expand Down
32 changes: 32 additions & 0 deletions cmd/receiver/templates/hosts.gohtml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{ define "content" }}
<div class="container">

<h3 class="is-size-3">Hosts ({{ .RowCount }})</h3>

{{ if .Rows }}
<table class="table is-striped is-hoverable is-fullwidth">
<thead>
<tr>
<th>#</th>
<th>Hostname</th>
<th>Manage</th>
</tr>
</thead>
<tbody>
{{ range $index, $element := .Rows }}
<tr>
<th>{{ inc $index }}</th>
<td>
<a href="/host/{{ .Hostname }}">{{ .Hostname }}{{ if .Errors }}{{ .Errors }}{{ end }}</a></td>
<td><a href="/node/remove/?node={{ .Hostname }}" onclick="return confirm('Are you sure you want to remove this node?')">remove</a></td>
</tr>
{{ end }}
</tbody>
</table>

{{ else }}
<p>Nothing yet, sorry.</p>
{{ end }}

</div>
{{ end }}
1 change: 1 addition & 0 deletions cmd/receiver/templates/layout.gohtml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
<div class="navbar-start">
<a class="navbar-item" href="/dashboard">Dashboard</a>
<a class="navbar-item" href="/dashboard/full">Full Dashboard</a>
<a class="navbar-item" href="/hosts">Hosts</a>
<div class="navbar-item">
<div class="buttons">
<a href="/export/json" class="button">Export JSON</a>
Expand Down
54 changes: 48 additions & 6 deletions cmd/receiver/web.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"html/template"
"log"
"net/http"
"runtime"
"sort"
"strings"
"time"
Expand All @@ -24,8 +23,6 @@ func rootHandler(w http.ResponseWriter, r *http.Request) {
func dashboardHandler(w http.ResponseWriter, r *http.Request) {
var (
data HTMLData
subFooterHTML = fmt.Sprintf("See <a href=\"https://%s\" target=\"_blank\">%s</a> for more info.", vcms.ProjectURL, vcms.ProjectURL)
footerHTML = fmt.Sprintf("<strong>%s</strong> v%s (%s), built with %s, %s/%s. %s", vcms.AppTitle, vcms.AppVersion, vcms.AppDate, runtime.Version(), runtime.GOOS, runtime.GOARCH, subFooterHTML)
dashboardType = "light"
)

Expand All @@ -49,7 +46,7 @@ func dashboardHandler(w http.ResponseWriter, r *http.Request) {
// Build the HTML.
data.Title = vcms.AppTitle
data.Subtitle = fmt.Sprintf("%s Dashboard", strings.Title(dashboardType))
data.Footer = template.HTML(footerHTML)
data.Footer = template.HTML(makeHTMLFooter())
for _, key := range keys {
var row rowData
if len(nodes[key].Meta.Errors) > 0 {
Expand All @@ -58,8 +55,8 @@ func dashboardHandler(w http.ResponseWriter, r *http.Request) {
row.Hostname = nodes[key].Hostname
row.IPAddress = nodes[key].IPAddress
row.Username = nodes[key].Username
row.FirstSeen = template.HTML(fmt.Sprintf("%s <span class=\"has-text-grey-light\"><small>(%s ago)</small></span>", nodes[key].FirstSeen.Format(conciseDateTimeFormat), durafmt.Parse(time.Since(nodes[key].FirstSeen).Round(time.Second))))
row.LastSeen = template.HTML(fmt.Sprintf("%s <span class=\"has-text-grey-light\"><small>(%s ago)</small></span>", nodes[key].LastSeen.Format(conciseDateTimeFormat), durafmt.Parse(time.Since(nodes[key].LastSeen).Round(time.Second))))
row.FirstSeen = template.HTML(fmt.Sprintf("%s <span class=\"has-text-grey-light\"><br><small>(%s ago)</small></span>", nodes[key].FirstSeen.Format(conciseDateTimeFormat), durafmt.Parse(time.Since(nodes[key].FirstSeen).Round(time.Second)).LimitFirstN(3)))
row.LastSeen = template.HTML(fmt.Sprintf("%s <span class=\"has-text-grey-light\"><br><small>(%s ago)</small></span>", nodes[key].LastSeen.Format(conciseDateTimeFormat), durafmt.Parse(time.Since(nodes[key].LastSeen).Round(time.Second)).LimitFirstN(3)))
row.HostUptime = nodes[key].HostUptime
row.OSVersion = nodes[key].OSVersion
row.CPU = getCPUHTML(nodes[key])
Expand Down Expand Up @@ -87,6 +84,7 @@ func dashboardHandler(w http.ResponseWriter, r *http.Request) {
row.OSImage = getOSImage(nodes[key])

data.Rows = append(data.Rows, row)
data.RowCount++
}

tmpl := template.Must(template.New("layout.gohtml").Funcs(funcMap).ParseFS(embeddedFiles, "templates/layout.gohtml", fmt.Sprintf("templates/dashboard_%s.gohtml", dashboardType)))
Expand All @@ -98,6 +96,50 @@ func dashboardHandler(w http.ResponseWriter, r *http.Request) {
log.Printf("Dashboard (%s) accessed.\n", dashboardType)
}

func hostsHandler(w http.ResponseWriter, r *http.Request) {
var (
data HTMLData
)

funcMap := template.FuncMap{
"inc": func(i int) int {
return i + 1
},
}

// Sorting the map into order by hostname.
keys := make([]string, 0, len(nodes))
for key := range nodes {
keys = append(keys, key)
}
sort.Strings(keys)

// Build the HTML.
data.Title = vcms.AppTitle
data.Subtitle = "Hosts"
data.Footer = template.HTML(makeHTMLFooter())
for _, key := range keys {
var row rowData
if len(nodes[key].Meta.Errors) > 0 {
row.Errors = fmt.Sprintf(" <span style=\"color: red;\" title=\"%s\">ERROR!</span>", strings.Join(nodes[key].Meta.Errors, "\n"))
}
row.Hostname = nodes[key].Hostname
// row.IPAddress = nodes[key].IPAddress
// row.OSImage = getOSImage(nodes[key])

data.Rows = append(data.Rows, row)
data.RowCount++
}

tmpl := template.Must(template.New("layout.gohtml").Funcs(funcMap).ParseFS(embeddedFiles, "templates/layout.gohtml", "templates/hosts.gohtml"))
err := tmpl.Execute(w, data)
if err != nil {
log.Panic(err)
}

log.Println("Hosts accessed.")
}

func hostHandler(w http.ResponseWriter, r *http.Request) {
node := r.URL.Path[6:]
if node == "" {
Expand Down

0 comments on commit 87f9df7

Please sign in to comment.