Batch-fetch action widgets so the dashboard can show free/total memory and disk usage without N+1 requests.
75 lines
2.2 KiB
Go
75 lines
2.2 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"codeberg.org/SquidSE/ClusterCanvas/service/internal/settings"
|
|
)
|
|
|
|
type actionWidgetsResponse struct {
|
|
Widgets []settings.ActionWidgetSnapshot `json:"widgets"`
|
|
}
|
|
|
|
func (app *App) actionWidgetsListHandler(writer http.ResponseWriter, request *http.Request) {
|
|
node, ok := app.loadAccessibleNode(writer, request)
|
|
if !ok {
|
|
return
|
|
}
|
|
store, err := settings.LoadActionWidgetsOrEmpty(app.ConfigDir)
|
|
if err != nil {
|
|
writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
writeJSON(writer, http.StatusOK, actionWidgetsResponse{
|
|
Widgets: settings.WidgetsForNode(store, node.ID),
|
|
})
|
|
}
|
|
|
|
// actionWidgetsListAllHandler returns widget snapshots for every node the caller can access.
|
|
func (app *App) actionWidgetsListAllHandler(writer http.ResponseWriter, request *http.Request) {
|
|
if err := app.authorizeNodesRead(request); err != nil {
|
|
writeJSON(writer, http.StatusForbidden, apiErrorResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
user, ok := UserFromContext(request.Context())
|
|
if !ok {
|
|
writeJSON(writer, http.StatusUnauthorized, apiErrorResponse{Error: "authentication required"})
|
|
return
|
|
}
|
|
|
|
settingsPayload, err := loadSettingsOrDefault(app.ConfigDir)
|
|
if err != nil {
|
|
writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
nodesStore, err := settings.LoadNodesOrEmpty(app.ConfigDir)
|
|
if err != nil {
|
|
writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
accessibleNodeIDs := make(map[string]struct{}, len(nodesStore.Nodes))
|
|
for _, node := range nodesStore.Nodes {
|
|
if userCanAccessNode(user, settingsPayload.Groups, node) {
|
|
accessibleNodeIDs[node.ID] = struct{}{}
|
|
}
|
|
}
|
|
|
|
widgetStore, err := settings.LoadActionWidgetsOrEmpty(app.ConfigDir)
|
|
if err != nil {
|
|
writeJSON(writer, http.StatusInternalServerError, apiErrorResponse{Error: err.Error()})
|
|
return
|
|
}
|
|
|
|
filtered := make([]settings.ActionWidgetSnapshot, 0)
|
|
for _, widget := range widgetStore.Widgets {
|
|
if _, ok := accessibleNodeIDs[widget.NodeID]; ok {
|
|
filtered = append(filtered, widget)
|
|
}
|
|
}
|
|
|
|
writeJSON(writer, http.StatusOK, actionWidgetsResponse{Widgets: filtered})
|
|
}
|