package control import ( "errors" "fmt" "strings" "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/modules/util" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/control" 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" "github.com/spf13/cobra" ) var listRulesCmd = &cobra.Command{ Use: "list-rules", Short: "List local overrides", Long: "List local APE overrides of the node", 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") ) 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) } return nil } func listRules(cmd *cobra.Command, _ []string) { pk := key.Get(cmd) target := parseTarget(cmd) req := &control.ListChainLocalOverridesRequest{ Body: &control.ListChainLocalOverridesRequest_Body{ Target: target, }, } signRequest(cmd, pk, req) cli := getClient(cmd, pk) var resp *control.ListChainLocalOverridesResponse var err error err = cli.ExecRaw(func(client *client.Client) error { resp, err = control.ListChainLocalOverrides(client, req) return err }) commonCmd.ExitOnErr(cmd, "rpc error: %w", err) verifyResponse(cmd, resp.GetSignature(), resp.GetBody()) chains := resp.GetBody().GetChains() if len(chains) == 0 { cmd.Printf("Local overrides are not defined for the %s.\n", strings.ToLower(target.GetType().String())) return } for _, c := range chains { var chain apechain.Chain commonCmd.ExitOnErr(cmd, "decode error: %w", chain.DecodeBytes(c)) util.PrintHumanReadableAPEChain(cmd, &chain) } } func initControlListRulesCmd() { initControlFlags(listRulesCmd) ff := listRulesCmd.Flags() ff.String(targetNameFlag, "", targetNameDesc) ff.String(targetTypeFlag, "", targetTypeDesc) _ = listRulesCmd.MarkFlagRequired(targetTypeFlag) }