Server side sorting for the websessions page. No longer using LinkedMap as a result.
This commit is contained in:
parent
1de3c90146
commit
3574b64842
@ -21,7 +21,7 @@ func pageHandler(w http.ResponseWriter, r *http.Request) {
|
||||
case "downloads.html":
|
||||
templates2.DownloadsTab().Render(r.Context(), w)
|
||||
case "sessions.html":
|
||||
templates2.SessionsTab(nil, access.Location).Render(r.Context(), w)
|
||||
templates2.SessionsTab(nil, nil, access.Location).Render(r.Context(), w)
|
||||
default:
|
||||
http.NotFound(w, r)
|
||||
}
|
||||
|
@ -24,10 +24,10 @@ func NewPrometheusState(state *models.State) *PrometheusState {
|
||||
agents: collections.NewLinkedMap[models.AgentGuid, *models.Agent](),
|
||||
clients: collections.NewLinkedMap[models.ClientGuid, *models.Client](),
|
||||
}
|
||||
for agent := range state.Agents.RangeValues() {
|
||||
for _, agent := range state.Agents {
|
||||
res.agents.Put(agent.Guid, agent)
|
||||
}
|
||||
for client := range state.Clients.RangeValues() {
|
||||
for _, client := range state.Clients {
|
||||
res.clients.Put(client.Guid, client)
|
||||
}
|
||||
return &res
|
||||
|
@ -70,7 +70,7 @@ func main() {
|
||||
render(dir, "downloads.html", templates2.Downloads)
|
||||
|
||||
render(dir, "sessions-none.html", func() templ.Component {
|
||||
return templates2.SessionsTab(nil, netherlands)
|
||||
return templates2.SessionsTab(nil, nil, netherlands)
|
||||
})
|
||||
render(dir, "sessions.html", func() templ.Component {
|
||||
|
||||
@ -94,7 +94,7 @@ func main() {
|
||||
},
|
||||
}
|
||||
agent.SetExpiryTime(time.Now().In(japan).Add(10 * time.Minute))
|
||||
state.Agents.Put(agent.Guid, &agent)
|
||||
state.Agents[agent.Guid] = &agent
|
||||
client := models.Client{
|
||||
Guid: models.ClientGuid(strconv.Itoa(rand.Int())),
|
||||
RemoteAddr: models.RemoteAddr("10.1.3.3"),
|
||||
@ -104,7 +104,9 @@ func main() {
|
||||
StartTime: time.Now().In(japan),
|
||||
SessionType: models.SessionType("sftp"),
|
||||
}
|
||||
state.Clients.Put(client.Guid, &client)
|
||||
return templates2.SessionsTab(state, netherlands)
|
||||
state.Clients[client.Guid] = &client
|
||||
|
||||
agents, clients := state.Slices()
|
||||
return templates2.SessionsTab(agents, clients, netherlands)
|
||||
})
|
||||
}
|
||||
|
@ -2,7 +2,7 @@ package models
|
||||
|
||||
import (
|
||||
"git.wamblee.org/converge/pkg/comms"
|
||||
"git.wamblee.org/converge/pkg/support/collections"
|
||||
"sort"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
@ -56,25 +56,43 @@ type Client struct {
|
||||
// Created by the server and used for updating the web client
|
||||
// and prometheus metrics.
|
||||
type State struct {
|
||||
Agents *collections.LinkedMap[AgentGuid, *Agent]
|
||||
Clients *collections.LinkedMap[ClientGuid, *Client]
|
||||
Agents map[AgentGuid]*Agent
|
||||
Clients map[ClientGuid]*Client
|
||||
}
|
||||
|
||||
func NewState() *State {
|
||||
return &State{
|
||||
Agents: collections.NewLinkedMap[AgentGuid, *Agent](),
|
||||
Clients: collections.NewLinkedMap[ClientGuid, *Client](),
|
||||
Agents: make(map[AgentGuid]*Agent),
|
||||
Clients: make(map[ClientGuid]*Client),
|
||||
}
|
||||
}
|
||||
|
||||
// for copy on write
|
||||
func (state *State) Copy() *State {
|
||||
res := NewState()
|
||||
for entry := range state.Agents.RangeEntries() {
|
||||
res.Agents.Put(entry.Key, entry.Value)
|
||||
for k, v := range state.Agents {
|
||||
res.Agents[k] = v
|
||||
}
|
||||
for entry := range state.Clients.RangeEntries() {
|
||||
res.Clients.Put(entry.Key, entry.Value)
|
||||
for k, v := range state.Clients {
|
||||
res.Clients[k] = v
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func (state *State) Slices() ([]*Agent, []*Client) {
|
||||
agents := make([]*Agent, 0, len(state.Agents))
|
||||
clients := make([]*Client, 0, len(state.Clients))
|
||||
for _, agent := range state.Agents {
|
||||
agents = append(agents, agent)
|
||||
}
|
||||
for _, client := range state.Clients {
|
||||
clients = append(clients, client)
|
||||
}
|
||||
sort.Slice(agents, func(i int, j int) bool {
|
||||
return agents[i].StartTime.Before(agents[j].StartTime)
|
||||
})
|
||||
sort.Slice(clients, func(i int, j int) bool {
|
||||
return clients[i].StartTime.Before(clients[j].StartTime)
|
||||
})
|
||||
return agents, clients
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ func (admin *Admin) AddAgent(publicId models.RendezVousId, agentInfo comms.Envir
|
||||
agent := newAgent(commChannel, publicId, agentInfo)
|
||||
|
||||
admin.state = admin.state.Copy()
|
||||
admin.state.Agents.Put(agent.Info.Guid, agent.Info)
|
||||
admin.state.Agents[agent.Info.Guid] = agent.Info
|
||||
admin.agents[publicId] = agent
|
||||
return agent, nil
|
||||
}
|
||||
@ -175,7 +175,7 @@ func (admin *Admin) AddClient(publicId models.RendezVousId, clientConn iowrapper
|
||||
}
|
||||
|
||||
admin.state = admin.state.Copy()
|
||||
admin.state.Clients.Put(client.Info.Guid, client.Info)
|
||||
admin.state.Clients[client.Info.Guid] = client.Info
|
||||
admin.clients[client.Info.ClientId] = client
|
||||
return client, nil
|
||||
}
|
||||
@ -206,7 +206,7 @@ func (admin *Admin) RemoveAgent(publicId models.RendezVousId) error {
|
||||
log.Printf("Could not close yamux client session for '%s'\n", publicId)
|
||||
}
|
||||
admin.state = admin.state.Copy()
|
||||
admin.state.Agents.Delete(agent.Info.Guid)
|
||||
delete(admin.state.Agents, agent.Info.Guid)
|
||||
delete(admin.agents, publicId)
|
||||
return nil
|
||||
}
|
||||
@ -222,7 +222,7 @@ func (admin *Admin) RemoveClient(client *clientConnection) error {
|
||||
_ = client.clientConnection.Close()
|
||||
|
||||
admin.state = admin.state.Copy()
|
||||
admin.state.Clients.Delete(client.Info.Guid)
|
||||
delete(admin.state.Clients, client.Info.Guid)
|
||||
delete(admin.clients, client.Info.ClientId)
|
||||
return nil
|
||||
}
|
||||
@ -230,7 +230,7 @@ func (admin *Admin) RemoveClient(client *clientConnection) error {
|
||||
func (admin *Admin) SetSessionType(clientId models.ClientId, sessionType models.SessionType) {
|
||||
admin.mutex.Lock()
|
||||
defer admin.mutex.Unlock()
|
||||
for client := range admin.state.Clients.RangeValues() {
|
||||
for _, client := range admin.state.Clients {
|
||||
if client.ClientId == clientId {
|
||||
client.SessionType = sessionType
|
||||
break
|
||||
|
@ -134,7 +134,7 @@ func logStatusImpl(admin *models.State, notifier Notifier) {
|
||||
|
||||
lines = append(lines, fmt.Sprintf(format, "AGENT", "ACTIVE_SINCE", "EXPIRY_TIME",
|
||||
"USER", "HOST", "OS"))
|
||||
for agent := range admin.Agents.RangeValues() {
|
||||
for _, agent := range admin.Agents {
|
||||
lines = append(lines, fmt.Sprintf(format, agent.PublicId,
|
||||
agent.StartTime.Format(time.DateTime),
|
||||
agent.GetExpiryTime().Format(time.DateTime),
|
||||
@ -145,7 +145,7 @@ func logStatusImpl(admin *models.State, notifier Notifier) {
|
||||
lines = append(lines, "")
|
||||
format = "%-10s %-20s %-20s %-20s %-20s"
|
||||
lines = append(lines, fmt.Sprintf(format, "CLIENT", "AGENT", "ACTIVE_SINCE", "REMOTE_ADDRESS", "SESSION_TYPE"))
|
||||
for client := range admin.Clients.RangeValues() {
|
||||
for _, client := range admin.Clients {
|
||||
lines = append(lines, fmt.Sprintf(format,
|
||||
client.ClientId,
|
||||
client.PublicId,
|
||||
|
@ -137,7 +137,8 @@ func (session *WebSession) WriteNotifications(location *time.Location, ctx conte
|
||||
}
|
||||
|
||||
func (session *WebSession) writeNotificationToClient(location *time.Location, notification *models.State) bool {
|
||||
err := templates.State(notification, location).Render(context.Background(), session.conn)
|
||||
agents, clients := notification.Slices()
|
||||
err := templates.State(agents, clients, location).Render(context.Background(), session.conn)
|
||||
if err != nil {
|
||||
log.Printf("WS connection closed: %v", err)
|
||||
return false
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
|
||||
templ Sessions(state *models.State, loc *time.Location) {
|
||||
templ Sessions(agents []*models.Agent, clients []*models.Client, loc *time.Location) {
|
||||
<div>
|
||||
<div ws-send
|
||||
hx-trigger="load"
|
||||
@ -16,8 +16,8 @@ templ Sessions(state *models.State, loc *time.Location) {
|
||||
<h1>sessions</h1>
|
||||
|
||||
<div id="status">
|
||||
if state != nil {
|
||||
@State(state, loc)
|
||||
if len(agents) > 0 {
|
||||
@State(agents, clients, loc)
|
||||
} else {
|
||||
Loading...
|
||||
}
|
||||
@ -26,12 +26,12 @@ templ Sessions(state *models.State, loc *time.Location) {
|
||||
|
||||
}
|
||||
|
||||
templ State(state *models.State, location *time.Location) {
|
||||
templ State(agents []*models.Agent, clients []*models.Client, location *time.Location) {
|
||||
<div id="status">
|
||||
|
||||
<h3>agents</h3>
|
||||
|
||||
if state.Agents.Len() == 0 {
|
||||
if len(agents) == 0 {
|
||||
<p>-</p>
|
||||
} else {
|
||||
<table class="table">
|
||||
@ -46,7 +46,7 @@ templ State(state *models.State, location *time.Location) {
|
||||
<th>shell</th>
|
||||
</tr>
|
||||
</thead>
|
||||
for agent := range state.Agents.RangeValues() {
|
||||
for _, agent := range agents {
|
||||
<tr>
|
||||
<td>{string(agent.PublicId)}</td>
|
||||
<td>{agent.StartTime.In(location).Format(time.DateTime)}</td>
|
||||
@ -64,7 +64,7 @@ templ State(state *models.State, location *time.Location) {
|
||||
|
||||
<h3>clients</h3>
|
||||
|
||||
if state.Clients.Len() == 0 {
|
||||
if len(clients) == 0 {
|
||||
<p>-</p>
|
||||
} else {
|
||||
<table class="table">
|
||||
@ -80,7 +80,7 @@ templ State(state *models.State, location *time.Location) {
|
||||
<th>shell</th>
|
||||
</tr>
|
||||
</thead>
|
||||
for client := range state.Clients.RangeValues() {
|
||||
for _, client := range clients {
|
||||
<tr>
|
||||
<td>{string(client.ClientId)}</td>
|
||||
<td>{client.StartTime.In(location).Format(time.DateTime)}</td>
|
||||
@ -98,8 +98,8 @@ templ State(state *models.State, location *time.Location) {
|
||||
}
|
||||
|
||||
|
||||
templ SessionsTab(state *models.State, loc *time.Location) {
|
||||
templ SessionsTab(agents []*models.Agent, clients []*models.Client, loc *time.Location) {
|
||||
@BasePage(4) {
|
||||
@Sessions(state, loc)
|
||||
@Sessions(agents, clients, loc)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user