WIP: cli, adm: Improve add rule commands #990

Closed
aarifullin wants to merge 3 commits from aarifullin/frostfs-node:feat/cli_parse_json_any into master
2 changed files with 45 additions and 10 deletions
Showing only changes of commit 2ebb4d614e - Show all commits

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"
@ -14,6 +15,7 @@ import (
const ( const (
ruleFlag = "rule" ruleFlag = "rule"
pathFlag = "path"
) )
var addRuleCmd = &cobra.Command{ var addRuleCmd = &cobra.Command{
@ -23,15 +25,13 @@ var addRuleCmd = &cobra.Command{
Example: `control add-rule --endpoint ... -w ... --address ... --chain-id ChainID --cid ... --rule "allow Object.Get *" Example: `control add-rule --endpoint ... -w ... --address ... --chain-id ChainID --cid ... --rule "allow Object.Get *"
--rule "deny Object.Get EbxzAdz5LB4uqxuz6crWKAumBNtZyK2rKsqQP7TdZvwr/*" --rule "deny Object.Get EbxzAdz5LB4uqxuz6crWKAumBNtZyK2rKsqQP7TdZvwr/*"
--rule "deny:QuotaLimitReached Object.Put Object.Resource:Department=HR *" --rule "deny:QuotaLimitReached Object.Put Object.Resource:Department=HR *"
control add-rule --endpoint ... -w ... --address ... --chain-id ChainID --cid ... --path some_chain.json
`, `,
Run: addRule, Run: addRule,
} }
func addRule(cmd *cobra.Command, _ []string) { func parseChain(cmd *cobra.Command) *apechain.Chain {
pk := key.Get(cmd)
target := parseTarget(cmd)
chainID, _ := cmd.Flags().GetString(chainIDFlag) chainID, _ := cmd.Flags().GetString(chainIDFlag)
hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag) hexEncoded, _ := cmd.Flags().GetBool(chainIDHexFlag)
@ -43,20 +43,34 @@ func addRule(cmd *cobra.Command, _ []string) {
commonCmd.ExitOnErr(cmd, "can't decode chain ID as hex: %w", err) commonCmd.ExitOnErr(cmd, "can't decode chain ID as hex: %w", err)
} }
rule, _ := cmd.Flags().GetStringArray(ruleFlag)
chain := new(apechain.Chain) chain := new(apechain.Chain)
commonCmd.ExitOnErr(cmd, "parser error: %w", util.ParseAPEChain(chain, rule))
chain.ID = apechain.ID(chainIDRaw) chain.ID = apechain.ID(chainIDRaw)
serializedChain := chain.Bytes()
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:") cmd.Println("Parsed chain:")
util.PrintHumanReadableAPEChain(cmd, chain) util.PrintHumanReadableAPEChain(cmd, chain)
return chain
}
func addRule(cmd *cobra.Command, _ []string) {
pk := key.Get(cmd)
target := parseTarget(cmd)
parsed := parseChain(cmd)
req := &control.AddChainLocalOverrideRequest{ req := &control.AddChainLocalOverrideRequest{
Body: &control.AddChainLocalOverrideRequest_Body{ Body: &control.AddChainLocalOverrideRequest_Body{
Target: target, Target: target,
Chain: serializedChain, Chain: parsed.Bytes(),
}, },
} }
@ -81,9 +95,12 @@ func initControlAddRuleCmd() {
ff := addRuleCmd.Flags() ff := addRuleCmd.Flags()
ff.StringArray(ruleFlag, []string{}, "Rule statement") 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(chainIDFlag, "", "Assign ID to the parsed chain")
ff.String(targetNameFlag, "", targetNameDesc) ff.String(targetNameFlag, "", targetNameDesc)
ff.String(targetTypeFlag, "", targetTypeDesc) ff.String(targetTypeFlag, "", targetTypeDesc)
_ = addRuleCmd.MarkFlagRequired(targetTypeFlag) _ = addRuleCmd.MarkFlagRequired(targetTypeFlag)
ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex") ff.Bool(chainIDHexFlag, false, "Flag to parse chain ID as hex")
addRuleCmd.MarkFlagsMutuallyExclusive(pathFlag, ruleFlag)
} }

View file

@ -3,6 +3,7 @@ package util
import ( import (
"errors" "errors"
"fmt" "fmt"
"os"
"strconv" "strconv"
"strings" "strings"
@ -57,6 +58,23 @@ func PrintHumanReadableAPEChain(cmd *cobra.Command, chain *apechain.Chain) {
} }
} }
func ParseAPEChainBinaryOrJSON(chain *apechain.Chain, path string) error {
data, err := os.ReadFile(path)
if err != nil {
return fmt.Errorf("read file <%s>: %w", path, err)
}
err = chain.UnmarshalBinary(data)
if err != nil {
err = chain.UnmarshalJSON(data)
if err != nil {
return errors.New("invalid format")
}
}
return nil
}
// ParseAPEChain parses APE chain rules. // ParseAPEChain parses APE chain rules.
func ParseAPEChain(chain *apechain.Chain, rules []string) error { func ParseAPEChain(chain *apechain.Chain, rules []string) error {
if len(rules) == 0 { if len(rules) == 0 {