[#1962] cli: common.PrintVerbose prints via cobra.Command.Printf

Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Anton Nikiforov 2022-12-27 12:36:30 +03:00 committed by fyrchik
parent cff4184cd3
commit 8ee590794f
24 changed files with 116 additions and 134 deletions

View file

@ -8,6 +8,8 @@ Changelog for FrostFS Node
- Doc for extended headers (#2128) - Doc for extended headers (#2128)
### Changed ### Changed
- `common.PrintVerbose` prints via `cobra.Command.Printf` (#1962)
### Fixed ### Fixed
- Big object removal with non-local parts (#1978) - Big object removal with non-local parts (#1978)
- Disable pilorama when moving to degraded mode (#2197) - Disable pilorama when moving to degraded mode (#2197)

View file

@ -21,25 +21,25 @@ var errInvalidEndpoint = errors.New("provided RPC endpoint is incorrect")
// GetSDKClientByFlag returns default frostfs-sdk-go client using the specified flag for the address. // GetSDKClientByFlag returns default frostfs-sdk-go client using the specified flag for the address.
// On error, outputs to stderr of cmd and exits with non-zero code. // On error, outputs to stderr of cmd and exits with non-zero code.
func GetSDKClientByFlag(cmd *cobra.Command, key *ecdsa.PrivateKey, endpointFlag string) *client.Client { func GetSDKClientByFlag(cmd *cobra.Command, key *ecdsa.PrivateKey, endpointFlag string) *client.Client {
cli, err := getSDKClientByFlag(key, endpointFlag) cli, err := getSDKClientByFlag(cmd, key, endpointFlag)
if err != nil { if err != nil {
common.ExitOnErr(cmd, "can't create API client: %w", err) common.ExitOnErr(cmd, "can't create API client: %w", err)
} }
return cli return cli
} }
func getSDKClientByFlag(key *ecdsa.PrivateKey, endpointFlag string) (*client.Client, error) { func getSDKClientByFlag(cmd *cobra.Command, key *ecdsa.PrivateKey, endpointFlag string) (*client.Client, error) {
var addr network.Address var addr network.Address
err := addr.FromString(viper.GetString(endpointFlag)) err := addr.FromString(viper.GetString(endpointFlag))
if err != nil { if err != nil {
return nil, fmt.Errorf("%v: %w", errInvalidEndpoint, err) return nil, fmt.Errorf("%v: %w", errInvalidEndpoint, err)
} }
return GetSDKClient(key, addr) return GetSDKClient(cmd, key, addr)
} }
// GetSDKClient returns default frostfs-sdk-go client. // GetSDKClient returns default frostfs-sdk-go client.
func GetSDKClient(key *ecdsa.PrivateKey, addr network.Address) (*client.Client, error) { func GetSDKClient(cmd *cobra.Command, key *ecdsa.PrivateKey, addr network.Address) (*client.Client, error) {
var ( var (
c client.Client c client.Client
prmInit client.PrmInit prmInit client.PrmInit
@ -56,7 +56,7 @@ func GetSDKClient(key *ecdsa.PrivateKey, addr network.Address) (*client.Client,
prmDial.SetTimeout(timeout) prmDial.SetTimeout(timeout)
prmDial.SetStreamTimeout(timeout) prmDial.SetStreamTimeout(timeout)
common.PrintVerbose("Set request timeout to %s.", timeout) common.PrintVerbose(cmd, "Set request timeout to %s.", timeout)
} }
c.Init(prmInit) c.Init(prmInit)
@ -69,7 +69,7 @@ func GetSDKClient(key *ecdsa.PrivateKey, addr network.Address) (*client.Client,
} }
// GetCurrentEpoch returns current epoch. // GetCurrentEpoch returns current epoch.
func GetCurrentEpoch(ctx context.Context, endpoint string) (uint64, error) { func GetCurrentEpoch(ctx context.Context, cmd *cobra.Command, endpoint string) (uint64, error) {
var addr network.Address var addr network.Address
if err := addr.FromString(endpoint); err != nil { if err := addr.FromString(endpoint); err != nil {
@ -81,7 +81,7 @@ func GetCurrentEpoch(ctx context.Context, endpoint string) (uint64, error) {
return 0, fmt.Errorf("can't generate key to sign query: %w", err) return 0, fmt.Errorf("can't generate key to sign query: %w", err)
} }
c, err := GetSDKClient(key, addr) c, err := GetSDKClient(cmd, key, addr)
if err != nil { if err != nil {
return 0, err return 0, err
} }

View file

@ -19,7 +19,7 @@ func ReadEACL(cmd *cobra.Command, eaclPath string) *eacl.Table {
ExitOnErr(cmd, "", errors.New("incorrect path to file with EACL")) ExitOnErr(cmd, "", errors.New("incorrect path to file with EACL"))
} }
PrintVerbose("Reading EACL from file: %s", eaclPath) PrintVerbose(cmd, "Reading EACL from file: %s", eaclPath)
data, err := os.ReadFile(eaclPath) data, err := os.ReadFile(eaclPath)
ExitOnErr(cmd, "can't read file with EACL: %w", err) ExitOnErr(cmd, "can't read file with EACL: %w", err)
@ -28,13 +28,13 @@ func ReadEACL(cmd *cobra.Command, eaclPath string) *eacl.Table {
if err = table.UnmarshalJSON(data); err == nil { if err = table.UnmarshalJSON(data); err == nil {
validateAndFixEACLVersion(table) validateAndFixEACLVersion(table)
PrintVerbose("Parsed JSON encoded EACL table") PrintVerbose(cmd, "Parsed JSON encoded EACL table")
return table return table
} }
if err = table.Unmarshal(data); err == nil { if err = table.Unmarshal(data); err == nil {
validateAndFixEACLVersion(table) validateAndFixEACLVersion(table)
PrintVerbose("Parsed binary encoded EACL table") PrintVerbose(cmd, "Parsed binary encoded EACL table")
return table return table
} }

View file

@ -11,12 +11,12 @@ import (
func PrettyPrintJSON(cmd *cobra.Command, m json.Marshaler, entity string) { func PrettyPrintJSON(cmd *cobra.Command, m json.Marshaler, entity string) {
data, err := m.MarshalJSON() data, err := m.MarshalJSON()
if err != nil { if err != nil {
PrintVerbose("Can't convert %s to json: %w", entity, err) PrintVerbose(cmd, "Can't convert %s to json: %w", entity, err)
return return
} }
buf := new(bytes.Buffer) buf := new(bytes.Buffer)
if err := json.Indent(buf, data, "", " "); err != nil { if err := json.Indent(buf, data, "", " "); err != nil {
PrintVerbose("Can't pretty print json: %w", err) PrintVerbose(cmd, "Can't pretty print json: %w", err)
return return
} }
cmd.Println(buf) cmd.Println(buf)

View file

@ -19,11 +19,11 @@ func ReadBearerToken(cmd *cobra.Command, flagname string) *bearer.Token {
return nil return nil
} }
PrintVerbose("Reading bearer token from file [%s]...", path) PrintVerbose(cmd, "Reading bearer token from file [%s]...", path)
var tok bearer.Token var tok bearer.Token
err = ReadBinaryOrJSON(&tok, path) err = ReadBinaryOrJSON(cmd, &tok, path)
ExitOnErr(cmd, "invalid bearer token: %v", err) ExitOnErr(cmd, "invalid bearer token: %v", err)
return &tok return &tok
@ -38,8 +38,8 @@ type BinaryOrJSON interface {
// ReadBinaryOrJSON reads file data using provided path and decodes // ReadBinaryOrJSON reads file data using provided path and decodes
// BinaryOrJSON from the data. // BinaryOrJSON from the data.
func ReadBinaryOrJSON(dst BinaryOrJSON, fPath string) error { func ReadBinaryOrJSON(cmd *cobra.Command, dst BinaryOrJSON, fPath string) error {
PrintVerbose("Reading file [%s]...", fPath) PrintVerbose(cmd, "Reading file [%s]...", fPath)
// try to read session token from file // try to read session token from file
data, err := os.ReadFile(fPath) data, err := os.ReadFile(fPath)
@ -47,17 +47,17 @@ func ReadBinaryOrJSON(dst BinaryOrJSON, fPath string) error {
return fmt.Errorf("read file <%s>: %w", fPath, err) return fmt.Errorf("read file <%s>: %w", fPath, err)
} }
PrintVerbose("Trying to decode binary...") PrintVerbose(cmd, "Trying to decode binary...")
err = dst.Unmarshal(data) err = dst.Unmarshal(data)
if err != nil { if err != nil {
PrintVerbose("Failed to decode binary: %v", err) PrintVerbose(cmd, "Failed to decode binary: %v", err)
PrintVerbose("Trying to decode JSON...") PrintVerbose(cmd, "Trying to decode JSON...")
err = dst.UnmarshalJSON(data) err = dst.UnmarshalJSON(data)
if err != nil { if err != nil {
PrintVerbose("Failed to decode JSON: %v", err) PrintVerbose(cmd, "Failed to decode JSON: %v", err)
return errors.New("invalid format") return errors.New("invalid format")
} }
} }

View file

@ -2,7 +2,6 @@ package common
import ( import (
"encoding/hex" "encoding/hex"
"fmt"
"strconv" "strconv"
"time" "time"
@ -13,9 +12,9 @@ import (
) )
// PrintVerbose prints to the stdout if the commonflags.Verbose flag is on. // PrintVerbose prints to the stdout if the commonflags.Verbose flag is on.
func PrintVerbose(format string, a ...interface{}) { func PrintVerbose(cmd *cobra.Command, format string, a ...interface{}) {
if viper.GetBool(commonflags.Verbose) { if viper.GetBool(commonflags.Verbose) {
fmt.Printf(format+"\n", a...) cmd.Printf(format+"\n", a...)
} }
} }

View file

@ -11,11 +11,18 @@ import (
"github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/cli/input"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"golang.org/x/term" "golang.org/x/term"
) )
var testCmd = &cobra.Command{
Use: "test",
Short: "test",
Run: func(cmd *cobra.Command, args []string) {},
}
func Test_getOrGenerate(t *testing.T) { func Test_getOrGenerate(t *testing.T) {
dir := t.TempDir() dir := t.TempDir()
@ -96,7 +103,7 @@ func Test_getOrGenerate(t *testing.T) {
t.Run("generate", func(t *testing.T) { t.Run("generate", func(t *testing.T) {
viper.Set(commonflags.GenerateKey, true) viper.Set(commonflags.GenerateKey, true)
actual, err := getOrGenerate() actual, err := getOrGenerate(testCmd)
require.NoError(t, err) require.NoError(t, err)
require.NotNil(t, actual) require.NotNil(t, actual)
for _, p := range []*keys.PrivateKey{nep2Key, rawKey, wifKey, acc1.PrivateKey(), acc2.PrivateKey()} { for _, p := range []*keys.PrivateKey{nep2Key, rawKey, wifKey, acc1.PrivateKey(), acc2.PrivateKey()} {
@ -107,13 +114,13 @@ func Test_getOrGenerate(t *testing.T) {
func checkKeyError(t *testing.T, desc string, err error) { func checkKeyError(t *testing.T, desc string, err error) {
viper.Set(commonflags.WalletPath, desc) viper.Set(commonflags.WalletPath, desc)
_, actualErr := getOrGenerate() _, actualErr := getOrGenerate(testCmd)
require.ErrorIs(t, actualErr, err) require.ErrorIs(t, actualErr, err)
} }
func checkKey(t *testing.T, desc string, expected *keys.PrivateKey) { func checkKey(t *testing.T, desc string, expected *keys.PrivateKey) {
viper.Set(commonflags.WalletPath, desc) viper.Set(commonflags.WalletPath, desc)
actual, err := getOrGenerate() actual, err := getOrGenerate(testCmd)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, &expected.PrivateKey, actual) require.Equal(t, &expected.PrivateKey, actual)
} }

View file

@ -20,12 +20,12 @@ var errCantGenerateKey = errors.New("can't generate new private key")
// Ideally we want to touch file-system on the last step. // Ideally we want to touch file-system on the last step.
// This function assumes that all flags were bind to viper in a `PersistentPreRun`. // This function assumes that all flags were bind to viper in a `PersistentPreRun`.
func Get(cmd *cobra.Command) *ecdsa.PrivateKey { func Get(cmd *cobra.Command) *ecdsa.PrivateKey {
pk, err := get() pk, err := get(cmd)
common.ExitOnErr(cmd, "can't fetch private key: %w", err) common.ExitOnErr(cmd, "can't fetch private key: %w", err)
return pk return pk
} }
func get() (*ecdsa.PrivateKey, error) { func get(cmd *cobra.Command) (*ecdsa.PrivateKey, error) {
keyDesc := viper.GetString(commonflags.WalletPath) keyDesc := viper.GetString(commonflags.WalletPath)
data, err := os.ReadFile(keyDesc) data, err := os.ReadFile(keyDesc)
if err != nil { if err != nil {
@ -36,7 +36,7 @@ func get() (*ecdsa.PrivateKey, error) {
if err != nil { if err != nil {
w, err := wallet.NewWalletFromFile(keyDesc) w, err := wallet.NewWalletFromFile(keyDesc)
if err == nil { if err == nil {
return FromWallet(w, viper.GetString(commonflags.Account)) return FromWallet(cmd, w, viper.GetString(commonflags.Account))
} }
return nil, fmt.Errorf("%w: %v", ErrInvalidKey, err) return nil, fmt.Errorf("%w: %v", ErrInvalidKey, err)
} }
@ -45,12 +45,12 @@ func get() (*ecdsa.PrivateKey, error) {
// GetOrGenerate is similar to get but generates a new key if commonflags.GenerateKey is set. // GetOrGenerate is similar to get but generates a new key if commonflags.GenerateKey is set.
func GetOrGenerate(cmd *cobra.Command) *ecdsa.PrivateKey { func GetOrGenerate(cmd *cobra.Command) *ecdsa.PrivateKey {
pk, err := getOrGenerate() pk, err := getOrGenerate(cmd)
common.ExitOnErr(cmd, "can't fetch private key: %w", err) common.ExitOnErr(cmd, "can't fetch private key: %w", err)
return pk return pk
} }
func getOrGenerate() (*ecdsa.PrivateKey, error) { func getOrGenerate(cmd *cobra.Command) (*ecdsa.PrivateKey, error) {
if viper.GetBool(commonflags.GenerateKey) { if viper.GetBool(commonflags.GenerateKey) {
priv, err := keys.NewPrivateKey() priv, err := keys.NewPrivateKey()
if err != nil { if err != nil {
@ -58,5 +58,5 @@ func getOrGenerate() (*ecdsa.PrivateKey, error) {
} }
return &priv.PrivateKey, nil return &priv.PrivateKey, nil
} }
return get() return get(cmd)
} }

View file

@ -3,13 +3,14 @@ package key
import ( import (
"crypto/ecdsa" "crypto/ecdsa"
"errors" "errors"
"fmt"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
"github.com/nspcc-dev/neo-go/cli/flags" "github.com/nspcc-dev/neo-go/cli/flags"
"github.com/nspcc-dev/neo-go/cli/input" "github.com/nspcc-dev/neo-go/cli/input"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/spf13/cobra"
"github.com/spf13/viper" "github.com/spf13/viper"
) )
@ -22,37 +23,37 @@ var (
) )
// FromWallet returns private key of the wallet account. // FromWallet returns private key of the wallet account.
func FromWallet(w *wallet.Wallet, addrStr string) (*ecdsa.PrivateKey, error) { func FromWallet(cmd *cobra.Command, w *wallet.Wallet, addrStr string) (*ecdsa.PrivateKey, error) {
var ( var (
addr util.Uint160 addr util.Uint160
err error err error
) )
if addrStr == "" { if addrStr == "" {
printVerbose("Using default wallet address") common.PrintVerbose(cmd, "Using default wallet address")
addr = w.GetChangeAddress() addr = w.GetChangeAddress()
} else { } else {
addr, err = flags.ParseAddress(addrStr) addr, err = flags.ParseAddress(addrStr)
if err != nil { if err != nil {
printVerbose("Can't parse address: %s", addrStr) common.PrintVerbose(cmd, "Can't parse address: %s", addrStr)
return nil, ErrInvalidAddress return nil, ErrInvalidAddress
} }
} }
acc := w.GetAccount(addr) acc := w.GetAccount(addr)
if acc == nil { if acc == nil {
printVerbose("Can't find wallet account for %s", addrStr) common.PrintVerbose(cmd, "Can't find wallet account for %s", addrStr)
return nil, ErrInvalidAddress return nil, ErrInvalidAddress
} }
pass, err := getPassword() pass, err := getPassword()
if err != nil { if err != nil {
printVerbose("Can't read password: %v", err) common.PrintVerbose(cmd, "Can't read password: %v", err)
return nil, ErrInvalidPassword return nil, ErrInvalidPassword
} }
if err := acc.Decrypt(pass, keys.NEP2ScryptParams()); err != nil { if err := acc.Decrypt(pass, keys.NEP2ScryptParams()); err != nil {
printVerbose("Can't decrypt account: %v", err) common.PrintVerbose(cmd, "Can't decrypt account: %v", err)
return nil, ErrInvalidPassword return nil, ErrInvalidPassword
} }
@ -67,9 +68,3 @@ func getPassword() (string, error) {
return input.ReadPassword("Enter password > ") return input.ReadPassword("Enter password > ")
} }
func printVerbose(format string, a ...interface{}) {
if viper.GetBool("verbose") {
fmt.Printf(format+"\n", a...)
}
}

View file

@ -71,7 +71,7 @@ func createToken(cmd *cobra.Command, _ []string) {
defer cancel() defer cancel()
endpoint, _ := cmd.Flags().GetString(commonflags.RPC) endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
currEpoch, err := internalclient.GetCurrentEpoch(ctx, endpoint) currEpoch, err := internalclient.GetCurrentEpoch(ctx, cmd, endpoint)
common.ExitOnErr(cmd, "can't fetch current epoch: %w", err) common.ExitOnErr(cmd, "can't fetch current epoch: %w", err)
if iatRelative { if iatRelative {

View file

@ -36,7 +36,7 @@ var createContainerCmd = &cobra.Command{
Long: `Create new container and register it in the NeoFS. Long: `Create new container and register it in the NeoFS.
It will be stored in sidechain when inner ring will accepts it.`, It will be stored in sidechain when inner ring will accepts it.`,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {
placementPolicy, err := parseContainerPolicy(containerPolicy) placementPolicy, err := parseContainerPolicy(cmd, containerPolicy)
common.ExitOnErr(cmd, "", err) common.ExitOnErr(cmd, "", err)
key := key.Get(cmd) key := key.Get(cmd)
@ -165,10 +165,10 @@ func initContainerCreateCmd() {
"Skip placement validity check") "Skip placement validity check")
} }
func parseContainerPolicy(policyString string) (*netmap.PlacementPolicy, error) { func parseContainerPolicy(cmd *cobra.Command, policyString string) (*netmap.PlacementPolicy, error) {
_, err := os.Stat(policyString) // check if `policyString` is a path to file with placement policy _, err := os.Stat(policyString) // check if `policyString` is a path to file with placement policy
if err == nil { if err == nil {
common.PrintVerbose("Reading placement policy from file: %s", policyString) common.PrintVerbose(cmd, "Reading placement policy from file: %s", policyString)
data, err := os.ReadFile(policyString) data, err := os.ReadFile(policyString)
if err != nil { if err != nil {
@ -182,12 +182,12 @@ func parseContainerPolicy(policyString string) (*netmap.PlacementPolicy, error)
err = result.DecodeString(policyString) err = result.DecodeString(policyString)
if err == nil { if err == nil {
common.PrintVerbose("Parsed QL encoded policy") common.PrintVerbose(cmd, "Parsed QL encoded policy")
return &result, nil return &result, nil
} }
if err = result.UnmarshalJSON([]byte(policyString)); err == nil { if err = result.UnmarshalJSON([]byte(policyString)); err == nil {
common.PrintVerbose("Parsed JSON encoded policy") common.PrintVerbose(cmd, "Parsed JSON encoded policy")
return &result, nil return &result, nil
} }

View file

@ -27,7 +27,7 @@ Only owner of the container has a permission to remove container.`,
cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC) cli := internalclient.GetSDKClientByFlag(cmd, pk, commonflags.RPC)
if force, _ := cmd.Flags().GetBool(commonflags.ForceFlag); !force { if force, _ := cmd.Flags().GetBool(commonflags.ForceFlag); !force {
common.PrintVerbose("Reading the container to check ownership...") common.PrintVerbose(cmd, "Reading the container to check ownership...")
var getPrm internalclient.GetContainerPrm var getPrm internalclient.GetContainerPrm
getPrm.SetClient(cli) getPrm.SetClient(cli)
@ -39,13 +39,13 @@ Only owner of the container has a permission to remove container.`,
owner := resGet.Container().Owner() owner := resGet.Container().Owner()
if tok != nil { if tok != nil {
common.PrintVerbose("Checking session issuer...") common.PrintVerbose(cmd, "Checking session issuer...")
if !tok.Issuer().Equals(owner) { if !tok.Issuer().Equals(owner) {
common.ExitOnErr(cmd, "", fmt.Errorf("session issuer differs with the container owner: expected %s, has %s", owner, tok.Issuer())) common.ExitOnErr(cmd, "", fmt.Errorf("session issuer differs with the container owner: expected %s, has %s", owner, tok.Issuer()))
} }
} else { } else {
common.PrintVerbose("Checking provided account...") common.PrintVerbose(cmd, "Checking provided account...")
var acc user.ID var acc user.ID
user.IDFromKey(&acc, pk.PublicKey) user.IDFromKey(&acc, pk.PublicKey)
@ -55,10 +55,10 @@ Only owner of the container has a permission to remove container.`,
} }
} }
common.PrintVerbose("Account matches the container owner.") common.PrintVerbose(cmd, "Account matches the container owner.")
if tok != nil { if tok != nil {
common.PrintVerbose("Skip searching for LOCK objects - session provided.") common.PrintVerbose(cmd, "Skip searching for LOCK objects - session provided.")
} else { } else {
fs := objectSDK.NewSearchFilters() fs := objectSDK.NewSearchFilters()
fs.AddTypeFilter(objectSDK.MatchStringEqual, objectSDK.TypeLock) fs.AddTypeFilter(objectSDK.MatchStringEqual, objectSDK.TypeLock)
@ -69,7 +69,7 @@ Only owner of the container has a permission to remove container.`,
searchPrm.SetFilters(fs) searchPrm.SetFilters(fs)
searchPrm.SetTTL(2) searchPrm.SetTTL(2)
common.PrintVerbose("Searching for LOCK objects...") common.PrintVerbose(cmd, "Searching for LOCK objects...")
res, err := internalclient.SearchObjects(searchPrm) res, err := internalclient.SearchObjects(searchPrm)
common.ExitOnErr(cmd, "can't search for LOCK objects: %w", err) common.ExitOnErr(cmd, "can't search for LOCK objects: %w", err)

View file

@ -1,9 +1,7 @@
package container package container
import ( import (
"bytes"
"crypto/ecdsa" "crypto/ecdsa"
"encoding/json"
"os" "os"
internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client" internalclient "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/client"
@ -77,18 +75,7 @@ func (x *stringWriter) WriteString(s string) (n int, err error) {
func prettyPrintContainer(cmd *cobra.Command, cnr container.Container, jsonEncoding bool) { func prettyPrintContainer(cmd *cobra.Command, cnr container.Container, jsonEncoding bool) {
if jsonEncoding { if jsonEncoding {
data, err := cnr.MarshalJSON() common.PrettyPrintJSON(cmd, cnr, "container")
if err != nil {
common.PrintVerbose("Can't convert container to json: %w", err)
return
}
buf := new(bytes.Buffer)
if err := json.Indent(buf, data, "", " "); err != nil {
common.PrintVerbose("Can't pretty print json: %w", err)
}
cmd.Println(buf)
return return
} }

View file

@ -36,22 +36,22 @@ func parseContainerID(cmd *cobra.Command) cid.ID {
// decodes session.Container from the file by path provided in // decodes session.Container from the file by path provided in
// commonflags.SessionToken flag. Returns nil if the path is not specified. // commonflags.SessionToken flag. Returns nil if the path is not specified.
func getSession(cmd *cobra.Command) *session.Container { func getSession(cmd *cobra.Command) *session.Container {
common.PrintVerbose("Reading container session...") common.PrintVerbose(cmd, "Reading container session...")
path, _ := cmd.Flags().GetString(commonflags.SessionToken) path, _ := cmd.Flags().GetString(commonflags.SessionToken)
if path == "" { if path == "" {
common.PrintVerbose("Session not provided.") common.PrintVerbose(cmd, "Session not provided.")
return nil return nil
} }
common.PrintVerbose("Reading container session from the file [%s]...", path) common.PrintVerbose(cmd, "Reading container session from the file [%s]...", path)
var res session.Container var res session.Container
err := common.ReadBinaryOrJSON(&res, path) err := common.ReadBinaryOrJSON(cmd, &res, path)
common.ExitOnErr(cmd, "read container session: %v", err) common.ExitOnErr(cmd, "read container session: %v", err)
common.PrintVerbose("Session successfully read.") common.PrintVerbose(cmd, "Session successfully read.")
return &res return &res
} }

View file

@ -51,7 +51,7 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) {
printIgnoreForce := func(st control.NetmapStatus) { printIgnoreForce := func(st control.NetmapStatus) {
if force { if force {
common.PrintVerbose("Ignore --%s flag for %s state.", commonflags.ForceFlag, st) common.PrintVerbose(cmd, "Ignore --%s flag for %s state.", commonflags.ForceFlag, st)
} }
} }
@ -69,7 +69,7 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) {
if force { if force {
body.SetForceMaintenance() body.SetForceMaintenance()
common.PrintVerbose("Local maintenance will be forced.") common.PrintVerbose(cmd, "Local maintenance will be forced.")
} }
} }

View file

@ -60,13 +60,13 @@ var objectLockCmd = &cobra.Command{
endpoint, _ := cmd.Flags().GetString(commonflags.RPC) endpoint, _ := cmd.Flags().GetString(commonflags.RPC)
currEpoch, err := internalclient.GetCurrentEpoch(ctx, endpoint) currEpoch, err := internalclient.GetCurrentEpoch(ctx, cmd, endpoint)
common.ExitOnErr(cmd, "Request current epoch: %w", err) common.ExitOnErr(cmd, "Request current epoch: %w", err)
exp = currEpoch + lifetime exp = currEpoch + lifetime
} }
common.PrintVerbose("Lock object will expire after %d epoch", exp) common.PrintVerbose(cmd, "Lock object will expire after %d epoch", exp)
var expirationAttr objectSDK.Attribute var expirationAttr objectSDK.Attribute
expirationAttr.SetKey(objectV2.SysAttributeExpEpoch) expirationAttr.SetKey(objectV2.SysAttributeExpEpoch)

View file

@ -46,7 +46,7 @@ func InitBearer(cmd *cobra.Command) {
// Prepare prepares object-related parameters for a command. // Prepare prepares object-related parameters for a command.
func Prepare(cmd *cobra.Command, prms ...RPCParameters) { func Prepare(cmd *cobra.Command, prms ...RPCParameters) {
ttl := viper.GetUint32(commonflags.TTL) ttl := viper.GetUint32(commonflags.TTL)
common.PrintVerbose("TTL: %d", ttl) common.PrintVerbose(cmd, "TTL: %d", ttl)
for i := range prms { for i := range prms {
btok := common.ReadBearerToken(cmd, bearerTokenFlag) btok := common.ReadBearerToken(cmd, bearerTokenFlag)
@ -127,19 +127,19 @@ func readSession(cmd *cobra.Command, dst SessionPrm, key *ecdsa.PrivateKey, cnr
// decodes session.Object from the file by path specified in the // decodes session.Object from the file by path specified in the
// commonflags.SessionToken flag. Returns nil if flag is not set. // commonflags.SessionToken flag. Returns nil if flag is not set.
func getSession(cmd *cobra.Command) *session.Object { func getSession(cmd *cobra.Command) *session.Object {
common.PrintVerbose("Trying to read session from the file...") common.PrintVerbose(cmd, "Trying to read session from the file...")
path, _ := cmd.Flags().GetString(commonflags.SessionToken) path, _ := cmd.Flags().GetString(commonflags.SessionToken)
if path == "" { if path == "" {
common.PrintVerbose("File with session token is not provided.") common.PrintVerbose(cmd, "File with session token is not provided.")
return nil return nil
} }
common.PrintVerbose("Reading session from the file [%s]...", path) common.PrintVerbose(cmd, "Reading session from the file [%s]...", path)
var tok session.Object var tok session.Object
err := common.ReadBinaryOrJSON(&tok, path) err := common.ReadBinaryOrJSON(cmd, &tok, path)
common.ExitOnErr(cmd, "read session: %v", err) common.ExitOnErr(cmd, "read session: %v", err)
return &tok return &tok
@ -185,7 +185,7 @@ func _readVerifiedSession(cmd *cobra.Command, dst SessionPrm, key *ecdsa.Private
return return
} }
common.PrintVerbose("Checking session correctness...") common.PrintVerbose(cmd, "Checking session correctness...")
switch false { switch false {
case tok.AssertContainer(cnr): case tok.AssertContainer(cnr):
@ -200,7 +200,7 @@ func _readVerifiedSession(cmd *cobra.Command, dst SessionPrm, key *ecdsa.Private
common.ExitOnErr(cmd, "", errors.New("invalid signature of the session data")) common.ExitOnErr(cmd, "", errors.New("invalid signature of the session data"))
} }
common.PrintVerbose("Session is correct.") common.PrintVerbose(cmd, "Session is correct.")
dst.SetSessionToken(tok) dst.SetSessionToken(tok)
} }
@ -227,7 +227,7 @@ func ReadOrOpenSessionViaClient(cmd *cobra.Command, dst SessionPrm, cli *client.
objs = []oid.ID{*obj} objs = []oid.ID{*obj}
if _, ok := dst.(*internal.DeleteObjectPrm); ok { if _, ok := dst.(*internal.DeleteObjectPrm); ok {
common.PrintVerbose("Collecting relatives of the removal object...") common.PrintVerbose(cmd, "Collecting relatives of the removal object...")
objs = append(objs, collectObjectRelatives(cmd, cli, cnr, *obj)...) objs = append(objs, collectObjectRelatives(cmd, cli, cnr, *obj)...)
} }
@ -259,7 +259,7 @@ func OpenSessionViaClient(cmd *cobra.Command, dst SessionPrm, cli *client.Client
if obj != nil { if obj != nil {
if _, ok := dst.(*internal.DeleteObjectPrm); ok { if _, ok := dst.(*internal.DeleteObjectPrm); ok {
common.PrintVerbose("Collecting relatives of the removal object...") common.PrintVerbose(cmd, "Collecting relatives of the removal object...")
rels := collectObjectRelatives(cmd, cli, cnr, *obj) rels := collectObjectRelatives(cmd, cli, cnr, *obj)
@ -275,12 +275,12 @@ func OpenSessionViaClient(cmd *cobra.Command, dst SessionPrm, cli *client.Client
const sessionLifetime = 10 // in NeoFS epochs const sessionLifetime = 10 // in NeoFS epochs
common.PrintVerbose("Opening remote session with the node...") common.PrintVerbose(cmd, "Opening remote session with the node...")
err := sessionCli.CreateSession(&tok, cli, sessionLifetime) err := sessionCli.CreateSession(&tok, cli, sessionLifetime)
common.ExitOnErr(cmd, "open remote session: %w", err) common.ExitOnErr(cmd, "open remote session: %w", err)
common.PrintVerbose("Session successfully opened.") common.PrintVerbose(cmd, "Session successfully opened.")
finalizeSession(cmd, dst, &tok, key, cnr, objs...) finalizeSession(cmd, dst, &tok, key, cnr, objs...)
@ -297,33 +297,33 @@ func OpenSessionViaClient(cmd *cobra.Command, dst SessionPrm, cli *client.Client
// *internal.PutObjectPrm // *internal.PutObjectPrm
// *internal.DeleteObjectPrm // *internal.DeleteObjectPrm
func finalizeSession(cmd *cobra.Command, dst SessionPrm, tok *session.Object, key *ecdsa.PrivateKey, cnr cid.ID, objs ...oid.ID) { func finalizeSession(cmd *cobra.Command, dst SessionPrm, tok *session.Object, key *ecdsa.PrivateKey, cnr cid.ID, objs ...oid.ID) {
common.PrintVerbose("Finalizing session token...") common.PrintVerbose(cmd, "Finalizing session token...")
switch dst.(type) { switch dst.(type) {
default: default:
panic(fmt.Sprintf("unsupported op parameters %T", dst)) panic(fmt.Sprintf("unsupported op parameters %T", dst))
case *internal.PutObjectPrm: case *internal.PutObjectPrm:
common.PrintVerbose("Binding session to object PUT...") common.PrintVerbose(cmd, "Binding session to object PUT...")
tok.ForVerb(session.VerbObjectPut) tok.ForVerb(session.VerbObjectPut)
case *internal.DeleteObjectPrm: case *internal.DeleteObjectPrm:
common.PrintVerbose("Binding session to object DELETE...") common.PrintVerbose(cmd, "Binding session to object DELETE...")
tok.ForVerb(session.VerbObjectDelete) tok.ForVerb(session.VerbObjectDelete)
} }
common.PrintVerbose("Binding session to container %s...", cnr) common.PrintVerbose(cmd, "Binding session to container %s...", cnr)
tok.BindContainer(cnr) tok.BindContainer(cnr)
if len(objs) > 0 { if len(objs) > 0 {
common.PrintVerbose("Limiting session by the objects %v...", objs) common.PrintVerbose(cmd, "Limiting session by the objects %v...", objs)
tok.LimitByObjects(objs...) tok.LimitByObjects(objs...)
} }
common.PrintVerbose("Signing session...") common.PrintVerbose(cmd, "Signing session...")
err := tok.Sign(*key) err := tok.Sign(*key)
common.ExitOnErr(cmd, "sign session: %w", err) common.ExitOnErr(cmd, "sign session: %w", err)
common.PrintVerbose("Session token successfully formed and attached to the request.") common.PrintVerbose(cmd, "Session token successfully formed and attached to the request.")
dst.SetSessionToken(tok) dst.SetSessionToken(tok)
} }
@ -339,7 +339,7 @@ func initFlagSession(cmd *cobra.Command, verb string) {
// //
// The object itself is not included in the result. // The object itself is not included in the result.
func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID, obj oid.ID) []oid.ID { func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID, obj oid.ID) []oid.ID {
common.PrintVerbose("Fetching raw object header...") common.PrintVerbose(cmd, "Fetching raw object header...")
// request raw header first // request raw header first
var addrObj oid.Address var addrObj oid.Address
@ -361,10 +361,10 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
default: default:
common.ExitOnErr(cmd, "failed to get raw object header: %w", err) common.ExitOnErr(cmd, "failed to get raw object header: %w", err)
case err == nil: case err == nil:
common.PrintVerbose("Raw header received - object is singular.") common.PrintVerbose(cmd, "Raw header received - object is singular.")
return nil return nil
case errors.As(err, &errSplit): case errors.As(err, &errSplit):
common.PrintVerbose("Split information received - object is virtual.") common.PrintVerbose(cmd, "Split information received - object is virtual.")
} }
splitInfo := errSplit.SplitInfo() splitInfo := errSplit.SplitInfo()
@ -373,7 +373,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
// If any approach fails, we don't try the next since we assume that it will fail too. // If any approach fails, we don't try the next since we assume that it will fail too.
if idLinking, ok := splitInfo.Link(); ok { if idLinking, ok := splitInfo.Link(); ok {
common.PrintVerbose("Collecting split members using linking object %s...", idLinking) common.PrintVerbose(cmd, "Collecting split members using linking object %s...", idLinking)
addrObj.SetObject(idLinking) addrObj.SetObject(idLinking)
prmHead.SetAddress(addrObj) prmHead.SetAddress(addrObj)
@ -381,18 +381,22 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
// client is already set // client is already set
res, err := internal.HeadObject(prmHead) res, err := internal.HeadObject(prmHead)
common.ExitOnErr(cmd, "failed to get linking object's header: %w", err) if err == nil {
children := res.Header().Children()
children := res.Header().Children() common.PrintVerbose(cmd, "Received split members from the linking object: %v", children)
common.PrintVerbose("Received split members from the linking object: %v", children) // include linking object
return append(children, idLinking)
}
// include linking object // linking object is not required for
return append(children, idLinking) // object collecting
common.PrintVerbose(cmd, "failed to get linking object's header: %w", err)
} }
if idSplit := splitInfo.SplitID(); idSplit != nil { if idSplit := splitInfo.SplitID(); idSplit != nil {
common.PrintVerbose("Collecting split members by split ID...") common.PrintVerbose(cmd, "Collecting split members by split ID...")
var query object.SearchFilters var query object.SearchFilters
query.AddSplitIDFilter(object.MatchStringEqual, idSplit) query.AddSplitIDFilter(object.MatchStringEqual, idSplit)
@ -407,7 +411,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
members := res.IDList() members := res.IDList()
common.PrintVerbose("Found objects by split ID: %v", res.IDList()) common.PrintVerbose(cmd, "Found objects by split ID: %v", res.IDList())
return members return members
} }
@ -417,7 +421,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
common.ExitOnErr(cmd, "", errors.New("missing any data in received object split information")) common.ExitOnErr(cmd, "", errors.New("missing any data in received object split information"))
} }
common.PrintVerbose("Traverse the object split chain in reverse...", idMember) common.PrintVerbose(cmd, "Traverse the object split chain in reverse...", idMember)
var res *internal.HeadObjectRes var res *internal.HeadObjectRes
chain := []oid.ID{idMember} chain := []oid.ID{idMember}
@ -427,7 +431,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
// split members are almost definitely singular, but don't get hung up on it // split members are almost definitely singular, but don't get hung up on it
for { for {
common.PrintVerbose("Reading previous element of the split chain member %s...", idMember) common.PrintVerbose(cmd, "Reading previous element of the split chain member %s...", idMember)
addrObj.SetObject(idMember) addrObj.SetObject(idMember)
@ -436,7 +440,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
idMember, ok = res.Header().PreviousID() idMember, ok = res.Header().PreviousID()
if !ok { if !ok {
common.PrintVerbose("Chain ended.") common.PrintVerbose(cmd, "Chain ended.")
break break
} }
@ -448,7 +452,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
chainSet[idMember] = struct{}{} chainSet[idMember] = struct{}{}
} }
common.PrintVerbose("Looking for a linking object...") common.PrintVerbose(cmd, "Looking for a linking object...")
var query object.SearchFilters var query object.SearchFilters
query.AddParentIDFilter(object.MatchStringEqual, obj) query.AddParentIDFilter(object.MatchStringEqual, obj)
@ -465,7 +469,7 @@ func collectObjectRelatives(cmd *cobra.Command, cli *client.Client, cnr cid.ID,
for i := range list { for i := range list {
if _, ok = chainSet[list[i]]; !ok { if _, ok = chainSet[list[i]]; !ok {
common.PrintVerbose("Found one more related object %s.", list[i]) common.PrintVerbose(cmd, "Found one more related object %s.", list[i])
chain = append(chain, list[i]) chain = append(chain, list[i])
} }
} }

View file

@ -118,6 +118,6 @@ func initConfig() {
// If a config file is found, read it in. // If a config file is found, read it in.
if err := viper.ReadInConfig(); err == nil { if err := viper.ReadInConfig(); err == nil {
common.PrintVerbose("Using config file: %s", viper.ConfigFileUsed()) common.PrintVerbose(rootCmd, "Using config file: %s", viper.ConfigFileUsed())
} }
} }

View file

@ -54,7 +54,7 @@ func createSession(cmd *cobra.Command, _ []string) {
addrStr, _ := cmd.Flags().GetString(commonflags.RPC) addrStr, _ := cmd.Flags().GetString(commonflags.RPC)
common.ExitOnErr(cmd, "can't parse endpoint: %w", netAddr.FromString(addrStr)) common.ExitOnErr(cmd, "can't parse endpoint: %w", netAddr.FromString(addrStr))
c, err := internalclient.GetSDKClient(privKey, netAddr) c, err := internalclient.GetSDKClient(cmd, privKey, netAddr)
common.ExitOnErr(cmd, "can't create client: %w", err) common.ExitOnErr(cmd, "can't create client: %w", err)
lifetime := uint64(defaultLifetime) lifetime := uint64(defaultLifetime)

View file

@ -83,7 +83,7 @@ func addByPath(cmd *cobra.Command, _ []string) {
nn := resp.GetBody().GetNodes() nn := resp.GetBody().GetNodes()
if len(nn) == 0 { if len(nn) == 0 {
common.PrintVerbose("No new nodes were created") common.PrintVerbose(cmd, "No new nodes were created")
return return
} }

View file

@ -80,7 +80,7 @@ func getByPath(cmd *cobra.Command, _ []string) {
nn := resp.GetBody().GetNodes() nn := resp.GetBody().GetNodes()
if len(nn) == 0 { if len(nn) == 0 {
common.PrintVerbose("The node is not found") common.PrintVerbose(cmd, "The node is not found")
return return
} }

View file

@ -1,8 +1,6 @@
package util package util
import ( import (
"bytes"
"encoding/json"
"os" "os"
"github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "github.com/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common"
@ -45,7 +43,7 @@ func convertEACLTable(cmd *cobra.Command, _ []string) {
} }
if len(to) == 0 { if len(to) == 0 {
prettyPrintJSON(cmd, data) common.PrettyPrintJSON(cmd, table, "eACL")
return return
} }
@ -54,12 +52,3 @@ func convertEACLTable(cmd *cobra.Command, _ []string) {
cmd.Printf("extended ACL table was successfully dumped to %s\n", to) cmd.Printf("extended ACL table was successfully dumped to %s\n", to)
} }
func prettyPrintJSON(cmd *cobra.Command, data []byte) {
buf := new(bytes.Buffer)
if err := json.Indent(buf, data, "", " "); err != nil {
common.PrintVerbose("Can't pretty print json: %w", err)
}
cmd.Println(buf)
}

View file

@ -51,8 +51,7 @@ func signBearerToken(cmd *cobra.Command, _ []string) {
} }
if len(to) == 0 { if len(to) == 0 {
prettyPrintJSON(cmd, data) common.PrettyPrintJSON(cmd, btok, "bearer token")
return return
} }

View file

@ -52,7 +52,7 @@ func signSessionToken(cmd *cobra.Command, _ []string) {
new(session.Object), new(session.Object),
new(session.Container), new(session.Container),
} { } {
errLast = common.ReadBinaryOrJSON(el, fPath) errLast = common.ReadBinaryOrJSON(cmd, el, fPath)
if errLast == nil { if errLast == nil {
stok = el stok = el
break break
@ -71,7 +71,7 @@ func signSessionToken(cmd *cobra.Command, _ []string) {
to := cmd.Flag(signToFlag).Value.String() to := cmd.Flag(signToFlag).Value.String()
if len(to) == 0 { if len(to) == 0 {
prettyPrintJSON(cmd, data) common.PrettyPrintJSON(cmd, stok, "session token")
return return
} }