160 lines
4.0 KiB
Go
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()
|
|
}
|