[#1652] cli/container: Pre-check ACL extensibility in set-eacl

Container ACL in NeoFS can be extended only for container in which the
corresponding option is enabled. In previous implementation command
`set-eacl` could hang up on modifying eACL of the non-existent or
non-extendable container. To improve UX, there is a need to pre-check
the availability of `SETEACL` operation.

Add boolean `precheck` flag to `set-eacl` cmd which reads the container
before the actual transaction formation. If flag is set, command fails
on non-extendable container ACL.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2022-08-17 14:22:05 +04:00 committed by LeL
parent 17059b34ea
commit 491a908af1
2 changed files with 34 additions and 0 deletions

View file

@ -131,6 +131,21 @@ func GetContainer(prm GetContainerPrm) (res GetContainerRes, err error) {
return return
} }
// IsACLExtendable checks if ACL of the container referenced by the given identifier
// can be extended. Client connection MUST BE correctly established in advance.
func IsACLExtendable(c *client.Client, cnr cid.ID) (bool, error) {
var prm GetContainerPrm
prm.SetClient(c)
prm.SetContainer(cnr)
res, err := GetContainer(prm)
if err != nil {
return false, fmt.Errorf("get container from the NeoFS: %w", err)
}
return res.Container().BasicACL().Extendable(), nil
}
// DeleteContainerPrm groups parameters of DeleteContainerPrm operation. // DeleteContainerPrm groups parameters of DeleteContainerPrm operation.
type DeleteContainerPrm struct { type DeleteContainerPrm struct {
commonPrm commonPrm

View file

@ -2,6 +2,7 @@ package container
import ( import (
"bytes" "bytes"
"errors"
"time" "time"
internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client"
@ -14,6 +15,10 @@ import (
var eaclPathFrom string var eaclPathFrom string
var flagVarsSetEACL struct {
preCheck bool
}
var setExtendedACLCmd = &cobra.Command{ var setExtendedACLCmd = &cobra.Command{
Use: "set-eacl", Use: "set-eacl",
Short: "Set new extended ACL table for container", Short: "Set new extended ACL table for container",
@ -36,6 +41,19 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
pk := key.GetOrGenerate(cmd) pk := key.GetOrGenerate(cmd)
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC) cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
if flagVarsSetEACL.preCheck {
cmd.Println("Checking the ability to modify access rights in the container...")
extendable, err := internalclient.IsACLExtendable(cli, id)
common.ExitOnErr(cmd, "Extensibility check failure: %w", err)
if !extendable {
common.ExitOnErr(cmd, "", errors.New("container ACL is immutable"))
}
cmd.Println("ACL extension is enabled in the container, continue processing.")
}
var setEACLPrm internalclient.SetEACLPrm var setEACLPrm internalclient.SetEACLPrm
setEACLPrm.SetClient(cli) setEACLPrm.SetClient(cli)
setEACLPrm.SetTable(*eaclTable) setEACLPrm.SetTable(*eaclTable)
@ -88,4 +106,5 @@ func initContainerSetEACLCmd() {
flags.StringVar(&containerID, "cid", "", "container ID") flags.StringVar(&containerID, "cid", "", "container ID")
flags.StringVar(&eaclPathFrom, "table", "", "path to file with JSON or binary encoded EACL table") flags.StringVar(&eaclPathFrom, "table", "", "path to file with JSON or binary encoded EACL table")
flags.BoolVar(&containerAwait, "await", false, "block execution until EACL is persisted") flags.BoolVar(&containerAwait, "await", false, "block execution until EACL is persisted")
flags.BoolVar(&flagVarsSetEACL.preCheck, "precheck", false, "pre-check the extensibility of the container ACL")
} }