mnd/console/server: endpoint with index.html added
Change-Id: Ic5154feaa995bf5c26c851024079f7e82612f306
This commit is contained in:
parent
24d60384c5
commit
135d846aff
@ -133,32 +133,15 @@ func (controller *Nodes) Get(w http.ResponseWriter, r *http.Request) {
|
||||
node, err := controller.service.Get(ctx, nodeID)
|
||||
if err != nil {
|
||||
controller.log.Error("get node not found error", zap.Error(err))
|
||||
controller.serveError(w, http.StatusNotFound, ErrNodes.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewEncoder(w).Encode(node); err != nil {
|
||||
controller.log.Error("failed to write json response", zap.Error(err))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// List handles retrieving list of nodes.
|
||||
func (controller *Nodes) List(w http.ResponseWriter, r *http.Request) {
|
||||
ctx := r.Context()
|
||||
var err error
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
w.Header().Add("Content-Type", "application/json")
|
||||
|
||||
list, err := controller.service.List(ctx)
|
||||
if err != nil {
|
||||
controller.log.Error("list nodes internal error", zap.Error(err))
|
||||
if nodes.ErrNoNode.Has(err) {
|
||||
controller.serveError(w, http.StatusNotFound, ErrNodes.Wrap(err))
|
||||
return
|
||||
}
|
||||
controller.serveError(w, http.StatusInternalServerError, ErrNodes.Wrap(err))
|
||||
return
|
||||
}
|
||||
|
||||
if err = json.NewEncoder(w).Encode(list); err != nil {
|
||||
if err = json.NewEncoder(w).Encode(node); err != nil {
|
||||
controller.log.Error("failed to write json response", zap.Error(err))
|
||||
return
|
||||
}
|
||||
|
@ -5,8 +5,10 @@ package server
|
||||
|
||||
import (
|
||||
"context"
|
||||
"html/template"
|
||||
"net"
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/zeebo/errs"
|
||||
@ -39,6 +41,8 @@ type Server struct {
|
||||
|
||||
listener net.Listener
|
||||
http http.Server
|
||||
|
||||
index *template.Template
|
||||
}
|
||||
|
||||
// NewServer returns new instance of Multinode Dashboard http server.
|
||||
@ -51,13 +55,14 @@ func NewServer(log *zap.Logger, config Config, nodes *nodes.Service, listener ne
|
||||
}
|
||||
|
||||
router := mux.NewRouter()
|
||||
fs := http.FileServer(http.Dir(server.config.StaticDir))
|
||||
|
||||
apiRouter := router.PathPrefix("/api/v0").Subrouter()
|
||||
apiRouter.NotFoundHandler = controllers.NewNotFound(server.log)
|
||||
|
||||
nodesController := controllers.NewNodes(server.log, server.nodes)
|
||||
nodesRouter := apiRouter.PathPrefix("/nodes").Subrouter()
|
||||
nodesRouter.HandleFunc("", nodesController.Add).Methods(http.MethodPost)
|
||||
nodesRouter.HandleFunc("", nodesController.List).Methods(http.MethodGet)
|
||||
nodesRouter.HandleFunc("/infos", nodesController.ListInfos).Methods(http.MethodGet)
|
||||
nodesRouter.HandleFunc("/infos/{satelliteID}", nodesController.ListInfosSatellite).Methods(http.MethodGet)
|
||||
nodesRouter.HandleFunc("/trusted-satellites", nodesController.TrustedSatellites).Methods(http.MethodGet)
|
||||
@ -65,6 +70,11 @@ func NewServer(log *zap.Logger, config Config, nodes *nodes.Service, listener ne
|
||||
nodesRouter.HandleFunc("/{id}", nodesController.UpdateName).Methods(http.MethodPatch)
|
||||
nodesRouter.HandleFunc("/{id}", nodesController.Delete).Methods(http.MethodDelete)
|
||||
|
||||
if server.config.StaticDir != "" {
|
||||
router.PathPrefix("/static/").Handler(http.StripPrefix("/static", fs))
|
||||
router.PathPrefix("/").HandlerFunc(server.appHandler)
|
||||
}
|
||||
|
||||
server.http = http.Server{
|
||||
Handler: router,
|
||||
}
|
||||
@ -72,10 +82,33 @@ func NewServer(log *zap.Logger, config Config, nodes *nodes.Service, listener ne
|
||||
return &server, nil
|
||||
}
|
||||
|
||||
// appHandler is web app http handler function.
|
||||
func (server *Server) appHandler(w http.ResponseWriter, r *http.Request) {
|
||||
header := w.Header()
|
||||
|
||||
header.Set("Content-Type", "text/html; charset=UTF-8")
|
||||
header.Set("X-Content-Type-Options", "nosniff")
|
||||
header.Set("Referrer-Policy", "same-origin")
|
||||
|
||||
if server.index == nil {
|
||||
server.log.Error("index template is not set")
|
||||
return
|
||||
}
|
||||
|
||||
if err := server.index.Execute(w, nil); err != nil {
|
||||
server.log.Error("index template could not be executed", zap.Error(Error.Wrap(err)))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Run starts the server that host webapp and api endpoints.
|
||||
func (server *Server) Run(ctx context.Context) (err error) {
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
err = server.initializeTemplates()
|
||||
if err != nil {
|
||||
return Error.Wrap(err)
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithCancel(ctx)
|
||||
var group errgroup.Group
|
||||
|
||||
group.Go(func() error {
|
||||
@ -94,3 +127,13 @@ func (server *Server) Run(ctx context.Context) (err error) {
|
||||
func (server *Server) Close() error {
|
||||
return Error.Wrap(server.http.Close())
|
||||
}
|
||||
|
||||
// initializeTemplates is used to initialize all templates.
|
||||
func (server *Server) initializeTemplates() (err error) {
|
||||
server.index, err = template.ParseFiles(filepath.Join(server.config.StaticDir, "dist", "index.html"))
|
||||
if err != nil {
|
||||
server.log.Error("dist folder is not generated. use 'npm run build' command", zap.Error(err))
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
@ -33,32 +33,33 @@ var ErrNoNode = errs.Class("no such node")
|
||||
|
||||
// Node is a representation of storagenode, that SNO could add to the Multinode Dashboard.
|
||||
type Node struct {
|
||||
ID storj.NodeID
|
||||
ID storj.NodeID `json:"id"`
|
||||
// APISecret is a secret issued by storagenode, that will be main auth mechanism in MND <-> SNO api.
|
||||
APISecret []byte
|
||||
PublicAddress string
|
||||
Name string
|
||||
APISecret []byte `json:"apiSecret"`
|
||||
PublicAddress string `json:"publicAddress"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// NodeInfo contains basic node internal state.
|
||||
type NodeInfo struct {
|
||||
ID storj.NodeID
|
||||
Name string
|
||||
Version string
|
||||
LastContact time.Time
|
||||
DiskSpaceUsed int64
|
||||
DiskSpaceLeft int64
|
||||
BandwidthUsed int64
|
||||
TotalEarned int64
|
||||
ID storj.NodeID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
LastContact time.Time `json:"lastContact"`
|
||||
DiskSpaceUsed int64 `json:"diskSpaceUsed"`
|
||||
DiskSpaceLeft int64 `json:"diskSpaceLeft"`
|
||||
BandwidthUsed int64 `json:"bandwidthUsed"`
|
||||
TotalEarned int64 `json:"totalEarned"`
|
||||
}
|
||||
|
||||
// NodeInfoSatellite contains satellite specific node internal state.
|
||||
type NodeInfoSatellite struct {
|
||||
ID storj.NodeID
|
||||
Name string
|
||||
Version string
|
||||
LastContact time.Time
|
||||
OnlineScore float64
|
||||
AuditScore float64
|
||||
SuspensionScore float64
|
||||
ID storj.NodeID `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
LastContact time.Time `json:"lastContact"`
|
||||
OnlineScore float64 `json:"onlineScore"`
|
||||
AuditScore float64 `json:"auditScore"`
|
||||
SuspensionScore float64 `json:"suspensionScore"`
|
||||
TotalEarned int64 `json:"totalEarned"`
|
||||
}
|
||||
|
@ -66,18 +66,6 @@ func (service *Service) Get(ctx context.Context, id storj.NodeID) (_ Node, err e
|
||||
|
||||
}
|
||||
|
||||
// List retrieves list of all added nodes.
|
||||
func (service *Service) List(ctx context.Context) (_ []Node, err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
|
||||
nodes, err := service.nodes.List(ctx)
|
||||
if err != nil {
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return nodes, nil
|
||||
}
|
||||
|
||||
// Remove removes node from the system.
|
||||
func (service *Service) Remove(ctx context.Context, id storj.NodeID) (err error) {
|
||||
defer mon.Task()(&ctx)(&err)
|
||||
@ -90,6 +78,9 @@ func (service *Service) ListInfos(ctx context.Context) (_ []NodeInfo, err error)
|
||||
|
||||
nodes, err := service.nodes.List(ctx)
|
||||
if err != nil {
|
||||
if ErrNoNode.Has(err) {
|
||||
return []NodeInfo{}, nil
|
||||
}
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
@ -172,6 +163,9 @@ func (service *Service) ListInfosSatellite(ctx context.Context, satelliteID stor
|
||||
|
||||
nodes, err := service.nodes.List(ctx)
|
||||
if err != nil {
|
||||
if ErrNoNode.Has(err) {
|
||||
return []NodeInfoSatellite{}, nil
|
||||
}
|
||||
return nil, Error.Wrap(err)
|
||||
}
|
||||
|
||||
@ -191,6 +185,7 @@ func (service *Service) ListInfosSatellite(ctx context.Context, satelliteID stor
|
||||
}()
|
||||
|
||||
nodeClient := multinodepb.NewDRPCNodeClient(conn)
|
||||
payoutClient := multinodepb.NewDRPCPayoutClient(conn)
|
||||
|
||||
header := &multinodepb.RequestHeader{
|
||||
ApiKey: node.APISecret,
|
||||
@ -214,6 +209,11 @@ func (service *Service) ListInfosSatellite(ctx context.Context, satelliteID stor
|
||||
return NodeInfoSatellite{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
earned, err := payoutClient.Earned(ctx, &multinodepb.EarnedRequest{Header: header})
|
||||
if err != nil {
|
||||
return NodeInfoSatellite{}, Error.Wrap(err)
|
||||
}
|
||||
|
||||
return NodeInfoSatellite{
|
||||
ID: node.ID,
|
||||
Name: node.Name,
|
||||
@ -222,6 +222,7 @@ func (service *Service) ListInfosSatellite(ctx context.Context, satelliteID stor
|
||||
OnlineScore: rep.Online.Score,
|
||||
AuditScore: rep.Audit.Score,
|
||||
SuspensionScore: rep.Audit.SuspensionScore,
|
||||
TotalEarned: earned.Total,
|
||||
}, nil
|
||||
}()
|
||||
if err != nil {
|
||||
|
Loading…
Reference in New Issue
Block a user