package control import ( "bytes" "context" "fmt" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/netmap" control "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control/ir" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" ) // HealthCheck returns health status of the local IR node. // // If request is not signed with a key from white list, permission error returns. func (s *Server) HealthCheck(_ context.Context, req *control.HealthCheckRequest) (*control.HealthCheckResponse, error) { if err := s.isValidRequest(req); err != nil { return nil, status.Error(codes.PermissionDenied, err.Error()) } resp := new(control.HealthCheckResponse) body := new(control.HealthCheckResponse_Body) resp.SetBody(body) body.SetHealthStatus(s.prm.healthChecker.HealthStatus()) if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil { return nil, status.Error(codes.Internal, err.Error()) } return resp, nil } // TickEpoch forces a new epoch. // // If request is not signed with a key from white list, permission error returns. func (s *Server) TickEpoch(_ context.Context, req *control.TickEpochRequest) (*control.TickEpochResponse, error) { if err := s.isValidRequest(req); err != nil { return nil, status.Error(codes.PermissionDenied, err.Error()) } resp := new(control.TickEpochResponse) resp.SetBody(new(control.TickEpochResponse_Body)) epoch, err := s.netmapClient.Epoch() if err != nil { return nil, fmt.Errorf("getting current epoch: %w", err) } if err := s.netmapClient.NewEpoch(epoch+1, true); err != nil { return nil, fmt.Errorf("forcing new epoch: %w", err) } if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil { return nil, status.Error(codes.Internal, err.Error()) } return resp, nil } // RemoveNode forces a node removal. // // If request is not signed with a key from white list, permission error returns. func (s *Server) RemoveNode(_ context.Context, req *control.RemoveNodeRequest) (*control.RemoveNodeResponse, error) { if err := s.isValidRequest(req); err != nil { return nil, status.Error(codes.PermissionDenied, err.Error()) } resp := new(control.RemoveNodeResponse) resp.SetBody(new(control.RemoveNodeResponse_Body)) nm, err := s.netmapClient.NetMap() if err != nil { return nil, fmt.Errorf("getting netmap: %w", err) } var nodeInfo netmap.NodeInfo for _, info := range nm.Nodes() { if bytes.Equal(info.PublicKey(), req.GetBody().GetKey()) { nodeInfo = info break } } if len(nodeInfo.PublicKey()) == 0 { return nil, status.Error(codes.NotFound, "no such node") } if nodeInfo.IsOffline() { return nil, status.Error(codes.FailedPrecondition, "node is already offline") } if err := s.netmapClient.ForceRemovePeer(nodeInfo); err != nil { return nil, fmt.Errorf("forcing node removal: %w", err) } if err := SignMessage(&s.prm.key.PrivateKey, resp); err != nil { return nil, status.Error(codes.Internal, err.Error()) } return resp, nil }