Skip to content

Commit

Permalink
cli: unify usage of expired-at flag and lifetime flag
Browse files Browse the repository at this point in the history
Refactor CLI usage to standardize the expired-at flag and lifetime flag. This change is aimed at preventing confusion during flag interpretation and empowering users.

Closes #1574.

Signed-off-by: Ekaterina Pavlova <ekt@morphbits.io>
  • Loading branch information
AliceInHunterland committed Aug 23, 2023
1 parent e979a59 commit aa6d58f
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 30 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ minor release, the component will be purged, so be prepared (see `Updating` sect
- SN's version and capacity is announced via the attributes automatically but can be overwritten explicitly (#2455, #602)
- `peapod` command for `neofs-lens` (#2507)
- New CLI exit code for awaiting timeout (#2380)
- To `neofs-cli` commands: `bearer create`, `object put` added `--lifetime` flag; to `neofs-cli` commands `session create`, `storagegroup put` added `--expired-at` flag (#1574)

### Fixed
- `neo-go` RPC connection loss handling (#1337)
Expand Down
13 changes: 11 additions & 2 deletions cmd/neofs-cli/modules/bearer/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package bearer
import (
"context"
"encoding/json"
"errors"
"fmt"
"os"
"time"
Expand Down Expand Up @@ -46,27 +47,32 @@ func init() {
createCmd.Flags().String(outFlag, "", "File to write token to")
createCmd.Flags().Bool(jsonFlag, false, "Output token in JSON")
createCmd.Flags().StringP(commonflags.RPC, commonflags.RPCShorthand, commonflags.RPCDefault, commonflags.RPCUsage)
createCmd.Flags().Uint64P(commonflags.Lifetime, "l", 0, "Number of epochs for token to stay valid")

_ = cobra.MarkFlagFilename(createCmd.Flags(), eaclFlag)

_ = cobra.MarkFlagRequired(createCmd.Flags(), issuedAtFlag)
_ = cobra.MarkFlagRequired(createCmd.Flags(), notValidBeforeFlag)
_ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.ExpireAt)
_ = cobra.MarkFlagRequired(createCmd.Flags(), ownerFlag)
_ = cobra.MarkFlagRequired(createCmd.Flags(), outFlag)
createCmd.MarkFlagsMutuallyExclusive(commonflags.ExpireAt, commonflags.Lifetime)
}

func createToken(cmd *cobra.Command, _ []string) {
iat, iatRelative, err := common.ParseEpoch(cmd, issuedAtFlag)
common.ExitOnErr(cmd, "can't parse --"+issuedAtFlag+" flag: %w", err)

lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime)
exp, expRelative, err := common.ParseEpoch(cmd, commonflags.ExpireAt)
common.ExitOnErr(cmd, "can't parse --"+commonflags.ExpireAt+" flag: %w", err)
if exp == 0 && lifetime == 0 {
common.ExitOnErr(cmd, "", errors.New("expiration epoch or lifetime period is required"))
}

nvb, nvbRelative, err := common.ParseEpoch(cmd, notValidBeforeFlag)
common.ExitOnErr(cmd, "can't parse --"+notValidBeforeFlag+" flag: %w", err)

if iatRelative || expRelative || nvbRelative {
if iatRelative || expRelative || nvbRelative || lifetime != 0 {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()

Expand All @@ -83,6 +89,9 @@ func createToken(cmd *cobra.Command, _ []string) {
if nvbRelative {
nvb += currEpoch
}
if lifetime != 0 {
exp = currEpoch + lifetime
}
}
if exp < nvb {
common.ExitOnErr(cmd, "",
Expand Down
2 changes: 1 addition & 1 deletion cmd/neofs-cli/modules/object/lock.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ var objectLockCmd = &cobra.Command{
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"))
common.ExitOnErr(cmd, "", errors.New("expiration epoch or lifetime period is required"))
}

if lifetime != 0 {
Expand Down
11 changes: 11 additions & 0 deletions cmd/neofs-cli/modules/object/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,12 @@ func initObjectPutCmd() {
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, commonflags.ExpireAt, "e", 0, "The last active epoch in the life of the object")
flags.Uint64P(commonflags.Lifetime, "l", 0, "Number of epochs for object to stay valid")
flags.Bool(noProgressFlag, false, "Do not show progress bar")

flags.String(notificationFlag, "", "Object notification in the form of *epoch*:*topic*; '-' topic means using default")
flags.Bool(binaryFlag, false, "Deserialize object structure from given file.")
objectPutCmd.MarkFlagsMutuallyExclusive(commonflags.ExpireAt, commonflags.Lifetime)
}

func putObject(cmd *cobra.Command, _ []string) {
Expand Down Expand Up @@ -99,6 +101,15 @@ func putObject(cmd *cobra.Command, _ []string) {
common.ExitOnErr(cmd, "can't parse object attributes: %w", err)

expiresOn, _ := cmd.Flags().GetUint64(commonflags.ExpireAt)
lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime)
if lifetime > 0 {
endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
currEpoch, err := internalclient.GetCurrentEpoch(ctx, endpoint)
common.ExitOnErr(cmd, "Request current epoch: %w", err)

expiresOn = currEpoch + lifetime
}

if expiresOn > 0 {
var expAttrFound bool
expAttrValue := strconv.FormatUint(expiresOn, 10)
Expand Down
7 changes: 5 additions & 2 deletions cmd/neofs-cli/modules/object/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -278,8 +278,11 @@ func OpenSessionViaClient(ctx context.Context, cmd *cobra.Command, dst SessionPr
const sessionLifetime = 10 // in NeoFS epochs

common.PrintVerbose(cmd, "Opening remote session with the node...")

err := sessionCli.CreateSession(ctx, &tok, cli, *key, sessionLifetime)
endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
currEpoch, err := internal.GetCurrentEpoch(ctx, endpoint)
common.ExitOnErr(cmd, "can't fetch current epoch: %w", err)
exp := currEpoch + sessionLifetime
err = sessionCli.CreateSession(ctx, &tok, cli, *key, exp)
common.ExitOnErr(cmd, "open remote session: %w", err)

common.PrintVerbose(cmd, "Session successfully opened.")
Expand Down
37 changes: 19 additions & 18 deletions cmd/neofs-cli/modules/session/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package session
import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"os"

Expand Down Expand Up @@ -43,10 +44,12 @@ func init() {
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)
createCmd.Flags().Uint64P(commonflags.ExpireAt, "e", 0, "The last active epoch for token to stay valid")

_ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.WalletPath)
_ = cobra.MarkFlagRequired(createCmd.Flags(), outFlag)
_ = cobra.MarkFlagRequired(createCmd.Flags(), commonflags.RPC)
createCmd.MarkFlagsMutuallyExclusive(commonflags.ExpireAt, commonflags.Lifetime)
}

func createSession(cmd *cobra.Command, _ []string) {
Expand All @@ -61,14 +64,24 @@ func createSession(cmd *cobra.Command, _ []string) {
c, err := internalclient.GetSDKClient(ctx, netAddr)
common.ExitOnErr(cmd, "can't create client: %w", err)

endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
currEpoch, err := internalclient.GetCurrentEpoch(ctx, endpoint)
common.ExitOnErr(cmd, "can't get current epoch: %w", err)

exp, _ := cmd.Flags().GetUint64(commonflags.ExpireAt)
lifetime := uint64(defaultLifetime)
if lfArg, _ := cmd.Flags().GetUint64(commonflags.Lifetime); lfArg != 0 {
lifetime = lfArg
exp = currEpoch + lfArg
}
if exp == 0 {
exp = currEpoch + lifetime
}
if exp <= currEpoch {
common.ExitOnErr(cmd, "", errors.New("expiration epoch must be greater than current epoch"))
}

var tok session.Object

err = CreateSession(ctx, &tok, c, *privKey, lifetime)
err = CreateSession(ctx, &tok, c, *privKey, exp)
common.ExitOnErr(cmd, "can't create session: %w", err)

var data []byte
Expand All @@ -90,21 +103,11 @@ func createSession(cmd *cobra.Command, _ []string) {
// number of epochs.
//
// Fills ID, lifetime and session key.
func CreateSession(ctx context.Context, dst *session.Object, c *client.Client, key ecdsa.PrivateKey, lifetime uint64) error {
var netInfoPrm internalclient.NetworkInfoPrm
netInfoPrm.SetClient(c)

ni, err := internalclient.NetworkInfo(ctx, netInfoPrm)
if err != nil {
return fmt.Errorf("can't fetch network info: %w", err)
}

cur := ni.NetworkInfo().CurrentEpoch()
exp := cur + lifetime
func CreateSession(ctx context.Context, dst *session.Object, c *client.Client, key ecdsa.PrivateKey, expireAt uint64) error {

Check failure on line 106 in cmd/neofs-cli/modules/session/create.go

View workflow job for this annotation

GitHub Actions / lint

unnecessary leading newline (whitespace)

var sessionPrm internalclient.CreateSessionPrm
sessionPrm.SetClient(c)
sessionPrm.SetExp(exp)
sessionPrm.SetExp(expireAt)
sessionPrm.SetPrivateKey(key)

sessionRes, err := internalclient.CreateSession(ctx, sessionPrm)
Expand All @@ -129,9 +132,7 @@ func CreateSession(ctx context.Context, dst *session.Object, c *client.Client, k
}

dst.SetID(idSession)
dst.SetNbf(cur)
dst.SetIat(cur)
dst.SetExp(exp)
dst.SetExp(expireAt)
dst.SetAuthKey(&keySession)

return nil
Expand Down
25 changes: 18 additions & 7 deletions cmd/neofs-cli/modules/storagegroup/put.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,18 @@ func initSGPutCmd() {
_ = sgPutCmd.MarkFlagRequired(sgMembersFlag)

flags.Uint64(commonflags.Lifetime, 0, "Storage group lifetime in epochs")
_ = sgPutCmd.MarkFlagRequired(commonflags.Lifetime)
flags.Uint64P(commonflags.ExpireAt, "e", 0, "The last active epoch of the storage group")
sgPutCmd.MarkFlagsMutuallyExclusive(commonflags.ExpireAt, commonflags.Lifetime)
}

func putSG(cmd *cobra.Command, _ []string) {
// with 1.8.0 cobra release we can use this instead of below
// sgPutCmd.MarkFlagsOneRequired("expire-at", "lifetime")
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("expiration epoch or lifetime period is required"))
}
ctx, cancel := commonflags.GetCommandContext(cmd)
defer cancel()

Expand Down Expand Up @@ -100,14 +108,17 @@ func putSG(cmd *cobra.Command, _ []string) {
}, cnr, members, !resGetCnr.Container().IsHomomorphicHashingDisabled())
common.ExitOnErr(cmd, "could not collect storage group members: %w", err)

var netInfoPrm internalclient.NetworkInfoPrm
netInfoPrm.SetClient(cli)
if lifetime != 0 {
var netInfoPrm internalclient.NetworkInfoPrm
netInfoPrm.SetClient(cli)

ni, err := internalclient.NetworkInfo(ctx, netInfoPrm)
common.ExitOnErr(cmd, "can't fetch network info: %w", err)
ni, err := internalclient.NetworkInfo(ctx, netInfoPrm)
common.ExitOnErr(cmd, "can't fetch network info: %w", err)
currEpoch := ni.NetworkInfo().CurrentEpoch()
exp = currEpoch + lifetime
}

lifetime, _ := cmd.Flags().GetUint64(commonflags.Lifetime)
sg.SetExpirationEpoch(ni.NetworkInfo().CurrentEpoch() + lifetime)
sg.SetExpirationEpoch(exp)

obj := object.New()
obj.SetContainerID(cnr)
Expand Down

0 comments on commit aa6d58f

Please sign in to comment.