package container import ( "bytes" "errors" "time" internalclient "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "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" "github.com/spf13/cobra" ) var flagVarsSetEACL struct { noPreCheck bool srcPath string } var setExtendedACLCmd = &cobra.Command{ Use: "set-eacl", Short: "Set new extended ACL table for container", Long: `Set new extended ACL table for container. Container ID in EACL table will be substituted with ID from the CLI.`, Run: func(cmd *cobra.Command, args []string) { id := parseContainerID(cmd) eaclTable := common.ReadEACL(cmd, flagVarsSetEACL.srcPath) tok := getSession(cmd) eaclTable.SetCID(id) pk := key.GetOrGenerate(cmd) cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC) if !flagVarsSetEACL.noPreCheck { cmd.Println("Checking the ability to modify access rights in the container...") extendable, err := internalclient.IsACLExtendable(cmd.Context(), cli, id) commonCmd.ExitOnErr(cmd, "Extensibility check failure: %w", err) if !extendable { commonCmd.ExitOnErr(cmd, "", errors.New("container ACL is immutable")) } cmd.Println("ACL extension is enabled in the container, continue processing.") } var setEACLPrm internalclient.SetEACLPrm setEACLPrm.SetClient(cli) setEACLPrm.SetTable(*eaclTable) if tok != nil { setEACLPrm.WithinSession(*tok) } _, err := internalclient.SetEACL(cmd.Context(), setEACLPrm) commonCmd.ExitOnErr(cmd, "rpc error: %w", err) if containerAwait { exp, err := eaclTable.Marshal() commonCmd.ExitOnErr(cmd, "broken EACL table: %w", err) cmd.Println("awaiting...") var getEACLPrm internalclient.EACLPrm getEACLPrm.SetClient(cli) getEACLPrm.SetContainer(id) for i := 0; i < awaitTimeout; i++ { time.Sleep(1 * time.Second) res, err := internalclient.EACL(cmd.Context(), getEACLPrm) if err == nil { // compare binary values because EACL could have been set already table := res.EACL() got, err := table.Marshal() if err != nil { continue } if bytes.Equal(exp, got) { cmd.Println("EACL has been persisted on sidechain") return } } } commonCmd.ExitOnErr(cmd, "", errSetEACLTimeout) } }, } func initContainerSetEACLCmd() { commonflags.Init(setExtendedACLCmd) flags := setExtendedACLCmd.Flags() flags.StringVar(&containerID, commonflags.CIDFlag, "", commonflags.CIDFlagUsage) flags.StringVar(&flagVarsSetEACL.srcPath, "table", "", "path to file with JSON or binary encoded EACL table") flags.BoolVar(&containerAwait, "await", false, "block execution until EACL is persisted") flags.BoolVar(&flagVarsSetEACL.noPreCheck, "no-precheck", false, "do not pre-check the extensibility of the container ACL") }