diff --git a/pkg/services/control/rpc.go b/pkg/services/control/rpc.go index 3fd4d4ae..24b20f87 100644 --- a/pkg/services/control/rpc.go +++ b/pkg/services/control/rpc.go @@ -8,23 +8,24 @@ import ( const serviceName = "control.ControlService" const ( - rpcHealthCheck = "HealthCheck" - rpcSetNetmapStatus = "SetNetmapStatus" - rpcDropObjects = "DropObjects" - rpcListShards = "ListShards" - rpcSetShardMode = "SetShardMode" - rpcSynchronizeTree = "SynchronizeTree" - rpcEvacuateShard = "EvacuateShard" - rpcStartShardEvacuation = "StartShardEvacuation" - rpcGetShardEvacuationStatus = "GetShardEvacuationStatus" - rpcStopShardEvacuation = "StopShardEvacuation" - rpcFlushCache = "FlushCache" - rpcDoctor = "Doctor" - rpcAddChainLocalOverride = "AddChainLocalOverride" - rpcGetChainLocalOverride = "GetChainLocalOverride" - rpcListChainLocalOverrides = "ListChainLocalOverrides" - rpcRemoveChainLocalOverride = "RemoveChainLocalOverride" - rpcSealWriteCache = "SealWriteCache" + rpcHealthCheck = "HealthCheck" + rpcSetNetmapStatus = "SetNetmapStatus" + rpcDropObjects = "DropObjects" + rpcListShards = "ListShards" + rpcSetShardMode = "SetShardMode" + rpcSynchronizeTree = "SynchronizeTree" + rpcEvacuateShard = "EvacuateShard" + rpcStartShardEvacuation = "StartShardEvacuation" + rpcGetShardEvacuationStatus = "GetShardEvacuationStatus" + rpcStopShardEvacuation = "StopShardEvacuation" + rpcFlushCache = "FlushCache" + rpcDoctor = "Doctor" + rpcAddChainLocalOverride = "AddChainLocalOverride" + rpcGetChainLocalOverride = "GetChainLocalOverride" + rpcListChainLocalOverrides = "ListChainLocalOverrides" + rpcRemoveChainLocalOverride = "RemoveChainLocalOverride" + rpcSealWriteCache = "SealWriteCache" + rpcListTargetsLocalOverrides = "ListTargetsLocalOverrides" ) // HealthCheck executes ControlService.HealthCheck RPC. @@ -240,6 +241,19 @@ func ListChainLocalOverrides(cli *client.Client, req *ListChainLocalOverridesReq return wResp.message, nil } +// ListTargetsLocalOverrides executes ControlService.ListTargetsLocalOverrides RPC. +func ListTargetsLocalOverrides(cli *client.Client, req *ListTargetsLocalOverridesRequest, opts ...client.CallOption) (*ListTargetsLocalOverridesResponse, error) { + wResp := newResponseWrapper[ListTargetsLocalOverridesResponse]() + wReq := &requestWrapper{m: req} + + err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcListTargetsLocalOverrides), wReq, wResp, opts...) + if err != nil { + return nil, err + } + + return wResp.message, nil +} + // RemoveChainLocalOverride executes ControlService.RemoveChainLocalOverride RPC. func GetChainLocalOverride(cli *client.Client, req *GetChainLocalOverrideRequest, opts ...client.CallOption) (*GetChainLocalOverrideResponse, error) { wResp := newResponseWrapper[GetChainLocalOverrideResponse]() diff --git a/pkg/services/control/server/policy_engine.go b/pkg/services/control/server/policy_engine.go index bd7f35f4..079b605a 100644 --- a/pkg/services/control/server/policy_engine.go +++ b/pkg/services/control/server/policy_engine.go @@ -25,6 +25,29 @@ func apeTarget(chainTarget *control.ChainTarget) (engine.Target, error) { fmt.Errorf("target type is not supported: %s", chainTarget.GetType().String()).Error()) } +func controlTarget(chainTarget *engine.Target) (control.ChainTarget, error) { + switch chainTarget.Type { + case engine.Container: + return control.ChainTarget{ + Name: chainTarget.Name, + Type: control.ChainTarget_CONTAINER, + }, nil + case engine.Namespace: + // If namespace is empty, we take it for root namespace. + nm := chainTarget.Name + if nm == "root" { + nm = "" + } + return control.ChainTarget{ + Name: nm, + Type: control.ChainTarget_NAMESPACE, + }, nil + default: + } + return control.ChainTarget{}, status.Error(codes.InvalidArgument, + fmt.Errorf("target type is not supported: %c", chainTarget.Type).Error()) +} + func (s *Server) AddChainLocalOverride(_ context.Context, req *control.AddChainLocalOverrideRequest) (*control.AddChainLocalOverrideResponse, error) { if err := s.isValidRequest(req); err != nil { return nil, status.Error(codes.PermissionDenied, err.Error()) @@ -157,6 +180,37 @@ func (s *Server) RemoveChainLocalOverride(_ context.Context, req *control.Remove return resp, nil } +func (s *Server) ListTargetsLocalOverrides(_ context.Context, req *control.ListTargetsLocalOverridesRequest) (*control.ListTargetsLocalOverridesResponse, error) { + if err := s.isValidRequest(req); err != nil { + return nil, status.Error(codes.PermissionDenied, err.Error()) + } + + apeChainName := apechain.Name(req.GetBody().GetChainName()) + apeTargets, err := s.localOverrideStorage.LocalStorage().ListOverrideDefinedTargets(apeChainName) + if err != nil { + return nil, status.Error(getCodeByLocalStorageErr(err), err.Error()) + } + targets := make([]*control.ChainTarget, 0, len(apeTargets)) + for i := range apeTargets { + target, err := controlTarget(&apeTargets[i]) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + targets = append(targets, &target) + } + + resp := &control.ListTargetsLocalOverridesResponse{ + Body: &control.ListTargetsLocalOverridesResponse_Body{ + Targets: targets, + }, + } + err = SignMessage(s.key, resp) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + return resp, nil +} + func getCodeByLocalStorageErr(err error) codes.Code { if errors.Is(err, engine.ErrChainNotFound) || errors.Is(err, engine.ErrChainNameNotFound) { return codes.NotFound diff --git a/pkg/services/control/service.pb.go b/pkg/services/control/service.pb.go index f6b9ef60..e0c6e062 100644 Binary files a/pkg/services/control/service.pb.go and b/pkg/services/control/service.pb.go differ diff --git a/pkg/services/control/service.proto b/pkg/services/control/service.proto index b76645b6..dc63a718 100644 --- a/pkg/services/control/service.proto +++ b/pkg/services/control/service.proto @@ -57,6 +57,9 @@ service ControlService { // Remove local access policy engine overrides stored in the node by chaind id. rpc RemoveChainLocalOverride (RemoveChainLocalOverrideRequest) returns (RemoveChainLocalOverrideResponse); + // List targets of the local APE overrides stored in the node. + rpc ListTargetsLocalOverrides (ListTargetsLocalOverridesRequest) returns (ListTargetsLocalOverridesResponse); + // Flush objects from write-cache and move it to degraded read only mode. rpc SealWriteCache(SealWriteCacheRequest) returns (SealWriteCacheResponse); } @@ -505,6 +508,30 @@ message ListChainLocalOverridesResponse { Signature signature = 2; } +// ListTargetsLocalOverrides request. +message ListTargetsLocalOverridesRequest { + message Body { + // Target for which the overrides are applied. + string chainName = 1; + } + + Body body = 1; + + Signature signature = 2; +} + +// ListTargetsLocalOverrides response. +message ListTargetsLocalOverridesResponse { + message Body { + // The list of chain targets. + repeated ChainTarget targets = 1; + } + + Body body = 1; + + Signature signature = 2; +} + message RemoveChainLocalOverrideRequest { message Body { // Target for which the overrides are applied. @@ -556,4 +583,4 @@ message SealWriteCacheResponse { Body body = 1; Signature signature = 2; -} \ No newline at end of file +} diff --git a/pkg/services/control/service_frostfs.pb.go b/pkg/services/control/service_frostfs.pb.go index 574ab13c..b72fc0f1 100644 Binary files a/pkg/services/control/service_frostfs.pb.go and b/pkg/services/control/service_frostfs.pb.go differ diff --git a/pkg/services/control/service_grpc.pb.go b/pkg/services/control/service_grpc.pb.go index e09f6750..89337323 100644 Binary files a/pkg/services/control/service_grpc.pb.go and b/pkg/services/control/service_grpc.pb.go differ