frostfs-node/pkg/services/control/server/server.go
Leonard Lyubich 60e9de8d63 [#1916] control: Check maintenance allowance on Control server
In previous implementation turning to maintenance mode using NeoFS CLI
required NeoFS API endpoint. This was not convenient from the user
perspective. It's worth to move networks settings' check to the server
side.

Add `force_maintenance` field to `SetNetmapStatusRequest.Body` message
of Control API. Add `force` flag to `neofs-cli control set-status`
command which sets corresponding field in the requests body if status is
`maintenance`. Force flag is ignored for any other status.

Signed-off-by: Leonard Lyubich <ctulhurider@gmail.com>
2022-10-24 09:20:24 +04:00

153 lines
3.7 KiB
Go

package control
import (
"crypto/ecdsa"
"github.com/nspcc-dev/neofs-node/pkg/core/container"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/nspcc-dev/neofs-node/pkg/local_object_storage/engine"
"github.com/nspcc-dev/neofs-node/pkg/services/control"
"github.com/nspcc-dev/neofs-node/pkg/services/replicator"
)
// Server is an entity that serves
// Control service on storage node.
type Server struct {
*cfg
}
// HealthChecker is component interface for calculating
// the current health status of a node.
type HealthChecker interface {
// Must calculate and return current status of the node in NeoFS network map.
//
// If status can not be calculated for any reason,
// control.netmapStatus_STATUS_UNDEFINED should be returned.
NetmapStatus() control.NetmapStatus
// Must calculate and return current health status of the node application.
//
// If status can not be calculated for any reason,
// control.HealthStatus_HEALTH_STATUS_UNDEFINED should be returned.
HealthStatus() control.HealthStatus
}
// NodeState is an interface of storage node network state.
type NodeState interface {
// SetNetmapStatus switches the storage node to the given network status.
//
// If status is control.NetmapStatus_MAINTENANCE and maintenance is allowed
// in the network settings, the node additionally starts local maintenance.
SetNetmapStatus(st control.NetmapStatus) error
// ForceMaintenance works like SetNetmapStatus(control.NetmapStatus_MAINTENANCE)
// but starts local maintenance regardless of the network settings.
ForceMaintenance() error
}
// Option of the Server's constructor.
type Option func(*cfg)
type cfg struct {
key *ecdsa.PrivateKey
allowedKeys [][]byte
healthChecker HealthChecker
netMapSrc netmap.Source
cnrSrc container.Source
replicator *replicator.Replicator
nodeState NodeState
treeService TreeService
s *engine.StorageEngine
}
func defaultCfg() *cfg {
return &cfg{}
}
// New creates, initializes and returns new Server instance.
func New(opts ...Option) *Server {
c := defaultCfg()
for _, opt := range opts {
opt(c)
}
return &Server{
cfg: c,
}
}
// WithKey returns option to set private key
// used for signing responses.
func WithKey(key *ecdsa.PrivateKey) Option {
return func(c *cfg) {
c.key = key
}
}
// WithAuthorizedKeys returns option to add list of public
// keys that have rights to use Control service.
func WithAuthorizedKeys(keys [][]byte) Option {
return func(c *cfg) {
c.allowedKeys = append(c.allowedKeys, keys...)
}
}
// WithHealthChecker returns option to set component
// to calculate node health status.
func WithHealthChecker(hc HealthChecker) Option {
return func(c *cfg) {
c.healthChecker = hc
}
}
// WithNetMapSource returns option to set network map storage.
func WithNetMapSource(netMapSrc netmap.Source) Option {
return func(c *cfg) {
c.netMapSrc = netMapSrc
}
}
// WithContainerSource returns option to set container storage.
func WithContainerSource(cnrSrc container.Source) Option {
return func(c *cfg) {
c.cnrSrc = cnrSrc
}
}
// WithReplicator returns option to set network map storage.
func WithReplicator(r *replicator.Replicator) Option {
return func(c *cfg) {
c.replicator = r
}
}
// WithNodeState returns option to set node network state component.
func WithNodeState(state NodeState) Option {
return func(c *cfg) {
c.nodeState = state
}
}
// WithLocalStorage returns option to set local storage engine that
// contains information about shards.
func WithLocalStorage(engine *engine.StorageEngine) Option {
return func(c *cfg) {
c.s = engine
}
}
// WithTreeService returns an option to set tree service.
func WithTreeService(s TreeService) Option {
return func(c *cfg) {
c.treeService = s
}
}