From 68eb68f59a10284025ae345407f486f63a7b620a Mon Sep 17 00:00:00 2001 From: Airat Arifullin Date: Tue, 18 Jun 2024 18:29:56 +0300 Subject: [PATCH] [#1189] cli: Make util subcommand convert eACL to APE chains Signed-off-by: Airat Arifullin --- cmd/frostfs-cli/modules/util/convert_eacl.go | 33 ++++++++--- internal/ape/converter.go | 60 +++++++++++++++----- 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/cmd/frostfs-cli/modules/util/convert_eacl.go b/cmd/frostfs-cli/modules/util/convert_eacl.go index 774d500bc..d588ba35d 100644 --- a/cmd/frostfs-cli/modules/util/convert_eacl.go +++ b/cmd/frostfs-cli/modules/util/convert_eacl.go @@ -6,9 +6,17 @@ 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" + "git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain" "github.com/spf13/cobra" ) +const ( + fromFlagStr = "from" + toFlagStr = "to" + apeFlagStr = "ape" +) + var convertEACLCmd = &cobra.Command{ Use: "eacl", Short: "Convert representation of extended ACL table", @@ -18,24 +26,35 @@ var convertEACLCmd = &cobra.Command{ func initConvertEACLCmd() { flags := convertEACLCmd.Flags() - flags.String("from", "", "File with JSON or binary encoded extended ACL table") - _ = convertEACLCmd.MarkFlagFilename("from") - _ = convertEACLCmd.MarkFlagRequired("from") + flags.String(fromFlagStr, "", "File with JSON or binary encoded extended ACL table") + _ = convertEACLCmd.MarkFlagFilename(fromFlagStr) + _ = convertEACLCmd.MarkFlagRequired(fromFlagStr) - flags.String("to", "", "File to dump extended ACL table (default: binary encoded)") + flags.String(toFlagStr, "", "File to dump extended ACL table (default: binary encoded)") flags.Bool(commonflags.JSON, false, "Dump extended ACL table in JSON encoding") + + flags.Bool(apeFlagStr, false, "Dump converted eACL table to APE chain format") + + convertEACLCmd.MarkFlagsMutuallyExclusive(apeFlagStr, commonflags.JSON) } func convertEACLTable(cmd *cobra.Command, _ []string) { - pathFrom := cmd.Flag("from").Value.String() - to := cmd.Flag("to").Value.String() + pathFrom := cmd.Flag(fromFlagStr).Value.String() + to := cmd.Flag(toFlagStr).Value.String() jsonFlag, _ := cmd.Flags().GetBool(commonflags.JSON) + apeFlag, _ := cmd.Flags().GetBool(apeFlagStr) table := common.ReadEACL(cmd, pathFrom) var data []byte var err error - if jsonFlag || len(to) == 0 { + + if apeFlag { + var ch *chain.Chain + ch, err = apeutil.ConvertEACLToAPE(table) + commonCmd.ExitOnErr(cmd, "convert eACL table to APE chain error: %w", err) + data = ch.Bytes() + } else if jsonFlag || len(to) == 0 { data, err = table.MarshalJSON() commonCmd.ExitOnErr(cmd, "can't JSON encode extended ACL table: %w", err) } else { diff --git a/internal/ape/converter.go b/internal/ape/converter.go index a0cc138d1..eb80e7ded 100644 --- a/internal/ape/converter.go +++ b/internal/ape/converter.go @@ -69,6 +69,50 @@ func ConvertEACLToAPE(eaclTable *eacl.Table) (*apechain.Chain, error) { return res, nil } +func apeRoleConds(role eacl.Role) (res []apechain.Condition) { + switch role { + case eacl.RoleSystem: + res = append(res, + apechain.Condition{ + Op: apechain.CondStringEquals, + Kind: apechain.KindRequest, + Key: nativeschema.PropertyKeyActorRole, + Value: nativeschema.PropertyValueContainerRoleContainer, + }, + ) + res = append(res, + apechain.Condition{ + Op: apechain.CondStringEquals, + Kind: apechain.KindRequest, + Key: nativeschema.PropertyKeyActorRole, + Value: nativeschema.PropertyValueContainerRoleIR, + }, + ) + case eacl.RoleOthers: + res = append(res, + apechain.Condition{ + Op: apechain.CondStringEquals, + Kind: apechain.KindRequest, + Key: nativeschema.PropertyKeyActorRole, + Value: nativeschema.PropertyValueContainerRoleOthers, + }, + ) + case eacl.RoleUser: + res = append(res, + apechain.Condition{ + Op: apechain.CondStringEquals, + Kind: apechain.KindRequest, + Key: nativeschema.PropertyKeyActorRole, + Value: nativeschema.PropertyValueContainerRoleOwner, + }, + ) + case eacl.RoleUnknown: + // such condition has no effect + default: + } + return +} + func appendTargetsOnly(source []apechain.Rule, st apechain.Status, act apechain.Actions, res apechain.Resources, targets []eacl.Target) []apechain.Rule { // see https://git.frostfs.info/TrueCloudLab/frostfs-sdk-go/src/commit/ab75edd70939564421936d207ef80d6c1398b51b/eacl/validator.go#L101 // role OR public key must be equal @@ -79,13 +123,7 @@ func appendTargetsOnly(source []apechain.Rule, st apechain.Status, act apechain. Any: true, } for _, target := range targets { - var roleCondition apechain.Condition - roleCondition.Kind = apechain.KindRequest - roleCondition.Key = nativeschema.PropertyKeyActorRole - roleCondition.Value = target.Role().String() - roleCondition.Op = apechain.CondStringEquals - rule.Condition = append(rule.Condition, roleCondition) - + rule.Condition = append(rule.Condition, apeRoleConds(target.Role())...) for _, binKey := range target.BinaryKeys() { var pubKeyCondition apechain.Condition pubKeyCondition.Kind = apechain.KindRequest @@ -111,13 +149,7 @@ func appendTargetsAndFilters(source []apechain.Rule, st apechain.Status, act ape Actions: act, Resources: res, } - var roleCondition apechain.Condition - roleCondition.Kind = apechain.KindRequest - roleCondition.Key = nativeschema.PropertyKeyActorRole - roleCondition.Value = target.Role().String() - roleCondition.Op = apechain.CondStringEquals - - rule.Condition = append(rule.Condition, roleCondition) + rule.Condition = append(rule.Condition, apeRoleConds(target.Role())...) rule.Condition, err = appendFilters(rule.Condition, filters) if err != nil { return nil, err