diff --git a/cmd/neofs-cli/internal/common/exit.go b/cmd/neofs-cli/internal/common/exit.go new file mode 100644 index 00000000..1b616e08 --- /dev/null +++ b/cmd/neofs-cli/internal/common/exit.go @@ -0,0 +1,50 @@ +package common + +import ( + "errors" + "fmt" + "os" + + sdkstatus "github.com/nspcc-dev/neofs-sdk-go/client/status" + "github.com/spf13/cobra" +) + +// ExitOnErr prints error and exits with a code that matches +// one of the common errors from sdk library. If no errors +// found, exits with 1 code. +// Does nothing if passed error in nil. +func ExitOnErr(cmd *cobra.Command, errFmt string, err error) { + if err == nil { + return + } + + if errFmt != "" { + err = fmt.Errorf(errFmt, err) + } + + const ( + _ = iota + internal + aclDenied + ) + + var ( + code int + + internalErr = new(sdkstatus.ServerInternal) + accessErr = new(sdkstatus.ObjectAccessDenied) + ) + + switch { + case errors.As(err, &internalErr): + code = internal + case errors.As(err, &accessErr): + code = aclDenied + err = fmt.Errorf("%w: %s", err, accessErr.Reason()) + default: + code = internal + } + + cmd.PrintErrln(err) + os.Exit(code) +} diff --git a/cmd/neofs-cli/modules/accounting.go b/cmd/neofs-cli/modules/accounting.go index aa2e1847..a573ee02 100644 --- a/cmd/neofs-cli/modules/accounting.go +++ b/cmd/neofs-cli/modules/accounting.go @@ -5,6 +5,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/pkg/util/precision" "github.com/nspcc-dev/neofs-sdk-go/accounting" @@ -39,13 +40,13 @@ var accountingBalanceCmd = &cobra.Command{ var oid *owner.ID key, err := getKey() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) if balanceOwner == "" { oid = owner.NewIDFromPublicKey(&key.PublicKey) } else { oid, err = ownerFromString(balanceOwner) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) } var prm internalclient.BalanceOfPrm @@ -54,7 +55,7 @@ var accountingBalanceCmd = &cobra.Command{ prm.SetAccount(*oid) res, err := internalclient.BalanceOf(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) // print to stdout prettyPrintDecimal(cmd, res.Balance()) diff --git a/cmd/neofs-cli/modules/container.go b/cmd/neofs-cli/modules/container.go index 2c95eb76..ec44fc44 100644 --- a/cmd/neofs-cli/modules/container.go +++ b/cmd/neofs-cli/modules/container.go @@ -13,6 +13,7 @@ import ( "github.com/google/uuid" "github.com/nspcc-dev/neofs-api-go/v2/refs" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/pkg/core/version" "github.com/nspcc-dev/neofs-sdk-go/acl" @@ -116,13 +117,13 @@ var listContainersCmd = &cobra.Command{ var oid *owner.ID key, err := getKey() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) if containerOwner == "" { oid = owner.NewIDFromPublicKey(&key.PublicKey) } else { oid, err = ownerFromString(containerOwner) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) } var prm internalclient.ListContainersPrm @@ -131,7 +132,7 @@ var listContainersCmd = &cobra.Command{ prm.SetAccount(*oid) res, err := internalclient.ListContainers(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) // print to stdout prettyPrintContainerList(cmd, res.IDList()) @@ -145,27 +146,27 @@ var createContainerCmd = &cobra.Command{ It will be stored in sidechain when inner ring will accepts it.`, Run: func(cmd *cobra.Command, args []string) { placementPolicy, err := parseContainerPolicy(containerPolicy) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) subnetID, err := parseSubnetID(containerSubnet) - exitOnErr(cmd, errf("could not parse subnetID: %w", err)) + common.ExitOnErr(cmd, "could not parse subnetID: %w", err) placementPolicy.SetSubnetID(subnetID) attributes, err := parseAttributes(containerAttributes) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) basicACL, err := parseBasicACL(containerACL) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) nonce, err := parseNonce(containerNonce) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) tok, err := getSessionToken(sessionTokenPath) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) key, err := getKey() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var idOwner *owner.ID @@ -193,7 +194,7 @@ It will be stored in sidechain when inner ring will accepts it.`, putPrm.SetContainer(*cnr) res, err := internalclient.PutContainer(putPrm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) id := res.ID() @@ -214,7 +215,7 @@ It will be stored in sidechain when inner ring will accepts it.`, } } - exitOnErr(cmd, errCreateTimeout) + common.ExitOnErr(cmd, "", errCreateTimeout) } }, } @@ -226,10 +227,10 @@ var deleteContainerCmd = &cobra.Command{ Only owner of the container has a permission to remove container.`, Run: func(cmd *cobra.Command, args []string) { id, err := parseContainerID(containerID) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) tok, err := getSessionToken(sessionTokenPath) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var ( delPrm internalclient.DeleteContainerPrm @@ -244,7 +245,7 @@ Only owner of the container has a permission to remove container.`, } _, err = internalclient.DeleteContainer(delPrm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) cmd.Println("container delete method invoked") @@ -263,7 +264,7 @@ Only owner of the container has a permission to remove container.`, } } - exitOnErr(cmd, errDeleteTimeout) + common.ExitOnErr(cmd, "", errDeleteTimeout) } }, } @@ -274,7 +275,7 @@ var listContainerObjectsCmd = &cobra.Command{ Long: `List existing objects in container`, Run: func(cmd *cobra.Command, args []string) { id, err := parseContainerID(containerID) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) filters := new(object.SearchFilters) filters.AddRootFilter() // search only user created objects @@ -289,7 +290,7 @@ var listContainerObjectsCmd = &cobra.Command{ prm.SetFilters(*filters) res, err := internalclient.SearchObjects(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) objectIDs := res.IDList() @@ -308,14 +309,14 @@ var getContainerInfoCmd = &cobra.Command{ if containerPathFrom != "" { data, err := os.ReadFile(containerPathFrom) - exitOnErr(cmd, errf("can't read file: %w", err)) + common.ExitOnErr(cmd, "can't read file: %w", err) cnr = container.New() err = cnr.Unmarshal(data) - exitOnErr(cmd, errf("can't unmarshal container: %w", err)) + common.ExitOnErr(cmd, "can't unmarshal container: %w", err) } else { id, err := parseContainerID(containerID) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var prm internalclient.GetContainerPrm @@ -323,7 +324,7 @@ var getContainerInfoCmd = &cobra.Command{ prm.SetContainer(*id) res, err := internalclient.GetContainer(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) cnr = res.Container() } @@ -338,14 +339,14 @@ var getContainerInfoCmd = &cobra.Command{ if containerJSON { data, err = cnr.MarshalJSON() - exitOnErr(cmd, errf("can't JSON encode container: %w", err)) + common.ExitOnErr(cmd, "can't JSON encode container: %w", err) } else { data, err = cnr.Marshal() - exitOnErr(cmd, errf("can't binary encode container: %w", err)) + common.ExitOnErr(cmd, "can't binary encode container: %w", err) } err = os.WriteFile(containerPathTo, data, 0644) - exitOnErr(cmd, errf("can't write container to file: %w", err)) + common.ExitOnErr(cmd, "can't write container to file: %w", err) } }, } @@ -356,7 +357,7 @@ var getExtendedACLCmd = &cobra.Command{ Long: `Get extended ACL talbe of container`, Run: func(cmd *cobra.Command, args []string) { id, err := parseContainerID(containerID) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var eaclPrm internalclient.EACLPrm @@ -364,7 +365,7 @@ var getExtendedACLCmd = &cobra.Command{ eaclPrm.SetContainer(*id) res, err := internalclient.EACL(eaclPrm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) eaclTable := res.EACL() @@ -391,10 +392,10 @@ var getExtendedACLCmd = &cobra.Command{ if containerJSON { data, err = eaclTable.MarshalJSON() - exitOnErr(cmd, errf("can't encode to JSON: %w", err)) + common.ExitOnErr(cmd, "can't encode to JSON: %w", err) } else { data, err = eaclTable.Marshal() - exitOnErr(cmd, errf("can't encode to binary: %w", err)) + common.ExitOnErr(cmd, "can't encode to binary: %w", err) } cmd.Println("dumping data to file:", containerPathTo) @@ -403,7 +404,7 @@ var getExtendedACLCmd = &cobra.Command{ printJSONMarshaler(cmd, &sigV2, "signature") err = os.WriteFile(containerPathTo, data, 0644) - exitOnErr(cmd, errf("could not write eACL to file: %w", err)) + common.ExitOnErr(cmd, "could not write eACL to file: %w", err) }, } @@ -414,13 +415,13 @@ var setExtendedACLCmd = &cobra.Command{ Container ID in EACL table will be substituted with ID from the CLI.`, Run: func(cmd *cobra.Command, args []string) { id, err := parseContainerID(containerID) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) eaclTable, err := parseEACL(eaclPathFrom) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) tok, err := getSessionToken(sessionTokenPath) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) eaclTable.SetCID(*id) eaclTable.SetSessionToken(tok) @@ -434,11 +435,11 @@ Container ID in EACL table will be substituted with ID from the CLI.`, setEACLPrm.SetTable(*eaclTable) _, err = internalclient.SetEACL(setEACLPrm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) if containerAwait { exp, err := eaclTable.Marshal() - exitOnErr(cmd, errf("broken EACL table: %w", err)) + common.ExitOnErr(cmd, "broken EACL table: %w", err) cmd.Println("awaiting...") @@ -462,7 +463,7 @@ Container ID in EACL table will be substituted with ID from the CLI.`, } } - exitOnErr(cmd, errSetEACLTimeout) + common.ExitOnErr(cmd, "", errSetEACLTimeout) } }, } diff --git a/cmd/neofs-cli/modules/control.go b/cmd/neofs-cli/modules/control.go index 8426b224..57350441 100644 --- a/cmd/neofs-cli/modules/control.go +++ b/cmd/neofs-cli/modules/control.go @@ -9,6 +9,7 @@ import ( "github.com/nspcc-dev/neofs-api-go/v2/refs" rawclient "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/pkg/services/control" ircontrol "github.com/nspcc-dev/neofs-node/pkg/services/control/ir" @@ -220,11 +221,11 @@ func verifyResponseControl(cmd *cobra.Command, }, ) { if sigControl == nil { - exitOnErr(cmd, errors.New("missing response signature")) + common.ExitOnErr(cmd, "", errors.New("missing response signature")) } bodyData, err := body.StableMarshal(nil) - exitOnErr(cmd, errf("marshal response body: %w", err)) + common.ExitOnErr(cmd, "marshal response body: %w", err) // TODO(@cthulhu-rider): #1387 use Signature message from NeoFS API to avoid conversion var sigV2 refs.Signature @@ -236,16 +237,16 @@ func verifyResponseControl(cmd *cobra.Command, sig.ReadFromV2(sigV2) if !sig.Verify(bodyData) { - exitOnErr(cmd, errors.New("invalid response signature")) + common.ExitOnErr(cmd, "", errors.New("invalid response signature")) } } func healthCheck(cmd *cobra.Command, _ []string) { key, err := getKeyNoGenerate() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) cli, err := getControlSDKClient(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) if healthCheckIRVar { healthCheckIR(cmd, key, cli) @@ -257,14 +258,14 @@ func healthCheck(cmd *cobra.Command, _ []string) { req.SetBody(new(control.HealthCheckRequest_Body)) err = controlSvc.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign message: %w", err)) + common.ExitOnErr(cmd, "could not sign message: %w", err) var resp *control.HealthCheckResponse err = cli.ExecRaw(func(client *rawclient.Client) error { resp, err = control.HealthCheck(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) @@ -278,14 +279,14 @@ func healthCheckIR(cmd *cobra.Command, key *ecdsa.PrivateKey, c *client.Client) req.SetBody(new(ircontrol.HealthCheckRequest_Body)) err := ircontrolsrv.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign request: %w", err)) + common.ExitOnErr(cmd, "could not sign request: %w", err) var resp *ircontrol.HealthCheckResponse err = c.ExecRaw(func(client *rawclient.Client) error { resp, err = ircontrol.HealthCheck(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) @@ -294,13 +295,13 @@ func healthCheckIR(cmd *cobra.Command, key *ecdsa.PrivateKey, c *client.Client) func setNetmapStatus(cmd *cobra.Command, _ []string) { key, err := getKeyNoGenerate() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var status control.NetmapStatus switch netmapStatus { default: - exitOnErr(cmd, fmt.Errorf("unsupported status %s", netmapStatus)) + common.ExitOnErr(cmd, "", fmt.Errorf("unsupported status %s", netmapStatus)) case netmapStatusOnline: status = control.NetmapStatus_ONLINE case netmapStatusOffline: @@ -317,17 +318,17 @@ func setNetmapStatus(cmd *cobra.Command, _ []string) { body.SetStatus(status) err = controlSvc.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign request: %w", err)) + common.ExitOnErr(cmd, "could not sign request: %w", err) cli, err := getControlSDKClient(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var resp *control.SetNetmapStatusResponse err = cli.ExecRaw(func(client *rawclient.Client) error { resp, err = control.SetNetmapStatus(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) @@ -344,7 +345,7 @@ var dropObjectsCmd = &cobra.Command{ Long: "Drop objects from the node's local storage", Run: func(cmd *cobra.Command, args []string) { key, err := getKeyNoGenerate() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) binAddrList := make([][]byte, 0, len(dropObjectsList)) @@ -353,11 +354,11 @@ var dropObjectsCmd = &cobra.Command{ err := a.Parse(dropObjectsList[i]) if err != nil { - exitOnErr(cmd, fmt.Errorf("could not parse address #%d: %w", i, err)) + common.ExitOnErr(cmd, "", fmt.Errorf("could not parse address #%d: %w", i, err)) } binAddr, err := a.Marshal() - exitOnErr(cmd, errf("could not marshal the address: %w", err)) + common.ExitOnErr(cmd, "could not marshal the address: %w", err) binAddrList = append(binAddrList, binAddr) } @@ -370,17 +371,17 @@ var dropObjectsCmd = &cobra.Command{ body.SetAddressList(binAddrList) err = controlSvc.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign request: %w", err)) + common.ExitOnErr(cmd, "could not sign request: %w", err) cli, err := getControlSDKClient(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var resp *control.DropObjectsResponse err = cli.ExecRaw(func(client *rawclient.Client) error { resp, err = control.DropObjects(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) @@ -394,23 +395,23 @@ var snapshotCmd = &cobra.Command{ Long: "Get network map snapshot", Run: func(cmd *cobra.Command, args []string) { key, err := getKeyNoGenerate() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) req := new(control.NetmapSnapshotRequest) req.SetBody(new(control.NetmapSnapshotRequest_Body)) err = controlSvc.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign request: %w", err)) + common.ExitOnErr(cmd, "could not sign request: %w", err) cli, err := getControlSDKClient(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var resp *control.NetmapSnapshotResponse err = cli.ExecRaw(func(client *rawclient.Client) error { resp, err = control.NetmapSnapshot(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) @@ -420,23 +421,23 @@ var snapshotCmd = &cobra.Command{ func listShards(cmd *cobra.Command, _ []string) { key, err := getKeyNoGenerate() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) req := new(control.ListShardsRequest) req.SetBody(new(control.ListShardsRequest_Body)) err = controlSvc.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign request: %w", err)) + common.ExitOnErr(cmd, "could not sign request: %w", err) cli, err := getControlSDKClient(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var resp *control.ListShardsResponse err = cli.ExecRaw(func(client *rawclient.Client) error { resp, err = control.ListShards(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) @@ -484,13 +485,13 @@ func prettyPrintShards(cmd *cobra.Command, ii []*control.ShardInfo) { func setShardMode(cmd *cobra.Command, _ []string) { key, err := getKeyNoGenerate() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var mode control.ShardMode switch shardMode { default: - exitOnErr(cmd, fmt.Errorf("unsupported mode %s", mode)) + common.ExitOnErr(cmd, "", fmt.Errorf("unsupported mode %s", mode)) case shardModeReadWrite: mode = control.ShardMode_READ_WRITE case shardModeReadOnly: @@ -505,7 +506,7 @@ func setShardMode(cmd *cobra.Command, _ []string) { req.SetBody(body) rawID, err := base58.Decode(shardID) - exitOnErr(cmd, errf("incorrect shard ID encoding: %w", err)) + common.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err) body.SetMode(mode) body.SetShardID(rawID) @@ -514,17 +515,17 @@ func setShardMode(cmd *cobra.Command, _ []string) { body.ClearErrorCounter(reset) err = controlSvc.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign request: %w", err)) + common.ExitOnErr(cmd, "could not sign request: %w", err) cli, err := getControlSDKClient(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var resp *control.SetShardModeResponse err = cli.ExecRaw(func(client *rawclient.Client) error { resp, err = control.SetShardMode(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) diff --git a/cmd/neofs-cli/modules/dump.go b/cmd/neofs-cli/modules/dump.go index 5245147e..907011a4 100644 --- a/cmd/neofs-cli/modules/dump.go +++ b/cmd/neofs-cli/modules/dump.go @@ -3,6 +3,7 @@ package cmd import ( "github.com/mr-tron/base58" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/pkg/services/control" controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server" @@ -23,12 +24,12 @@ var dumpShardCmd = &cobra.Command{ func dumpShard(cmd *cobra.Command, _ []string) { key, err := getKeyNoGenerate() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) body := new(control.DumpShardRequest_Body) rawID, err := base58.Decode(shardID) - exitOnErr(cmd, errf("incorrect shard ID encoding: %w", err)) + common.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err) body.SetShardID(rawID) p, _ := cmd.Flags().GetString(dumpFilepathFlag) @@ -41,17 +42,17 @@ func dumpShard(cmd *cobra.Command, _ []string) { req.SetBody(body) err = controlSvc.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign request: %w", err)) + common.ExitOnErr(cmd, "could not sign request: %w", err) cli, err := getControlSDKClient(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var resp *control.DumpShardResponse err = cli.ExecRaw(func(client *client.Client) error { resp, err = control.DumpShard(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) diff --git a/cmd/neofs-cli/modules/lock.go b/cmd/neofs-cli/modules/lock.go index 78cb4046..1d8c29d5 100644 --- a/cmd/neofs-cli/modules/lock.go +++ b/cmd/neofs-cli/modules/lock.go @@ -4,6 +4,7 @@ import ( "fmt" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" objectcore "github.com/nspcc-dev/neofs-node/pkg/core/object" cid "github.com/nspcc-dev/neofs-sdk-go/container/id" @@ -22,7 +23,7 @@ var cmdObjectLock = &cobra.Command{ var cnr cid.ID err := cnr.DecodeString(args[0]) - exitOnErr(cmd, errf("Incorrect container arg: %v", err)) + common.ExitOnErr(cmd, "Incorrect container arg: %v", err) argsList := args[1:] @@ -30,14 +31,14 @@ var cmdObjectLock = &cobra.Command{ for i := range argsList { err = lockList[i].DecodeString(argsList[i]) - exitOnErr(cmd, errf(fmt.Sprintf("Incorrect object arg #%d: %%v", i+1), err)) + common.ExitOnErr(cmd, fmt.Sprintf("Incorrect object arg #%d: %%v", i+1), err) } key, err := getKey() - exitOnErr(cmd, errf("can't fetch private key: %w", err)) + common.ExitOnErr(cmd, "can't fetch private key: %w", err) idOwner, err := getOwnerID(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var lock object.Lock lock.WriteMembers(lockList) @@ -55,7 +56,7 @@ var cmdObjectLock = &cobra.Command{ prm.SetHeader(obj) _, err = internalclient.PutObject(prm) - exitOnErr(cmd, errf("Store lock object in NeoFS: %w", err)) + common.ExitOnErr(cmd, "Store lock object in NeoFS: %w", err) cmd.Println("Objects successfully locked.") }, diff --git a/cmd/neofs-cli/modules/netmap.go b/cmd/neofs-cli/modules/netmap.go index 3b370055..e53ada98 100644 --- a/cmd/neofs-cli/modules/netmap.go +++ b/cmd/neofs-cli/modules/netmap.go @@ -7,6 +7,7 @@ import ( "github.com/mr-tron/base58" "github.com/nspcc-dev/neo-go/pkg/config/netmode" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" nmClient "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap" "github.com/nspcc-dev/neofs-node/pkg/services/control" @@ -67,7 +68,7 @@ var getEpochCmd = &cobra.Command{ prepareAPIClient(cmd, &prm) res, err := internalclient.NetworkInfo(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) netInfo := res.NetworkInfo() @@ -85,7 +86,7 @@ var localNodeInfoCmd = &cobra.Command{ prepareAPIClient(cmd, &prm) res, err := internalclient.NodeInfo(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) prettyPrintNodeInfo(cmd, res.NodeInfo(), nodeInfoJSON) }, @@ -157,7 +158,7 @@ var netInfoCmd = &cobra.Command{ prepareAPIClient(cmd, &prm) res, err := internalclient.NetworkInfo(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) netInfo := res.NetworkInfo() @@ -182,7 +183,7 @@ var netInfoCmd = &cobra.Command{ return err }) - exitOnErr(cmd, errf("read config: %w", err)) + common.ExitOnErr(cmd, "read config: %w", err) }, } diff --git a/cmd/neofs-cli/modules/object.go b/cmd/neofs-cli/modules/object.go index e4a2175f..1026d3ac 100644 --- a/cmd/neofs-cli/modules/object.go +++ b/cmd/neofs-cli/modules/object.go @@ -18,6 +18,7 @@ import ( objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object" "github.com/nspcc-dev/neofs-api-go/v2/refs" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" sessionCli "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/session" "github.com/nspcc-dev/neofs-sdk-go/bearer" @@ -318,14 +319,14 @@ type clientKeySession interface { func prepareSessionPrm(cmd *cobra.Command, addr *addressSDK.Address, prms ...clientKeySession) { key, err := getKey() - exitOnErr(cmd, errf("get private key: %w", err)) + common.ExitOnErr(cmd, "get private key: %w", err) prepareSessionPrmWithKey(cmd, addr, key, prms...) } func prepareSessionPrmWithKey(cmd *cobra.Command, addr *addressSDK.Address, key *ecdsa.PrivateKey, prms ...clientKeySession) { ownerID, err := getOwnerID(key) - exitOnErr(cmd, errf("owner ID from key: %w", err)) + common.ExitOnErr(cmd, "owner ID from key: %w", err) prepareSessionPrmWithOwner(cmd, addr, key, ownerID, prms...) } @@ -338,21 +339,21 @@ func prepareSessionPrmWithOwner( prms ...clientKeySession, ) { cli, err := internalclient.GetSDKClientByFlag(key, commonflags.RPC) - exitOnErr(cmd, errf("create API client: %w", err)) + common.ExitOnErr(cmd, "create API client: %w", err) var sessionToken *session.Token if tokenPath, _ := cmd.Flags().GetString(sessionTokenFlag); len(tokenPath) != 0 { data, err := ioutil.ReadFile(tokenPath) - exitOnErr(cmd, errf("can't read session token: %w", err)) + common.ExitOnErr(cmd, "can't read session token: %w", err) sessionToken = session.NewToken() if err := sessionToken.Unmarshal(data); err != nil { err = sessionToken.UnmarshalJSON(data) - exitOnErr(cmd, errf("can't unmarshal session token: %w", err)) + common.ExitOnErr(cmd, "can't unmarshal session token: %w", err) } } else { sessionToken, err = sessionCli.CreateSession(cli, ownerID, sessionTokenLifetime) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) } for i := range prms { @@ -387,7 +388,7 @@ func prepareSessionPrmWithOwner( tok.SetNbf(sessionToken.Nbf()) err = tok.Sign(key) - exitOnErr(cmd, errf("session token signing: %w", err)) + common.ExitOnErr(cmd, "session token signing: %w", err) prms[i].SetClient(cli) prms[i].SetSessionToken(tok) @@ -421,21 +422,21 @@ func prepareObjectPrmRaw(cmd *cobra.Command, prm interface { func putObject(cmd *cobra.Command, _ []string) { key, err := getKey() - exitOnErr(cmd, errf("can't fetch private key: %w", err)) + common.ExitOnErr(cmd, "can't fetch private key: %w", err) ownerID, err := getOwnerID(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) cnr, err := getCID(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) filename := cmd.Flag("file").Value.String() f, err := os.OpenFile(filename, os.O_RDONLY, os.ModePerm) if err != nil { - exitOnErr(cmd, fmt.Errorf("can't open file '%s': %w", filename, err)) + common.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err)) } attrs, err := parseObjectAttrs(cmd) - exitOnErr(cmd, errf("can't parse object attributes: %w", err)) + common.ExitOnErr(cmd, "can't parse object attributes: %w", err) expiresOn, _ := cmd.Flags().GetUint64(putExpiresOnFlag) if expiresOn > 0 { @@ -464,7 +465,7 @@ func putObject(cmd *cobra.Command, _ []string) { obj.SetAttributes(attrs...) notificationInfo, err := parseObjectNotifications(cmd) - exitOnErr(cmd, errf("can't parse object notification information: %w", err)) + common.ExitOnErr(cmd, "can't parse object notification information: %w", err) if notificationInfo != nil { obj.SetNotification(*notificationInfo) @@ -497,7 +498,7 @@ func putObject(cmd *cobra.Command, _ []string) { } res, err := internalclient.PutObject(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) if p != nil { p.Finish() @@ -508,7 +509,7 @@ func putObject(cmd *cobra.Command, _ []string) { func deleteObject(cmd *cobra.Command, _ []string) { objAddr, err := getObjectAddress(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var prm internalclient.DeleteObjectPrm @@ -517,7 +518,7 @@ func deleteObject(cmd *cobra.Command, _ []string) { prm.SetAddress(objAddr) res, err := internalclient.DeleteObject(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) tombstoneAddr := res.TombstoneAddress() @@ -545,7 +546,7 @@ func deleteObject(cmd *cobra.Command, _ []string) { func getObject(cmd *cobra.Command, _ []string) { objAddr, err := getObjectAddress(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var out io.Writer filename := cmd.Flag("file").Value.String() @@ -554,7 +555,7 @@ func getObject(cmd *cobra.Command, _ []string) { } else { f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, os.ModePerm) if err != nil { - exitOnErr(cmd, fmt.Errorf("can't open file '%s': %w", filename, err)) + common.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err)) } defer f.Close() @@ -589,7 +590,7 @@ func getObject(cmd *cobra.Command, _ []string) { return } - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) } hdrFile := cmd.Flag("header").Value.String() @@ -605,13 +606,13 @@ func getObject(cmd *cobra.Command, _ []string) { // Print header only if file is not streamed to stdout. if filename != "" || hdrFile != "" { err = saveAndPrintHeader(cmd, res.Header(), hdrFile) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) } } func getObjectHeader(cmd *cobra.Command, _ []string) { objAddr, err := getObjectAddress(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) mainOnly, _ := cmd.Flags().GetBool("main-only") @@ -628,19 +629,19 @@ func getObjectHeader(cmd *cobra.Command, _ []string) { return } - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) } err = saveAndPrintHeader(cmd, res.Header(), cmd.Flag("file").Value.String()) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) } func searchObject(cmd *cobra.Command, _ []string) { cnr, err := getCID(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) sf, err := parseSearchFilters(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var prm internalclient.SearchObjectsPrm @@ -652,7 +653,7 @@ func searchObject(cmd *cobra.Command, _ []string) { prm.SetFilters(sf) res, err := internalclient.SearchObjects(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) ids := res.IDList() @@ -664,16 +665,16 @@ func searchObject(cmd *cobra.Command, _ []string) { func getObjectHash(cmd *cobra.Command, _ []string) { objAddr, err := getObjectAddress(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) ranges, err := getRangeList(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) typ, err := getHashType(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) strSalt := strings.TrimPrefix(cmd.Flag(getRangeHashSaltFlag).Value.String(), "0x") salt, err := hex.DecodeString(strSalt) - exitOnErr(cmd, errf("could not decode salt: %w", err)) + common.ExitOnErr(cmd, "could not decode salt: %w", err) var ( hashPrm internalclient.HashPayloadRangesPrm @@ -699,7 +700,7 @@ func getObjectHash(cmd *cobra.Command, _ []string) { // get hash of full payload through HEAD (may be user can do it through dedicated command?) res, err := internalclient.HeadObject(headPrm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) var cs checksum.Checksum var csSet bool @@ -728,7 +729,7 @@ func getObjectHash(cmd *cobra.Command, _ []string) { } res, err := internalclient.HashPayloadRanges(hashPrm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) hs := res.HashList() @@ -1134,13 +1135,13 @@ func getBearerToken(cmd *cobra.Command, flagname string) (*bearer.Token, error) func getObjectRange(cmd *cobra.Command, _ []string) { objAddr, err := getObjectAddress(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) ranges, err := getRangeList(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) if len(ranges) != 1 { - exitOnErr(cmd, fmt.Errorf("exactly one range must be specified, got: %d", len(ranges))) + common.ExitOnErr(cmd, "", fmt.Errorf("exactly one range must be specified, got: %d", len(ranges))) } var out io.Writer @@ -1151,7 +1152,7 @@ func getObjectRange(cmd *cobra.Command, _ []string) { } else { f, err := os.OpenFile(filename, os.O_CREATE|os.O_WRONLY, os.ModePerm) if err != nil { - exitOnErr(cmd, fmt.Errorf("can't open file '%s': %w", filename, err)) + common.ExitOnErr(cmd, "", fmt.Errorf("can't open file '%s': %w", filename, err)) } defer f.Close() @@ -1173,7 +1174,7 @@ func getObjectRange(cmd *cobra.Command, _ []string) { return } - exitOnErr(cmd, fmt.Errorf("can't get object payload range: %w", err)) + common.ExitOnErr(cmd, "can't get object payload range: %w", err) } if filename != "" { @@ -1196,7 +1197,7 @@ func printSplitInfoErr(cmd *cobra.Command, err error) bool { func printSplitInfo(cmd *cobra.Command, info *object.SplitInfo) { bs, err := marshalSplitInfo(cmd, info) - exitOnErr(cmd, errf("can't marshal split info: %w", err)) + common.ExitOnErr(cmd, "can't marshal split info: %w", err) cmd.Println(string(bs)) } diff --git a/cmd/neofs-cli/modules/restore.go b/cmd/neofs-cli/modules/restore.go index 7ddd265b..fb2c44f5 100644 --- a/cmd/neofs-cli/modules/restore.go +++ b/cmd/neofs-cli/modules/restore.go @@ -3,6 +3,7 @@ package cmd import ( "github.com/mr-tron/base58" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/pkg/services/control" controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server" @@ -23,12 +24,12 @@ var restoreShardCmd = &cobra.Command{ func restoreShard(cmd *cobra.Command, _ []string) { key, err := getKeyNoGenerate() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) body := new(control.RestoreShardRequest_Body) rawID, err := base58.Decode(shardID) - exitOnErr(cmd, errf("incorrect shard ID encoding: %w", err)) + common.ExitOnErr(cmd, "incorrect shard ID encoding: %w", err) body.SetShardID(rawID) p, _ := cmd.Flags().GetString(restoreFilepathFlag) @@ -41,17 +42,17 @@ func restoreShard(cmd *cobra.Command, _ []string) { req.SetBody(body) err = controlSvc.SignMessage(key, req) - exitOnErr(cmd, errf("could not sign request: %w", err)) + common.ExitOnErr(cmd, "could not sign request: %w", err) cli, err := getControlSDKClient(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var resp *control.RestoreShardResponse err = cli.ExecRaw(func(client *client.Client) error { resp, err = control.RestoreShard(client, req) return err }) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) verifyResponseControl(cmd, resp.GetSignature(), resp.GetBody()) diff --git a/cmd/neofs-cli/modules/root.go b/cmd/neofs-cli/modules/root.go index e8e827ce..c367d2d8 100644 --- a/cmd/neofs-cli/modules/root.go +++ b/cmd/neofs-cli/modules/root.go @@ -10,6 +10,7 @@ import ( "github.com/mitchellh/go-homedir" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/key" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/modules/acl" @@ -65,7 +66,7 @@ and much more!`, // This is called by main.main(). It only needs to happen once to the rootCmd. func Execute() { err := rootCmd.Execute() - exitOnErr(rootCmd, err) + common.ExitOnErr(rootCmd, "", err) } func init() { @@ -116,7 +117,7 @@ func initConfig() { } else { // Find home directory. home, err := homedir.Dir() - exitOnErr(rootCmd, err) + common.ExitOnErr(rootCmd, "", err) // Search config in `$HOME/.config/neofs-cli/` with name "config.yaml" viper.AddConfigPath(filepath.Join(home, ".config", "neofs-cli")) @@ -149,7 +150,7 @@ type clientWithKey interface { // reads private key from command args and call prepareAPIClientWithKey with it. func prepareAPIClient(cmd *cobra.Command, dst ...clientWithKey) { p, err := getKey() - exitOnErr(cmd, errf("get private key: %w", err)) + common.ExitOnErr(cmd, "get private key: %w", err) prepareAPIClientWithKey(cmd, p, dst...) } @@ -157,7 +158,7 @@ func prepareAPIClient(cmd *cobra.Command, dst ...clientWithKey) { // creates NeoFS API client and writes it to target along with the private key. func prepareAPIClientWithKey(cmd *cobra.Command, key *ecdsa.PrivateKey, dst ...clientWithKey) { cli, err := internalclient.GetSDKClientByFlag(key, commonflags.RPC) - exitOnErr(cmd, errf("create API client: %w", err)) + common.ExitOnErr(cmd, "create API client: %w", err) for _, d := range dst { d.SetClient(cli) @@ -170,7 +171,7 @@ type bearerPrm interface { func prepareBearerPrm(cmd *cobra.Command, prm bearerPrm) { btok, err := getBearerToken(cmd, bearerTokenFlag) - exitOnErr(cmd, errf("bearer token: %w", err)) + common.ExitOnErr(cmd, "bearer token: %w", err) prm.SetBearerToken(btok) } diff --git a/cmd/neofs-cli/modules/storagegroup.go b/cmd/neofs-cli/modules/storagegroup.go index 88454b15..7534ba3e 100644 --- a/cmd/neofs-cli/modules/storagegroup.go +++ b/cmd/neofs-cli/modules/storagegroup.go @@ -7,6 +7,7 @@ import ( "fmt" internalclient "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/client" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/pkg/services/object_manager/storagegroup" "github.com/nspcc-dev/neofs-sdk-go/object" @@ -163,19 +164,19 @@ func (c sgHeadReceiver) Head(addr *addressSDK.Address) (interface{}, error) { func putSG(cmd *cobra.Command, _ []string) { key, err := getKey() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) ownerID, err := getOwnerID(key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) cnr, err := getCID(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) members := make([]oidSDK.ID, len(sgMembers)) for i := range sgMembers { err = members[i].DecodeString(sgMembers[i]) - exitOnErr(cmd, errf("could not parse object ID: %w", err)) + common.ExitOnErr(cmd, "could not parse object ID: %w", err) } var ( @@ -196,10 +197,10 @@ func putSG(cmd *cobra.Command, _ []string) { ownerID: ownerID, prm: headPrm, }, cnr, members) - exitOnErr(cmd, errf("could not collect storage group members: %w", err)) + common.ExitOnErr(cmd, "could not collect storage group members: %w", err) sgContent, err := sg.Marshal() - exitOnErr(cmd, errf("could not marshal storage group: %w", err)) + common.ExitOnErr(cmd, "could not marshal storage group: %w", err) obj := object.New() obj.SetContainerID(*cnr) @@ -210,7 +211,7 @@ func putSG(cmd *cobra.Command, _ []string) { putPrm.SetPayloadReader(bytes.NewReader(sgContent)) res, err := internalclient.PutObject(putPrm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) cmd.Println("Storage group successfully stored") cmd.Printf(" ID: %s\n CID: %s\n", res.ID(), cnr) @@ -228,10 +229,10 @@ func getSGID() (*oidSDK.ID, error) { func getSG(cmd *cobra.Command, _ []string) { cnr, err := getCID(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) id, err := getSGID() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) addr := addressSDK.NewAddress() addr.SetContainerID(*cnr) @@ -247,12 +248,12 @@ func getSG(cmd *cobra.Command, _ []string) { prm.SetPayloadWriter(buf) _, err = internalclient.GetObject(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) var sg storagegroupAPI.StorageGroup err = sg.Unmarshal(buf.Bytes()) - exitOnErr(cmd, errf("could not unmarshal storage group: %w", err)) + common.ExitOnErr(cmd, "could not unmarshal storage group: %w", err) cmd.Printf("Expiration epoch: %d\n", sg.ExpirationEpoch()) cmd.Printf("Group size: %d\n", sg.ValidationDataSize()) @@ -269,7 +270,7 @@ func getSG(cmd *cobra.Command, _ []string) { func listSG(cmd *cobra.Command, _ []string) { cnr, err := getCID(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var prm internalclient.SearchObjectsPrm @@ -281,7 +282,7 @@ func listSG(cmd *cobra.Command, _ []string) { prm.SetFilters(storagegroup.SearchQuery()) res, err := internalclient.SearchObjects(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) ids := res.IDList() @@ -294,10 +295,10 @@ func listSG(cmd *cobra.Command, _ []string) { func delSG(cmd *cobra.Command, _ []string) { cnr, err := getCID(cmd) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) id, err := getSGID() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) addr := addressSDK.NewAddress() addr.SetContainerID(*cnr) @@ -310,7 +311,7 @@ func delSG(cmd *cobra.Command, _ []string) { prm.SetAddress(addr) res, err := internalclient.DeleteObject(prm) - exitOnErr(cmd, errf("rpc error: %w", err)) + common.ExitOnErr(cmd, "rpc error: %w", err) tombstone := res.TombstoneAddress() diff --git a/cmd/neofs-cli/modules/util.go b/cmd/neofs-cli/modules/util.go index 854498e5..423317d3 100644 --- a/cmd/neofs-cli/modules/util.go +++ b/cmd/neofs-cli/modules/util.go @@ -10,6 +10,7 @@ import ( "strconv" "time" + "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/common" "github.com/nspcc-dev/neofs-node/cmd/neofs-cli/internal/commonflags" "github.com/nspcc-dev/neofs-node/pkg/util/keyer" locodedb "github.com/nspcc-dev/neofs-node/pkg/util/locode/db" @@ -17,7 +18,6 @@ import ( locodebolt "github.com/nspcc-dev/neofs-node/pkg/util/locode/db/boltdb" continentsdb "github.com/nspcc-dev/neofs-node/pkg/util/locode/db/continents/geojson" csvlocode "github.com/nspcc-dev/neofs-node/pkg/util/locode/table/csv" - sdkstatus "github.com/nspcc-dev/neofs-sdk-go/client/status" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -126,7 +126,7 @@ var ( }) err := targetDB.Open() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) defer targetDB.Close() @@ -136,7 +136,7 @@ var ( } err = locodedb.FillDatabase(locodeDB, airportDB, continentsDB, names, targetDB) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) }, } ) @@ -159,12 +159,12 @@ var ( }, locodebolt.ReadOnly()) err := targetDB.Open() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) defer targetDB.Close() record, err := locodedb.LocodeRecord(targetDB, locodeInfoCode) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) cmd.Printf("Country: %s\n", record.CountryName()) cmd.Printf("Location: %s\n", record.LocationName()) @@ -281,13 +281,13 @@ func init() { func signBearerToken(cmd *cobra.Command, _ []string) { btok, err := getBearerToken(cmd, "from") - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) key, err := getKey() - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) err = btok.Sign(*key) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) to := cmd.Flag("to").Value.String() jsonFlag, _ := cmd.Flags().GetBool("json") @@ -295,7 +295,7 @@ func signBearerToken(cmd *cobra.Command, _ []string) { var data []byte if jsonFlag || len(to) == 0 { data, err = btok.MarshalJSON() - exitOnErr(cmd, errf("can't JSON encode bearer token: %w", err)) + common.ExitOnErr(cmd, "can't JSON encode bearer token: %w", err) } else { data = btok.Marshal() } @@ -307,28 +307,28 @@ func signBearerToken(cmd *cobra.Command, _ []string) { } err = os.WriteFile(to, data, 0644) - exitOnErr(cmd, errf("can't write signed bearer token to file: %w", err)) + common.ExitOnErr(cmd, "can't write signed bearer token to file: %w", err) cmd.Printf("signed bearer token was successfully dumped to %s\n", to) } func signSessionToken(cmd *cobra.Command, _ []string) { path, err := cmd.Flags().GetString("from") - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) stok, err := getSessionToken(path) if err != nil { - exitOnErr(cmd, fmt.Errorf("can't read session token from %s: %w", path, err)) + common.ExitOnErr(cmd, "", fmt.Errorf("can't read session token from %s: %w", path, err)) } key, err := getKey() - exitOnErr(cmd, errf("can't get private key, make sure it is provided: %w", err)) + common.ExitOnErr(cmd, "can't get private key, make sure it is provided: %w", err) err = stok.Sign(key) - exitOnErr(cmd, errf("can't sign token: %w", err)) + common.ExitOnErr(cmd, "can't sign token: %w", err) data, err := stok.MarshalJSON() - exitOnErr(cmd, errf("can't encode session token: %w", err)) + common.ExitOnErr(cmd, "can't encode session token: %w", err) to := cmd.Flag("to").Value.String() if len(to) == 0 { @@ -338,7 +338,7 @@ func signSessionToken(cmd *cobra.Command, _ []string) { err = os.WriteFile(to, data, 0644) if err != nil { - exitOnErr(cmd, fmt.Errorf("can't write signed session token to %s: %w", to, err)) + common.ExitOnErr(cmd, "", fmt.Errorf("can't write signed session token to %s: %w", to, err)) } cmd.Printf("signed session token saved in %s\n", to) @@ -350,24 +350,23 @@ func convertEACLTable(cmd *cobra.Command, _ []string) { jsonFlag, _ := cmd.Flags().GetBool("json") table, err := parseEACL(pathFrom) - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) var data []byte if jsonFlag || len(to) == 0 { data, err = table.MarshalJSON() - exitOnErr(cmd, errf("can't JSON encode extended ACL table: %w", err)) + common.ExitOnErr(cmd, "can't JSON encode extended ACL table: %w", err) } else { data, err = table.Marshal() - exitOnErr(cmd, errf("can't binary encode extended ACL table: %w", err)) + common.ExitOnErr(cmd, "can't binary encode extended ACL table: %w", err) } if len(to) == 0 { prettyPrintJSON(cmd, data) return } - err = os.WriteFile(to, data, 0644) - exitOnErr(cmd, errf("can't write exteded ACL table to file: %w", err)) + common.ExitOnErr(cmd, "can't write exteded ACL table to file: %w", err) cmd.Printf("extended ACL table was successfully dumped to %s\n", to) } @@ -387,7 +386,7 @@ func processKeyer(cmd *cobra.Command, args []string) { err = result.ParseMultiSig(args) } else { if len(args) > 1 { - exitOnErr(cmd, errKeyerSingleArgument) + common.ExitOnErr(cmd, "", errKeyerSingleArgument) } var argument string @@ -405,7 +404,7 @@ func processKeyer(cmd *cobra.Command, args []string) { } } - exitOnErr(cmd, err) + common.ExitOnErr(cmd, "", err) result.PrettyPrint(uncompressed, useHex) } @@ -467,49 +466,3 @@ func keyerParseFile(filename string, d *keyer.Dashboard) error { return d.ParseBinary(data) } - -// errf returns formatted error in errFmt format -// if err is not nil. -func errf(errFmt string, err error) error { - if err == nil { - return nil - } - - return fmt.Errorf(errFmt, err) -} - -// exitOnErr prints error and exits with a code that matches -// one of the common errors from sdk library. If no errors -// found, exits with 1 code. -// Does nothing if passed error in nil. -func exitOnErr(cmd *cobra.Command, err error) { - if err == nil { - return - } - - const ( - _ = iota - internal - aclDenied - ) - - var ( - code int - - internalErr = new(sdkstatus.ServerInternal) - accessErr = new(sdkstatus.ObjectAccessDenied) - ) - - switch { - case errors.As(err, &internalErr): - code = internal - case errors.As(err, &accessErr): - code = aclDenied - err = fmt.Errorf("%w: %s", err, accessErr.Reason()) - default: - code = internal - } - - cmd.PrintErrln(err) - os.Exit(code) -}