Files
nodemaster/controllers/nodes.go
T
2026-07-27 14:41:04 +02:00

160 lines
4.0 KiB
Go

package controllers
import (
"encoding/json"
"io"
"net/http"
"nodemaster/models"
"time"
beego "github.com/beego/beego/v2/server/web"
)
// NodesController manages the registry of remote nodes.
type NodesController struct {
beego.Controller
}
// @Title GetAllNodes
// @Description list all registered remote nodes
// @Success 200 {object} []models.RemoteNode
// @router / [get]
func (c *NodesController) GetAll() {
c.Data["json"] = models.GetAllRemoteNodes()
c.ServeJSON()
}
// @Title AddNode
// @Description register a remote node
// @Param body body models.RemoteNode true "node to register"
// @Success 201 {object} models.RemoteNode
// @Failure 400 invalid body
// @router / [post]
func (c *NodesController) Post() {
var n models.RemoteNode
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &n); err != nil {
c.Ctx.Output.SetStatus(400)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
created, err := models.AddRemoteNode(n)
if err != nil {
c.Ctx.Output.SetStatus(500)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
c.Ctx.Output.SetStatus(201)
c.Data["json"] = created
c.ServeJSON()
}
// @Title GetNode
// @Description get a remote node by id
// @Param id path string true "node id"
// @Success 200 {object} models.RemoteNode
// @Failure 404 not found
// @router /:id [get]
func (c *NodesController) Get() {
id := c.Ctx.Input.Param(":id")
n, err := models.GetRemoteNode(id)
if err != nil {
c.Ctx.Output.SetStatus(404)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
c.Data["json"] = n
c.ServeJSON()
}
// @Title UpdateNode
// @Description update a remote node
// @Param id path string true "node id"
// @Param body body models.RemoteNode true "updated node data"
// @Success 200 {object} models.RemoteNode
// @Failure 400 invalid body
// @Failure 404 not found
// @router /:id [put]
func (c *NodesController) Put() {
id := c.Ctx.Input.Param(":id")
var n models.RemoteNode
if err := json.Unmarshal(c.Ctx.Input.RequestBody, &n); err != nil {
c.Ctx.Output.SetStatus(400)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
updated, err := models.UpdateRemoteNode(id, n)
if err != nil {
c.Ctx.Output.SetStatus(404)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
c.Data["json"] = updated
c.ServeJSON()
}
// @Title DeleteNode
// @Description delete a remote node
// @Param id path string true "node id"
// @Success 200 {string} delete success
// @Failure 404 not found
// @router /:id [delete]
func (c *NodesController) Delete() {
id := c.Ctx.Input.Param(":id")
if err := models.DeleteRemoteNode(id); err != nil {
c.Ctx.Output.SetStatus(404)
c.Data["json"] = map[string]string{"error": err.Error()}
c.ServeJSON()
return
}
c.Data["json"] = map[string]string{"message": "delete success"}
c.ServeJSON()
}
type nodeServices struct {
Node models.RemoteNode `json:"node"`
Services []models.Service `json:"services"`
Error string `json:"error,omitempty"`
}
// @Title GetAggregated
// @Description query all registered nodes for their services and return an aggregated view
// @Success 200 {object} []nodeServices
// @router /aggregated [get]
func (c *NodesController) GetAggregated() {
nodes := models.GetAllRemoteNodes()
client := &http.Client{Timeout: 10 * time.Second}
results := make([]nodeServices, 0, len(nodes))
for _, node := range nodes {
entry := nodeServices{Node: node}
resp, err := client.Get(node.URL + "/v1/services")
if err != nil {
entry.Error = err.Error()
results = append(results, entry)
continue
}
body, err := io.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
entry.Error = err.Error()
results = append(results, entry)
continue
}
var svcs []models.Service
if err := json.Unmarshal(body, &svcs); err != nil {
entry.Error = "failed to parse services: " + err.Error()
} else {
entry.Services = svcs
}
results = append(results, entry)
}
c.Data["json"] = results
c.ServeJSON()
}