diff --git a/cmd/neofs-cli/internal/commonflags/expiration.go b/cmd/neofs-cli/internal/commonflags/expiration.go new file mode 100644 index 0000000000..b266b47c8c --- /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 e41539d94c..ca3210bce8 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 860cbce704..da50a7e4a2 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 3fad9bbe95..e6b16be352 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 ab0bb8fccd..45d81b2937 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 6665c45edf..ce82db0722 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 5b5d58654d..534bbffe05 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,