package ape import ( "errors" "strings" "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/invoker" "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, } var ( errUnknownTargetType = errors.New("unknown target type") errChainIDCannotBeEmpty = errors.New("chain id cannot be empty") errRuleIsNotParsed = errors.New("rule is not passed") errUnsupportedChainName = errors.New("unsupported chain name") ) func parseTarget(cmd *cobra.Command) policyengine.Target { name, _ := cmd.Flags().GetString(targetNameFlag) typ, err := parseTargetType(cmd) // interpret "root" namespace as empty if typ == policyengine.Namespace && name == "root" { name = "" } commonCmd.ExitOnErr(cmd, "read target type error: %w", err) return policyengine.Target{ Name: name, Type: typ, } } func parseTargetType(cmd *cobra.Command) (policyengine.TargetType, error) { typ, _ := cmd.Flags().GetString(targetTypeFlag) switch typ { case namespaceTarget: return policyengine.Namespace, nil case containerTarget: return policyengine.Container, nil case userTarget: return policyengine.User, nil case groupTarget: return policyengine.Group, nil } return -1, errUnknownTargetType } func parseChainID(cmd *cobra.Command) apechain.ID { chainID, _ := cmd.Flags().GetString(chainIDFlag) if chainID == "" { commonCmd.ExitOnErr(cmd, "read chain id error: %w", errChainIDCannotBeEmpty) } return apechain.ID(chainID) } func parseChain(cmd *cobra.Command) *apechain.Chain { chain := new(apechain.Chain) if rules, _ := cmd.Flags().GetStringArray(ruleFlag); len(rules) > 0 { commonCmd.ExitOnErr(cmd, "parser error: %w", parseutil.ParseAPEChain(chain, rules)) } else if encPath, _ := cmd.Flags().GetString(pathFlag); encPath != "" { commonCmd.ExitOnErr(cmd, "decode binary or json error: %w", parseutil.ParseAPEChainBinaryOrJSON(chain, encPath)) } else { commonCmd.ExitOnErr(cmd, "parser error: %w", errRuleIsNotParsed) } chain.ID = parseChainID(cmd) cmd.Println("Parsed chain:") parseutil.PrintHumanReadableAPEChain(cmd, chain) 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, "", errUnsupportedChainName) } return apeChainName } // invokerAdapter adapats invoker.Invoker to ContractStorageInvoker interface. type invokerAdapter struct { *invoker.Invoker rpcActor invoker.RPCInvoke } func (n *invokerAdapter) GetRPCInvoker() invoker.RPCInvoke { return n.rpcActor } func newPolicyContractReaderInterface(cmd *cobra.Command) (*morph.ContractStorageReader, *invoker.Invoker) { c, err := helper.GetN3Client(viper.GetViper()) commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err) inv := invoker.New(c, nil) var ch util.Uint160 r := management.NewReader(inv) nnsCs, err := helper.GetContractByID(r, 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) invokerAdapter := &invokerAdapter{ Invoker: inv, rpcActor: c, } return morph.NewContractStorageReader(invokerAdapter, ch), inv } func newPolicyContractInterface(cmd *cobra.Command) (*morph.ContractStorage, *helper.LocalActor) { c, err := helper.GetN3Client(viper.GetViper()) commonCmd.ExitOnErr(cmd, "unable to create NEO rpc client: %w", err) ac, err := helper.NewLocalActor(cmd, c, constants.ConsensusAccountName) commonCmd.ExitOnErr(cmd, "can't create actor: %w", err) var ch util.Uint160 r := management.NewReader(ac.Invoker) nnsCs, err := helper.GetContractByID(r, 1) commonCmd.ExitOnErr(cmd, "can't get NNS contract state: %w", err) ch, err = helper.NNSResolveHash(ac.Invoker, nnsCs.Hash, helper.DomainOf(constants.PolicyContract)) commonCmd.ExitOnErr(cmd, "unable to resolve policy contract hash: %w", err) return morph.NewContractStorage(ac, ch), ac }