2020-10-02 17:21:58 +01:00
|
|
|
// Copyright (C) 2020 Storj Labs, Inc.
|
|
|
|
// See LICENSE for copying information.
|
|
|
|
|
2020-10-14 15:26:50 +01:00
|
|
|
package multinodedb
|
2020-10-02 17:21:58 +01:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-11-16 12:46:49 +00:00
|
|
|
"database/sql"
|
|
|
|
"errors"
|
2020-10-02 17:21:58 +01:00
|
|
|
|
|
|
|
"github.com/zeebo/errs"
|
|
|
|
|
|
|
|
"storj.io/common/storj"
|
2020-10-14 15:26:50 +01:00
|
|
|
"storj.io/storj/multinode/multinodedb/dbx"
|
2020-12-09 16:34:37 +00:00
|
|
|
"storj.io/storj/multinode/nodes"
|
2020-10-02 17:21:58 +01:00
|
|
|
)
|
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
// ErrNodesDB indicates about internal NodesDB error.
|
2021-04-28 09:06:17 +01:00
|
|
|
var ErrNodesDB = errs.Class("NodesDB")
|
2020-10-02 17:21:58 +01:00
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
// ensures that nodesdb implements console.Nodes.
|
|
|
|
var _ nodes.DB = (*nodesdb)(nil)
|
2020-10-02 17:21:58 +01:00
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
// nodesdb exposes needed by MND NodesDB functionality.
|
2020-10-02 17:21:58 +01:00
|
|
|
// dbx implementation of console.Nodes.
|
|
|
|
//
|
|
|
|
// architecture: Database
|
2020-12-09 16:34:37 +00:00
|
|
|
type nodesdb struct {
|
2020-10-02 17:21:58 +01:00
|
|
|
methods dbx.Methods
|
|
|
|
}
|
|
|
|
|
2020-12-17 15:05:18 +00:00
|
|
|
// List returns all connected nodes.
|
|
|
|
func (n *nodesdb) List(ctx context.Context) (allNodes []nodes.Node, err error) {
|
2020-11-16 12:46:49 +00:00
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
dbxNodes, err := n.methods.All_Node(ctx)
|
|
|
|
if err != nil {
|
2020-12-09 16:34:37 +00:00
|
|
|
return []nodes.Node{}, ErrNodesDB.Wrap(err)
|
2020-11-16 12:46:49 +00:00
|
|
|
}
|
|
|
|
if len(dbxNodes) == 0 {
|
2020-12-09 16:34:37 +00:00
|
|
|
return []nodes.Node{}, nodes.ErrNoNode.New("no nodes")
|
2020-11-16 12:46:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
for _, dbxNode := range dbxNodes {
|
|
|
|
node, err := fromDBXNode(ctx, dbxNode)
|
|
|
|
if err != nil {
|
2020-12-09 16:34:37 +00:00
|
|
|
return []nodes.Node{}, ErrNodesDB.Wrap(err)
|
2020-11-16 12:46:49 +00:00
|
|
|
}
|
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
allNodes = append(allNodes, node)
|
2020-11-16 12:46:49 +00:00
|
|
|
}
|
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
return allNodes, ErrNodesDB.Wrap(err)
|
2020-11-16 12:46:49 +00:00
|
|
|
}
|
|
|
|
|
2021-06-01 08:06:53 +01:00
|
|
|
// ListPaged returns paginated nodes list.
|
|
|
|
func (n *nodesdb) ListPaged(ctx context.Context, cursor nodes.Cursor) (page nodes.Page, err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
page = nodes.Page{
|
|
|
|
CurrentPage: cursor.Page,
|
|
|
|
Limit: cursor.Limit,
|
|
|
|
Offset: (cursor.Page - 1) * cursor.Limit,
|
|
|
|
}
|
|
|
|
totalCount, err := n.methods.Count_Node(ctx)
|
|
|
|
if err != nil {
|
|
|
|
return nodes.Page{}, ErrNodesDB.Wrap(err)
|
|
|
|
}
|
2021-06-01 08:37:48 +01:00
|
|
|
page.TotalCount = totalCount
|
2021-06-01 08:06:53 +01:00
|
|
|
page.PageCount = page.TotalCount / cursor.Limit
|
|
|
|
if page.TotalCount%cursor.Limit != 0 {
|
|
|
|
page.PageCount++
|
|
|
|
}
|
2021-06-01 08:37:48 +01:00
|
|
|
dbxNodes, err := n.methods.Limited_Node(ctx, int(page.Limit), page.Offset)
|
2021-06-01 08:06:53 +01:00
|
|
|
if err != nil {
|
|
|
|
return nodes.Page{}, ErrNodesDB.Wrap(err)
|
|
|
|
}
|
|
|
|
for _, dbxNode := range dbxNodes {
|
|
|
|
node, err := fromDBXNode(ctx, dbxNode)
|
|
|
|
if err != nil {
|
|
|
|
return nodes.Page{}, ErrNodesDB.Wrap(err)
|
|
|
|
}
|
|
|
|
page.Nodes = append(page.Nodes, node)
|
|
|
|
}
|
|
|
|
return page, nil
|
|
|
|
}
|
|
|
|
|
2020-12-17 15:05:18 +00:00
|
|
|
// Get return node from NodesDB by its id.
|
|
|
|
func (n *nodesdb) Get(ctx context.Context, id storj.NodeID) (_ nodes.Node, err error) {
|
2020-11-16 12:46:49 +00:00
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
dbxNode, err := n.methods.Get_Node_By_Id(ctx, dbx.Node_Id(id.Bytes()))
|
|
|
|
if err != nil {
|
|
|
|
if errors.Is(err, sql.ErrNoRows) {
|
2020-12-09 16:34:37 +00:00
|
|
|
return nodes.Node{}, nodes.ErrNoNode.Wrap(err)
|
2020-11-16 12:46:49 +00:00
|
|
|
}
|
2020-12-09 16:34:37 +00:00
|
|
|
return nodes.Node{}, ErrNodesDB.Wrap(err)
|
2020-11-16 12:46:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
node, err := fromDBXNode(ctx, dbxNode)
|
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
return node, ErrNodesDB.Wrap(err)
|
2020-11-16 12:46:49 +00:00
|
|
|
}
|
|
|
|
|
2020-10-02 17:21:58 +01:00
|
|
|
// Add creates new node in NodesDB.
|
2021-12-07 07:38:25 +00:00
|
|
|
func (n *nodesdb) Add(ctx context.Context, node nodes.Node) (err error) {
|
2020-10-02 17:21:58 +01:00
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
_, err = n.methods.Create_Node(
|
|
|
|
ctx,
|
2021-12-07 07:38:25 +00:00
|
|
|
dbx.Node_Id(node.ID.Bytes()),
|
|
|
|
dbx.Node_Name(node.Name),
|
|
|
|
dbx.Node_PublicAddress(node.PublicAddress),
|
|
|
|
dbx.Node_ApiSecret(node.APISecret),
|
2020-10-02 17:21:58 +01:00
|
|
|
)
|
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
return ErrNodesDB.Wrap(err)
|
2020-10-02 17:21:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// Remove removed node from NodesDB.
|
2020-12-09 16:34:37 +00:00
|
|
|
func (n *nodesdb) Remove(ctx context.Context, id storj.NodeID) (err error) {
|
2020-10-02 17:21:58 +01:00
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
_, err = n.methods.Delete_Node_By_Id(ctx, dbx.Node_Id(id.Bytes()))
|
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
return ErrNodesDB.Wrap(err)
|
|
|
|
}
|
|
|
|
|
|
|
|
// UpdateName will update name of the specified node in database.
|
|
|
|
func (n *nodesdb) UpdateName(ctx context.Context, id storj.NodeID, name string) (err error) {
|
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
err = n.methods.UpdateNoReturn_Node_By_Id(ctx, dbx.Node_Id(id.Bytes()), dbx.Node_Update_Fields{
|
|
|
|
Name: dbx.Node_Name(name),
|
|
|
|
})
|
|
|
|
|
|
|
|
return ErrNodesDB.Wrap(err)
|
2020-10-02 17:21:58 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// fromDBXNode converts dbx.Node to console.Node.
|
2020-12-09 16:34:37 +00:00
|
|
|
func fromDBXNode(ctx context.Context, node *dbx.Node) (_ nodes.Node, err error) {
|
2020-10-02 17:21:58 +01:00
|
|
|
defer mon.Task()(&ctx)(&err)
|
|
|
|
|
|
|
|
id, err := storj.NodeIDFromBytes(node.Id)
|
|
|
|
if err != nil {
|
2020-12-09 16:34:37 +00:00
|
|
|
return nodes.Node{}, err
|
2020-10-02 17:21:58 +01:00
|
|
|
}
|
|
|
|
|
2020-12-09 16:34:37 +00:00
|
|
|
result := nodes.Node{
|
2020-10-02 17:21:58 +01:00
|
|
|
ID: id,
|
|
|
|
APISecret: node.ApiSecret,
|
2020-11-16 12:46:49 +00:00
|
|
|
Name: node.Name,
|
2020-10-02 17:21:58 +01:00
|
|
|
PublicAddress: node.PublicAddress,
|
|
|
|
}
|
|
|
|
|
|
|
|
return result, nil
|
|
|
|
}
|