2020-03-10 12:20:34 -07:00
|
|
|
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
|
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
|
|
|
|
package admin
|
|
|
|
|
|
|
|
import (
|
|
|
|
"net/http"
|
|
|
|
|
|
|
|
"github.com/gorilla/rpc/v2"
|
|
|
|
|
|
|
|
"github.com/ava-labs/gecko/api"
|
|
|
|
"github.com/ava-labs/gecko/chains"
|
2020-06-19 15:36:45 -07:00
|
|
|
"github.com/ava-labs/gecko/genesis"
|
|
|
|
"github.com/ava-labs/gecko/ids"
|
2020-05-30 11:23:08 -07:00
|
|
|
"github.com/ava-labs/gecko/network"
|
2020-03-10 12:20:34 -07:00
|
|
|
"github.com/ava-labs/gecko/snow/engine/common"
|
|
|
|
"github.com/ava-labs/gecko/utils/logging"
|
2020-06-19 15:36:45 -07:00
|
|
|
"github.com/ava-labs/gecko/version"
|
2020-03-10 12:20:34 -07:00
|
|
|
|
|
|
|
cjson "github.com/ava-labs/gecko/utils/json"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Admin is the API service for node admin management
|
|
|
|
type Admin struct {
|
2020-06-19 15:36:45 -07:00
|
|
|
version version.Version
|
|
|
|
nodeID ids.ShortID
|
|
|
|
networkID uint32
|
2020-03-10 12:20:34 -07:00
|
|
|
log logging.Logger
|
2020-06-19 15:36:45 -07:00
|
|
|
networking network.Network
|
2020-03-10 12:20:34 -07:00
|
|
|
performance Performance
|
|
|
|
chainManager chains.Manager
|
|
|
|
httpServer *api.Server
|
|
|
|
}
|
|
|
|
|
|
|
|
// NewService returns a new admin API service
|
2020-06-19 15:36:45 -07:00
|
|
|
func NewService(version version.Version, nodeID ids.ShortID, networkID uint32, log logging.Logger, chainManager chains.Manager, peers network.Network, httpServer *api.Server) *common.HTTPHandler {
|
2020-03-10 12:20:34 -07:00
|
|
|
newServer := rpc.NewServer()
|
|
|
|
codec := cjson.NewCodec()
|
|
|
|
newServer.RegisterCodec(codec, "application/json")
|
|
|
|
newServer.RegisterCodec(codec, "application/json;charset=UTF-8")
|
|
|
|
newServer.RegisterService(&Admin{
|
2020-06-19 15:36:45 -07:00
|
|
|
version: version,
|
|
|
|
nodeID: nodeID,
|
|
|
|
networkID: networkID,
|
2020-03-10 12:20:34 -07:00
|
|
|
log: log,
|
|
|
|
chainManager: chainManager,
|
2020-06-19 15:36:45 -07:00
|
|
|
networking: peers,
|
2020-05-30 11:23:08 -07:00
|
|
|
httpServer: httpServer,
|
2020-03-10 12:20:34 -07:00
|
|
|
}, "admin")
|
|
|
|
return &common.HTTPHandler{Handler: newServer}
|
|
|
|
}
|
|
|
|
|
2020-06-19 15:36:45 -07:00
|
|
|
// GetNodeVersionReply are the results from calling GetNodeVersion
|
|
|
|
type GetNodeVersionReply struct {
|
|
|
|
Version string `json:"version"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNodeVersion returns the version this node is running
|
|
|
|
func (service *Admin) GetNodeVersion(_ *http.Request, _ *struct{}, reply *GetNodeVersionReply) error {
|
|
|
|
service.log.Info("Admin: GetNodeVersion called")
|
|
|
|
|
|
|
|
reply.Version = service.version.String()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNodeIDReply are the results from calling GetNodeID
|
|
|
|
type GetNodeIDReply struct {
|
|
|
|
NodeID ids.ShortID `json:"nodeID"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNodeID returns the node ID of this node
|
|
|
|
func (service *Admin) GetNodeID(_ *http.Request, _ *struct{}, reply *GetNodeIDReply) error {
|
|
|
|
service.log.Info("Admin: GetNodeID called")
|
|
|
|
|
|
|
|
reply.NodeID = service.nodeID
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNetworkIDReply are the results from calling GetNetworkID
|
|
|
|
type GetNetworkIDReply struct {
|
|
|
|
NetworkID cjson.Uint32 `json:"networkID"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNetworkID returns the network ID this node is running on
|
|
|
|
func (service *Admin) GetNetworkID(_ *http.Request, _ *struct{}, reply *GetNetworkIDReply) error {
|
|
|
|
service.log.Info("Admin: GetNetworkID called")
|
|
|
|
|
|
|
|
reply.NetworkID = cjson.Uint32(service.networkID)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNetworkNameReply is the result from calling GetNetworkName
|
|
|
|
type GetNetworkNameReply struct {
|
|
|
|
NetworkName string `json:"networkName"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetNetworkName returns the network name this node is running on
|
|
|
|
func (service *Admin) GetNetworkName(_ *http.Request, _ *struct{}, reply *GetNetworkNameReply) error {
|
|
|
|
service.log.Info("Admin: GetNetworkName called")
|
|
|
|
|
|
|
|
reply.NetworkName = genesis.NetworkName(service.networkID)
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetBlockchainIDArgs are the arguments for calling GetBlockchainID
|
|
|
|
type GetBlockchainIDArgs struct {
|
|
|
|
Alias string `json:"alias"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetBlockchainIDReply are the results from calling GetBlockchainID
|
|
|
|
type GetBlockchainIDReply struct {
|
|
|
|
BlockchainID string `json:"blockchainID"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetBlockchainID returns the blockchain ID that resolves the alias that was supplied
|
|
|
|
func (service *Admin) GetBlockchainID(_ *http.Request, args *GetBlockchainIDArgs, reply *GetBlockchainIDReply) error {
|
|
|
|
service.log.Info("Admin: GetBlockchainID called")
|
|
|
|
|
|
|
|
bID, err := service.chainManager.Lookup(args.Alias)
|
|
|
|
reply.BlockchainID = bID.String()
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// PeersReply are the results from calling Peers
|
|
|
|
type PeersReply struct {
|
|
|
|
Peers []network.PeerID `json:"peers"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Peers returns the list of current validators
|
|
|
|
func (service *Admin) Peers(_ *http.Request, _ *struct{}, reply *PeersReply) error {
|
|
|
|
service.log.Info("Admin: Peers called")
|
|
|
|
reply.Peers = service.networking.Peers()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2020-03-10 12:20:34 -07:00
|
|
|
// StartCPUProfilerReply are the results from calling StartCPUProfiler
|
|
|
|
type StartCPUProfilerReply struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// StartCPUProfiler starts a cpu profile writing to the specified file
|
2020-06-22 10:18:14 -07:00
|
|
|
func (service *Admin) StartCPUProfiler(_ *http.Request, args *struct{}, reply *StartCPUProfilerReply) error {
|
|
|
|
service.log.Info("Admin: StartCPUProfiler called")
|
2020-03-10 12:20:34 -07:00
|
|
|
reply.Success = true
|
2020-06-22 10:18:14 -07:00
|
|
|
return service.performance.StartCPUProfiler()
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// StopCPUProfilerReply are the results from calling StopCPUProfiler
|
|
|
|
type StopCPUProfilerReply struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// StopCPUProfiler stops the cpu profile
|
2020-06-06 08:52:16 -07:00
|
|
|
func (service *Admin) StopCPUProfiler(_ *http.Request, _ *struct{}, reply *StopCPUProfilerReply) error {
|
2020-06-15 09:35:41 -07:00
|
|
|
service.log.Info("Admin: StopCPUProfiler called")
|
2020-03-10 12:20:34 -07:00
|
|
|
reply.Success = true
|
|
|
|
return service.performance.StopCPUProfiler()
|
|
|
|
}
|
|
|
|
|
|
|
|
// MemoryProfileReply are the results from calling MemoryProfile
|
|
|
|
type MemoryProfileReply struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// MemoryProfile runs a memory profile writing to the specified file
|
2020-06-22 10:18:14 -07:00
|
|
|
func (service *Admin) MemoryProfile(_ *http.Request, args *struct{}, reply *MemoryProfileReply) error {
|
|
|
|
service.log.Info("Admin: MemoryProfile called")
|
2020-03-10 12:20:34 -07:00
|
|
|
reply.Success = true
|
2020-06-22 10:18:14 -07:00
|
|
|
return service.performance.MemoryProfile()
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// LockProfileReply are the results from calling LockProfile
|
|
|
|
type LockProfileReply struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// LockProfile runs a mutex profile writing to the specified file
|
2020-06-22 10:18:14 -07:00
|
|
|
func (service *Admin) LockProfile(_ *http.Request, args *struct{}, reply *LockProfileReply) error {
|
|
|
|
service.log.Info("Admin: LockProfile called")
|
2020-03-10 12:20:34 -07:00
|
|
|
reply.Success = true
|
2020-06-22 10:18:14 -07:00
|
|
|
return service.performance.LockProfile()
|
2020-03-10 12:20:34 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// AliasArgs are the arguments for calling Alias
|
|
|
|
type AliasArgs struct {
|
|
|
|
Endpoint string `json:"endpoint"`
|
|
|
|
Alias string `json:"alias"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// AliasReply are the results from calling Alias
|
|
|
|
type AliasReply struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Alias attempts to alias an HTTP endpoint to a new name
|
2020-06-06 08:52:16 -07:00
|
|
|
func (service *Admin) Alias(_ *http.Request, args *AliasArgs, reply *AliasReply) error {
|
2020-06-15 09:35:41 -07:00
|
|
|
service.log.Info("Admin: Alias called with URL: %s, Alias: %s", args.Endpoint, args.Alias)
|
2020-03-10 12:20:34 -07:00
|
|
|
reply.Success = true
|
|
|
|
return service.httpServer.AddAliasesWithReadLock(args.Endpoint, args.Alias)
|
|
|
|
}
|
|
|
|
|
|
|
|
// AliasChainArgs are the arguments for calling AliasChain
|
|
|
|
type AliasChainArgs struct {
|
|
|
|
Chain string `json:"chain"`
|
|
|
|
Alias string `json:"alias"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// AliasChainReply are the results from calling AliasChain
|
|
|
|
type AliasChainReply struct {
|
|
|
|
Success bool `json:"success"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// AliasChain attempts to alias a chain to a new name
|
|
|
|
func (service *Admin) AliasChain(_ *http.Request, args *AliasChainArgs, reply *AliasChainReply) error {
|
2020-06-15 09:35:41 -07:00
|
|
|
service.log.Info("Admin: AliasChain called with Chain: %s, Alias: %s", args.Chain, args.Alias)
|
2020-03-10 12:20:34 -07:00
|
|
|
|
|
|
|
chainID, err := service.chainManager.Lookup(args.Chain)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := service.chainManager.Alias(chainID, args.Alias); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
reply.Success = true
|
|
|
|
return service.httpServer.AddAliasesWithReadLock("bc/"+chainID.String(), "bc/"+args.Alias)
|
|
|
|
}
|
2020-05-17 20:47:43 -07:00
|
|
|
|
|
|
|
// StacktraceArgs are the arguments for calling Stacktrace
|
|
|
|
type StacktraceArgs struct{}
|
|
|
|
|
|
|
|
// StacktraceReply are the results from calling Stacktrace
|
|
|
|
type StacktraceReply struct {
|
|
|
|
Stacktrace string `json:"stacktrace"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// Stacktrace returns the current global stacktrace
|
2020-06-06 08:52:16 -07:00
|
|
|
func (service *Admin) Stacktrace(_ *http.Request, _ *struct{}, reply *StacktraceReply) error {
|
2020-05-17 20:47:43 -07:00
|
|
|
reply.Stacktrace = logging.Stacktrace{Global: true}.String()
|
|
|
|
return nil
|
|
|
|
}
|