Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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>
AliceInHunterland committed Aug 23, 2023
1 parent e979a59 commit 7fda793
Showing 7 changed files with 66 additions and 31 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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)
13 changes: 11 additions & 2 deletions cmd/neofs-cli/modules/bearer/create.go
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ package bearer
import (
"context"
"encoding/json"
"errors"
"fmt"
"os"
"time"
@@ -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()

@@ -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, "",
2 changes: 1 addition & 1 deletion cmd/neofs-cli/modules/object/lock.go
Original file line number Diff line number Diff line change
@@ -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 {
11 changes: 11 additions & 0 deletions cmd/neofs-cli/modules/object/put.go
Original file line number Diff line number Diff line change
@@ -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) {
@@ -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)
7 changes: 5 additions & 2 deletions cmd/neofs-cli/modules/object/util.go
Original file line number Diff line number Diff line change
@@ -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.")
38 changes: 19 additions & 19 deletions cmd/neofs-cli/modules/session/create.go
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@ package session
import (
"context"
"crypto/ecdsa"
"errors"
"fmt"
"os"

@@ -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) {
@@ -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
@@ -90,21 +103,10 @@ 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 {
var sessionPrm internalclient.CreateSessionPrm
sessionPrm.SetClient(c)
sessionPrm.SetExp(exp)
sessionPrm.SetExp(expireAt)
sessionPrm.SetPrivateKey(key)

sessionRes, err := internalclient.CreateSession(ctx, sessionPrm)
@@ -129,9 +131,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
25 changes: 18 additions & 7 deletions cmd/neofs-cli/modules/storagegroup/put.go
Original file line number Diff line number Diff line change
@@ -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()

@@ -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)

0 comments on commit 7fda793

Please sign in to comment.