From 64b2df39b5f182b86aa5ded461c2222adb1d15a0 Mon Sep 17 00:00:00 2001 From: Aaron Buchwald Date: Wed, 10 Jun 2020 16:47:31 -0400 Subject: [PATCH] Split admin api into admin and info apis --- api/admin/service.go | 96 +------------------------------- api/info/service.go | 130 +++++++++++++++++++++++++++++++++++++++++++ main/params.go | 1 + node/config.go | 1 + node/node.go | 12 +++- 5 files changed, 144 insertions(+), 96 deletions(-) create mode 100644 api/info/service.go diff --git a/api/admin/service.go b/api/admin/service.go index e05a440..baf8fe7 100644 --- a/api/admin/service.go +++ b/api/admin/service.go @@ -10,129 +10,35 @@ import ( "github.com/ava-labs/gecko/api" "github.com/ava-labs/gecko/chains" - "github.com/ava-labs/gecko/genesis" - "github.com/ava-labs/gecko/ids" "github.com/ava-labs/gecko/network" "github.com/ava-labs/gecko/snow/engine/common" "github.com/ava-labs/gecko/utils/logging" - "github.com/ava-labs/gecko/version" cjson "github.com/ava-labs/gecko/utils/json" ) // Admin is the API service for node admin management type Admin struct { - version version.Version - nodeID ids.ShortID - networkID uint32 log logging.Logger - networking network.Network performance Performance chainManager chains.Manager httpServer *api.Server } // NewService returns a new admin API service -func NewService(version version.Version, nodeID ids.ShortID, networkID uint32, log logging.Logger, chainManager chains.Manager, peers network.Network, httpServer *api.Server) *common.HTTPHandler { +func NewService(log logging.Logger, chainManager chains.Manager, peers network.Network, httpServer *api.Server) *common.HTTPHandler { newServer := rpc.NewServer() codec := cjson.NewCodec() newServer.RegisterCodec(codec, "application/json") newServer.RegisterCodec(codec, "application/json;charset=UTF-8") newServer.RegisterService(&Admin{ - version: version, - nodeID: nodeID, - networkID: networkID, log: log, chainManager: chainManager, - networking: peers, httpServer: httpServer, }, "admin") return &common.HTTPHandler{Handler: newServer} } -// 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.Debug("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.Debug("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.Debug("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.Debug("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.Debug("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.Debug("Admin: Peers called") - reply.Peers = service.networking.Peers() - return nil -} - // StartCPUProfilerArgs are the arguments for calling StartCPUProfiler type StartCPUProfilerArgs struct { Filename string `json:"filename"` diff --git a/api/info/service.go b/api/info/service.go new file mode 100644 index 0000000..a1e1937 --- /dev/null +++ b/api/info/service.go @@ -0,0 +1,130 @@ +// (c) 2019-2020, Ava Labs, Inc. All rights reserved. +// See the file LICENSE for licensing terms. + +package info + +import ( + "net/http" + + "github.com/gorilla/rpc/v2" + + "github.com/ava-labs/gecko/chains" + "github.com/ava-labs/gecko/genesis" + "github.com/ava-labs/gecko/ids" + "github.com/ava-labs/gecko/network" + "github.com/ava-labs/gecko/snow/engine/common" + "github.com/ava-labs/gecko/utils/logging" + "github.com/ava-labs/gecko/version" + + cjson "github.com/ava-labs/gecko/utils/json" +) + +// Info is the API service for unprivileged info on a node +type Info struct { + version version.Version + nodeID ids.ShortID + networkID uint32 + log logging.Logger + networking network.Network + chainManager chains.Manager +} + +// NewService returns a new admin API service +func NewService(log logging.Logger, version version.Version, nodeID ids.ShortID, networkID uint32, chainManager chains.Manager, peers network.Network) *common.HTTPHandler { + newServer := rpc.NewServer() + codec := cjson.NewCodec() + newServer.RegisterCodec(codec, "application/json") + newServer.RegisterCodec(codec, "application/json;charset=UTF-8") + newServer.RegisterService(&Info{ + version: version, + nodeID: nodeID, + networkID: networkID, + log: log, + chainManager: chainManager, + networking: peers, + }, "info") + return &common.HTTPHandler{Handler: newServer} +} + +// GetNodeVersionReply are the results from calling GetNodeVersion +type GetNodeVersionReply struct { + Version string `json:"version"` +} + +// GetNodeVersion returns the version this node is running +func (service *Info) GetNodeVersion(_ *http.Request, _ *struct{}, reply *GetNodeVersionReply) error { + service.log.Debug("Info: 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 *Info) GetNodeID(_ *http.Request, _ *struct{}, reply *GetNodeIDReply) error { + service.log.Debug("Info: 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 *Info) GetNetworkID(_ *http.Request, _ *struct{}, reply *GetNetworkIDReply) error { + service.log.Debug("Info: 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 *Info) GetNetworkName(_ *http.Request, _ *struct{}, reply *GetNetworkNameReply) error { + service.log.Debug("Info: 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 *Info) GetBlockchainID(_ *http.Request, args *GetBlockchainIDArgs, reply *GetBlockchainIDReply) error { + service.log.Debug("Info: 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 *Info) Peers(_ *http.Request, _ *struct{}, reply *PeersReply) error { + service.log.Debug("Info: Peers called") + reply.Peers = service.networking.Peers() + return nil +} diff --git a/main/params.go b/main/params.go index eef8e60..74383bd 100644 --- a/main/params.go +++ b/main/params.go @@ -222,6 +222,7 @@ func init() { // Enable/Disable APIs: fs.BoolVar(&Config.AdminAPIEnabled, "api-admin-enabled", true, "If true, this node exposes the Admin API") + fs.BoolVar(&Config.InfoAPIEnabled, "api-info-enabled", true, "If true, this node exposes the Info API") fs.BoolVar(&Config.KeystoreAPIEnabled, "api-keystore-enabled", true, "If true, this node exposes the Keystore API") fs.BoolVar(&Config.MetricsAPIEnabled, "api-metrics-enabled", true, "If true, this node exposes the Metrics API") fs.BoolVar(&Config.HealthAPIEnabled, "api-health-enabled", true, "If true, this node exposes the Health API") diff --git a/node/config.go b/node/config.go index 74ff491..29e79b9 100644 --- a/node/config.go +++ b/node/config.go @@ -50,6 +50,7 @@ type Config struct { // Enable/Disable APIs AdminAPIEnabled bool + InfoAPIEnabled bool KeystoreAPIEnabled bool MetricsAPIEnabled bool HealthAPIEnabled bool diff --git a/node/node.go b/node/node.go index ea0e8fc..0bb2c24 100644 --- a/node/node.go +++ b/node/node.go @@ -18,6 +18,7 @@ import ( "github.com/ava-labs/gecko/api" "github.com/ava-labs/gecko/api/admin" "github.com/ava-labs/gecko/api/health" + "github.com/ava-labs/gecko/api/info" "github.com/ava-labs/gecko/api/ipcs" "github.com/ava-labs/gecko/api/keystore" "github.com/ava-labs/gecko/api/metrics" @@ -461,11 +462,19 @@ func (n *Node) initMetricsAPI() { func (n *Node) initAdminAPI() { if n.Config.AdminAPIEnabled { n.Log.Info("initializing Admin API") - service := admin.NewService(Version, n.ID, n.Config.NetworkID, n.Log, n.chainManager, n.Net, &n.APIServer) + service := admin.NewService(n.Log, n.chainManager, n.Net, &n.APIServer) n.APIServer.AddRoute(service, &sync.RWMutex{}, "admin", "", n.HTTPLog) } } +func (n *Node) initInfoAPI() { + if n.Config.InfoAPIEnabled { + n.Log.Info("initializing Info API") + service := info.NewService(n.Log, Version, n.ID, n.Config.NetworkID, n.chainManager, n.Net) + n.APIServer.AddRoute(service, &sync.RWMutex{}, "info", "", n.HTTPLog) + } +} + // initHealthAPI initializes the Health API service // Assumes n.Log, n.ConsensusAPI, and n.ValidatorAPI already initialized func (n *Node) initHealthAPI() { @@ -562,6 +571,7 @@ func (n *Node) Initialize(Config *Config, logger logging.Logger, logFactory logg n.initChainManager() // Set up the chain manager n.initAdminAPI() // Start the Admin API + n.initInfoAPI() // Start the Info API n.initHealthAPI() // Start the Health API n.initIPCAPI() // Start the IPC API