Refactor APE-related commands #1501
|
@ -5,8 +5,8 @@ import (
|
|||
"encoding/json"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||
parseutil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
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"
|
||||
|
@ -14,26 +14,10 @@ import (
|
|||
)
|
||||
|
||||
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)"
|
||||
jsonFlag = "json"
|
||||
jsonFlagDesc = "Output rule chains in JSON format"
|
||||
addrAdminFlag = "addr"
|
||||
addrAdminDesc = "The address of the admins wallet"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -101,17 +85,17 @@ func initAddRuleChainCmd() {
|
|||
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(apeCmd.TargetTypeFlag, "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = addRuleChainCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
addRuleChainCmd.Flags().String(apeCmd.TargetNameFlag, "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = addRuleChainCmd.MarkFlagRequired(apeCmd.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)
|
||||
addRuleChainCmd.Flags().String(apeCmd.ChainIDFlag, "", apeCmd.ChainIDFlagDesc)
|
||||
_ = addRuleChainCmd.MarkFlagRequired(apeCmd.ChainIDFlag)
|
||||
addRuleChainCmd.Flags().StringArray(apeCmd.RuleFlag, []string{}, apeCmd.RuleFlagDesc)
|
||||
addRuleChainCmd.Flags().String(apeCmd.PathFlag, "", apeCmd.PathFlagDesc)
|
||||
addRuleChainCmd.Flags().String(apeCmd.ChainNameFlag, apeCmd.Ingress, apeCmd.ChainNameFlagDesc)
|
||||
addRuleChainCmd.MarkFlagsMutuallyExclusive(apeCmd.RuleFlag, apeCmd.PathFlag)
|
||||
}
|
||||
|
||||
func initRemoveRuleChainCmd() {
|
||||
|
@ -120,26 +104,25 @@ func initRemoveRuleChainCmd() {
|
|||
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().String(apeCmd.TargetTypeFlag, "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = removeRuleChainCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
removeRuleChainCmd.Flags().String(apeCmd.TargetNameFlag, "", apeCmd.TargetNameFlagDesc)
|
||||
_ = removeRuleChainCmd.MarkFlagRequired(apeCmd.TargetNameFlag)
|
||||
removeRuleChainCmd.Flags().String(apeCmd.ChainIDFlag, "", apeCmd.ChainIDFlagDesc)
|
||||
removeRuleChainCmd.Flags().String(apeCmd.ChainNameFlag, apeCmd.Ingress, apeCmd.ChainNameFlagDesc)
|
||||
removeRuleChainCmd.Flags().Bool(commonflags.AllFlag, false, "Remove all chains for target")
|
||||
removeRuleChainCmd.MarkFlagsMutuallyExclusive(commonflags.AllFlag, chainIDFlag)
|
||||
removeRuleChainCmd.MarkFlagsMutuallyExclusive(commonflags.AllFlag, apeCmd.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().StringP(apeCmd.TargetTypeFlag, "t", "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = listRuleChainsCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
listRuleChainsCmd.Flags().String(apeCmd.TargetNameFlag, "", apeCmd.TargetNameFlagDesc)
|
||||
listRuleChainsCmd.Flags().Bool(jsonFlag, false, jsonFlagDesc)
|
||||
listRuleChainsCmd.Flags().String(chainNameFlag, ingress, chainNameFlagDesc)
|
||||
listRuleChainsCmd.Flags().String(apeCmd.ChainNameFlag, apeCmd.Ingress, apeCmd.ChainNameFlagDesc)
|
||||
}
|
||||
|
||||
func initSetAdminCmd() {
|
||||
|
@ -161,15 +144,15 @@ func initListTargetsCmd() {
|
|||
Cmd.AddCommand(listTargetsCmd)
|
||||
|
||||
listTargetsCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc)
|
||||
listTargetsCmd.Flags().StringP(targetTypeFlag, "t", "", targetTypeDesc)
|
||||
_ = listTargetsCmd.MarkFlagRequired(targetTypeFlag)
|
||||
listTargetsCmd.Flags().StringP(apeCmd.TargetTypeFlag, "t", "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = listTargetsCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
}
|
||||
|
||||
func addRuleChain(cmd *cobra.Command, _ []string) {
|
||||
chain := parseChain(cmd)
|
||||
chain := apeCmd.ParseChain(cmd)
|
||||
target := parseTarget(cmd)
|
||||
pci, ac := newPolicyContractInterface(cmd)
|
||||
h, vub, err := pci.AddMorphRuleChain(parseChainName(cmd), target, chain)
|
||||
h, vub, err := pci.AddMorphRuleChain(apeCmd.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)
|
||||
|
@ -181,14 +164,14 @@ func removeRuleChain(cmd *cobra.Command, _ []string) {
|
|||
pci, ac := newPolicyContractInterface(cmd)
|
||||
removeAll, _ := cmd.Flags().GetBool(commonflags.AllFlag)
|
||||
if removeAll {
|
||||
h, vub, err := pci.RemoveMorphRuleChainsByTarget(parseChainName(cmd), target)
|
||||
h, vub, err := pci.RemoveMorphRuleChainsByTarget(apeCmd.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)
|
||||
chainID := apeCmd.ParseChainID(cmd)
|
||||
h, vub, err := pci.RemoveMorphRuleChain(apeCmd.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)
|
||||
|
@ -199,7 +182,7 @@ func removeRuleChain(cmd *cobra.Command, _ []string) {
|
|||
func listRuleChains(cmd *cobra.Command, _ []string) {
|
||||
target := parseTarget(cmd)
|
||||
pci, _ := newPolicyContractReaderInterface(cmd)
|
||||
chains, err := pci.ListMorphRuleChains(parseChainName(cmd), target)
|
||||
chains, err := pci.ListMorphRuleChains(apeCmd.ParseChainName(cmd), target)
|
||||
commonCmd.ExitOnErr(cmd, "list rule chains error: %w", err)
|
||||
if len(chains) == 0 {
|
||||
return
|
||||
|
@ -210,7 +193,7 @@ func listRuleChains(cmd *cobra.Command, _ []string) {
|
|||
prettyJSONFormat(cmd, chains)
|
||||
} else {
|
||||
for _, c := range chains {
|
||||
parseutil.PrintHumanReadableAPEChain(cmd, c)
|
||||
apeCmd.PrintHumanReadableAPEChain(cmd, c)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -235,8 +218,7 @@ func getAdmin(cmd *cobra.Command, _ []string) {
|
|||
}
|
||||
|
||||
func listTargets(cmd *cobra.Command, _ []string) {
|
||||
typ, err := parseTargetType(cmd)
|
||||
commonCmd.ExitOnErr(cmd, "parse target type error: %w", err)
|
||||
typ := apeCmd.ParseTargetType(cmd)
|
||||
pci, inv := newPolicyContractReaderInterface(cmd)
|
||||
|
||||
sid, it, err := pci.ListTargetsIterator(typ)
|
||||
|
|
|
@ -2,13 +2,12 @@ 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"
|
||||
apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
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"
|
||||
|
@ -18,90 +17,29 @@ import (
|
|||
"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")
|
||||
)
|
||||
var errUnknownTargetType = errors.New("unknown target type")
|
||||
|
||||
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)
|
||||
typ := apeCmd.ParseTargetType(cmd)
|
||||
name, _ := cmd.Flags().GetString(apeCmd.TargetNameFlag)
|
||||
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
|
||||
case policyengine.Namespace:
|
||||
if name == "root" {
|
||||
name = ""
|
||||
}
|
||||
return policyengine.NamespaceTarget(name)
|
||||
case policyengine.Container:
|
||||
var cnr cid.ID
|
||||
commonCmd.ExitOnErr(cmd, "can't decode container ID: %w", cnr.DecodeString(name))
|
||||
return policyengine.ContainerTarget(name)
|
||||
case policyengine.User:
|
||||
return policyengine.UserTarget(name)
|
||||
case policyengine.Group:
|
||||
return policyengine.GroupTarget(name)
|
||||
default:
|
||||
commonCmd.ExitOnErr(cmd, "read target type error: %w", errUnknownTargetType)
|
||||
}
|
||||
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
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// invokerAdapter adapats invoker.Invoker to ContractStorageInvoker interface.
|
||||
|
|
|
@ -1,44 +1,19 @@
|
|||
package apemanager
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
apeSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
|
||||
client_sdk "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
chainIDFlag = "chain-id"
|
||||
chainIDHexFlag = "chain-id-hex"
|
||||
ruleFlag = "rule"
|
||||
pathFlag = "path"
|
||||
)
|
||||
|
||||
const (
|
||||
targetNameFlag = "target-name"
|
||||
targetNameDesc = "Resource name in APE resource name format"
|
||||
targetTypeFlag = "target-type"
|
||||
targetTypeDesc = "Resource type(container/namespace)"
|
||||
)
|
||||
|
||||
const (
|
||||
namespaceTarget = "namespace"
|
||||
containerTarget = "container"
|
||||
userTarget = "user"
|
||||
groupTarget = "group"
|
||||
)
|
||||
|
||||
var errUnknownTargetType = errors.New("unknown target type")
|
||||
|
||||
var addCmd = &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add rule chain for a target",
|
||||
|
@ -49,55 +24,28 @@ var addCmd = &cobra.Command{
|
|||
}
|
||||
|
||||
func parseTarget(cmd *cobra.Command) (ct apeSDK.ChainTarget) {
|
||||
typ, _ := cmd.Flags().GetString(targetTypeFlag)
|
||||
name, _ := cmd.Flags().GetString(targetNameFlag)
|
||||
t := apeCmd.ParseTarget(cmd)
|
||||
|
||||
ct.Name = name
|
||||
ct.Name = t.Name
|
||||
|
||||
switch typ {
|
||||
case namespaceTarget:
|
||||
switch t.Type {
|
||||
case engine.Namespace:
|
||||
ct.TargetType = apeSDK.TargetTypeNamespace
|
||||
case containerTarget:
|
||||
var cnr cid.ID
|
||||
commonCmd.ExitOnErr(cmd, "can't decode container ID: %w", cnr.DecodeString(name))
|
||||
case engine.Container:
|
||||
ct.TargetType = apeSDK.TargetTypeContainer
|
||||
case userTarget:
|
||||
case engine.User:
|
||||
ct.TargetType = apeSDK.TargetTypeUser
|
||||
case groupTarget:
|
||||
case engine.Group:
|
||||
ct.TargetType = apeSDK.TargetTypeGroup
|
||||
default:
|
||||
commonCmd.ExitOnErr(cmd, "read target type error: %w", errUnknownTargetType)
|
||||
commonCmd.ExitOnErr(cmd, "conversion error: %w", fmt.Errorf("unknown type '%c'", t.Type))
|
||||
}
|
||||
return ct
|
||||
}
|
||||
|
||||
func parseChain(cmd *cobra.Command) apeSDK.Chain {
|
||||
chainID, _ := cmd.Flags().GetString(chainIDFlag)
|
||||
hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag)
|
||||
|
||||
chainIDRaw := []byte(chainID)
|
||||
|
||||
if hexEncoded {
|
||||
var err error
|
||||
chainIDRaw, err = hex.DecodeString(chainID)
|
||||
commonCmd.ExitOnErr(cmd, "can't decode chain ID as hex: %w", err)
|
||||
}
|
||||
|
||||
chain := new(apechain.Chain)
|
||||
chain.ID = apechain.ID(chainIDRaw)
|
||||
|
||||
if rules, _ := cmd.Flags().GetStringArray(ruleFlag); len(rules) > 0 {
|
||||
commonCmd.ExitOnErr(cmd, "parser error: %w", util.ParseAPEChain(chain, rules))
|
||||
} else if encPath, _ := cmd.Flags().GetString(pathFlag); encPath != "" {
|
||||
commonCmd.ExitOnErr(cmd, "decode binary or json error: %w", util.ParseAPEChainBinaryOrJSON(chain, encPath))
|
||||
} else {
|
||||
commonCmd.ExitOnErr(cmd, "parser error: %w", errors.New("rule is not passed"))
|
||||
}
|
||||
|
||||
cmd.Println("Parsed chain:")
|
||||
util.PrintHumanReadableAPEChain(cmd, chain)
|
||||
|
||||
serialized := chain.Bytes()
|
||||
c := apeCmd.ParseChain(cmd)
|
||||
serialized := c.Bytes()
|
||||
return apeSDK.Chain{
|
||||
Raw: serialized,
|
||||
}
|
||||
|
@ -126,13 +74,13 @@ func initAddCmd() {
|
|||
commonflags.Init(addCmd)
|
||||
|
||||
ff := addCmd.Flags()
|
||||
ff.StringArray(ruleFlag, []string{}, "Rule statement")
|
||||
ff.String(pathFlag, "", "Path to encoded chain in JSON or binary format")
|
||||
ff.String(chainIDFlag, "", "Assign ID to the parsed chain")
|
||||
ff.String(targetNameFlag, "", targetNameDesc)
|
||||
ff.String(targetTypeFlag, "", targetTypeDesc)
|
||||
_ = addCmd.MarkFlagRequired(targetTypeFlag)
|
||||
ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
ff.StringArray(apeCmd.RuleFlag, []string{}, apeCmd.RuleFlagDesc)
|
||||
ff.String(apeCmd.PathFlag, "", apeCmd.PathFlagDesc)
|
||||
ff.String(apeCmd.ChainIDFlag, "", apeCmd.ChainIDFlagDesc)
|
||||
ff.String(apeCmd.TargetNameFlag, "", apeCmd.TargetNameFlagDesc)
|
||||
ff.String(apeCmd.TargetTypeFlag, "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = addCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
ff.Bool(apeCmd.ChainIDHexFlag, false, apeCmd.ChainIDHexFlagDesc)
|
||||
|
||||
addCmd.MarkFlagsMutuallyExclusive(pathFlag, ruleFlag)
|
||||
addCmd.MarkFlagsMutuallyExclusive(apeCmd.PathFlag, apeCmd.RuleFlag)
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
apeutil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
client_sdk "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/spf13/cobra"
|
||||
|
@ -35,7 +35,7 @@ func list(cmd *cobra.Command, _ []string) {
|
|||
for _, respChain := range resp.Chains {
|
||||
var chain apechain.Chain
|
||||
commonCmd.ExitOnErr(cmd, "decode error: %w", chain.DecodeBytes(respChain.Raw))
|
||||
apeutil.PrintHumanReadableAPEChain(cmd, &chain)
|
||||
apeCmd.PrintHumanReadableAPEChain(cmd, &chain)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,7 +43,7 @@ func initListCmd() {
|
|||
commonflags.Init(listCmd)
|
||||
|
||||
ff := listCmd.Flags()
|
||||
ff.String(targetNameFlag, "", targetNameDesc)
|
||||
ff.String(targetTypeFlag, "", targetTypeDesc)
|
||||
_ = listCmd.MarkFlagRequired(targetTypeFlag)
|
||||
ff.String(apeCmd.TargetNameFlag, "", apeCmd.TargetNameFlagDesc)
|
||||
ff.String(apeCmd.TargetTypeFlag, "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = listCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
}
|
||||
|
|
|
@ -1,29 +1,23 @@
|
|||
package apemanager
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
client_sdk "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
errEmptyChainID = errors.New("chain id cannot be empty")
|
||||
|
||||
removeCmd = &cobra.Command{
|
||||
Use: "remove",
|
||||
Short: "Remove rule chain for a target",
|
||||
Run: remove,
|
||||
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
|
||||
commonflags.Bind(cmd)
|
||||
},
|
||||
}
|
||||
)
|
||||
var removeCmd = &cobra.Command{
|
||||
Use: "remove",
|
||||
Short: "Remove rule chain for a target",
|
||||
Run: remove,
|
||||
PersistentPreRun: func(cmd *cobra.Command, _ []string) {
|
||||
commonflags.Bind(cmd)
|
||||
},
|
||||
}
|
||||
|
||||
func remove(cmd *cobra.Command, _ []string) {
|
||||
target := parseTarget(cmd)
|
||||
|
@ -31,19 +25,9 @@ func remove(cmd *cobra.Command, _ []string) {
|
|||
key := key.Get(cmd)
|
||||
cli := internalclient.GetSDKClientByFlag(cmd, key, commonflags.RPC)
|
||||
|
||||
chainID, _ := cmd.Flags().GetString(chainIDFlag)
|
||||
if chainID == "" {
|
||||
commonCmd.ExitOnErr(cmd, "read chain id error: %w", errEmptyChainID)
|
||||
}
|
||||
chainID := apeCmd.ParseChainID(cmd)
|
||||
chainIDRaw := []byte(chainID)
|
||||
|
||||
hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag)
|
||||
if hexEncoded {
|
||||
var err error
|
||||
chainIDRaw, err = hex.DecodeString(chainID)
|
||||
commonCmd.ExitOnErr(cmd, "can't decode chain ID as hex: %w", err)
|
||||
}
|
||||
|
||||
_, err := cli.APEManagerRemoveChain(cmd.Context(), client_sdk.PrmAPEManagerRemoveChain{
|
||||
ChainTarget: target,
|
||||
ChainID: chainIDRaw,
|
||||
|
@ -58,9 +42,10 @@ func initRemoveCmd() {
|
|||
commonflags.Init(removeCmd)
|
||||
|
||||
ff := removeCmd.Flags()
|
||||
ff.String(targetNameFlag, "", targetNameDesc)
|
||||
ff.String(targetTypeFlag, "", targetTypeDesc)
|
||||
_ = removeCmd.MarkFlagRequired(targetTypeFlag)
|
||||
ff.String(chainIDFlag, "", "Chain id")
|
||||
ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
ff.String(apeCmd.TargetNameFlag, "", apeCmd.TargetNameFlagDesc)
|
||||
ff.String(apeCmd.TargetTypeFlag, "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = removeCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
ff.String(apeCmd.ChainIDFlag, "", apeCmd.ChainIDFlagDesc)
|
||||
_ = removeCmd.MarkFlagRequired(apeCmd.ChainIDFlag)
|
||||
ff.Bool(apeCmd.ChainIDHexFlag, false, apeCmd.ChainIDHexFlagDesc)
|
||||
}
|
||||
|
|
|
@ -1,31 +1,20 @@
|
|||
package bearer
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
parseutil "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
apeSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/ape"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||
cidSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
errChainIDCannotBeEmpty = errors.New("chain id cannot be empty")
|
||||
errRuleIsNotParsed = errors.New("rule is not passed")
|
||||
)
|
||||
|
||||
const (
|
||||
chainIDFlag = "chain-id"
|
||||
chainIDHexFlag = "chain-id-hex"
|
||||
ruleFlag = "rule"
|
||||
pathFlag = "path"
|
||||
outputFlag = "output"
|
||||
outputFlag = "output"
|
||||
)
|
||||
|
||||
var generateAPEOverrideCmd = &cobra.Command{
|
||||
|
@ -40,7 +29,7 @@ Generated APE override can be dumped to a file in JSON format that is passed to
|
|||
}
|
||||
|
||||
func genereateAPEOverride(cmd *cobra.Command, _ []string) {
|
||||
c := parseChain(cmd)
|
||||
c := apeCmd.ParseChain(cmd)
|
||||
|
||||
targetCID, _ := cmd.Flags().GetString(commonflags.CIDFlag)
|
||||
var cid cidSDK.ID
|
||||
|
@ -77,39 +66,11 @@ func init() {
|
|||
ff.StringP(commonflags.CIDFlag, "", "", "Target container ID.")
|
||||
_ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.CIDFlag)
|
||||
|
||||
ff.StringArray(ruleFlag, []string{}, "Rule statement")
|
||||
ff.String(pathFlag, "", "Path to encoded chain in JSON or binary format")
|
||||
ff.String(chainIDFlag, "", "Assign ID to the parsed chain")
|
||||
ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
ff.StringArray(apeCmd.RuleFlag, []string{}, "Rule statement")
|
||||
ff.String(apeCmd.PathFlag, "", "Path to encoded chain in JSON or binary format")
|
||||
ff.String(apeCmd.ChainIDFlag, "", "Assign ID to the parsed chain")
|
||||
ff.Bool(apeCmd.ChainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
|
||||
ff.String(outputFlag, "", "Output path to dump result JSON-encoded APE override")
|
||||
_ = cobra.MarkFlagFilename(createCmd.Flags(), outputFlag)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
|
|
@ -1,23 +1,14 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
ruleFlag = "rule"
|
||||
pathFlag = "path"
|
||||
)
|
||||
|
||||
var addRuleCmd = &cobra.Command{
|
||||
Use: "add-rule",
|
||||
Short: "Add local override",
|
||||
|
@ -31,41 +22,12 @@ control add-rule --endpoint ... -w ... --address ... --chain-id ChainID --cid ..
|
|||
Run: addRule,
|
||||
}
|
||||
|
||||
func parseChain(cmd *cobra.Command) *apechain.Chain {
|
||||
chainID, _ := cmd.Flags().GetString(chainIDFlag)
|
||||
hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag)
|
||||
|
||||
chainIDRaw := []byte(chainID)
|
||||
|
||||
if hexEncoded {
|
||||
var err error
|
||||
chainIDRaw, err = hex.DecodeString(chainID)
|
||||
commonCmd.ExitOnErr(cmd, "can't decode chain ID as hex: %w", err)
|
||||
}
|
||||
|
||||
chain := new(apechain.Chain)
|
||||
chain.ID = apechain.ID(chainIDRaw)
|
||||
|
||||
if rules, _ := cmd.Flags().GetStringArray(ruleFlag); len(rules) > 0 {
|
||||
commonCmd.ExitOnErr(cmd, "parser error: %w", util.ParseAPEChain(chain, rules))
|
||||
} else if encPath, _ := cmd.Flags().GetString(pathFlag); encPath != "" {
|
||||
commonCmd.ExitOnErr(cmd, "decode binary or json error: %w", util.ParseAPEChainBinaryOrJSON(chain, encPath))
|
||||
} else {
|
||||
commonCmd.ExitOnErr(cmd, "parser error", errors.New("rule is not passed"))
|
||||
}
|
||||
|
||||
cmd.Println("Parsed chain:")
|
||||
util.PrintHumanReadableAPEChain(cmd, chain)
|
||||
|
||||
return chain
|
||||
}
|
||||
|
||||
func addRule(cmd *cobra.Command, _ []string) {
|
||||
pk := key.Get(cmd)
|
||||
|
||||
target := parseTarget(cmd)
|
||||
|
||||
parsed := parseChain(cmd)
|
||||
parsed := apeCmd.ParseChain(cmd)
|
||||
|
||||
req := &control.AddChainLocalOverrideRequest{
|
||||
Body: &control.AddChainLocalOverrideRequest_Body{
|
||||
|
@ -94,13 +56,13 @@ func initControlAddRuleCmd() {
|
|||
initControlFlags(addRuleCmd)
|
||||
|
||||
ff := addRuleCmd.Flags()
|
||||
ff.StringArray(ruleFlag, []string{}, "Rule statement")
|
||||
ff.String(pathFlag, "", "Path to encoded chain in JSON or binary format")
|
||||
ff.String(chainIDFlag, "", "Assign ID to the parsed chain")
|
||||
ff.String(targetNameFlag, "", targetNameDesc)
|
||||
ff.String(targetTypeFlag, "", targetTypeDesc)
|
||||
_ = addRuleCmd.MarkFlagRequired(targetTypeFlag)
|
||||
ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
ff.StringArray(apeCmd.RuleFlag, []string{}, "Rule statement")
|
||||
ff.String(apeCmd.PathFlag, "", "Path to encoded chain in JSON or binary format")
|
||||
ff.String(apeCmd.ChainIDFlag, "", "Assign ID to the parsed chain")
|
||||
ff.String(apeCmd.TargetNameFlag, "", apeCmd.TargetNameFlagDesc)
|
||||
ff.String(apeCmd.TargetTypeFlag, "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = addRuleCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
ff.Bool(apeCmd.ChainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
|
||||
addRuleCmd.MarkFlagsMutuallyExclusive(pathFlag, ruleFlag)
|
||||
addRuleCmd.MarkFlagsMutuallyExclusive(apeCmd.PathFlag, apeCmd.RuleFlag)
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@ import (
|
|||
"encoding/hex"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apecmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
|
@ -24,8 +24,8 @@ func getRule(cmd *cobra.Command, _ []string) {
|
|||
|
||||
target := parseTarget(cmd)
|
||||
|
||||
chainID, _ := cmd.Flags().GetString(chainIDFlag)
|
||||
hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag)
|
||||
chainID, _ := cmd.Flags().GetString(apecmd.ChainIDFlag)
|
||||
hexEncoded, _ := cmd.Flags().GetBool(apecmd.ChainIDHexFlag)
|
||||
|
||||
if hexEncoded {
|
||||
chainIDBytes, err := hex.DecodeString(chainID)
|
||||
|
@ -56,16 +56,16 @@ func getRule(cmd *cobra.Command, _ []string) {
|
|||
|
||||
var chain apechain.Chain
|
||||
commonCmd.ExitOnErr(cmd, "decode error: %w", chain.DecodeBytes(resp.GetBody().GetChain()))
|
||||
util.PrintHumanReadableAPEChain(cmd, &chain)
|
||||
apecmd.PrintHumanReadableAPEChain(cmd, &chain)
|
||||
}
|
||||
|
||||
func initControGetRuleCmd() {
|
||||
initControlFlags(getRuleCmd)
|
||||
|
||||
ff := getRuleCmd.Flags()
|
||||
ff.String(targetNameFlag, "", targetNameDesc)
|
||||
ff.String(targetTypeFlag, "", targetTypeDesc)
|
||||
_ = getRuleCmd.MarkFlagRequired(targetTypeFlag)
|
||||
ff.String(chainIDFlag, "", "Chain id")
|
||||
ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
ff.String(apecmd.TargetNameFlag, "", apecmd.TargetNameFlagDesc)
|
||||
ff.String(apecmd.TargetTypeFlag, "", apecmd.TargetTypeFlagDesc)
|
||||
_ = getRuleCmd.MarkFlagRequired(apecmd.TargetTypeFlag)
|
||||
ff.String(apecmd.ChainIDFlag, "", "Chain id")
|
||||
ff.Bool(apecmd.ChainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
}
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
package control
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/modules/util"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
policyengine "git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
|
@ -23,65 +21,25 @@ var listRulesCmd = &cobra.Command{
|
|||
Run: listRules,
|
||||
}
|
||||
|
||||
const (
|
||||
defaultNamespace = "root"
|
||||
namespaceTarget = "namespace"
|
||||
containerTarget = "container"
|
||||
userTarget = "user"
|
||||
groupTarget = "group"
|
||||
)
|
||||
|
||||
const (
|
||||
targetNameFlag = "target-name"
|
||||
targetNameDesc = "Resource name in APE resource name format"
|
||||
targetTypeFlag = "target-type"
|
||||
targetTypeDesc = "Resource type(container/namespace)"
|
||||
)
|
||||
|
||||
var (
|
||||
errSettingDefaultValueWasDeclined = errors.New("setting default value was declined")
|
||||
errUnknownTargetType = errors.New("unknown target type")
|
||||
)
|
||||
var engineToControlSvcType = map[policyengine.TargetType]control.ChainTarget_TargetType{
|
||||
policyengine.Namespace: control.ChainTarget_NAMESPACE,
|
||||
policyengine.Container: control.ChainTarget_CONTAINER,
|
||||
policyengine.User: control.ChainTarget_USER,
|
||||
policyengine.Group: control.ChainTarget_GROUP,
|
||||
}
|
||||
|
||||
func parseTarget(cmd *cobra.Command) *control.ChainTarget {
|
||||
typ, _ := cmd.Flags().GetString(targetTypeFlag)
|
||||
name, _ := cmd.Flags().GetString(targetNameFlag)
|
||||
switch typ {
|
||||
case namespaceTarget:
|
||||
if name == "" {
|
||||
ln, err := input.ReadLine(fmt.Sprintf("Target name is not set. Confirm to use %s namespace (n|Y)> ", defaultNamespace))
|
||||
commonCmd.ExitOnErr(cmd, "read line error: %w", err)
|
||||
ln = strings.ToLower(ln)
|
||||
if len(ln) > 0 && (ln[0] == 'n') {
|
||||
commonCmd.ExitOnErr(cmd, "read namespace error: %w", errSettingDefaultValueWasDeclined)
|
||||
}
|
||||
name = defaultNamespace
|
||||
}
|
||||
return &control.ChainTarget{
|
||||
Name: name,
|
||||
Type: control.ChainTarget_NAMESPACE,
|
||||
}
|
||||
case containerTarget:
|
||||
var cnr cid.ID
|
||||
commonCmd.ExitOnErr(cmd, "can't decode container ID: %w", cnr.DecodeString(name))
|
||||
return &control.ChainTarget{
|
||||
Name: name,
|
||||
Type: control.ChainTarget_CONTAINER,
|
||||
}
|
||||
case userTarget:
|
||||
return &control.ChainTarget{
|
||||
Name: name,
|
||||
Type: control.ChainTarget_USER,
|
||||
}
|
||||
case groupTarget:
|
||||
return &control.ChainTarget{
|
||||
Name: name,
|
||||
Type: control.ChainTarget_GROUP,
|
||||
}
|
||||
default:
|
||||
commonCmd.ExitOnErr(cmd, "read target type error: %w", errUnknownTargetType)
|
||||
target := apeCmd.ParseTarget(cmd)
|
||||
|
||||
typ, ok := engineToControlSvcType[target.Type]
|
||||
if !ok {
|
||||
fyrchik marked this conversation as resolved
|
||||
commonCmd.ExitOnErr(cmd, "%w", fmt.Errorf("unknown type '%c", target.Type))
|
||||
}
|
||||
|
||||
return &control.ChainTarget{
|
||||
Name: target.Name,
|
||||
Type: typ,
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func listRules(cmd *cobra.Command, _ []string) {
|
||||
|
@ -117,7 +75,7 @@ func listRules(cmd *cobra.Command, _ []string) {
|
|||
for _, c := range chains {
|
||||
var chain apechain.Chain
|
||||
commonCmd.ExitOnErr(cmd, "decode error: %w", chain.DecodeBytes(c))
|
||||
util.PrintHumanReadableAPEChain(cmd, &chain)
|
||||
apeCmd.PrintHumanReadableAPEChain(cmd, &chain)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -125,7 +83,7 @@ func initControlListRulesCmd() {
|
|||
initControlFlags(listRulesCmd)
|
||||
|
||||
ff := listRulesCmd.Flags()
|
||||
ff.String(targetNameFlag, "", targetNameDesc)
|
||||
ff.String(targetTypeFlag, "", targetTypeDesc)
|
||||
_ = listRulesCmd.MarkFlagRequired(targetTypeFlag)
|
||||
ff.String(apeCmd.TargetNameFlag, "", apeCmd.TargetNameFlagDesc)
|
||||
ff.String(apeCmd.TargetTypeFlag, "", apeCmd.TargetTypeFlagDesc)
|
||||
_ = listRulesCmd.MarkFlagRequired(apeCmd.TargetTypeFlag)
|
||||
}
|
||||
|
|
|
@ -2,26 +2,20 @@ package control
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"text/tabwriter"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"github.com/spf13/cobra"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
const (
|
||||
chainNameFlag = "chain-name"
|
||||
chainNameFlagUsage = "Chain name(ingress|s3)"
|
||||
)
|
||||
|
||||
var listTargetsCmd = &cobra.Command{
|
||||
Use: "list-targets",
|
||||
Short: "List local targets",
|
||||
|
@ -32,15 +26,11 @@ var listTargetsCmd = &cobra.Command{
|
|||
func listTargets(cmd *cobra.Command, _ []string) {
|
||||
pk := key.Get(cmd)
|
||||
|
||||
var cnr cid.ID
|
||||
chainName, _ := cmd.Flags().GetString(chainNameFlag)
|
||||
|
||||
rawCID := make([]byte, sha256.Size)
|
||||
cnr.Encode(rawCID)
|
||||
chainName := apeCmd.ParseChainName(cmd)
|
||||
|
||||
req := &control.ListTargetsLocalOverridesRequest{
|
||||
Body: &control.ListTargetsLocalOverridesRequest_Body{
|
||||
ChainName: chainName,
|
||||
ChainName: string(chainName),
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -82,7 +72,7 @@ func initControlListTargetsCmd() {
|
|||
initControlFlags(listTargetsCmd)
|
||||
|
||||
ff := listTargetsCmd.Flags()
|
||||
ff.String(chainNameFlag, "", chainNameFlagUsage)
|
||||
ff.String(apeCmd.ChainNameFlag, "", apeCmd.ChainNameFlagDesc)
|
||||
|
||||
_ = cobra.MarkFlagRequired(ff, chainNameFlag)
|
||||
_ = cobra.MarkFlagRequired(ff, apeCmd.ChainNameFlag)
|
||||
}
|
||||
|
|
|
@ -6,17 +6,12 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apecmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common/ape"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/api/rpc/client"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
chainIDFlag = "chain-id"
|
||||
chainIDHexFlag = "chain-id-hex"
|
||||
allFlag = "all"
|
||||
)
|
||||
|
||||
var (
|
||||
errEmptyChainID = errors.New("chain id cannot be empty")
|
||||
|
||||
|
@ -30,8 +25,8 @@ var (
|
|||
|
||||
func removeRule(cmd *cobra.Command, _ []string) {
|
||||
pk := key.Get(cmd)
|
||||
hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag)
|
||||
removeAll, _ := cmd.Flags().GetBool(allFlag)
|
||||
hexEncoded, _ := cmd.Flags().GetBool(apecmd.ChainIDHexFlag)
|
||||
removeAll, _ := cmd.Flags().GetBool(apecmd.AllFlag)
|
||||
if removeAll {
|
||||
req := &control.RemoveChainLocalOverridesByTargetRequest{
|
||||
Body: &control.RemoveChainLocalOverridesByTargetRequest_Body{
|
||||
|
@ -52,7 +47,7 @@ func removeRule(cmd *cobra.Command, _ []string) {
|
|||
return
|
||||
}
|
||||
|
||||
chainID, _ := cmd.Flags().GetString(chainIDFlag)
|
||||
chainID, _ := cmd.Flags().GetString(apecmd.ChainIDFlag)
|
||||
if chainID == "" {
|
||||
commonCmd.ExitOnErr(cmd, "read chain id error: %w", errEmptyChainID)
|
||||
}
|
||||
|
@ -92,11 +87,11 @@ func initControlRemoveRuleCmd() {
|
|||
initControlFlags(removeRuleCmd)
|
||||
|
||||
ff := removeRuleCmd.Flags()
|
||||
ff.String(targetNameFlag, "", targetNameDesc)
|
||||
ff.String(targetTypeFlag, "", targetTypeDesc)
|
||||
_ = removeRuleCmd.MarkFlagRequired(targetTypeFlag)
|
||||
ff.String(chainIDFlag, "", "Chain id")
|
||||
ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex")
|
||||
ff.Bool(allFlag, false, "Remove all chains")
|
||||
removeRuleCmd.MarkFlagsMutuallyExclusive(allFlag, chainIDFlag)
|
||||
ff.String(apecmd.TargetNameFlag, "", apecmd.TargetNameFlagDesc)
|
||||
ff.String(apecmd.TargetTypeFlag, "", apecmd.TargetTypeFlagDesc)
|
||||
_ = removeRuleCmd.MarkFlagRequired(apecmd.TargetTypeFlag)
|
||||
ff.String(apecmd.ChainIDFlag, "", apecmd.ChainIDFlagDesc)
|
||||
ff.Bool(apecmd.ChainIDHexFlag, false, apecmd.ChainIDHexFlagDesc)
|
||||
ff.Bool(apecmd.AllFlag, false, "Remove all chains")
|
||||
removeRuleCmd.MarkFlagsMutuallyExclusive(apecmd.AllFlag, apecmd.ChainIDFlag)
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags"
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeutil "git.frostfs.info/TrueCloudLab/frostfs-node/internal/ape"
|
||||
apeutil "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/ape"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
|
167
cmd/internal/common/ape/commands.go
Normal file
|
@ -0,0 +1,167 @@
|
|||
package ape
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common"
|
||||
apeutil "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/ape"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||
"github.com/nspcc-dev/neo-go/cli/input"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultNamespace = "root"
|
||||
namespaceTarget = "namespace"
|
||||
containerTarget = "container"
|
||||
userTarget = "user"
|
||||
groupTarget = "group"
|
||||
|
||||
Ingress = "ingress"
|
||||
S3 = "s3"
|
||||
)
|
||||
|
||||
var mChainName = map[string]apechain.Name{
|
||||
Ingress: apechain.Ingress,
|
||||
S3: apechain.S3,
|
||||
}
|
||||
|
||||
var (
|
||||
errSettingDefaultValueWasDeclined = errors.New("setting default value was declined")
|
||||
errUnknownTargetType = errors.New("unknown target type")
|
||||
errUnsupportedChainName = errors.New("unsupported chain name")
|
||||
)
|
||||
|
||||
// PrintHumanReadableAPEChain print APE chain rules.
|
||||
func PrintHumanReadableAPEChain(cmd *cobra.Command, chain *apechain.Chain) {
|
||||
cmd.Println("Chain ID: " + string(chain.ID))
|
||||
cmd.Printf(" HEX: %x\n", chain.ID)
|
||||
cmd.Println("Rules:")
|
||||
for _, rule := range chain.Rules {
|
||||
cmd.Println("\n\tStatus: " + rule.Status.String())
|
||||
cmd.Println("\tAny: " + strconv.FormatBool(rule.Any))
|
||||
cmd.Println("\tConditions:")
|
||||
for _, c := range rule.Condition {
|
||||
var ot string
|
||||
switch c.Kind {
|
||||
case apechain.KindResource:
|
||||
ot = "Resource"
|
||||
case apechain.KindRequest:
|
||||
ot = "Request"
|
||||
default:
|
||||
panic("unknown object type")
|
||||
}
|
||||
cmd.Println(fmt.Sprintf("\t\t%s %s %s %s", ot, c.Key, c.Op, c.Value))
|
||||
}
|
||||
cmd.Println("\tActions:\tInverted:" + strconv.FormatBool(rule.Actions.Inverted))
|
||||
for _, name := range rule.Actions.Names {
|
||||
cmd.Println("\t\t" + name)
|
||||
}
|
||||
cmd.Println("\tResources:\tInverted:" + strconv.FormatBool(rule.Resources.Inverted))
|
||||
for _, name := range rule.Resources.Names {
|
||||
cmd.Println("\t\t" + name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ParseTarget handles target parsing of an APE chain.
|
||||
func ParseTarget(cmd *cobra.Command) engine.Target {
|
||||
typ := ParseTargetType(cmd)
|
||||
name, _ := cmd.Flags().GetString(TargetNameFlag)
|
||||
switch typ {
|
||||
fyrchik
commented
This looks like a bad idea: you have taken two different functions and created a new one with a bool flag which switches the behaviour. The amount of different code between these functions is comparable to their size. And they were not that long before. This looks like a bad idea: you have taken two different functions and created a new one with a bool flag which switches the behaviour. The amount of different code between these functions is comparable to their size. And they were not that long before.
Let's leave them as they were.
aarifullin
commented
Now I am wondering: it's fine, if we omit this flag but leave prompt anyway. Prompt is used in Now I am wondering: it's fine, if we omit this flag but leave prompt anyway. Prompt is used in `frostfs-cli`. `frostfs-adm` also correctly receives and processes `--target-name root`, but ignores empty input (`--target-name ""` is taken for fine input). I think that won't be wrong if `frostfs-adm` will also output this prompt. AFAIR, autotests use only `--target-name root`
|
||||
case engine.Namespace:
|
||||
if name == "" {
|
||||
ln, err := input.ReadLine(fmt.Sprintf("Target name is not set. Confirm to use %s namespace (n|Y)> ", defaultNamespace))
|
||||
commonCmd.ExitOnErr(cmd, "read line error: %w", err)
|
||||
ln = strings.ToLower(ln)
|
||||
if len(ln) > 0 && (ln[0] == 'n') {
|
||||
commonCmd.ExitOnErr(cmd, "read namespace error: %w", errSettingDefaultValueWasDeclined)
|
||||
}
|
||||
name = defaultNamespace
|
||||
}
|
||||
return engine.NamespaceTarget(name)
|
||||
case engine.Container:
|
||||
var cnr cid.ID
|
||||
commonCmd.ExitOnErr(cmd, "can't decode container ID: %w", cnr.DecodeString(name))
|
||||
return engine.ContainerTarget(name)
|
||||
case engine.User:
|
||||
return engine.UserTarget(name)
|
||||
case engine.Group:
|
||||
return engine.GroupTarget(name)
|
||||
default:
|
||||
commonCmd.ExitOnErr(cmd, "read target type error: %w", errUnknownTargetType)
|
||||
}
|
||||
panic("unreachable")
|
||||
fyrchik marked this conversation as resolved
Outdated
fyrchik
commented
Here too. I would also move it to Here too. I would also move it to `default` to communicate that the switch is exhaustive.
aarifullin
commented
fixed fixed
|
||||
}
|
||||
|
||||
// ParseTargetType handles target type parsing of an APE chain.
|
||||
func ParseTargetType(cmd *cobra.Command) engine.TargetType {
|
||||
typ, _ := cmd.Flags().GetString(TargetTypeFlag)
|
||||
switch typ {
|
||||
case namespaceTarget:
|
||||
return engine.Namespace
|
||||
case containerTarget:
|
||||
return engine.Container
|
||||
case userTarget:
|
||||
return engine.User
|
||||
case groupTarget:
|
||||
return engine.Group
|
||||
default:
|
||||
commonCmd.ExitOnErr(cmd, "parse target type error: %w", errUnknownTargetType)
|
||||
}
|
||||
fyrchik marked this conversation as resolved
fyrchik
commented
I think it is more idiomatic to panic with I think it is more idiomatic to panic with `panic("unreachable")`.
aarifullin
commented
fixed fixed
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
// ParseChainID handles the parsing of APE-chain identifier.
|
||||
// For some subcommands, chain ID is optional as an input parameter and should be generated by
|
||||
// the service instead.
|
||||
fyrchik
commented
This is very dirty: you use some obscure cobra internal in order to be able to use a single function from 2 places. Just copy the function, no problem. This is very dirty: you use some obscure cobra internal in order to be able to use a single function from 2 places. Just copy the function, no problem.
And again, it questions the benefit of this refactoring.
aarifullin
commented
Okay. Also, as flags are already marked Required, we don't need this extra checks at all - user will receive error from subcommands anyway > Just copy the function, no problem
Okay. Also, as flags are already marked **Required**, we don't need this extra checks at all - user will receive error from subcommands anyway
|
||||
func ParseChainID(cmd *cobra.Command) (id apechain.ID) {
|
||||
chainID, _ := cmd.Flags().GetString(ChainIDFlag)
|
||||
id = apechain.ID(chainID)
|
||||
|
||||
hexEncoded, _ := cmd.Flags().GetBool(ChainIDHexFlag)
|
||||
if !hexEncoded {
|
||||
return
|
||||
}
|
||||
|
||||
chainIDRaw, err := hex.DecodeString(chainID)
|
||||
commonCmd.ExitOnErr(cmd, "can't decode chain ID as hex: %w", err)
|
||||
id = apechain.ID(chainIDRaw)
|
||||
return
|
||||
}
|
||||
|
||||
// ParseChain parses an APE chain which can be provided either as a rule statement
|
||||
// or loaded from a binary/JSON file path.
|
||||
func ParseChain(cmd *cobra.Command) *apechain.Chain {
|
||||
chain := new(apechain.Chain)
|
||||
chain.ID = ParseChainID(cmd)
|
||||
|
||||
if rules, _ := cmd.Flags().GetStringArray(RuleFlag); len(rules) > 0 {
|
||||
commonCmd.ExitOnErr(cmd, "parser error: %w", apeutil.ParseAPEChain(chain, rules))
|
||||
} else if encPath, _ := cmd.Flags().GetString(PathFlag); encPath != "" {
|
||||
commonCmd.ExitOnErr(cmd, "decode binary or json error: %w", apeutil.ParseAPEChainBinaryOrJSON(chain, encPath))
|
||||
} else {
|
||||
commonCmd.ExitOnErr(cmd, "parser error", errors.New("rule is not passed"))
|
||||
}
|
||||
|
||||
cmd.Println("Parsed chain:")
|
||||
PrintHumanReadableAPEChain(cmd, chain)
|
||||
|
||||
return chain
|
||||
}
|
||||
|
||||
// ParseChainName parses chain name: the place in the request lifecycle where policy is applied.
|
||||
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
|
||||
}
|
19
cmd/internal/common/ape/flags.go
Normal file
|
@ -0,0 +1,19 @@
|
|||
package ape
|
||||
|
||||
const (
|
||||
RuleFlag = "rule"
|
||||
RuleFlagDesc = "Rule statement"
|
||||
PathFlag = "path"
|
||||
PathFlagDesc = "Path to encoded chain in JSON or binary format"
|
||||
TargetNameFlag = "target-name"
|
||||
TargetNameFlagDesc = "Resource name in APE resource name format"
|
||||
TargetTypeFlag = "target-type"
|
||||
TargetTypeFlagDesc = "Resource type(container/namespace)"
|
||||
ChainIDFlag = "chain-id"
|
||||
ChainIDFlagDesc = "Chain id"
|
||||
ChainIDHexFlag = "chain-id-hex"
|
||||
ChainIDHexFlagDesc = "Flag to parse chain ID as hex"
|
||||
ChainNameFlag = "chain-name"
|
||||
ChainNameFlagDesc = "Chain name(ingress|s3)"
|
||||
AllFlag = "all"
|
||||
)
|
|
@ -1,16 +1,14 @@
|
|||
package util
|
||||
package ape
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
apechain "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
nativeschema "git.frostfs.info/TrueCloudLab/policy-engine/schema/native"
|
||||
"github.com/flynn-archive/go-shlex"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -27,38 +25,6 @@ var (
|
|||
errFailedToParseAllAny = errors.New("any/all is not parsed")
|
||||
)
|
||||
|
||||
// PrintHumanReadableAPEChain print APE chain rules.
|
||||
func PrintHumanReadableAPEChain(cmd *cobra.Command, chain *apechain.Chain) {
|
||||
cmd.Println("Chain ID: " + string(chain.ID))
|
||||
cmd.Printf(" HEX: %x\n", chain.ID)
|
||||
cmd.Println("Rules:")
|
||||
for _, rule := range chain.Rules {
|
||||
cmd.Println("\n\tStatus: " + rule.Status.String())
|
||||
cmd.Println("\tAny: " + strconv.FormatBool(rule.Any))
|
||||
cmd.Println("\tConditions:")
|
||||
for _, c := range rule.Condition {
|
||||
var ot string
|
||||
switch c.Kind {
|
||||
case apechain.KindResource:
|
||||
ot = "Resource"
|
||||
case apechain.KindRequest:
|
||||
ot = "Request"
|
||||
default:
|
||||
panic("unknown object type")
|
||||
}
|
||||
cmd.Println(fmt.Sprintf("\t\t%s %s %s %s", ot, c.Key, c.Op, c.Value))
|
||||
}
|
||||
cmd.Println("\tActions:\tInverted:" + strconv.FormatBool(rule.Actions.Inverted))
|
||||
for _, name := range rule.Actions.Names {
|
||||
cmd.Println("\t\t" + name)
|
||||
}
|
||||
cmd.Println("\tResources:\tInverted:" + strconv.FormatBool(rule.Resources.Inverted))
|
||||
for _, name := range rule.Resources.Names {
|
||||
cmd.Println("\t\t" + name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func ParseAPEChainBinaryOrJSON(chain *apechain.Chain, path string) error {
|
||||
data, err := os.ReadFile(path)
|
||||
if err != nil {
|
|
@ -1,4 +1,4 @@
|
|||
package util
|
||||
package ape
|
||||
|
||||
import (
|
||||
"fmt"
|
ParseTargetType
exists if target doesn't exist, so this condition is always false, right?I assume that we can add a new target in
policy-engine
parsable byapeCmd.ParseTarget
but not known for control service yet. In this case, we take this for unknown target