forked from TrueCloudLab/frostfs-node
[#278] cli: Support request X-Headers
Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
e53bf574b5
commit
51b85b0a73
5 changed files with 105 additions and 45 deletions
|
@ -6,7 +6,6 @@ import (
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/accounting"
|
"github.com/nspcc-dev/neofs-api-go/pkg/accounting"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/client"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -42,14 +41,14 @@ var accountingBalanceCmd = &cobra.Command{
|
||||||
|
|
||||||
switch balanceOwner {
|
switch balanceOwner {
|
||||||
case "":
|
case "":
|
||||||
response, err = cli.GetSelfBalance(ctx, client.WithTTL(getTTL()))
|
response, err = cli.GetSelfBalance(ctx, globalCallOptions()...)
|
||||||
default:
|
default:
|
||||||
oid, err = ownerFromString(balanceOwner)
|
oid, err = ownerFromString(balanceOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err = cli.GetBalance(ctx, oid, client.WithTTL(getTTL()))
|
response, err = cli.GetBalance(ctx, oid, globalCallOptions()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -80,14 +80,14 @@ var listContainersCmd = &cobra.Command{
|
||||||
|
|
||||||
switch containerOwner {
|
switch containerOwner {
|
||||||
case "":
|
case "":
|
||||||
response, err = cli.ListSelfContainers(ctx, client.WithTTL(getTTL()))
|
response, err = cli.ListSelfContainers(ctx, globalCallOptions()...)
|
||||||
default:
|
default:
|
||||||
oid, err = ownerFromString(containerOwner)
|
oid, err = ownerFromString(containerOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
response, err = cli.ListContainers(ctx, oid, client.WithTTL(getTTL()))
|
response, err = cli.ListContainers(ctx, oid, globalCallOptions()...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -140,7 +140,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
cnr.SetAttributes(attributes)
|
cnr.SetAttributes(attributes)
|
||||||
cnr.SetNonceUUID(nonce)
|
cnr.SetNonceUUID(nonce)
|
||||||
|
|
||||||
id, err := cli.PutContainer(ctx, cnr, client.WithTTL(getTTL()))
|
id, err := cli.PutContainer(ctx, cnr, globalCallOptions()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rpc error: %w", err)
|
return fmt.Errorf("rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ It will be stored in sidechain when inner ring will accepts it.`,
|
||||||
for i := 0; i < awaitTimeout; i++ {
|
for i := 0; i < awaitTimeout; i++ {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
_, err := cli.GetContainer(ctx, id, client.WithTTL(getTTL()))
|
_, err := cli.GetContainer(ctx, id, globalCallOptions()...)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
fmt.Println("container has been persisted on sidechain")
|
fmt.Println("container has been persisted on sidechain")
|
||||||
return nil
|
return nil
|
||||||
|
@ -185,7 +185,7 @@ Only owner of the container has a permission to remove container.`,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = cli.DeleteContainer(ctx, id, client.WithTTL(getTTL()))
|
err = cli.DeleteContainer(ctx, id, globalCallOptions()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rpc error: %w", err)
|
return fmt.Errorf("rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -198,7 +198,7 @@ Only owner of the container has a permission to remove container.`,
|
||||||
for i := 0; i < awaitTimeout; i++ {
|
for i := 0; i < awaitTimeout; i++ {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
_, err := cli.GetContainer(ctx, id, client.WithTTL(getTTL()))
|
_, err := cli.GetContainer(ctx, id, globalCallOptions()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("container has been removed:", containerID)
|
fmt.Println("container has been removed:", containerID)
|
||||||
return nil
|
return nil
|
||||||
|
@ -242,8 +242,10 @@ var listContainerObjectsCmd = &cobra.Command{
|
||||||
searchQuery.WithSearchFilters(*filters)
|
searchQuery.WithSearchFilters(*filters)
|
||||||
|
|
||||||
objectIDs, err := cli.SearchObject(ctx, searchQuery,
|
objectIDs, err := cli.SearchObject(ctx, searchQuery,
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(sessionToken))
|
client.WithSession(sessionToken),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rpc error: %w", err)
|
return fmt.Errorf("rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -288,7 +290,7 @@ var getContainerInfoCmd = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cnr, err = cli.GetContainer(ctx, id, client.WithTTL(getTTL()))
|
cnr, err = cli.GetContainer(ctx, id, globalCallOptions()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rpc error: %w", err)
|
return fmt.Errorf("rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -341,7 +343,7 @@ var getExtendedACLCmd = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := cli.GetEACLWithSignature(ctx, id, client.WithTTL(getTTL()))
|
res, err := cli.GetEACLWithSignature(ctx, id, globalCallOptions()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rpc error: %w", err)
|
return fmt.Errorf("rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -407,7 +409,7 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
|
||||||
|
|
||||||
eaclTable.SetCID(id)
|
eaclTable.SetCID(id)
|
||||||
|
|
||||||
err = cli.SetEACL(ctx, eaclTable, client.WithTTL(getTTL()))
|
err = cli.SetEACL(ctx, eaclTable, globalCallOptions()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rpc error: %w", err)
|
return fmt.Errorf("rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -423,7 +425,7 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
|
||||||
for i := 0; i < awaitTimeout; i++ {
|
for i := 0; i < awaitTimeout; i++ {
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
eaclSig, err := cli.GetEACLWithSignature(ctx, id, client.WithTTL(getTTL()))
|
eaclSig, err := cli.GetEACLWithSignature(ctx, id, globalCallOptions()...)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
// compare binary values because EACL could have been set already
|
// compare binary values because EACL could have been set already
|
||||||
got, err := eaclSig.EACL().Marshal()
|
got, err := eaclSig.EACL().Marshal()
|
||||||
|
|
|
@ -7,7 +7,6 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/client"
|
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
"github.com/nspcc-dev/neofs-api-go/pkg/netmap"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
@ -47,7 +46,7 @@ var getEpochCmd = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
e, err := cli.Epoch(context.Background(), client.WithTTL(getTTL()))
|
e, err := cli.Epoch(context.Background(), globalCallOptions()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rpc error: %w", err)
|
return fmt.Errorf("rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -68,7 +67,7 @@ var localNodeInfoCmd = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeInfo, err := cli.EndpointInfo(context.Background(), client.WithTTL(getTTL()))
|
nodeInfo, err := cli.EndpointInfo(context.Background(), globalCallOptions()...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("rpc error: %w", err)
|
return fmt.Errorf("rpc error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,9 +229,11 @@ func putObject(cmd *cobra.Command, _ []string) error {
|
||||||
new(client.PutObjectParams).
|
new(client.PutObjectParams).
|
||||||
WithObject(obj.Object()).
|
WithObject(obj.Object()).
|
||||||
WithPayloadReader(f),
|
WithPayloadReader(f),
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(tok),
|
client.WithSession(tok),
|
||||||
client.WithBearer(btok))
|
client.WithBearer(btok),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't put object: %w", err)
|
return fmt.Errorf("can't put object: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -259,9 +261,11 @@ func deleteObject(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
||||||
tombstoneAddr, err := client.DeleteObject(cli, ctx,
|
tombstoneAddr, err := client.DeleteObject(cli, ctx,
|
||||||
new(client.DeleteObjectParams).WithAddress(objAddr),
|
new(client.DeleteObjectParams).WithAddress(objAddr),
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(tok),
|
client.WithSession(tok),
|
||||||
client.WithBearer(btok))
|
client.WithBearer(btok),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -307,9 +311,11 @@ func getObject(cmd *cobra.Command, _ []string) error {
|
||||||
WithAddress(objAddr).
|
WithAddress(objAddr).
|
||||||
WithPayloadWriter(out).
|
WithPayloadWriter(out).
|
||||||
WithRawFlag(raw),
|
WithRawFlag(raw),
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(tok),
|
client.WithSession(tok),
|
||||||
client.WithBearer(btok))
|
client.WithBearer(btok),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ok := printSplitInfoErr(cmd, err); ok {
|
if ok := printSplitInfoErr(cmd, err); ok {
|
||||||
return nil
|
return nil
|
||||||
|
@ -354,9 +360,11 @@ func getObjectHeader(cmd *cobra.Command, _ []string) error {
|
||||||
ps.WithRawFlag(raw)
|
ps.WithRawFlag(raw)
|
||||||
|
|
||||||
obj, err := cli.GetObjectHeader(ctx, ps,
|
obj, err := cli.GetObjectHeader(ctx, ps,
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(tok),
|
client.WithSession(tok),
|
||||||
client.WithBearer(btok))
|
client.WithBearer(btok),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ok := printSplitInfoErr(cmd, err); ok {
|
if ok := printSplitInfoErr(cmd, err); ok {
|
||||||
return nil
|
return nil
|
||||||
|
@ -390,9 +398,11 @@ func searchObject(cmd *cobra.Command, _ []string) error {
|
||||||
}
|
}
|
||||||
ps := new(client.SearchObjectParams).WithContainerID(cid).WithSearchFilters(sf)
|
ps := new(client.SearchObjectParams).WithContainerID(cid).WithSearchFilters(sf)
|
||||||
ids, err := cli.SearchObject(ctx, ps,
|
ids, err := cli.SearchObject(ctx, ps,
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(tok),
|
client.WithSession(tok),
|
||||||
client.WithBearer(btok))
|
client.WithBearer(btok),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't put object: %w", err)
|
return fmt.Errorf("can't put object: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -429,9 +439,11 @@ func getObjectHash(cmd *cobra.Command, _ []string) error {
|
||||||
if len(ranges) == 0 { // hash of full payload
|
if len(ranges) == 0 { // hash of full payload
|
||||||
obj, err := cli.GetObjectHeader(ctx,
|
obj, err := cli.GetObjectHeader(ctx,
|
||||||
new(client.ObjectHeaderParams).WithAddress(objAddr),
|
new(client.ObjectHeaderParams).WithAddress(objAddr),
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(tok),
|
client.WithSession(tok),
|
||||||
client.WithBearer(btok))
|
client.WithBearer(btok),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't get object: %w", err)
|
return fmt.Errorf("can't get object: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -448,9 +460,11 @@ func getObjectHash(cmd *cobra.Command, _ []string) error {
|
||||||
switch typ {
|
switch typ {
|
||||||
case hashSha256:
|
case hashSha256:
|
||||||
res, err := cli.ObjectPayloadRangeSHA256(ctx, ps,
|
res, err := cli.ObjectPayloadRangeSHA256(ctx, ps,
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(tok),
|
client.WithSession(tok),
|
||||||
client.WithBearer(btok))
|
client.WithBearer(btok),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -460,9 +474,11 @@ func getObjectHash(cmd *cobra.Command, _ []string) error {
|
||||||
}
|
}
|
||||||
case hashTz:
|
case hashTz:
|
||||||
res, err := cli.ObjectPayloadRangeTZ(ctx, ps,
|
res, err := cli.ObjectPayloadRangeTZ(ctx, ps,
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(tok),
|
client.WithSession(tok),
|
||||||
client.WithBearer(btok))
|
client.WithBearer(btok),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -808,9 +824,11 @@ func getObjectRange(cmd *cobra.Command, _ []string) error {
|
||||||
WithRange(ranges[0]).
|
WithRange(ranges[0]).
|
||||||
WithDataWriter(out).
|
WithDataWriter(out).
|
||||||
WithRaw(raw),
|
WithRaw(raw),
|
||||||
client.WithTTL(getTTL()),
|
append(globalCallOptions(),
|
||||||
client.WithSession(sessionToken),
|
client.WithSession(sessionToken),
|
||||||
client.WithBearer(bearerToken))
|
client.WithBearer(bearerToken),
|
||||||
|
)...,
|
||||||
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if ok := printSplitInfoErr(cmd, err); ok {
|
if ok := printSplitInfoErr(cmd, err); ok {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -7,8 +7,10 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/client"
|
"github.com/nspcc-dev/neofs-api-go/pkg/client"
|
||||||
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||||
crypto "github.com/nspcc-dev/neofs-crypto"
|
crypto "github.com/nspcc-dev/neofs-crypto"
|
||||||
|
@ -25,6 +27,10 @@ const (
|
||||||
ttlDefaultValue = 2
|
ttlDefaultValue = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const xHeadersFlag = "xhdr"
|
||||||
|
|
||||||
|
var xHeaders []string
|
||||||
|
|
||||||
// Global scope flags.
|
// Global scope flags.
|
||||||
var (
|
var (
|
||||||
cfgFile string
|
cfgFile string
|
||||||
|
@ -80,6 +86,10 @@ func init() {
|
||||||
|
|
||||||
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
|
rootCmd.PersistentFlags().BoolVarP(&verbose, "verbose", "v", false, "verbose output")
|
||||||
|
|
||||||
|
rootCmd.PersistentFlags().StringSliceVarP(&xHeaders, xHeadersFlag, "x", nil,
|
||||||
|
"Request X-Headers in form of Key=Value")
|
||||||
|
_ = viper.BindPFlag(xHeadersFlag, rootCmd.PersistentFlags().Lookup(xHeadersFlag))
|
||||||
|
|
||||||
// Cobra also supports local flags, which will only run
|
// Cobra also supports local flags, which will only run
|
||||||
// when this action is called directly.
|
// when this action is called directly.
|
||||||
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
// rootCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
|
@ -194,3 +204,35 @@ func printVerbose(format string, a ...interface{}) {
|
||||||
fmt.Printf(format+"\n", a...)
|
fmt.Printf(format+"\n", a...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func parseXHeaders() []*pkg.XHeader {
|
||||||
|
xs := make([]*pkg.XHeader, 0, len(xHeaders))
|
||||||
|
|
||||||
|
for i := range xHeaders {
|
||||||
|
kv := strings.SplitN(xHeaders[i], "=", 2)
|
||||||
|
if len(kv) != 2 {
|
||||||
|
panic(fmt.Errorf("invalid X-Header format: %s", xHeaders[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
x := pkg.NewXHeader()
|
||||||
|
x.SetKey(kv[0])
|
||||||
|
x.SetValue(kv[1])
|
||||||
|
|
||||||
|
xs = append(xs, x)
|
||||||
|
}
|
||||||
|
|
||||||
|
return xs
|
||||||
|
}
|
||||||
|
|
||||||
|
func globalCallOptions() []client.CallOption {
|
||||||
|
xHdrs := parseXHeaders()
|
||||||
|
|
||||||
|
opts := make([]client.CallOption, 0, len(xHdrs)+1) // + TTL
|
||||||
|
opts = append(opts, client.WithTTL(getTTL()))
|
||||||
|
|
||||||
|
for i := range xHdrs {
|
||||||
|
opts = append(opts, client.WithXHeader(xHdrs[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return opts
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue