SNO Dshboard initial api endpoint added (#2284)

* initial api endpoint added
This commit is contained in:
Yehor Butko 2019-06-24 18:15:31 +03:00 committed by GitHub
parent 8226024ca8
commit 96bc0ccfa4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 188 additions and 8 deletions

View File

@ -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
}

View File

@ -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())
} }

View File

@ -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()
} }

View File

@ -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);