SNO Dshboard initial api endpoint added (#2284)
* initial api endpoint added
This commit is contained in:
parent
8226024ca8
commit
96bc0ccfa4
@ -5,19 +5,33 @@ package consoleserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/zeebo/errs"
|
"github.com/zeebo/errs"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
monkit "gopkg.in/spacemonkeygo/monkit.v2"
|
||||||
|
|
||||||
|
"storj.io/storj/internal/version"
|
||||||
|
"storj.io/storj/pkg/storj"
|
||||||
"storj.io/storj/storagenode/console"
|
"storj.io/storj/storagenode/console"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
contentType = "Content-Type"
|
||||||
|
|
||||||
|
applicationJSON = "application/json"
|
||||||
|
)
|
||||||
|
|
||||||
// Error is storagenode console web error type
|
// Error is storagenode console web error type
|
||||||
var Error = errs.Class("storagenode console web error")
|
var (
|
||||||
|
mon = monkit.Package()
|
||||||
|
Error = errs.Class("storagenode console web error")
|
||||||
|
)
|
||||||
|
|
||||||
// Config contains configuration for storagenode console web server
|
// Config contains configuration for storagenode console web server
|
||||||
type Config struct {
|
type Config struct {
|
||||||
@ -54,6 +68,7 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, list
|
|||||||
|
|
||||||
mux.Handle("/static/", http.StripPrefix("/static", fs))
|
mux.Handle("/static/", http.StripPrefix("/static", fs))
|
||||||
mux.Handle("/", http.HandlerFunc(server.appHandler))
|
mux.Handle("/", http.HandlerFunc(server.appHandler))
|
||||||
|
mux.Handle("/api/dashboard/", http.HandlerFunc(server.dashboardHandler))
|
||||||
}
|
}
|
||||||
|
|
||||||
server.server = http.Server{
|
server.server = http.Server{
|
||||||
@ -65,6 +80,8 @@ func NewServer(logger *zap.Logger, config Config, service *console.Service, list
|
|||||||
|
|
||||||
// Run starts the server that host webapp and api endpoints
|
// Run starts the server that host webapp and api endpoints
|
||||||
func (s *Server) Run(ctx context.Context) (err error) {
|
func (s *Server) Run(ctx context.Context) (err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
ctx, cancel := context.WithCancel(ctx)
|
ctx, cancel := context.WithCancel(ctx)
|
||||||
var group errgroup.Group
|
var group errgroup.Group
|
||||||
group.Go(func() error {
|
group.Go(func() error {
|
||||||
@ -88,3 +105,133 @@ func (s *Server) Close() error {
|
|||||||
func (s *Server) appHandler(w http.ResponseWriter, req *http.Request) {
|
func (s *Server) appHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
http.ServeFile(w, req, filepath.Join(s.config.StaticDir, "dist", "index.html"))
|
http.ServeFile(w, req, filepath.Join(s.config.StaticDir, "dist", "index.html"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// appHandler is web app http handler function
|
||||||
|
func (s *Server) dashboardHandler(w http.ResponseWriter, req *http.Request) {
|
||||||
|
ctx := req.Context()
|
||||||
|
defer mon.Task()(&ctx)(nil)
|
||||||
|
w.Header().Set(contentType, applicationJSON)
|
||||||
|
|
||||||
|
var response struct {
|
||||||
|
Data struct {
|
||||||
|
Bandwidth console.BandwidthInfo `json:"bandwidth"`
|
||||||
|
DiskSpace console.DiskSpaceInfo `json:"diskSpace"`
|
||||||
|
WalletAddress string `json:"walletAddress"`
|
||||||
|
VersionInfo version.Info `json:"versionInfo"`
|
||||||
|
IsLastVersion bool `json:"isLastVersion"`
|
||||||
|
Uptime time.Duration `json:"uptime"`
|
||||||
|
NodeID string `json:"nodeId"`
|
||||||
|
Satellites storj.NodeIDList `json:"satellites"`
|
||||||
|
} `json:"data"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
err := json.NewEncoder(w).Encode(&response)
|
||||||
|
if err != nil {
|
||||||
|
s.log.Error(err.Error())
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
satelliteIDParam := req.URL.Query().Get("satelliteId")
|
||||||
|
s.log.Info("param: " + satelliteIDParam)
|
||||||
|
satelliteID, err := s.parseSatelliteIDParam(satelliteIDParam)
|
||||||
|
if satelliteID != nil {
|
||||||
|
s.log.Info("ID: " + satelliteID.String())
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
s.log.Error("satellite id is not valid", zap.Error(err))
|
||||||
|
response.Error = "satellite id is not valid"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
satellites, err := s.service.GetSatellites(ctx)
|
||||||
|
if satellites == nil {
|
||||||
|
s.log.Info("SATELLITES ARE NIL")
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
s.log.Error("can not get satellites list", zap.Error(err))
|
||||||
|
response.Error = "can not get satellites list"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if satelliteID != nil {
|
||||||
|
if err = s.checkSatelliteID(satellites, *satelliteID); err != nil {
|
||||||
|
s.log.Error(err.Error())
|
||||||
|
response.Error = err.Error()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
space, err := s.getStorage(ctx, satelliteID)
|
||||||
|
if err != nil {
|
||||||
|
s.log.Error("can not get disk space usage", zap.Error(err))
|
||||||
|
response.Error = "can not get disk space usage"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
usage, err := s.getBandwidth(ctx, satelliteID)
|
||||||
|
if err != nil {
|
||||||
|
s.log.Error("can not get bandwidth usage", zap.Error(err))
|
||||||
|
response.Error = "can not get bandwidth usage"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
walletAddress := s.service.GetWalletAddress(ctx)
|
||||||
|
|
||||||
|
versionInfo := s.service.GetVersion(ctx)
|
||||||
|
|
||||||
|
err = s.service.CheckVersion(ctx)
|
||||||
|
if err != nil {
|
||||||
|
s.log.Error("can not check latest storage node version", zap.Error(err))
|
||||||
|
response.Error = "can not check latest storage node version"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uptime := s.service.GetUptime(ctx)
|
||||||
|
nodeID := s.service.GetNodeID(ctx)
|
||||||
|
|
||||||
|
response.Data.DiskSpace = *space
|
||||||
|
response.Data.Bandwidth = *usage
|
||||||
|
response.Data.WalletAddress = walletAddress
|
||||||
|
response.Data.VersionInfo = versionInfo
|
||||||
|
response.Data.IsLastVersion = true
|
||||||
|
response.Data.Uptime = uptime
|
||||||
|
response.Data.NodeID = nodeID.String()
|
||||||
|
response.Data.Satellites = satellites
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) getBandwidth(ctx context.Context, satelliteID *storj.NodeID) (_ *console.BandwidthInfo, err error) {
|
||||||
|
if satelliteID != nil {
|
||||||
|
return s.service.GetBandwidthBySatellite(ctx, *satelliteID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.service.GetUsedBandwidthTotal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) getStorage(ctx context.Context, satelliteID *storj.NodeID) (_ *console.DiskSpaceInfo, err error) {
|
||||||
|
if satelliteID != nil {
|
||||||
|
return s.service.GetUsedStorageBySatellite(ctx, *satelliteID)
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.service.GetUsedStorageTotal(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) checkSatelliteID(satelliteIDs storj.NodeIDList, satelliteID storj.NodeID) error {
|
||||||
|
for _, id := range satelliteIDs {
|
||||||
|
if satelliteID == id {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errs.New("satellite id in not found in the available satellite list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) parseSatelliteIDParam(satelliteID string) (*storj.NodeID, error) {
|
||||||
|
if satelliteID != "" {
|
||||||
|
id, err := storj.NodeIDFromString(satelliteID)
|
||||||
|
return &id, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"github.com/zeebo/errs"
|
"github.com/zeebo/errs"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
monkit "gopkg.in/spacemonkeygo/monkit.v2"
|
||||||
|
|
||||||
"storj.io/storj/internal/memory"
|
"storj.io/storj/internal/memory"
|
||||||
"storj.io/storj/internal/version"
|
"storj.io/storj/internal/version"
|
||||||
@ -18,6 +19,8 @@ import (
|
|||||||
"storj.io/storj/storagenode/pieces"
|
"storj.io/storj/storagenode/pieces"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var mon = monkit.Package()
|
||||||
|
|
||||||
// DB exposes methods for managing SNO dashboard related data.
|
// DB exposes methods for managing SNO dashboard related data.
|
||||||
type DB interface {
|
type DB interface {
|
||||||
GetSatelliteIDs(ctx context.Context, from, to time.Time) (storj.NodeIDList, error)
|
GetSatelliteIDs(ctx context.Context, from, to time.Time) (storj.NodeIDList, error)
|
||||||
@ -69,6 +72,7 @@ func NewService(log *zap.Logger, consoleDB DB, bandwidth bandwidth.DB, pieceInfo
|
|||||||
|
|
||||||
return &Service{
|
return &Service{
|
||||||
log: log,
|
log: log,
|
||||||
|
consoleDB: consoleDB,
|
||||||
bandwidthDB: bandwidth,
|
bandwidthDB: bandwidth,
|
||||||
pieceInfoDB: pieceInfo,
|
pieceInfoDB: pieceInfo,
|
||||||
kademlia: kademlia,
|
kademlia: kademlia,
|
||||||
@ -82,7 +86,9 @@ func NewService(log *zap.Logger, consoleDB DB, bandwidth bandwidth.DB, pieceInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetUsedBandwidthTotal returns all info about storage node bandwidth usage
|
// GetUsedBandwidthTotal returns all info about storage node bandwidth usage
|
||||||
func (s *Service) GetUsedBandwidthTotal(ctx context.Context) (*BandwidthInfo, error) {
|
func (s *Service) GetUsedBandwidthTotal(ctx context.Context) (_ *BandwidthInfo, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
usage, err := bandwidth.TotalMonthlySummary(ctx, s.bandwidthDB)
|
usage, err := bandwidth.TotalMonthlySummary(ctx, s.bandwidthDB)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -93,6 +99,8 @@ func (s *Service) GetUsedBandwidthTotal(ctx context.Context) (*BandwidthInfo, er
|
|||||||
|
|
||||||
// GetBandwidthBySatellite returns all info about storage node bandwidth usage by satellite
|
// GetBandwidthBySatellite returns all info about storage node bandwidth usage by satellite
|
||||||
func (s *Service) GetBandwidthBySatellite(ctx context.Context, satelliteID storj.NodeID) (_ *BandwidthInfo, err error) {
|
func (s *Service) GetBandwidthBySatellite(ctx context.Context, satelliteID storj.NodeID) (_ *BandwidthInfo, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
summaries, err := s.bandwidthDB.SummaryBySatellite(ctx, time.Time{}, time.Now())
|
summaries, err := s.bandwidthDB.SummaryBySatellite(ctx, time.Time{}, time.Now())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -103,7 +111,9 @@ func (s *Service) GetBandwidthBySatellite(ctx context.Context, satelliteID storj
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetUsedStorageTotal returns all info about storagenode disk space usage
|
// GetUsedStorageTotal returns all info about storagenode disk space usage
|
||||||
func (s *Service) GetUsedStorageTotal(ctx context.Context) (*DiskSpaceInfo, error) {
|
func (s *Service) GetUsedStorageTotal(ctx context.Context) (_ *DiskSpaceInfo, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
spaceUsed, err := s.pieceInfoDB.SpaceUsed(ctx)
|
spaceUsed, err := s.pieceInfoDB.SpaceUsed(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -113,7 +123,9 @@ func (s *Service) GetUsedStorageTotal(ctx context.Context) (*DiskSpaceInfo, erro
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetUsedStorageBySatellite returns all info about storagenode disk space usage
|
// GetUsedStorageBySatellite returns all info about storagenode disk space usage
|
||||||
func (s *Service) GetUsedStorageBySatellite(ctx context.Context, satelliteID storj.NodeID) (*DiskSpaceInfo, error) {
|
func (s *Service) GetUsedStorageBySatellite(ctx context.Context, satelliteID storj.NodeID) (_ *DiskSpaceInfo, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
spaceUsed, err := s.pieceInfoDB.SpaceUsedBySatellite(ctx, satelliteID)
|
spaceUsed, err := s.pieceInfoDB.SpaceUsedBySatellite(ctx, satelliteID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -122,32 +134,43 @@ func (s *Service) GetUsedStorageBySatellite(ctx context.Context, satelliteID sto
|
|||||||
return &DiskSpaceInfo{Available: s.allocatedDiskSpace.Int64() - spaceUsed, Used: spaceUsed}, nil
|
return &DiskSpaceInfo{Available: s.allocatedDiskSpace.Int64() - spaceUsed, Used: spaceUsed}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetWalletNumber return wallet number of node operator
|
// GetWalletAddress return wallet address of node operator
|
||||||
func (s *Service) GetWalletNumber(ctx context.Context) string {
|
func (s *Service) GetWalletAddress(ctx context.Context) string {
|
||||||
|
defer mon.Task()(&ctx)(nil)
|
||||||
|
|
||||||
return s.walletAddress
|
return s.walletAddress
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUptime return wallet number of node operator
|
// GetUptime return wallet number of node operator
|
||||||
func (s *Service) GetUptime(ctx context.Context) time.Duration {
|
func (s *Service) GetUptime(ctx context.Context) time.Duration {
|
||||||
|
defer mon.Task()(&ctx)(nil)
|
||||||
|
|
||||||
return time.Now().Sub(s.startedAt)
|
return time.Now().Sub(s.startedAt)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetNodeID return current node id
|
// GetNodeID return current node id
|
||||||
func (s *Service) GetNodeID(ctx context.Context) storj.NodeID {
|
func (s *Service) GetNodeID(ctx context.Context) storj.NodeID {
|
||||||
|
defer mon.Task()(&ctx)(nil)
|
||||||
|
|
||||||
return s.kademlia.Local().Id
|
return s.kademlia.Local().Id
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetVersion return current node version
|
// GetVersion return current node version
|
||||||
func (s *Service) GetVersion(ctx context.Context) version.Info {
|
func (s *Service) GetVersion(ctx context.Context) version.Info {
|
||||||
|
defer mon.Task()(&ctx)(nil)
|
||||||
return s.versionInfo
|
return s.versionInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
// CheckVersion checks to make sure the version is still okay, returning an error if not
|
// CheckVersion checks to make sure the version is still okay, returning an error if not
|
||||||
func (s *Service) CheckVersion(ctx context.Context) error {
|
func (s *Service) CheckVersion(ctx context.Context) (err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
return s.version.CheckVersion(ctx)
|
return s.version.CheckVersion(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetSatellites used to retrieve satellites list
|
// GetSatellites used to retrieve satellites list
|
||||||
func (s *Service) GetSatellites(ctx context.Context) (_ storj.NodeIDList, err error) {
|
func (s *Service) GetSatellites(ctx context.Context) (_ storj.NodeIDList, err error) {
|
||||||
|
defer mon.Task()(&ctx)(&err)
|
||||||
|
|
||||||
return s.consoleDB.GetSatelliteIDs(ctx, time.Time{}, time.Now())
|
return s.consoleDB.GetSatelliteIDs(ctx, time.Time{}, time.Now())
|
||||||
}
|
}
|
||||||
|
@ -391,6 +391,11 @@ func (peer *Peer) Close() error {
|
|||||||
if peer.Kademlia.RoutingTable != nil {
|
if peer.Kademlia.RoutingTable != nil {
|
||||||
errlist.Add(peer.Kademlia.RoutingTable.Close())
|
errlist.Add(peer.Kademlia.RoutingTable.Close())
|
||||||
}
|
}
|
||||||
|
if peer.Console.Endpoint != nil {
|
||||||
|
errlist.Add(peer.Console.Endpoint.Close())
|
||||||
|
} else if peer.Console.Listener != nil {
|
||||||
|
errlist.Add(peer.Console.Listener.Close())
|
||||||
|
}
|
||||||
|
|
||||||
return errlist.Err()
|
return errlist.Err()
|
||||||
}
|
}
|
||||||
|
7
web/operator/dist/build.js
vendored
7
web/operator/dist/build.js
vendored
@ -1,4 +1,9 @@
|
|||||||
// Copyright (C) 2019 Storj Labs, Inc.
|
// Copyright (C) 2019 Storj Labs, Inc.
|
||||||
// See LICENSE for copying information.
|
// See LICENSE for copying information.
|
||||||
|
|
||||||
alert('hello, node operator');
|
var xmlHttp = new XMLHttpRequest();
|
||||||
|
|
||||||
|
xmlHttp.open("GET", "/api/dashboard?satelliteId=12D1kqUXtJiCsS72UKeCGHyKSQy1FSonerZ5fb6nSQAaSim4Vag", false );
|
||||||
|
xmlHttp.send();
|
||||||
|
|
||||||
|
alert(xmlHttp.responseText);
|
Loading…
Reference in New Issue
Block a user