package ape import ( "encoding/json" "fmt" "os" "strings" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/constants" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/helper" parseutil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine" morph "git.frostfs.info/TrueCloudLab/policy-engine/pkg/morph/policy" "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" "github.com/nspcc-dev/neo-go/pkg/rpcclient/management" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/spf13/cobra" "github.com/spf13/viper" ) const ( ingress = "ingress" s3 = "s3" ) var mChainName = map[string]apechain.Name{ ingress: apechain.Ingress, s3: apechain.S3, } func parseTarget(cmd *cobra.Command) policyengine.Target { var targetType policyengine.TargetType typ, _ := cmd.Flags().GetString(targetTypeFlag) switch typ { case namespaceTarget: targetType = policyengine.Namespace case containerTarget: targetType = policyengine.Container default: commonCmd.ExitOnErr(cmd, "read target type error: %w", fmt.Errorf("unknown target type")) } name, _ := cmd.Flags().GetString(targetNameFlag) return policyengine.Target{ Name: name, Type: targetType, } } func parseChainID(cmd *cobra.Command) apechain.ID { chainID, _ := cmd.Flags().GetString(chainIDFlag) if chainID == "" { commonCmd.ExitOnErr(cmd, "read chain id error: %w", fmt.Errorf("chain id cannot be empty")) } return apechain.ID(chainID) } func parseChain(cmd *cobra.Command) *apechain.Chain { chain := new(apechain.Chain) if ruleStmt, _ := cmd.Flags().GetString(ruleFlag); ruleStmt != "" { parseErr := parseutil.ParseAPEChain(chain, []string{ruleStmt}) commonCmd.ExitOnErr(cmd, "ape chain parser error: %w", parseErr) } else if ruleJSON, _ := cmd.Flags().GetString(ruleJSONFlag); ruleJSON != "" { var rule []byte if _, err := os.Stat(ruleJSON); err == nil { rule, err = os.ReadFile(ruleJSON) commonCmd.ExitOnErr(cmd, "read file error: %w", err) } else { rule = []byte(ruleJSON) if !json.Valid(rule) { commonCmd.ExitOnErr(cmd, "read raw rule error: %w", fmt.Errorf("invalid JSON")) } } err := chain.DecodeBytes(rule) commonCmd.ExitOnErr(cmd, "chain decode error: %w", err) } else { commonCmd.ExitOnErr(cmd, "", fmt.Errorf("rule is not passed")) } chain.ID = parseChainID(cmd) return chain } func parseChainName(cmd *cobra.Command) apechain.Name { chainName, _ := cmd.Flags().GetString(chainNameFlag) apeChainName, ok := mChainName[strings.ToLower(chainName)] if !ok { commonCmd.ExitOnErr(cmd, "", fmt.Errorf("unsupported chain name")) } return apeChainName } func newPolicyContractInterface(cmd *cobra.Command) (*morph.ContractStorage, *actor.Actor) { v := viper.GetViper() c, err := helper.GetN3Client(v) commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err) walletDir := config.ResolveHomePath(viper.GetString(commonflags.AlphabetWalletsFlag)) wallets, err := helper.GetAlphabetWallets(v, walletDir) commonCmd.ExitOnErr(cmd, "unable to get alphabet wallets: %w", err) committeeAcc, err := helper.GetWalletAccount(wallets[0], constants.CommitteeAccountName) commonCmd.ExitOnErr(cmd, "can't find committee account: %w", err) ac, err := helper.NewActor(c, committeeAcc) commonCmd.ExitOnErr(cmd, "can't create actor: %w", err) inv := &ac.Invoker var ch util.Uint160 r := management.NewReader(inv) nnsCs, err := r.GetContractByID(1) commonCmd.ExitOnErr(cmd, "can't get NNS contract state: %w", err) ch, err = helper.NNSResolveHash(inv, nnsCs.Hash, helper.DomainOf(constants.PolicyContract)) commonCmd.ExitOnErr(cmd, "unable to resolve policy contract hash: %w", err) return morph.NewContractStorage(ac, ch), ac }