Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cli: unify usage of expired-at flag instead of lifetime flag #2521

Merged
merged 1 commit into from
Aug 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ minor release, the component will be purged, so be prepared (see `Updating` sect
- `peapod` command for `neofs-lens` (#2507)
- New CLI exit code for awaiting timeout (#2380)
- Validation of excessive positional arguments to `neofs-cli` commands (#1941)
- `--lifetime` flag to `bearer create` and `object put` CLI commands (#1574)
- `--expired-at` flag to `session create` and `storagegroup put` CLI commands (#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 @@ -47,27 +48,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)
carpawell marked this conversation as resolved.
Show resolved Hide resolved
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 @@ -84,6 +90,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 @@ -54,7 +54,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 @@ -53,10 +53,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 @@ -100,6 +102,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, currEpoch)
common.ExitOnErr(cmd, "open remote session: %w", err)

common.PrintVerbose(cmd, "Session successfully opened.")
Expand Down
41 changes: 21 additions & 20 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 @@ -44,10 +45,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 @@ -62,14 +65,23 @@ 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, currEpoch)
common.ExitOnErr(cmd, "can't create session: %w", err)

var data []byte
Expand All @@ -91,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, currEpoch uint64) error {
var sessionPrm internalclient.CreateSessionPrm
sessionPrm.SetClient(c)
sessionPrm.SetExp(exp)
sessionPrm.SetExp(expireAt)
sessionPrm.SetPrivateKey(key)

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

dst.SetID(idSession)
dst.SetNbf(cur)
dst.SetIat(cur)
roman-khimov marked this conversation as resolved.
Show resolved Hide resolved
dst.SetExp(exp)
dst.SetNbf(currEpoch)
dst.SetIat(currEpoch)
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 @@ -44,10 +44,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 @@ -101,14 +109,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
Loading