package ape import ( "bytes" "encoding/json" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape" apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" "github.com/nspcc-dev/neo-go/pkg/util" "github.com/spf13/cobra" "github.com/spf13/viper" ) const ( namespaceTarget = "namespace" containerTarget = "container" userTarget = "user" groupTarget = "group" jsonFlag = "json" jsonFlagDesc = "Output rule chains in JSON format" chainIDFlag = "chain-id" chainIDDesc = "Rule chain ID" ruleFlag = "rule" ruleFlagDesc = "Rule chain in text format" pathFlag = "path" pathFlagDesc = "path to encoded chain in JSON or binary format" targetNameFlag = "target-name" targetNameDesc = "Resource name in APE resource name format" targetTypeFlag = "target-type" targetTypeDesc = "Resource type(container/namespace)" addrAdminFlag = "addr" addrAdminDesc = "The address of the admins wallet" chainNameFlag = "chain-name" chainNameFlagDesc = "Chain name(ingress|s3)" ) var ( addRuleChainCmd = &cobra.Command{ Use: "add-rule-chain", Short: "Add rule chain", PreRun: func(cmd *cobra.Command, _ []string) { _ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag)) _ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag)) }, Run: addRuleChain, } removeRuleChainCmd = &cobra.Command{ Use: "rm-rule-chain", Short: "Remove rule chain", PreRun: func(cmd *cobra.Command, _ []string) { _ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag)) _ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag)) }, Run: removeRuleChain, } listRuleChainsCmd = &cobra.Command{ Use: "list-rule-chains", Short: "List rule chains", PreRun: func(cmd *cobra.Command, _ []string) { _ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag)) }, Run: listRuleChains, } setAdminCmd = &cobra.Command{ Use: "set-admin", Short: "Set admin", PreRun: func(cmd *cobra.Command, _ []string) { _ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag)) _ = viper.BindPFlag(commonflags.AlphabetWalletsFlag, cmd.Flags().Lookup(commonflags.AlphabetWalletsFlag)) }, Run: setAdmin, } getAdminCmd = &cobra.Command{ Use: "get-admin", Short: "Get admin", PreRun: func(cmd *cobra.Command, _ []string) { _ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag)) }, Run: getAdmin, } listTargetsCmd = &cobra.Command{ Use: "list-targets", Short: "List targets", PreRun: func(cmd *cobra.Command, _ []string) { _ = viper.BindPFlag(commonflags.EndpointFlag, cmd.Flags().Lookup(commonflags.EndpointFlag)) }, Run: listTargets, } ) func initAddRuleChainCmd() { Cmd.AddCommand(addRuleChainCmd) addRuleChainCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) addRuleChainCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc) addRuleChainCmd.Flags().String(targetTypeFlag, "", targetTypeDesc) _ = addRuleChainCmd.MarkFlagRequired(targetTypeFlag) addRuleChainCmd.Flags().String(targetNameFlag, "", targetNameDesc) _ = addRuleChainCmd.MarkFlagRequired(targetNameFlag) addRuleChainCmd.Flags().String(chainIDFlag, "", chainIDDesc) _ = addRuleChainCmd.MarkFlagRequired(chainIDFlag) addRuleChainCmd.Flags().StringArray(ruleFlag, []string{}, ruleFlagDesc) addRuleChainCmd.Flags().String(pathFlag, "", pathFlagDesc) addRuleChainCmd.Flags().String(chainNameFlag, ingress, chainNameFlagDesc) addRuleChainCmd.MarkFlagsMutuallyExclusive(ruleFlag, pathFlag) } func initRemoveRuleChainCmd() { Cmd.AddCommand(removeRuleChainCmd) removeRuleChainCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) removeRuleChainCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc) removeRuleChainCmd.Flags().String(targetTypeFlag, "", targetTypeDesc) _ = removeRuleChainCmd.MarkFlagRequired(targetTypeFlag) removeRuleChainCmd.Flags().String(targetNameFlag, "", targetNameDesc) _ = removeRuleChainCmd.MarkFlagRequired(targetNameFlag) removeRuleChainCmd.Flags().String(chainIDFlag, "", chainIDDesc) removeRuleChainCmd.Flags().String(chainNameFlag, ingress, chainNameFlagDesc) removeRuleChainCmd.Flags().Bool(commonflags.AllFlag, false, "Remove all chains for target") removeRuleChainCmd.MarkFlagsMutuallyExclusive(commonflags.AllFlag, chainIDFlag) } func initListRuleChainsCmd() { Cmd.AddCommand(listRuleChainsCmd) listRuleChainsCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) listRuleChainsCmd.Flags().StringP(targetTypeFlag, "t", "", targetTypeDesc) _ = listRuleChainsCmd.MarkFlagRequired(targetTypeFlag) listRuleChainsCmd.Flags().String(targetNameFlag, "", targetNameDesc) _ = listRuleChainsCmd.MarkFlagRequired(targetNameFlag) listRuleChainsCmd.Flags().Bool(jsonFlag, false, jsonFlagDesc) listRuleChainsCmd.Flags().String(chainNameFlag, ingress, chainNameFlagDesc) } func initSetAdminCmd() { Cmd.AddCommand(setAdminCmd) setAdminCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) setAdminCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc) setAdminCmd.Flags().String(addrAdminFlag, "", addrAdminDesc) _ = setAdminCmd.MarkFlagRequired(addrAdminFlag) } func initGetAdminCmd() { Cmd.AddCommand(getAdminCmd) getAdminCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) } func initListTargetsCmd() { Cmd.AddCommand(listTargetsCmd) listTargetsCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) listTargetsCmd.Flags().StringP(targetTypeFlag, "t", "", targetTypeDesc) _ = listTargetsCmd.MarkFlagRequired(targetTypeFlag) } func addRuleChain(cmd *cobra.Command, _ []string) { chain := parseChain(cmd) target := parseTarget(cmd) pci, ac := newPolicyContractInterface(cmd) h, vub, err := pci.AddMorphRuleChain(parseChainName(cmd), target, chain) cmd.Println("Waiting for transaction to persist...") _, err = ac.Wait(h, vub, err) commonCmd.ExitOnErr(cmd, "add rule chain error: %w", err) cmd.Println("Rule chain added successfully") } func removeRuleChain(cmd *cobra.Command, _ []string) { target := parseTarget(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) cmd.Println("Waiting for transaction to persist...") _, err = ac.Wait(h, vub, err) commonCmd.ExitOnErr(cmd, "remove rule chain error: %w", err) cmd.Println("Rule chain removed successfully") } } func listRuleChains(cmd *cobra.Command, _ []string) { target := parseTarget(cmd) pci, _ := newPolicyContractReaderInterface(cmd) chains, err := pci.ListMorphRuleChains(parseChainName(cmd), target) commonCmd.ExitOnErr(cmd, "list rule chains error: %w", err) if len(chains) == 0 { return } toJSON, _ := cmd.Flags().GetBool(jsonFlag) if toJSON { prettyJSONFormat(cmd, chains) } else { for _, c := range chains { apeCmd.PrintHumanReadableAPEChain(cmd, c) } } } func setAdmin(cmd *cobra.Command, _ []string) { s, _ := cmd.Flags().GetString(addrAdminFlag) addr, err := util.Uint160DecodeStringLE(s) commonCmd.ExitOnErr(cmd, "can't decode admin addr: %w", err) pci, ac := newPolicyContractInterface(cmd) h, vub, err := pci.SetAdmin(addr) cmd.Println("Waiting for transaction to persist...") _, err = ac.Wait(h, vub, err) commonCmd.ExitOnErr(cmd, "can't set admin: %w", err) cmd.Println("Admin set successfully") } func getAdmin(cmd *cobra.Command, _ []string) { pci, _ := newPolicyContractReaderInterface(cmd) addr, err := pci.GetAdmin() commonCmd.ExitOnErr(cmd, "unable to get admin: %w", err) cmd.Println(addr.StringLE()) } func listTargets(cmd *cobra.Command, _ []string) { typ, err := parseTargetType(cmd) commonCmd.ExitOnErr(cmd, "parse target type error: %w", err) pci, inv := newPolicyContractReaderInterface(cmd) sid, it, err := pci.ListTargetsIterator(typ) commonCmd.ExitOnErr(cmd, "list targets error: %w", err) items, err := inv.TraverseIterator(sid, &it, 0) for err == nil && len(items) != 0 { for _, item := range items { bts, err := item.TryBytes() commonCmd.ExitOnErr(cmd, "list targets error: %w", err) if len(bts) == 0 { cmd.Println("(no name)") } else { cmd.Println(string(bts)) } } items, err = inv.TraverseIterator(sid, &it, 0) commonCmd.ExitOnErr(cmd, "unable to list targets: %w", err) } } func prettyJSONFormat(cmd *cobra.Command, chains []*apechain.Chain) { wr := bytes.NewBufferString("") data, err := json.Marshal(chains) if err == nil { err = json.Indent(wr, data, "", " ") } commonCmd.ExitOnErr(cmd, "print rule chain error: %w", err) cmd.Println(wr) }