diff --git a/cmd/neofs-cli/internal/commonflags/expiration.go b/cmd/neofs-cli/internal/commonflags/expiration.go new file mode 100644 index 000000000..b266b47c8 --- /dev/null +++ b/cmd/neofs-cli/internal/commonflags/expiration.go @@ -0,0 +1,9 @@ +package commonflags + +const ( + // ExpireAt is a flag for setting last epoch of an object or a token. + ExpireAt = "expire-at" + // Lifetime is a flag for setting the lifetime of an object or a token, + // starting from the current epoch. + Lifetime = "lifetime" +) diff --git a/cmd/neofs-cli/modules/bearer/create.go b/cmd/neofs-cli/modules/bearer/create.go index e41539d94..ca3210bce 100644 --- a/cmd/neofs-cli/modules/bearer/create.go +++ b/cmd/neofs-cli/modules/bearer/create.go @@ -20,7 +20,6 @@ const ( eaclFlag = "eacl" issuedAtFlag = "issued-at" notValidBeforeFlag = "not-valid-before" - expireAtFlag = "expire-at" ownerFlag = "owner" outFlag = "out" jsonFlag = commonflags.JSON @@ -42,7 +41,7 @@ func init() { createCmd.Flags().StringP(eaclFlag, "e", "", "path to the extended ACL table") createCmd.Flags().StringP(issuedAtFlag, "i", "", "epoch to issue token at") createCmd.Flags().StringP(notValidBeforeFlag, "n", "", "not valid before epoch") - createCmd.Flags().StringP(expireAtFlag, "x", "", "expiration epoch") + createCmd.Flags().StringP(commonflags.ExpireAt, "x", "", "expiration epoch") createCmd.Flags().StringP(ownerFlag, "o", "", "token owner") createCmd.Flags().String(outFlag, "", "file to write token to") createCmd.Flags().Bool(jsonFlag, false, "output token in JSON") @@ -52,7 +51,7 @@ func init() { _ = cobra.MarkFlagRequired(createCmd.Flags(), issuedAtFlag) _ = cobra.MarkFlagRequired(createCmd.Flags(), notValidBeforeFlag) - _ = cobra.MarkFlagRequired(createCmd.Flags(), expireAtFlag) + _ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.ExpireAt) _ = cobra.MarkFlagRequired(createCmd.Flags(), ownerFlag) _ = cobra.MarkFlagRequired(createCmd.Flags(), outFlag) } @@ -62,7 +61,7 @@ func createToken(cmd *cobra.Command, _ []string) error { if err != nil { return err } - exp, expRelative, err := common.ParseEpoch(cmd, expireAtFlag) + exp, expRelative, err := common.ParseEpoch(cmd, commonflags.ExpireAt) if err != nil { return err } diff --git a/cmd/neofs-cli/modules/object/lock.go b/cmd/neofs-cli/modules/object/lock.go index 860cbce70..da50a7e4a 100644 --- a/cmd/neofs-cli/modules/object/lock.go +++ b/cmd/neofs-cli/modules/object/lock.go @@ -2,6 +2,7 @@ package object import ( "context" + "errors" "fmt" "strconv" "time" @@ -19,8 +20,6 @@ import ( "github.com/spf13/cobra" ) -const lockExpiresOnFlag = "expires-on" - // object lock command. var objectLockCmd = &cobra.Command{ Use: "lock CONTAINER OBJECT...", @@ -50,10 +49,13 @@ var objectLockCmd = &cobra.Command{ var lock objectSDK.Lock lock.WriteMembers(lockList) - exp, relative, err := common.ParseEpoch(cmd, lockExpiresOnFlag) - common.ExitOnErr(cmd, "Parsing expiration epoch: %w", err) + exp, _ := cmd.Flags().GetUint64(commonflags.ExpireAt) + lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime) + if exp == 0 && lifetime == 0 { // mutual exclusion is ensured by cobra + common.ExitOnErr(cmd, "", errors.New("either expiration epoch of a lifetime is required")) + } - if relative { + if lifetime != 0 { ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) defer cancel() @@ -94,6 +96,7 @@ func initCommandObjectLock() { commonflags.Init(objectLockCmd) commonflags.InitSession(objectLockCmd) - objectLockCmd.Flags().StringP(lockExpiresOnFlag, "e", "", "Lock expiration epoch") - _ = objectLockCmd.MarkFlagRequired(lockExpiresOnFlag) + objectLockCmd.Flags().Uint64P(commonflags.ExpireAt, "e", 0, "Lock expiration epoch") + objectLockCmd.Flags().Uint64(commonflags.Lifetime, 0, "Lock lifetime") + objectLockCmd.MarkFlagsMutuallyExclusive(commonflags.ExpireAt, commonflags.Lifetime) } diff --git a/cmd/neofs-cli/modules/object/put.go b/cmd/neofs-cli/modules/object/put.go index 3fad9bbe9..e6b16be35 100644 --- a/cmd/neofs-cli/modules/object/put.go +++ b/cmd/neofs-cli/modules/object/put.go @@ -22,7 +22,6 @@ import ( ) const ( - putExpiresOnFlag = "expires-on" noProgressFlag = "no-progress" notificationFlag = "notify" ) @@ -52,7 +51,7 @@ func initObjectPutCmd() { flags.String("attributes", "", "User attributes in form of Key1=Value1,Key2=Value2") flags.Bool("disable-filename", false, "Do not set well-known filename attribute") flags.Bool("disable-timestamp", false, "Do not set well-known timestamp attribute") - flags.Uint64VarP(&putExpiredOn, putExpiresOnFlag, "e", 0, "Last epoch in the life of the object") + flags.Uint64VarP(&putExpiredOn, commonflags.ExpireAt, "e", 0, "Last epoch in the life of the object") flags.Bool(noProgressFlag, false, "Do not show progress bar") flags.String(notificationFlag, "", "Object notification in the form of *epoch*:*topic*; '-' topic means using default") @@ -76,7 +75,7 @@ func putObject(cmd *cobra.Command, _ []string) { attrs, err := parseObjectAttrs(cmd) common.ExitOnErr(cmd, "can't parse object attributes: %w", err) - expiresOn, _ := cmd.Flags().GetUint64(putExpiresOnFlag) + expiresOn, _ := cmd.Flags().GetUint64(commonflags.ExpireAt) if expiresOn > 0 { var expAttrFound bool expAttrValue := strconv.FormatUint(expiresOn, 10) diff --git a/cmd/neofs-cli/modules/session/create.go b/cmd/neofs-cli/modules/session/create.go index ab0bb8fcc..45d81b293 100644 --- a/cmd/neofs-cli/modules/session/create.go +++ b/cmd/neofs-cli/modules/session/create.go @@ -17,9 +17,8 @@ import ( ) const ( - lifetimeFlag = "lifetime" - outFlag = "out" - jsonFlag = commonflags.JSON + outFlag = "out" + jsonFlag = commonflags.JSON ) const defaultLifetime = 10 @@ -35,14 +34,14 @@ var createCmd = &cobra.Command{ } func init() { - createCmd.Flags().Uint64P(lifetimeFlag, "l", defaultLifetime, "number of epochs for token to stay valid") + createCmd.Flags().Uint64P(commonflags.Lifetime, "l", defaultLifetime, "number of epochs for token to stay valid") createCmd.Flags().StringP(commonflags.WalletPath, commonflags.WalletPathShorthand, commonflags.WalletPathDefault, commonflags.WalletPathUsage) createCmd.Flags().StringP(commonflags.Account, commonflags.AccountShorthand, commonflags.AccountDefault, commonflags.AccountUsage) createCmd.Flags().String(outFlag, "", "file to write session token to") createCmd.Flags().Bool(jsonFlag, false, "output token in JSON") createCmd.Flags().StringP(commonflags.RPC, commonflags.RPCShorthand, commonflags.RPCDefault, commonflags.RPCUsage) - _ = cobra.MarkFlagRequired(createCmd.Flags(), lifetimeFlag) + _ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.Lifetime) _ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.WalletPath) _ = cobra.MarkFlagRequired(createCmd.Flags(), outFlag) _ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.RPC) @@ -63,7 +62,7 @@ func createSession(cmd *cobra.Command, _ []string) error { } lifetime := uint64(defaultLifetime) - if lfArg, _ := cmd.Flags().GetUint64(lifetimeFlag); lfArg != 0 { + if lfArg, _ := cmd.Flags().GetUint64(commonflags.Lifetime); lfArg != 0 { lifetime = lfArg } diff --git a/cmd/neofs-cli/modules/storagegroup/put.go b/cmd/neofs-cli/modules/storagegroup/put.go index 6665c45ed..ce82db072 100644 --- a/cmd/neofs-cli/modules/storagegroup/put.go +++ b/cmd/neofs-cli/modules/storagegroup/put.go @@ -5,7 +5,6 @@ import ( "crypto/ecdsa" "errors" "fmt" - "strconv" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" @@ -45,8 +44,8 @@ func initSGPutCmd() { flags.StringSliceVarP(&sgMembers, sgMembersFlag, "m", nil, "ID list of storage group members") _ = sgPutCmd.MarkFlagRequired(sgMembersFlag) - flags.Uint64(sgLifetimeFlag, 0, "Storage group lifetime in epochs") - _ = sgPutCmd.MarkFlagRequired(sgLifetimeFlag) + flags.Uint64(commonflags.Lifetime, 0, "Storage group lifetime in epochs") + _ = sgPutCmd.MarkFlagRequired(commonflags.Lifetime) } func putSG(cmd *cobra.Command, _ []string) { @@ -58,15 +57,11 @@ func putSG(cmd *cobra.Command, _ []string) { var cnr cid.ID readCID(cmd, &cnr) - lifetimeStr := cmd.Flag(sgLifetimeFlag).Value.String() - lifetime, err := strconv.ParseUint(lifetimeStr, 10, 64) - common.ExitOnErr(cmd, "could not parse lifetime: %w", err) - members := make([]oid.ID, len(sgMembers)) uniqueFilter := make(map[oid.ID]struct{}, len(sgMembers)) for i := range sgMembers { - err = members[i].DecodeString(sgMembers[i]) + err := members[i].DecodeString(sgMembers[i]) common.ExitOnErr(cmd, "could not parse object ID: %w", err) if _, alreadyExists := uniqueFilter[members[i]]; alreadyExists { @@ -108,6 +103,7 @@ func putSG(cmd *cobra.Command, _ []string) { ni, err := internalclient.NetworkInfo(netInfoPrm) common.ExitOnErr(cmd, "can't fetch network info: %w", err) + lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime) sg.SetExpirationEpoch(ni.NetworkInfo().CurrentEpoch() + lifetime) obj := object.New() diff --git a/cmd/neofs-cli/modules/storagegroup/root.go b/cmd/neofs-cli/modules/storagegroup/root.go index 5b5d58654..534bbffe0 100644 --- a/cmd/neofs-cli/modules/storagegroup/root.go +++ b/cmd/neofs-cli/modules/storagegroup/root.go @@ -25,8 +25,6 @@ const ( cidFlag = "cid" ) -const sgLifetimeFlag = "lifetime" - func init() { storageGroupChildCommands := []*cobra.Command{ sgPutCmd,