diff --git a/pkg/services/control/server/server.go b/pkg/services/control/server/server.go index 5fdf2791..fcd87859 100644 --- a/pkg/services/control/server/server.go +++ b/pkg/services/control/server/server.go @@ -29,6 +29,11 @@ type HealthChecker interface { HealthStatus() control.HealthStatus } +// NodeState is an interface of storage node network state. +type NodeState interface { + SetNetmapStatus(control.NetmapStatus) error +} + // Option of the Server's constructor. type Option func(*cfg) @@ -40,6 +45,8 @@ type cfg struct { healthChecker HealthChecker netMapSrc netmap.Source + + nodeState NodeState } func defaultCfg() *cfg { @@ -89,3 +96,10 @@ func WithNetMapSource(netMapSrc netmap.Source) Option { c.netMapSrc = netMapSrc } } + +// WithNodeState returns option to set node network state component. +func WithNodeState(state NodeState) Option { + return func(c *cfg) { + c.nodeState = state + } +} diff --git a/pkg/services/control/server/set_netmap_status.go b/pkg/services/control/server/set_netmap_status.go new file mode 100644 index 00000000..ec03bdec --- /dev/null +++ b/pkg/services/control/server/set_netmap_status.go @@ -0,0 +1,37 @@ +package control + +import ( + "context" + + "github.com/nspcc-dev/neofs-node/pkg/services/control" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/status" +) + +// SetNetmapStatus sets node status in NeoFS network. +// +// If request is unsigned or signed by disallowed key, permission error returns. +func (s *Server) SetNetmapStatus(ctx context.Context, req *control.SetNetmapStatusRequest) (*control.SetNetmapStatusResponse, error) { + // verify request + if err := s.isValidRequest(req); err != nil { + return nil, status.Error(codes.PermissionDenied, err.Error()) + } + + // set node status + if err := s.nodeState.SetNetmapStatus(req.GetBody().GetStatus()); err != nil { + return nil, status.Error(codes.Aborted, err.Error()) + } + + // create and fill response + resp := new(control.SetNetmapStatusResponse) + + body := new(control.SetNetmapStatusResponse_Body) + resp.SetBody(body) + + // sign the response + if err := SignMessage(s.key, resp); err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + + return resp, nil +}