ape: Remove all chains by target #1031

Merged
acid-ant merged 6 commits from acid-ant/frostfs-node:feature/976-remove-all-rules into master 2024-09-04 19:51:07 +00:00
16 changed files with 185 additions and 51 deletions

View file

@ -36,4 +36,5 @@ const (
HomomorphicHashDisabledInitFlag = "network.homomorphic_hash_disabled" HomomorphicHashDisabledInitFlag = "network.homomorphic_hash_disabled"
CustomZoneFlag = "domain" CustomZoneFlag = "domain"
AlphabetSizeFlag = "size" AlphabetSizeFlag = "size"
AllFlag = "all"
) )

View file

@ -114,8 +114,9 @@ func initRemoveRuleChainCmd() {
removeRuleChainCmd.Flags().String(targetNameFlag, "", targetNameDesc) removeRuleChainCmd.Flags().String(targetNameFlag, "", targetNameDesc)
_ = removeRuleChainCmd.MarkFlagRequired(targetNameFlag) _ = removeRuleChainCmd.MarkFlagRequired(targetNameFlag)
removeRuleChainCmd.Flags().String(chainIDFlag, "", chainIDDesc) removeRuleChainCmd.Flags().String(chainIDFlag, "", chainIDDesc)
_ = removeRuleChainCmd.MarkFlagRequired(chainIDFlag)
removeRuleChainCmd.Flags().String(chainNameFlag, ingress, chainNameFlagDesc) removeRuleChainCmd.Flags().String(chainNameFlag, ingress, chainNameFlagDesc)
removeRuleChainCmd.Flags().Bool(commonflags.AllFlag, false, "Remove all chains for target")
removeRuleChainCmd.MarkFlagsMutuallyExclusive(commonflags.AllFlag, chainIDFlag)
} }
func initListRuleChainsCmd() { func initListRuleChainsCmd() {
@ -157,15 +158,24 @@ func addRuleChain(cmd *cobra.Command, _ []string) {
} }
func removeRuleChain(cmd *cobra.Command, _ []string) { func removeRuleChain(cmd *cobra.Command, _ []string) {
chainID := parseChainID(cmd)
target := parseTarget(cmd) target := parseTarget(cmd)
pci, ac := newPolicyContractInterface(cmd) pci, ac := newPolicyContractInterface(cmd)
removeAll, _ := cmd.Flags().GetBool(commonflags.AllFlag)
if removeAll {
h, vub, err := pci.RemoveMorphRuleChainsByTarget(parseChainName(cmd), target)
cmd.Println("Waiting for transaction to persist...")
_, err = ac.Wait(h, vub, err)
commonCmd.ExitOnErr(cmd, "remove rule chain error: %w", err)
cmd.Println("All chains for target removed successfully")
} else {
chainID := parseChainID(cmd)
h, vub, err := pci.RemoveMorphRuleChain(parseChainName(cmd), target, chainID) h, vub, err := pci.RemoveMorphRuleChain(parseChainName(cmd), target, chainID)
cmd.Println("Waiting for transaction to persist...") cmd.Println("Waiting for transaction to persist...")
_, err = ac.Wait(h, vub, err) _, err = ac.Wait(h, vub, err)
commonCmd.ExitOnErr(cmd, "remove rule chain error: %w", err) commonCmd.ExitOnErr(cmd, "remove rule chain error: %w", err)
cmd.Println("Rule chain removed successfully") cmd.Println("Rule chain removed successfully")
} }
}
func listRuleChains(cmd *cobra.Command, _ []string) { func listRuleChains(cmd *cobra.Command, _ []string) {
target := parseTarget(cmd) target := parseTarget(cmd)

View file

@ -2,6 +2,7 @@ package control
import ( import (
"encoding/hex" "encoding/hex"
"errors"
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client" "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/rpc/client"
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
@ -13,21 +14,48 @@ import (
const ( const (
chainIDFlag = "chain-id" chainIDFlag = "chain-id"
chainIDHexFlag = "chain-id-hex" chainIDHexFlag = "chain-id-hex"
allFlag = "all"
) )
var removeRuleCmd = &cobra.Command{ var (
errEmptyChainID = errors.New("chain id cannot be empty")
removeRuleCmd = &cobra.Command{
Use: "remove-rule", Use: "remove-rule",
Short: "Remove local override", Short: "Remove local override",
Long: "Remove local APE override of the node", Long: "Remove local APE override of the node",
Run: removeRule, Run: removeRule,
} }
)
func removeRule(cmd *cobra.Command, _ []string) { func removeRule(cmd *cobra.Command, _ []string) {
pk := key.Get(cmd) pk := key.Get(cmd)
hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag)
removeAll, _ := cmd.Flags().GetBool(allFlag)
if removeAll {
req := &control.RemoveChainLocalOverridesByTargetRequest{
Body: &control.RemoveChainLocalOverridesByTargetRequest_Body{
Target: parseTarget(cmd),
},
}
signRequest(cmd, pk, req)
cli := getClient(cmd, pk)
var resp *control.RemoveChainLocalOverridesByTargetResponse
var err error
err = cli.ExecRaw(func(client *client.Client) error {
resp, err = control.RemoveChainLocalOverridesByTarget(client, req)
return err
})
commonCmd.ExitOnErr(cmd, "rpc error: %w", err)
verifyResponse(cmd, resp.GetSignature(), resp.GetBody())
cmd.Println("All rules have been removed.")
return
}
chainID, _ := cmd.Flags().GetString(chainIDFlag) chainID, _ := cmd.Flags().GetString(chainIDFlag)
hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag) if chainID == "" {
commonCmd.ExitOnErr(cmd, "read chain id error: %w", errEmptyChainID)
}
chainIDRaw := []byte(chainID) chainIDRaw := []byte(chainID)
if hexEncoded { if hexEncoded {
@ -69,4 +97,6 @@ func initControlRemoveRuleCmd() {
_ = removeRuleCmd.MarkFlagRequired(targetTypeFlag) _ = removeRuleCmd.MarkFlagRequired(targetTypeFlag)
ff.String(chainIDFlag, "", "Chain id") ff.String(chainIDFlag, "", "Chain id")
ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex") ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex")
ff.Bool(allFlag, false, "Remove all chains")
removeRuleCmd.MarkFlagsMutuallyExclusive(allFlag, chainIDFlag)
} }

4
go.mod
View file

@ -5,11 +5,11 @@ go 1.20
require ( require (
code.gitea.io/sdk/gitea v0.17.1 code.gitea.io/sdk/gitea v0.17.1
git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240215124401-634e24aba715 git.frostfs.info/TrueCloudLab/frostfs-api-go/v2 v2.16.1-0.20240215124401-634e24aba715
git.frostfs.info/TrueCloudLab/frostfs-contract v0.18.1-0.20240115082915-f2a82aa635aa git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.0
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20231101111734-b3ad3335ff65 git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20231101111734-b3ad3335ff65
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240301150205-6fe4e2541d0b git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240301150205-6fe4e2541d0b
git.frostfs.info/TrueCloudLab/hrw v1.2.1 git.frostfs.info/TrueCloudLab/hrw v1.2.1
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240304151211-839f22e1a36d git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240307151106-2ec958cbfdfd
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 git.frostfs.info/TrueCloudLab/tzhash v1.8.0
git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02 git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02
github.com/cheggaaa/pb v1.0.29 github.com/cheggaaa/pb v1.0.29

BIN
go.sum

Binary file not shown.

View file

@ -100,7 +100,7 @@ func (cs *boltLocalOverrideStorage) Close() error {
return err return err
} }
func getTargetBucket(tx *bbolt.Tx, name chain.Name, target policyengine.Target) (*bbolt.Bucket, error) { func getTypeBucket(tx *bbolt.Tx, name chain.Name, target policyengine.Target) (*bbolt.Bucket, error) {
cbucket := tx.Bucket(chainBucket) cbucket := tx.Bucket(chainBucket)
if cbucket == nil { if cbucket == nil {
return nil, ErrRootBucketNotFound return nil, ErrRootBucketNotFound
@ -110,16 +110,25 @@ func getTargetBucket(tx *bbolt.Tx, name chain.Name, target policyengine.Target)
if nbucket == nil { if nbucket == nil {
return nil, fmt.Errorf("%w: %w: %s", policyengine.ErrChainNotFound, ErrGlobalNamespaceBucketNotFound, name) return nil, fmt.Errorf("%w: %w: %s", policyengine.ErrChainNotFound, ErrGlobalNamespaceBucketNotFound, name)
} }
return nbucket.Bucket([]byte{byte(target.Type)}), nil
}
typeBucket := nbucket.Bucket([]byte{byte(target.Type)}) func normalizeTargetName(target *policyengine.Target) {
if target.Type == policyengine.Namespace && target.Name == "" {
target.Name = "root"
}
}
func getTargetBucket(tx *bbolt.Tx, name chain.Name, target policyengine.Target) (*bbolt.Bucket, error) {
typeBucket, err := getTypeBucket(tx, name, target)
if err != nil {
return nil, err
}
if typeBucket == nil { if typeBucket == nil {
return nil, fmt.Errorf("%w: %w: %c", policyengine.ErrChainNotFound, ErrTargetTypeBucketNotFound, target.Type) return nil, fmt.Errorf("%w: %w: %c", policyengine.ErrChainNotFound, ErrTargetTypeBucketNotFound, target.Type)
} }
if target.Type == policyengine.Namespace && target.Name == "" { normalizeTargetName(&target)
target.Name = "root"
}
rbucket := typeBucket.Bucket([]byte(target.Name)) rbucket := typeBucket.Bucket([]byte(target.Name))
if rbucket == nil { if rbucket == nil {
return nil, fmt.Errorf("%w: %w: %s", policyengine.ErrChainNotFound, ErrTargetNameBucketNotFound, target.Name) return nil, fmt.Errorf("%w: %w: %s", policyengine.ErrChainNotFound, ErrTargetNameBucketNotFound, target.Name)
@ -151,10 +160,7 @@ func getTargetBucketCreateIfEmpty(tx *bbolt.Tx, name chain.Name, target policyen
} }
} }
if target.Type == policyengine.Namespace && target.Name == "" { normalizeTargetName(&target)
target.Name = "root"
}
rbucket := typeBucket.Bucket([]byte(target.Name)) rbucket := typeBucket.Bucket([]byte(target.Name))
if rbucket == nil { if rbucket == nil {
var err error var err error
@ -220,6 +226,17 @@ func (cs *boltLocalOverrideStorage) RemoveOverride(name chain.Name, target polic
}) })
} }
func (cs *boltLocalOverrideStorage) RemoveOverridesByTarget(name chain.Name, target policyengine.Target) error {
return cs.db.Update(func(tx *bbolt.Tx) error {
typeBucket, err := getTypeBucket(tx, name, target)
if err != nil {
return err
}
normalizeTargetName(&target)
return typeBucket.DeleteBucket([]byte(target.Name))
})
}
func (cs *boltLocalOverrideStorage) ListOverrides(name chain.Name, target policyengine.Target) ([]*chain.Chain, error) { func (cs *boltLocalOverrideStorage) ListOverrides(name chain.Name, target policyengine.Target) ([]*chain.Chain, error) {
var serializedChains [][]byte var serializedChains [][]byte
var serializedChain []byte var serializedChain []byte

View file

@ -1,11 +1,13 @@
package client package client
import ( import (
"github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/config/netmode" "github.com/nspcc-dev/neo-go/pkg/config/netmode"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/neorpc/result"
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
) )
type actorProvider interface { type actorProvider interface {
@ -118,3 +120,15 @@ func (a *SwitchRPCGuardedActor) Sign(tx *transaction.Transaction) error {
func (a *SwitchRPCGuardedActor) SignAndSend(tx *transaction.Transaction) (util.Uint256, uint32, error) { func (a *SwitchRPCGuardedActor) SignAndSend(tx *transaction.Transaction) (util.Uint256, uint32, error) {
return a.actorProvider.GetActor().SignAndSend(tx) return a.actorProvider.GetActor().SignAndSend(tx)
} }
func (a *SwitchRPCGuardedActor) CallAndExpandIterator(contract util.Uint160, method string, maxItems int, params ...any) (*result.Invoke, error) {
return a.actorProvider.GetActor().CallAndExpandIterator(contract, method, maxItems, params...)
}
func (a *SwitchRPCGuardedActor) TerminateSession(sessionID uuid.UUID) error {
return a.actorProvider.GetActor().TerminateSession(sessionID)
}
func (a *SwitchRPCGuardedActor) TraverseIterator(sessionID uuid.UUID, iterator *result.Iterator, num int) ([]stackitem.Item, error) {
return a.actorProvider.GetActor().TraverseIterator(sessionID, iterator, num)
}

View file

@ -25,6 +25,7 @@ const (
rpcGetChainLocalOverride = "GetChainLocalOverride" rpcGetChainLocalOverride = "GetChainLocalOverride"
rpcListChainLocalOverrides = "ListChainLocalOverrides" rpcListChainLocalOverrides = "ListChainLocalOverrides"
rpcRemoveChainLocalOverride = "RemoveChainLocalOverride" rpcRemoveChainLocalOverride = "RemoveChainLocalOverride"
rpcRemoveChainLocalOverridesByTarget = "RemoveChainLocalOverridesByTarget"
rpcSealWriteCache = "SealWriteCache" rpcSealWriteCache = "SealWriteCache"
rpcListTargetsLocalOverrides = "ListTargetsLocalOverrides" rpcListTargetsLocalOverrides = "ListTargetsLocalOverrides"
rpcDetachShards = "DetachShards" rpcDetachShards = "DetachShards"
@ -295,6 +296,19 @@ func RemoveChainLocalOverride(cli *client.Client, req *RemoveChainLocalOverrideR
return wResp.message, nil return wResp.message, nil
} }
// RemoveChainLocalOverridesByTarget executes ControlService.RemoveChainLocalOverridesByTarget RPC.
func RemoveChainLocalOverridesByTarget(cli *client.Client, req *RemoveChainLocalOverridesByTargetRequest, opts ...client.CallOption) (*RemoveChainLocalOverridesByTargetResponse, error) {
wResp := newResponseWrapper[RemoveChainLocalOverridesByTargetResponse]()
wReq := &requestWrapper{m: req}
err := client.SendUnary(cli, common.CallMethodInfoUnary(serviceName, rpcRemoveChainLocalOverridesByTarget), wReq, wResp, opts...)
if err != nil {
return nil, err
}
return wResp.message, nil
}
// SealWriteCache executes ControlService.SealWriteCache RPC. // SealWriteCache executes ControlService.SealWriteCache RPC.
func SealWriteCache(cli *client.Client, req *SealWriteCacheRequest, opts ...client.CallOption) (*SealWriteCacheResponse, error) { func SealWriteCache(cli *client.Client, req *SealWriteCacheRequest, opts ...client.CallOption) (*SealWriteCacheResponse, error) {
wResp := newResponseWrapper[SealWriteCacheResponse]() wResp := newResponseWrapper[SealWriteCacheResponse]()

View file

@ -174,6 +174,31 @@ func (s *Server) RemoveChainLocalOverride(_ context.Context, req *control.Remove
return resp, nil return resp, nil
} }
func (s *Server) RemoveChainLocalOverridesByTarget(_ context.Context, req *control.RemoveChainLocalOverridesByTargetRequest) (*control.RemoveChainLocalOverridesByTargetResponse, error) {
if err := s.isValidRequest(req); err != nil {
return nil, status.Error(codes.PermissionDenied, err.Error())
}
target, err := apeTarget(req.GetBody().GetTarget())
if err != nil {
return nil, err
}
if err = s.localOverrideStorage.LocalStorage().RemoveOverridesByTarget(apechain.Ingress, target); err != nil {
if code := getCodeByLocalStorageErr(err); code != codes.NotFound {
return nil, status.Error(code, err.Error())
}
}
resp := &control.RemoveChainLocalOverridesByTargetResponse{
Body: &control.RemoveChainLocalOverridesByTargetResponse_Body{},
}
err = SignMessage(s.key, resp)
if err != nil {
return nil, status.Error(codes.Internal, err.Error())
}
return resp, nil
}
func (s *Server) ListTargetsLocalOverrides(_ context.Context, req *control.ListTargetsLocalOverridesRequest) (*control.ListTargetsLocalOverridesResponse, error) { func (s *Server) ListTargetsLocalOverrides(_ context.Context, req *control.ListTargetsLocalOverridesRequest) (*control.ListTargetsLocalOverridesResponse, error) {
if err := s.isValidRequest(req); err != nil { if err := s.isValidRequest(req); err != nil {
return nil, status.Error(codes.PermissionDenied, err.Error()) return nil, status.Error(codes.PermissionDenied, err.Error())

Binary file not shown.

View file

@ -60,6 +60,9 @@ service ControlService {
// Remove local access policy engine overrides stored in the node by chaind id. // Remove local access policy engine overrides stored in the node by chaind id.
rpc RemoveChainLocalOverride (RemoveChainLocalOverrideRequest) returns (RemoveChainLocalOverrideResponse); rpc RemoveChainLocalOverride (RemoveChainLocalOverrideRequest) returns (RemoveChainLocalOverrideResponse);
// Remove local access policy engine overrides stored in the node by chaind id.
rpc RemoveChainLocalOverridesByTarget (RemoveChainLocalOverridesByTargetRequest) returns (RemoveChainLocalOverridesByTargetResponse);
// List targets of the local APE overrides stored in the node. // List targets of the local APE overrides stored in the node.
rpc ListTargetsLocalOverrides (ListTargetsLocalOverridesRequest) returns (ListTargetsLocalOverridesResponse); rpc ListTargetsLocalOverrides (ListTargetsLocalOverridesRequest) returns (ListTargetsLocalOverridesResponse);
@ -592,6 +595,26 @@ message RemoveChainLocalOverrideResponse {
Signature signature = 2; Signature signature = 2;
} }
message RemoveChainLocalOverridesByTargetRequest {
message Body {
// Target for which the overrides are applied.
ChainTarget target = 1;
}
Body body = 1;
Signature signature = 2;
}
message RemoveChainLocalOverridesByTargetResponse {
message Body {
}
Body body = 1;
Signature signature = 2;
}
message SealWriteCacheRequest { message SealWriteCacheRequest {
// Request body structure. // Request body structure.
message Body { message Body {

Binary file not shown.

Binary file not shown.