forked from TrueCloudLab/frostfs-node
[#854] cli: Do not use global flags
Also delete `ttl` and `xhdr` flags from `accounting balance` command and refactor command initialization. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
4ccb3d05d8
commit
8c59ade4ed
8 changed files with 562 additions and 219 deletions
|
@ -8,6 +8,7 @@ import (
|
||||||
"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/owner"
|
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -19,6 +20,16 @@ var accountingCmd = &cobra.Command{
|
||||||
Use: "accounting",
|
Use: "accounting",
|
||||||
Short: "Operations with accounts and balances",
|
Short: "Operations with accounts and balances",
|
||||||
Long: `Operations with accounts and balances`,
|
Long: `Operations with accounts and balances`,
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
_ = viper.BindPFlag(binaryKey, flags.Lookup(binaryKey))
|
||||||
|
_ = viper.BindPFlag(walletPath, flags.Lookup(walletPath))
|
||||||
|
_ = viper.BindPFlag(wif, flags.Lookup(wif))
|
||||||
|
_ = viper.BindPFlag(address, flags.Lookup(address))
|
||||||
|
_ = viper.BindPFlag(rpc, flags.Lookup(rpc))
|
||||||
|
_ = viper.BindPFlag(verbose, flags.Lookup(verbose))
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var accountingBalanceCmd = &cobra.Command{
|
var accountingBalanceCmd = &cobra.Command{
|
||||||
|
@ -57,6 +68,19 @@ var accountingBalanceCmd = &cobra.Command{
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initAccountingBalanceCmd() {
|
||||||
|
ff := accountingBalanceCmd.Flags()
|
||||||
|
|
||||||
|
ff.StringP(binaryKey, binaryKeyShorthand, binaryKeyDefault, binaryKeyUsage)
|
||||||
|
ff.StringP(walletPath, walletPathShorthand, walletPathDefault, walletPathUsage)
|
||||||
|
ff.StringP(wif, wifShorthand, wifDefault, wifUsage)
|
||||||
|
ff.StringP(address, addressShorthand, addressDefault, addressUsage)
|
||||||
|
ff.StringP(rpc, rpcShorthand, rpcDefault, rpcUsage)
|
||||||
|
ff.BoolP(verbose, verboseShorthand, verboseDefault, verboseUsage)
|
||||||
|
|
||||||
|
accountingBalanceCmd.Flags().StringVar(&balanceOwner, "owner", "", "owner of balance account (omit to use owner from private key)")
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(accountingCmd)
|
rootCmd.AddCommand(accountingCmd)
|
||||||
accountingCmd.AddCommand(accountingBalanceCmd)
|
accountingCmd.AddCommand(accountingBalanceCmd)
|
||||||
|
@ -71,7 +95,7 @@ func init() {
|
||||||
// is called directly, e.g.:
|
// is called directly, e.g.:
|
||||||
// accountingCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
// accountingCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
|
|
||||||
accountingBalanceCmd.Flags().StringVar(&balanceOwner, "owner", "", "owner of balance account (omit to use owner from private key)")
|
initAccountingBalanceCmd()
|
||||||
}
|
}
|
||||||
|
|
||||||
func prettyPrintDecimal(cmd *cobra.Command, decimal *accounting.Decimal) {
|
func prettyPrintDecimal(cmd *cobra.Command, decimal *accounting.Decimal) {
|
||||||
|
@ -79,7 +103,7 @@ func prettyPrintDecimal(cmd *cobra.Command, decimal *accounting.Decimal) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if verbose {
|
if viper.GetBool(verbose) {
|
||||||
cmd.Println("value:", decimal.Value())
|
cmd.Println("value:", decimal.Value())
|
||||||
cmd.Println("precision:", decimal.Precision())
|
cmd.Println("precision:", decimal.Precision())
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -79,6 +79,11 @@ var containerCmd = &cobra.Command{
|
||||||
Use: "container",
|
Use: "container",
|
||||||
Short: "Operations with containers",
|
Short: "Operations with containers",
|
||||||
Long: "Operations with containers",
|
Long: "Operations with containers",
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
// bind exactly that cmd's flags to
|
||||||
|
// the viper before execution
|
||||||
|
bindCommonFlags(cmd)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var listContainersCmd = &cobra.Command{
|
var listContainersCmd = &cobra.Command{
|
||||||
|
@ -429,15 +434,89 @@ Container ID in EACL table will be substituted with ID from the CLI.`,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func initContainerListContainersCmd() {
|
||||||
|
initCommonFlags(listContainersCmd)
|
||||||
|
|
||||||
|
flags := listContainersCmd.Flags()
|
||||||
|
|
||||||
|
flags.StringVar(&containerOwner, "owner", "", "owner of containers (omit to use owner from private key)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initContainerCreateCmd() {
|
||||||
|
initCommonFlags(createContainerCmd)
|
||||||
|
|
||||||
|
flags := createContainerCmd.Flags()
|
||||||
|
|
||||||
|
flags.StringVar(&containerACL, "basic-acl", basicACLPrivate, fmt.Sprintf("hex encoded basic ACL value or keywords '%s', '%s', '%s'", basicACLPublic, basicACLPrivate, basicACLReadOnly))
|
||||||
|
flags.StringVarP(&containerPolicy, "policy", "p", "", "QL-encoded or JSON-encoded placement policy or path to file with it")
|
||||||
|
flags.StringSliceVarP(&containerAttributes, "attributes", "a", nil, "comma separated pairs of container attributes in form of Key1=Value1,Key2=Value2")
|
||||||
|
flags.StringVarP(&containerNonce, "nonce", "n", "", "UUIDv4 nonce value for container")
|
||||||
|
flags.BoolVar(&containerAwait, "await", false, "block execution until container is persisted")
|
||||||
|
flags.StringVar(&containerName, "name", "", "container name attribute")
|
||||||
|
flags.BoolVar(&containerNoTimestamp, "disable-timestamp", false, "disable timestamp container attribute")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initContainerDeleteCmd() {
|
||||||
|
initCommonFlags(deleteContainerCmd)
|
||||||
|
|
||||||
|
flags := deleteContainerCmd.Flags()
|
||||||
|
|
||||||
|
flags.StringVar(&containerID, "cid", "", "container ID")
|
||||||
|
flags.BoolVar(&containerAwait, "await", false, "block execution until container is removed")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initContainerListObjectsCmd() {
|
||||||
|
initCommonFlags(listContainerObjectsCmd)
|
||||||
|
|
||||||
|
flags := listContainerObjectsCmd.Flags()
|
||||||
|
|
||||||
|
flags.StringVar(&containerID, "cid", "", "container ID")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initContainerInfoCmd() {
|
||||||
|
initCommonFlags(getContainerInfoCmd)
|
||||||
|
|
||||||
|
flags := getContainerInfoCmd.Flags()
|
||||||
|
|
||||||
|
flags.StringVar(&containerID, "cid", "", "container ID")
|
||||||
|
flags.StringVar(&containerPathTo, "to", "", "path to dump encoded container")
|
||||||
|
flags.StringVar(&containerPathFrom, "from", "", "path to file with encoded container")
|
||||||
|
flags.BoolVar(&containerJSON, "json", false, "print or dump container in JSON format")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initContainerGetEACLCmd() {
|
||||||
|
initCommonFlags(getExtendedACLCmd)
|
||||||
|
|
||||||
|
flags := getExtendedACLCmd.Flags()
|
||||||
|
|
||||||
|
flags.StringVar(&containerID, "cid", "", "container ID")
|
||||||
|
flags.StringVar(&containerPathTo, "to", "", "path to dump encoded container (default: binary encoded)")
|
||||||
|
flags.BoolVar(&containerJSON, "json", false, "encode EACL table in json format")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initContainerSetEACLCmd() {
|
||||||
|
initCommonFlags(setExtendedACLCmd)
|
||||||
|
|
||||||
|
flags := setExtendedACLCmd.Flags()
|
||||||
|
flags.StringVar(&containerID, "cid", "", "container ID")
|
||||||
|
flags.StringVar(&eaclPathFrom, "table", "", "path to file with JSON or binary encoded EACL table")
|
||||||
|
flags.BoolVar(&containerAwait, "await", false, "block execution until EACL is persisted")
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
containerChildCommand := []*cobra.Command{
|
||||||
|
listContainersCmd,
|
||||||
|
createContainerCmd,
|
||||||
|
deleteContainerCmd,
|
||||||
|
listContainerObjectsCmd,
|
||||||
|
getContainerInfoCmd,
|
||||||
|
getExtendedACLCmd,
|
||||||
|
setExtendedACLCmd,
|
||||||
|
}
|
||||||
|
|
||||||
rootCmd.AddCommand(containerCmd)
|
rootCmd.AddCommand(containerCmd)
|
||||||
containerCmd.AddCommand(listContainersCmd)
|
|
||||||
containerCmd.AddCommand(createContainerCmd)
|
containerCmd.AddCommand(containerChildCommand...)
|
||||||
containerCmd.AddCommand(deleteContainerCmd)
|
|
||||||
containerCmd.AddCommand(listContainerObjectsCmd)
|
|
||||||
containerCmd.AddCommand(getContainerInfoCmd)
|
|
||||||
containerCmd.AddCommand(getExtendedACLCmd)
|
|
||||||
containerCmd.AddCommand(setExtendedACLCmd)
|
|
||||||
|
|
||||||
// Here you will define your flags and configuration settings.
|
// Here you will define your flags and configuration settings.
|
||||||
|
|
||||||
|
@ -449,43 +528,20 @@ func init() {
|
||||||
// is called directly, e.g.:
|
// is called directly, e.g.:
|
||||||
// containerCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
// containerCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
|
|
||||||
// container list
|
initContainerListContainersCmd()
|
||||||
listContainersCmd.Flags().StringVar(&containerOwner, "owner", "", "owner of containers (omit to use owner from private key)")
|
initContainerCreateCmd()
|
||||||
|
initContainerDeleteCmd()
|
||||||
|
initContainerListObjectsCmd()
|
||||||
|
initContainerInfoCmd()
|
||||||
|
initContainerGetEACLCmd()
|
||||||
|
initContainerSetEACLCmd()
|
||||||
|
|
||||||
// container create
|
for _, containerCommand := range containerChildCommand {
|
||||||
createContainerCmd.Flags().StringVar(&containerACL, "basic-acl", basicACLPrivate,
|
flags := containerCommand.Flags()
|
||||||
fmt.Sprintf("hex encoded basic ACL value or keywords '%s', '%s', '%s'", basicACLPublic, basicACLPrivate, basicACLReadOnly))
|
|
||||||
createContainerCmd.Flags().StringVarP(&containerPolicy, "policy", "p", "",
|
|
||||||
"QL-encoded or JSON-encoded placement policy or path to file with it")
|
|
||||||
createContainerCmd.Flags().StringSliceVarP(&containerAttributes, "attributes", "a", nil,
|
|
||||||
"comma separated pairs of container attributes in form of Key1=Value1,Key2=Value2")
|
|
||||||
createContainerCmd.Flags().StringVarP(&containerNonce, "nonce", "n", "", "UUIDv4 nonce value for container")
|
|
||||||
createContainerCmd.Flags().BoolVar(&containerAwait, "await", false, "block execution until container is persisted")
|
|
||||||
createContainerCmd.Flags().StringVar(&containerName, "name", "", "container name attribute")
|
|
||||||
createContainerCmd.Flags().BoolVar(&containerNoTimestamp, "disable-timestamp", false, "disable timestamp container attribute")
|
|
||||||
|
|
||||||
// container delete
|
flags.StringSliceVarP(&xHeaders, xHeadersKey, xHeadersShorthand, xHeadersDefault, xHeadersUsage)
|
||||||
deleteContainerCmd.Flags().StringVar(&containerID, "cid", "", "container ID")
|
flags.Uint32P(ttl, ttlShorthand, ttlDefault, ttlUsage)
|
||||||
deleteContainerCmd.Flags().BoolVar(&containerAwait, "await", false, "block execution until container is removed")
|
}
|
||||||
|
|
||||||
// container list-object
|
|
||||||
listContainerObjectsCmd.Flags().StringVar(&containerID, "cid", "", "container ID")
|
|
||||||
|
|
||||||
// container get
|
|
||||||
getContainerInfoCmd.Flags().StringVar(&containerID, "cid", "", "container ID")
|
|
||||||
getContainerInfoCmd.Flags().StringVar(&containerPathTo, "to", "", "path to dump encoded container")
|
|
||||||
getContainerInfoCmd.Flags().StringVar(&containerPathFrom, "from", "", "path to file with encoded container")
|
|
||||||
getContainerInfoCmd.Flags().BoolVar(&containerJSON, "json", false, "print or dump container in JSON format")
|
|
||||||
|
|
||||||
// container get-eacl
|
|
||||||
getExtendedACLCmd.Flags().StringVar(&containerID, "cid", "", "container ID")
|
|
||||||
getExtendedACLCmd.Flags().StringVar(&containerPathTo, "to", "", "path to dump encoded container (default: binary encoded)")
|
|
||||||
getExtendedACLCmd.Flags().BoolVar(&containerJSON, "json", false, "encode EACL table in json format")
|
|
||||||
|
|
||||||
// container set-eacl
|
|
||||||
setExtendedACLCmd.Flags().StringVar(&containerID, "cid", "", "container ID")
|
|
||||||
setExtendedACLCmd.Flags().StringVar(&eaclPathFrom, "table", "", "path to file with JSON or binary encoded EACL table")
|
|
||||||
setExtendedACLCmd.Flags().BoolVar(&containerAwait, "await", false, "block execution until EACL is persisted")
|
|
||||||
|
|
||||||
for _, cmd := range []*cobra.Command{
|
for _, cmd := range []*cobra.Command{
|
||||||
createContainerCmd,
|
createContainerCmd,
|
||||||
|
|
|
@ -53,6 +53,41 @@ var (
|
||||||
|
|
||||||
var netmapStatus string
|
var netmapStatus string
|
||||||
|
|
||||||
|
func initControlHealthCheckCmd() {
|
||||||
|
initCommonFlags(healthCheckCmd)
|
||||||
|
|
||||||
|
healthCheckCmd.Flags().BoolVar(&healthCheckIRVar, healthcheckIRFlag, false, "Communicate with IR node")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initControlSetNetmapStatusCmd() {
|
||||||
|
initCommonFlags(setNetmapStatusCmd)
|
||||||
|
|
||||||
|
setNetmapStatusCmd.Flags().StringVarP(&netmapStatus, netmapStatusFlag, "", "",
|
||||||
|
fmt.Sprintf("new netmap status keyword ('%s', '%s')",
|
||||||
|
netmapStatusOnline,
|
||||||
|
netmapStatusOffline,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = setNetmapStatusCmd.MarkFlagRequired(netmapStatusFlag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initControlDropObjectsCmd() {
|
||||||
|
initCommonFlags(dropObjectsCmd)
|
||||||
|
|
||||||
|
dropObjectsCmd.Flags().StringSliceVarP(&dropObjectsList, dropObjectsFlag, "o", nil,
|
||||||
|
"List of object addresses to be removed in string format")
|
||||||
|
|
||||||
|
_ = dropObjectsCmd.MarkFlagRequired(dropObjectsFlag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initControlSnapshotCmd() {
|
||||||
|
initCommonFlags(snapshotCmd)
|
||||||
|
|
||||||
|
snapshotCmd.Flags().BoolVar(&netmapSnapshotJSON, "json", false,
|
||||||
|
"print netmap structure in JSON format")
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(controlCmd)
|
rootCmd.AddCommand(controlCmd)
|
||||||
|
|
||||||
|
@ -63,24 +98,10 @@ func init() {
|
||||||
snapshotCmd,
|
snapshotCmd,
|
||||||
)
|
)
|
||||||
|
|
||||||
setNetmapStatusCmd.Flags().StringVarP(&netmapStatus, netmapStatusFlag, "", "",
|
initControlHealthCheckCmd()
|
||||||
fmt.Sprintf("new netmap status keyword ('%s', '%s')",
|
initControlSetNetmapStatusCmd()
|
||||||
netmapStatusOnline,
|
initControlDropObjectsCmd()
|
||||||
netmapStatusOffline,
|
initControlSnapshotCmd()
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
_ = setNetmapStatusCmd.MarkFlagRequired(netmapStatusFlag)
|
|
||||||
|
|
||||||
dropObjectsCmd.Flags().StringSliceVarP(&dropObjectsList, dropObjectsFlag, "o", nil,
|
|
||||||
"List of object addresses to be removed in string format")
|
|
||||||
|
|
||||||
_ = dropObjectsCmd.MarkFlagRequired(dropObjectsFlag)
|
|
||||||
|
|
||||||
healthCheckCmd.Flags().BoolVar(&healthCheckIRVar, healthcheckIRFlag, false, "Communicate with IR node")
|
|
||||||
|
|
||||||
snapshotCmd.Flags().BoolVar(&netmapSnapshotJSON, "json", false,
|
|
||||||
"print netmap structure in JSON format")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func healthCheck(cmd *cobra.Command, _ []string) {
|
func healthCheck(cmd *cobra.Command, _ []string) {
|
||||||
|
|
|
@ -22,18 +22,35 @@ var netmapCmd = &cobra.Command{
|
||||||
Use: "netmap",
|
Use: "netmap",
|
||||||
Short: "Operations with Network Map",
|
Short: "Operations with Network Map",
|
||||||
Long: `Operations with Network Map`,
|
Long: `Operations with Network Map`,
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
// bind exactly that cmd's flags to
|
||||||
|
// the viper before execution
|
||||||
|
bindCommonFlags(cmd)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(netmapCmd)
|
netmapChildCommands := []*cobra.Command{
|
||||||
|
|
||||||
netmapCmd.AddCommand(
|
|
||||||
getEpochCmd,
|
getEpochCmd,
|
||||||
localNodeInfoCmd,
|
localNodeInfoCmd,
|
||||||
netInfoCmd,
|
netInfoCmd,
|
||||||
)
|
}
|
||||||
|
|
||||||
|
rootCmd.AddCommand(netmapCmd)
|
||||||
|
netmapCmd.AddCommand(netmapChildCommands...)
|
||||||
|
|
||||||
|
initCommonFlags(getEpochCmd)
|
||||||
|
initCommonFlags(netInfoCmd)
|
||||||
|
|
||||||
|
initCommonFlags(localNodeInfoCmd)
|
||||||
localNodeInfoCmd.Flags().BoolVar(&nodeInfoJSON, "json", false, "print node info in JSON format")
|
localNodeInfoCmd.Flags().BoolVar(&nodeInfoJSON, "json", false, "print node info in JSON format")
|
||||||
|
|
||||||
|
for _, netmapCommand := range netmapChildCommands {
|
||||||
|
flags := netmapCommand.Flags()
|
||||||
|
|
||||||
|
flags.StringSliceVarP(&xHeaders, xHeadersKey, xHeadersShorthand, xHeadersDefault, xHeadersUsage)
|
||||||
|
flags.Uint32P(ttl, ttlShorthand, ttlDefault, ttlUsage)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var getEpochCmd = &cobra.Command{
|
var getEpochCmd = &cobra.Command{
|
||||||
|
|
|
@ -42,6 +42,11 @@ var (
|
||||||
Use: "object",
|
Use: "object",
|
||||||
Short: "Operations with Objects",
|
Short: "Operations with Objects",
|
||||||
Long: `Operations with Objects`,
|
Long: `Operations with Objects`,
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
// bind exactly that cmd's flags to
|
||||||
|
// the viper before execution
|
||||||
|
bindCommonFlags(cmd)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
objectPutCmd = &cobra.Command{
|
objectPutCmd = &cobra.Command{
|
||||||
|
@ -114,74 +119,139 @@ const putExpiresOnFlag = "expires-on"
|
||||||
|
|
||||||
var putExpiredOn uint64
|
var putExpiredOn uint64
|
||||||
|
|
||||||
func init() {
|
func initObjectPutCmd() {
|
||||||
rootCmd.AddCommand(objectCmd)
|
initCommonFlags(objectPutCmd)
|
||||||
objectCmd.PersistentFlags().String("bearer", "", "File with signed JSON or binary encoded bearer token")
|
|
||||||
|
|
||||||
objectCmd.AddCommand(objectPutCmd)
|
flags := objectPutCmd.Flags()
|
||||||
objectPutCmd.Flags().String("file", "", "File with object payload")
|
|
||||||
|
flags.String("file", "", "File with object payload")
|
||||||
_ = objectPutCmd.MarkFlagFilename("file")
|
_ = objectPutCmd.MarkFlagFilename("file")
|
||||||
_ = objectPutCmd.MarkFlagRequired("file")
|
_ = objectPutCmd.MarkFlagRequired("file")
|
||||||
objectPutCmd.Flags().String("cid", "", "Container ID")
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = objectPutCmd.MarkFlagRequired("cid")
|
_ = objectPutCmd.MarkFlagRequired("cid")
|
||||||
objectPutCmd.Flags().String("attributes", "", "User attributes in form of Key1=Value1,Key2=Value2")
|
|
||||||
objectPutCmd.Flags().Bool("disable-filename", false, "Do not set well-known filename attribute")
|
|
||||||
objectPutCmd.Flags().Bool("disable-timestamp", false, "Do not set well-known timestamp attribute")
|
|
||||||
objectPutCmd.Flags().Uint64VarP(&putExpiredOn, putExpiresOnFlag, "e", 0,
|
|
||||||
"Last epoch in the life of the object")
|
|
||||||
|
|
||||||
objectCmd.AddCommand(objectDelCmd)
|
flags.String("attributes", "", "User attributes in form of Key1=Value1,Key2=Value2")
|
||||||
objectDelCmd.Flags().String("cid", "", "Container ID")
|
flags.Bool("disable-filename", false, "Do not set well-known filename attribute")
|
||||||
|
flags.Bool("disable-timestamp", false, "Do not set well-known timestamp attribute")
|
||||||
|
flags.Uint64VarP(&putExpiredOn, putExpiresOnFlag, "e", 0, "Last epoch in the life of the object")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initObjectDeleteCmd() {
|
||||||
|
initCommonFlags(objectDelCmd)
|
||||||
|
|
||||||
|
flags := objectDelCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = objectDelCmd.MarkFlagRequired("cid")
|
_ = objectDelCmd.MarkFlagRequired("cid")
|
||||||
objectDelCmd.Flags().String("oid", "", "Object ID")
|
|
||||||
|
flags.String("oid", "", "Object ID")
|
||||||
_ = objectDelCmd.MarkFlagRequired("oid")
|
_ = objectDelCmd.MarkFlagRequired("oid")
|
||||||
|
}
|
||||||
|
|
||||||
objectCmd.AddCommand(objectGetCmd)
|
func initObjectGetCmd() {
|
||||||
objectGetCmd.Flags().String("file", "", "File to write object payload to. Default: stdout.")
|
initCommonFlags(objectGetCmd)
|
||||||
objectGetCmd.Flags().String("header", "", "File to write header to. Default: stdout.")
|
|
||||||
objectGetCmd.Flags().String("cid", "", "Container ID")
|
flags := objectGetCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = objectGetCmd.MarkFlagRequired("cid")
|
_ = objectGetCmd.MarkFlagRequired("cid")
|
||||||
objectGetCmd.Flags().String("oid", "", "Object ID")
|
|
||||||
|
flags.String("oid", "", "Object ID")
|
||||||
_ = objectGetCmd.MarkFlagRequired("oid")
|
_ = objectGetCmd.MarkFlagRequired("oid")
|
||||||
objectGetCmd.Flags().Bool(rawFlag, false, rawFlagDesc)
|
|
||||||
|
|
||||||
objectCmd.AddCommand(objectSearchCmd)
|
flags.String("file", "", "File to write object payload to. Default: stdout.")
|
||||||
objectSearchCmd.Flags().String("cid", "", "Container ID")
|
flags.String("header", "", "File to write header to. Default: stdout.")
|
||||||
|
flags.Bool(rawFlag, false, rawFlagDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initObjectSearchCmd() {
|
||||||
|
initCommonFlags(objectSearchCmd)
|
||||||
|
|
||||||
|
flags := objectSearchCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = objectSearchCmd.MarkFlagRequired("cid")
|
_ = objectSearchCmd.MarkFlagRequired("cid")
|
||||||
objectSearchCmd.Flags().StringSliceVarP(&searchFilters, "filters", "f", nil,
|
|
||||||
|
flags.StringSliceVarP(&searchFilters, "filters", "f", nil,
|
||||||
"Repeated filter expressions or files with protobuf JSON")
|
"Repeated filter expressions or files with protobuf JSON")
|
||||||
objectSearchCmd.Flags().Bool("root", false, "Search for user objects")
|
|
||||||
objectSearchCmd.Flags().Bool("phy", false, "Search physically stored objects")
|
|
||||||
objectSearchCmd.Flags().String(searchOIDFlag, "", "Search object by identifier")
|
|
||||||
|
|
||||||
objectCmd.AddCommand(objectHeadCmd)
|
flags.Bool("root", false, "Search for user objects")
|
||||||
objectHeadCmd.Flags().String("file", "", "File to write header to. Default: stdout.")
|
flags.Bool("phy", false, "Search physically stored objects")
|
||||||
objectHeadCmd.Flags().String("cid", "", "Container ID")
|
flags.String(searchOIDFlag, "", "Search object by identifier")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initObjectHeadCmd() {
|
||||||
|
initCommonFlags(objectHeadCmd)
|
||||||
|
|
||||||
|
flags := objectHeadCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = objectHeadCmd.MarkFlagRequired("cid")
|
_ = objectHeadCmd.MarkFlagRequired("cid")
|
||||||
objectHeadCmd.Flags().String("oid", "", "Object ID")
|
|
||||||
|
flags.String("oid", "", "Object ID")
|
||||||
_ = objectHeadCmd.MarkFlagRequired("oid")
|
_ = objectHeadCmd.MarkFlagRequired("oid")
|
||||||
objectHeadCmd.Flags().Bool("main-only", false, "Return only main fields")
|
|
||||||
objectHeadCmd.Flags().Bool("json", false, "Marshal output in JSON")
|
|
||||||
objectHeadCmd.Flags().Bool("proto", false, "Marshal output in Protobuf")
|
|
||||||
objectHeadCmd.Flags().Bool(rawFlag, false, rawFlagDesc)
|
|
||||||
|
|
||||||
objectCmd.AddCommand(objectHashCmd)
|
flags.String("file", "", "File to write header to. Default: stdout.")
|
||||||
objectHashCmd.Flags().String("cid", "", "Container ID")
|
flags.Bool("main-only", false, "Return only main fields")
|
||||||
|
flags.Bool("json", false, "Marshal output in JSON")
|
||||||
|
flags.Bool("proto", false, "Marshal output in Protobuf")
|
||||||
|
flags.Bool(rawFlag, false, rawFlagDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initObjectHashCmd() {
|
||||||
|
initCommonFlags(objectHashCmd)
|
||||||
|
|
||||||
|
flags := objectHashCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = objectHashCmd.MarkFlagRequired("cid")
|
_ = objectHashCmd.MarkFlagRequired("cid")
|
||||||
objectHashCmd.Flags().String("oid", "", "Object ID")
|
|
||||||
_ = objectHashCmd.MarkFlagRequired("oid")
|
|
||||||
objectHashCmd.Flags().String("range", "", "Range to take hash from in the form offset1:length1,...")
|
|
||||||
objectHashCmd.Flags().String("type", hashSha256, "Hash type. Either 'sha256' or 'tz'")
|
|
||||||
objectHashCmd.Flags().String(getRangeHashSaltFlag, "", "Salt in hex format")
|
|
||||||
|
|
||||||
objectCmd.AddCommand(objectRangeCmd)
|
flags.String("oid", "", "Object ID")
|
||||||
objectRangeCmd.Flags().String("cid", "", "Container ID")
|
_ = objectHashCmd.MarkFlagRequired("oid")
|
||||||
|
|
||||||
|
flags.String("range", "", "Range to take hash from in the form offset1:length1,...")
|
||||||
|
flags.String("type", hashSha256, "Hash type. Either 'sha256' or 'tz'")
|
||||||
|
flags.String(getRangeHashSaltFlag, "", "Salt in hex format")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initObjectRangeCmd() {
|
||||||
|
initCommonFlags(objectRangeCmd)
|
||||||
|
|
||||||
|
flags := objectRangeCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = objectRangeCmd.MarkFlagRequired("cid")
|
_ = objectRangeCmd.MarkFlagRequired("cid")
|
||||||
objectRangeCmd.Flags().String("oid", "", "Object ID")
|
|
||||||
|
flags.String("oid", "", "Object ID")
|
||||||
_ = objectRangeCmd.MarkFlagRequired("oid")
|
_ = objectRangeCmd.MarkFlagRequired("oid")
|
||||||
objectRangeCmd.Flags().String("range", "", "Range to take data from in the form offset:length")
|
|
||||||
objectRangeCmd.Flags().String("file", "", "File to write object payload to. Default: stdout.")
|
flags.String("range", "", "Range to take data from in the form offset:length")
|
||||||
objectRangeCmd.Flags().Bool(rawFlag, false, rawFlagDesc)
|
flags.String("file", "", "File to write object payload to. Default: stdout.")
|
||||||
|
flags.Bool(rawFlag, false, rawFlagDesc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
objectChildCommands := []*cobra.Command{
|
||||||
|
objectPutCmd,
|
||||||
|
objectDelCmd,
|
||||||
|
objectGetCmd,
|
||||||
|
objectSearchCmd,
|
||||||
|
objectHeadCmd,
|
||||||
|
objectHashCmd,
|
||||||
|
objectRangeCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
rootCmd.AddCommand(objectCmd)
|
||||||
|
objectCmd.AddCommand(objectChildCommands...)
|
||||||
|
|
||||||
|
for _, objCommand := range objectChildCommands {
|
||||||
|
flags := objCommand.Flags()
|
||||||
|
|
||||||
|
flags.String("bearer", "", "File with signed JSON or binary encoded bearer token")
|
||||||
|
flags.StringSliceVarP(&xHeaders, xHeadersKey, xHeadersShorthand, xHeadersDefault, xHeadersUsage)
|
||||||
|
flags.Uint32P(ttl, ttlShorthand, ttlDefault, ttlUsage)
|
||||||
|
}
|
||||||
|
|
||||||
// Here you will define your flags and configuration settings.
|
// Here you will define your flags and configuration settings.
|
||||||
|
|
||||||
|
@ -192,6 +262,14 @@ func init() {
|
||||||
// Cobra supports local flags which will only run when this command
|
// Cobra supports local flags which will only run when this command
|
||||||
// is called directly, e.g.:
|
// is called directly, e.g.:
|
||||||
// objectCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
// objectCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
|
||||||
|
|
||||||
|
initObjectPutCmd()
|
||||||
|
initObjectDeleteCmd()
|
||||||
|
initObjectGetCmd()
|
||||||
|
initObjectSearchCmd()
|
||||||
|
initObjectHeadCmd()
|
||||||
|
initObjectHashCmd()
|
||||||
|
initObjectRangeCmd()
|
||||||
}
|
}
|
||||||
|
|
||||||
func initSession(ctx context.Context, key *ecdsa.PrivateKey) (client.Client, *session.Token, error) {
|
func initSession(ctx context.Context, key *ecdsa.PrivateKey) (client.Client, *session.Token, error) {
|
||||||
|
|
|
@ -26,8 +26,6 @@ import (
|
||||||
|
|
||||||
const (
|
const (
|
||||||
envPrefix = "NEOFS_CLI"
|
envPrefix = "NEOFS_CLI"
|
||||||
|
|
||||||
ttlDefaultValue = 2
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const xHeadersFlag = "xhdr"
|
const xHeadersFlag = "xhdr"
|
||||||
|
@ -37,9 +35,58 @@ var xHeaders []string
|
||||||
// Global scope flags.
|
// Global scope flags.
|
||||||
var (
|
var (
|
||||||
cfgFile string
|
cfgFile string
|
||||||
verbose bool
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
// Common CLI flag keys, shorthands, default
|
||||||
|
// values and their usage descriptions.
|
||||||
|
generateKey = "generate-key"
|
||||||
|
generateKeyShorthand = ""
|
||||||
|
generateKeyDefault = false
|
||||||
|
generateKeyUsage = "generate new private key"
|
||||||
|
|
||||||
|
binaryKey = "binary-key"
|
||||||
|
binaryKeyShorthand = ""
|
||||||
|
binaryKeyDefault = ""
|
||||||
|
binaryKeyUsage = "path to the raw private key file"
|
||||||
|
|
||||||
|
walletPath = "wallet"
|
||||||
|
walletPathShorthand = "w"
|
||||||
|
walletPathDefault = ""
|
||||||
|
walletPathUsage = "path to the wallet"
|
||||||
|
|
||||||
|
wif = "wif"
|
||||||
|
wifShorthand = ""
|
||||||
|
wifDefault = ""
|
||||||
|
wifUsage = "WIF or NEP-2"
|
||||||
|
|
||||||
|
address = "address"
|
||||||
|
addressShorthand = ""
|
||||||
|
addressDefault = ""
|
||||||
|
addressUsage = "address of wallet account"
|
||||||
|
|
||||||
|
rpc = "rpc-endpoint"
|
||||||
|
rpcShorthand = "r"
|
||||||
|
rpcDefault = ""
|
||||||
|
rpcUsage = "remote node address (as 'multiaddr' or '<host>:<port>')"
|
||||||
|
|
||||||
|
verbose = "verbose"
|
||||||
|
verboseShorthand = "v"
|
||||||
|
verboseDefault = false
|
||||||
|
verboseUsage = "verbose output"
|
||||||
|
|
||||||
|
ttl = "ttl"
|
||||||
|
ttlShorthand = ""
|
||||||
|
ttlDefault = 2
|
||||||
|
ttlUsage = "TTL value in request meta header"
|
||||||
|
|
||||||
|
xHeadersKey = "xhdr"
|
||||||
|
xHeadersShorthand = "x"
|
||||||
|
xHeadersUsage = "Request X-Headers in form of Key=Value"
|
||||||
|
)
|
||||||
|
|
||||||
|
var xHeadersDefault []string
|
||||||
|
|
||||||
// rootCmd represents the base command when called without any subcommands
|
// rootCmd represents the base command when called without any subcommands
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
Use: "neofs-cli",
|
Use: "neofs-cli",
|
||||||
|
@ -71,42 +118,14 @@ func Execute() {
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(initConfig)
|
cobra.OnInitialize(initConfig)
|
||||||
|
|
||||||
// Here you will define your flags and configuration settings.
|
|
||||||
// Cobra supports persistent flags, which, if defined here,
|
|
||||||
// will be global for your application.
|
|
||||||
|
|
||||||
// use stdout as default output for cmd.Print()
|
// use stdout as default output for cmd.Print()
|
||||||
rootCmd.SetOut(os.Stdout)
|
rootCmd.SetOut(os.Stdout)
|
||||||
|
|
||||||
|
// Here you will define your flags and configuration settings.
|
||||||
|
// Cobra supports persistent flags, which, if defined here,
|
||||||
|
// will be global for your application.
|
||||||
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is $HOME/.config/neofs-cli/config.yaml)")
|
rootCmd.PersistentFlags().StringVarP(&cfgFile, "config", "c", "", "config file (default is $HOME/.config/neofs-cli/config.yaml)")
|
||||||
|
|
||||||
// Key options.
|
|
||||||
rootCmd.PersistentFlags().BoolP("generate-key", "", false, "generate new private key")
|
|
||||||
_ = viper.BindPFlag("generate-key", rootCmd.PersistentFlags().Lookup("generate-key"))
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringP("binary-key", "", "", "path to the raw private key file")
|
|
||||||
_ = viper.BindPFlag("binary-key", rootCmd.PersistentFlags().Lookup("binary-key"))
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringP("wif", "", "", "WIF or NEP-2")
|
|
||||||
_ = viper.BindPFlag("wif", rootCmd.PersistentFlags().Lookup("wif"))
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringP("wallet", "w", "", "path to the wallet")
|
|
||||||
_ = viper.BindPFlag("wallet", rootCmd.PersistentFlags().Lookup("wallet"))
|
|
||||||
rootCmd.PersistentFlags().StringP("address", "", "", "address of wallet account")
|
|
||||||
_ = viper.BindPFlag("address", rootCmd.PersistentFlags().Lookup("address"))
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().StringP("rpc-endpoint", "r", "", "remote node address (as 'multiaddr' or '<host>:<port>')")
|
|
||||||
_ = viper.BindPFlag("rpc", rootCmd.PersistentFlags().Lookup("rpc-endpoint"))
|
|
||||||
|
|
||||||
rootCmd.PersistentFlags().Uint32("ttl", ttlDefaultValue, "TTL value in request meta header")
|
|
||||||
_ = viper.BindPFlag("ttl", rootCmd.PersistentFlags().Lookup("ttl"))
|
|
||||||
|
|
||||||
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().Bool("version", false, "Application version and NeoFS API compatibility")
|
rootCmd.Flags().Bool("version", false, "Application version and NeoFS API compatibility")
|
||||||
|
@ -157,7 +176,7 @@ const nep2Base58Length = 58
|
||||||
|
|
||||||
// getKey returns private key that was provided in global arguments.
|
// getKey returns private key that was provided in global arguments.
|
||||||
func getKey() (*ecdsa.PrivateKey, error) {
|
func getKey() (*ecdsa.PrivateKey, error) {
|
||||||
if viper.GetBool("generate-key") {
|
if viper.GetBool(generateKey) {
|
||||||
priv, err := keys.NewPrivateKey()
|
priv, err := keys.NewPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errCantGenerateKey
|
return nil, errCantGenerateKey
|
||||||
|
@ -165,19 +184,19 @@ func getKey() (*ecdsa.PrivateKey, error) {
|
||||||
return &priv.PrivateKey, nil
|
return &priv.PrivateKey, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if keyPath := viper.GetString("binary-key"); keyPath != "" {
|
if keyPath := viper.GetString(binaryKey); keyPath != "" {
|
||||||
return getKeyFromFile(keyPath)
|
return getKeyFromFile(keyPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
if walletPath := viper.GetString("wallet"); walletPath != "" {
|
if walletPath := viper.GetString(walletPath); walletPath != "" {
|
||||||
w, err := wallet.NewWalletFromFile(walletPath)
|
w, err := wallet.NewWalletFromFile(walletPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%w: %v", errInvalidKey, err)
|
return nil, fmt.Errorf("%w: %v", errInvalidKey, err)
|
||||||
}
|
}
|
||||||
return getKeyFromWallet(w, viper.GetString("address"))
|
return getKeyFromWallet(w, viper.GetString(address))
|
||||||
}
|
}
|
||||||
|
|
||||||
wif := viper.GetString("wif")
|
wif := viper.GetString(wif)
|
||||||
if len(wif) == nep2Base58Length {
|
if len(wif) == nep2Base58Length {
|
||||||
return getKeyFromNEP2(wif)
|
return getKeyFromNEP2(wif)
|
||||||
}
|
}
|
||||||
|
@ -260,7 +279,7 @@ func getKeyFromWallet(w *wallet.Wallet, addrStr string) (*ecdsa.PrivateKey, erro
|
||||||
// getEndpointAddress returns network address structure that stores multiaddr
|
// getEndpointAddress returns network address structure that stores multiaddr
|
||||||
// inside, parsed from global arguments.
|
// inside, parsed from global arguments.
|
||||||
func getEndpointAddress() (addr network.Address, err error) {
|
func getEndpointAddress() (addr network.Address, err error) {
|
||||||
endpoint := viper.GetString("rpc")
|
endpoint := viper.GetString(rpc)
|
||||||
|
|
||||||
err = addr.FromString(endpoint)
|
err = addr.FromString(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -296,7 +315,7 @@ func getSDKClient(key *ecdsa.PrivateKey) (client.Client, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTTL() uint32 {
|
func getTTL() uint32 {
|
||||||
ttl := viper.GetUint32("ttl")
|
ttl := viper.GetUint32(ttl)
|
||||||
printVerbose("TTL: %d", ttl)
|
printVerbose("TTL: %d", ttl)
|
||||||
|
|
||||||
return ttl
|
return ttl
|
||||||
|
@ -315,7 +334,7 @@ func ownerFromString(s string) (*owner.ID, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func printVerbose(format string, a ...interface{}) {
|
func printVerbose(format string, a ...interface{}) {
|
||||||
if verbose {
|
if viper.GetBool(verbose) {
|
||||||
fmt.Printf(format+"\n", a...)
|
fmt.Printf(format+"\n", a...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -351,3 +370,35 @@ func globalCallOptions() []client.CallOption {
|
||||||
|
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add common flags to the command:
|
||||||
|
// - key;
|
||||||
|
// - wallet;
|
||||||
|
// - WIF;
|
||||||
|
// - address;
|
||||||
|
// - RPC;
|
||||||
|
// - verbose;
|
||||||
|
func initCommonFlags(cmd *cobra.Command) {
|
||||||
|
ff := cmd.Flags()
|
||||||
|
|
||||||
|
ff.BoolP(generateKey, generateKeyShorthand, generateKeyDefault, generateKeyUsage)
|
||||||
|
ff.StringP(binaryKey, binaryKeyShorthand, binaryKeyDefault, binaryKeyUsage)
|
||||||
|
ff.StringP(walletPath, walletPathShorthand, walletPathDefault, walletPathUsage)
|
||||||
|
ff.StringP(wif, wifShorthand, wifDefault, wifUsage)
|
||||||
|
ff.StringP(address, addressShorthand, addressDefault, addressUsage)
|
||||||
|
ff.StringP(rpc, rpcShorthand, rpcDefault, rpcUsage)
|
||||||
|
ff.BoolP(verbose, verboseShorthand, verboseDefault, verboseUsage)
|
||||||
|
}
|
||||||
|
|
||||||
|
// bind common command flags to the viper
|
||||||
|
func bindCommonFlags(cmd *cobra.Command) {
|
||||||
|
ff := cmd.Flags()
|
||||||
|
|
||||||
|
_ = viper.BindPFlag(generateKey, ff.Lookup(generateKey))
|
||||||
|
_ = viper.BindPFlag(binaryKey, ff.Lookup(binaryKey))
|
||||||
|
_ = viper.BindPFlag(walletPath, ff.Lookup(walletPath))
|
||||||
|
_ = viper.BindPFlag(wif, ff.Lookup(wif))
|
||||||
|
_ = viper.BindPFlag(address, ff.Lookup(address))
|
||||||
|
_ = viper.BindPFlag(rpc, ff.Lookup(rpc))
|
||||||
|
_ = viper.BindPFlag(verbose, ff.Lookup(verbose))
|
||||||
|
}
|
||||||
|
|
|
@ -20,6 +20,11 @@ var storagegroupCmd = &cobra.Command{
|
||||||
Use: "storagegroup",
|
Use: "storagegroup",
|
||||||
Short: "Operations with Storage Groups",
|
Short: "Operations with Storage Groups",
|
||||||
Long: `Operations with Storage Groups`,
|
Long: `Operations with Storage Groups`,
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
// bind exactly that cmd's flags to
|
||||||
|
// the viper before execution
|
||||||
|
bindCommonFlags(cmd)
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var sgPutCmd = &cobra.Command{
|
var sgPutCmd = &cobra.Command{
|
||||||
|
@ -61,36 +66,74 @@ var (
|
||||||
sgID string
|
sgID string
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func initSGPutCmd() {
|
||||||
rootCmd.AddCommand(storagegroupCmd)
|
initCommonFlags(sgPutCmd)
|
||||||
|
|
||||||
storagegroupCmd.PersistentFlags().String(sgBearerFlag, "",
|
flags := sgPutCmd.Flags()
|
||||||
"File with signed JSON or binary encoded bearer token")
|
|
||||||
|
|
||||||
storagegroupCmd.AddCommand(sgPutCmd)
|
flags.String("cid", "", "Container ID")
|
||||||
sgPutCmd.Flags().String("cid", "", "Container ID")
|
|
||||||
_ = sgPutCmd.MarkFlagRequired("cid")
|
_ = sgPutCmd.MarkFlagRequired("cid")
|
||||||
sgPutCmd.Flags().StringSliceVarP(&sgMembers, sgMembersFlag, "m", nil,
|
|
||||||
"ID list of storage group members")
|
flags.StringSliceVarP(&sgMembers, sgMembersFlag, "m", nil, "ID list of storage group members")
|
||||||
_ = sgPutCmd.MarkFlagRequired(sgMembersFlag)
|
_ = sgPutCmd.MarkFlagRequired(sgMembersFlag)
|
||||||
|
}
|
||||||
|
|
||||||
storagegroupCmd.AddCommand(sgGetCmd)
|
func initSGGetCmd() {
|
||||||
sgGetCmd.Flags().String("cid", "", "Container ID")
|
initCommonFlags(sgGetCmd)
|
||||||
|
|
||||||
|
flags := sgGetCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = sgGetCmd.MarkFlagRequired("cid")
|
_ = sgGetCmd.MarkFlagRequired("cid")
|
||||||
sgGetCmd.Flags().StringVarP(&sgID, sgIDFlag, "", "", "storage group identifier")
|
|
||||||
_ = sgGetCmd.MarkFlagRequired(sgIDFlag)
|
|
||||||
|
|
||||||
storagegroupCmd.AddCommand(sgListCmd)
|
flags.StringVarP(&sgID, sgIDFlag, "", "", "storage group identifier")
|
||||||
|
_ = sgGetCmd.MarkFlagRequired(sgIDFlag)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initSGListCmd() {
|
||||||
|
initCommonFlags(sgListCmd)
|
||||||
|
|
||||||
sgListCmd.Flags().String("cid", "", "Container ID")
|
sgListCmd.Flags().String("cid", "", "Container ID")
|
||||||
_ = sgListCmd.MarkFlagRequired("cid")
|
_ = sgListCmd.MarkFlagRequired("cid")
|
||||||
|
}
|
||||||
|
|
||||||
storagegroupCmd.AddCommand(sgDelCmd)
|
func initSGDeleteCmd() {
|
||||||
sgDelCmd.Flags().String("cid", "", "Container ID")
|
initCommonFlags(sgDelCmd)
|
||||||
|
|
||||||
|
flags := sgDelCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("cid", "", "Container ID")
|
||||||
_ = sgDelCmd.MarkFlagRequired("cid")
|
_ = sgDelCmd.MarkFlagRequired("cid")
|
||||||
sgDelCmd.Flags().StringVarP(&sgID, sgIDFlag, "", "", "storage group identifier")
|
|
||||||
|
flags.StringVarP(&sgID, sgIDFlag, "", "", "storage group identifier")
|
||||||
_ = sgDelCmd.MarkFlagRequired(sgIDFlag)
|
_ = sgDelCmd.MarkFlagRequired(sgIDFlag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
storageGroupChildCommands := []*cobra.Command{
|
||||||
|
sgPutCmd,
|
||||||
|
sgGetCmd,
|
||||||
|
sgListCmd,
|
||||||
|
sgDelCmd,
|
||||||
|
}
|
||||||
|
|
||||||
|
rootCmd.AddCommand(storagegroupCmd)
|
||||||
|
storagegroupCmd.AddCommand(storageGroupChildCommands...)
|
||||||
|
|
||||||
|
for _, sgCommand := range storageGroupChildCommands {
|
||||||
|
flags := sgCommand.Flags()
|
||||||
|
|
||||||
|
flags.String(sgBearerFlag, "", "File with signed JSON or binary encoded bearer token")
|
||||||
|
flags.StringSliceVarP(&xHeaders, xHeadersKey, xHeadersShorthand, xHeadersDefault, xHeadersUsage)
|
||||||
|
flags.Uint32P(ttl, ttlShorthand, ttlDefault, ttlUsage)
|
||||||
|
}
|
||||||
|
|
||||||
|
initSGPutCmd()
|
||||||
|
initSGGetCmd()
|
||||||
|
initSGListCmd()
|
||||||
|
initSGDeleteCmd()
|
||||||
|
}
|
||||||
|
|
||||||
type sgHeadReceiver struct {
|
type sgHeadReceiver struct {
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import (
|
||||||
continentsdb "github.com/nspcc-dev/neofs-node/pkg/util/locode/db/continents/geojson"
|
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"
|
csvlocode "github.com/nspcc-dev/neofs-node/pkg/util/locode/table/csv"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
var errKeyerSingleArgument = errors.New("pass only one argument at a time")
|
var errKeyerSingleArgument = errors.New("pass only one argument at a time")
|
||||||
|
@ -27,6 +28,16 @@ var (
|
||||||
utilCmd = &cobra.Command{
|
utilCmd = &cobra.Command{
|
||||||
Use: "util",
|
Use: "util",
|
||||||
Short: "Utility operations",
|
Short: "Utility operations",
|
||||||
|
PersistentPreRun: func(cmd *cobra.Command, args []string) {
|
||||||
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
_ = viper.BindPFlag(generateKey, flags.Lookup(generateKey))
|
||||||
|
_ = viper.BindPFlag(binaryKey, flags.Lookup(binaryKey))
|
||||||
|
_ = viper.BindPFlag(walletPath, flags.Lookup(walletPath))
|
||||||
|
_ = viper.BindPFlag(wif, flags.Lookup(wif))
|
||||||
|
_ = viper.BindPFlag(address, flags.Lookup(address))
|
||||||
|
_ = viper.BindPFlag(verbose, flags.Lookup(verbose))
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
signCmd = &cobra.Command{
|
signCmd = &cobra.Command{
|
||||||
|
@ -171,74 +182,116 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func initUtilKeyerCmd() {
|
||||||
rootCmd.AddCommand(utilCmd)
|
|
||||||
|
|
||||||
utilCmd.AddCommand(signCmd)
|
|
||||||
utilCmd.AddCommand(convertCmd)
|
|
||||||
utilCmd.AddCommand(keyerCmd)
|
|
||||||
utilCmd.AddCommand(locodeCmd)
|
|
||||||
|
|
||||||
signCmd.AddCommand(signBearerCmd)
|
|
||||||
signBearerCmd.Flags().String("from", "", "File with JSON or binary encoded bearer token to sign")
|
|
||||||
_ = signBearerCmd.MarkFlagFilename("from")
|
|
||||||
_ = signBearerCmd.MarkFlagRequired("from")
|
|
||||||
signBearerCmd.Flags().String("to", "", "File to dump signed bearer token (default: binary encoded)")
|
|
||||||
signBearerCmd.Flags().Bool("json", false, "Dump bearer token in JSON encoding")
|
|
||||||
|
|
||||||
signCmd.AddCommand(signSessionCmd)
|
|
||||||
signSessionCmd.Flags().String("from", "", "File with JSON encoded session token to sign")
|
|
||||||
_ = signSessionCmd.MarkFlagFilename("from")
|
|
||||||
_ = signSessionCmd.MarkFlagRequired("from")
|
|
||||||
signSessionCmd.Flags().String("to", "", "File to save signed session token (optional)")
|
|
||||||
|
|
||||||
convertCmd.AddCommand(convertEACLCmd)
|
|
||||||
convertEACLCmd.Flags().String("from", "", "File with JSON or binary encoded extended ACL table")
|
|
||||||
_ = convertEACLCmd.MarkFlagFilename("from")
|
|
||||||
_ = convertEACLCmd.MarkFlagRequired("from")
|
|
||||||
convertEACLCmd.Flags().String("to", "", "File to dump extended ACL table (default: binary encoded)")
|
|
||||||
convertEACLCmd.Flags().Bool("json", false, "Dump extended ACL table in JSON encoding")
|
|
||||||
|
|
||||||
keyerCmd.Flags().BoolP("generate", "g", false, "generate new private key")
|
keyerCmd.Flags().BoolP("generate", "g", false, "generate new private key")
|
||||||
keyerCmd.Flags().Bool("hex", false, "print all values in hex encoding")
|
keyerCmd.Flags().Bool("hex", false, "print all values in hex encoding")
|
||||||
keyerCmd.Flags().BoolP("uncompressed", "u", false, "use uncompressed public key format")
|
keyerCmd.Flags().BoolP("uncompressed", "u", false, "use uncompressed public key format")
|
||||||
keyerCmd.Flags().BoolP("multisig", "m", false, "calculate multisig address from public keys")
|
keyerCmd.Flags().BoolP("multisig", "m", false, "calculate multisig address from public keys")
|
||||||
|
}
|
||||||
|
|
||||||
locodeCmd.AddCommand(locodeGenerateCmd)
|
func initCommonFlagsWithoutRPC(cmd *cobra.Command) {
|
||||||
|
flags := cmd.Flags()
|
||||||
|
|
||||||
locodeGenerateCmd.Flags().StringSliceVar(&locodeGenerateInPaths, locodeGenerateInputFlag, nil,
|
flags.BoolP(generateKey, generateKeyShorthand, generateKeyDefault, generateKeyUsage)
|
||||||
"List of paths to UN/LOCODE tables (csv)")
|
flags.StringP(binaryKey, binaryKeyShorthand, binaryKeyDefault, binaryKeyUsage)
|
||||||
|
flags.StringP(walletPath, walletPathShorthand, walletPathDefault, walletPathUsage)
|
||||||
|
flags.StringP(wif, wifShorthand, wifDefault, wifUsage)
|
||||||
|
flags.StringP(address, addressShorthand, addressDefault, addressUsage)
|
||||||
|
flags.StringP(rpc, rpcShorthand, rpcDefault, rpcUsage)
|
||||||
|
flags.BoolP(verbose, verboseShorthand, verboseDefault, verboseUsage)
|
||||||
|
}
|
||||||
|
|
||||||
|
func initUtilSignBearerCmd() {
|
||||||
|
initCommonFlagsWithoutRPC(signBearerCmd)
|
||||||
|
|
||||||
|
flags := signBearerCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("from", "", "File with JSON or binary encoded bearer token to sign")
|
||||||
|
_ = signBearerCmd.MarkFlagFilename("from")
|
||||||
|
_ = signBearerCmd.MarkFlagRequired("from")
|
||||||
|
|
||||||
|
flags.String("to", "", "File to dump signed bearer token (default: binary encoded)")
|
||||||
|
flags.Bool("json", false, "Dump bearer token in JSON encoding")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initUtilSignSessionCmd() {
|
||||||
|
initCommonFlagsWithoutRPC(signSessionCmd)
|
||||||
|
|
||||||
|
flags := signSessionCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("from", "", "File with JSON encoded session token to sign")
|
||||||
|
_ = signSessionCmd.MarkFlagFilename("from")
|
||||||
|
_ = signSessionCmd.MarkFlagRequired("from")
|
||||||
|
|
||||||
|
flags.String("to", "", "File to save signed session token (optional)")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initUtilConvertEACLCmd() {
|
||||||
|
flags := convertEACLCmd.Flags()
|
||||||
|
|
||||||
|
flags.String("from", "", "File with JSON or binary encoded extended ACL table")
|
||||||
|
_ = convertEACLCmd.MarkFlagFilename("from")
|
||||||
|
_ = convertEACLCmd.MarkFlagRequired("from")
|
||||||
|
|
||||||
|
flags.String("to", "", "File to dump extended ACL table (default: binary encoded)")
|
||||||
|
flags.Bool("json", false, "Dump extended ACL table in JSON encoding")
|
||||||
|
}
|
||||||
|
|
||||||
|
func initUtilLocodeGenerateCmd() {
|
||||||
|
flags := locodeGenerateCmd.Flags()
|
||||||
|
|
||||||
|
flags.StringSliceVar(&locodeGenerateInPaths, locodeGenerateInputFlag, nil, "List of paths to UN/LOCODE tables (csv)")
|
||||||
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateInputFlag)
|
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateInputFlag)
|
||||||
|
|
||||||
locodeGenerateCmd.Flags().StringVar(&locodeGenerateSubDivPath, locodeGenerateSubDivFlag, "",
|
flags.StringVar(&locodeGenerateSubDivPath, locodeGenerateSubDivFlag, "", "Path to UN/LOCODE subdivision database (csv)")
|
||||||
"Path to UN/LOCODE subdivision database (csv)")
|
|
||||||
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateSubDivFlag)
|
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateSubDivFlag)
|
||||||
|
|
||||||
locodeGenerateCmd.Flags().StringVar(&locodeGenerateAirportsPath, locodeGenerateAirportsFlag, "",
|
flags.StringVar(&locodeGenerateAirportsPath, locodeGenerateAirportsFlag, "", "Path to OpenFlights airport database (csv)")
|
||||||
"Path to OpenFlights airport database (csv)")
|
|
||||||
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateAirportsFlag)
|
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateAirportsFlag)
|
||||||
|
|
||||||
locodeGenerateCmd.Flags().StringVar(&locodeGenerateCountriesPath, locodeGenerateCountriesFlag, "",
|
flags.StringVar(&locodeGenerateCountriesPath, locodeGenerateCountriesFlag, "", "Path to OpenFlights country database (csv)")
|
||||||
"Path to OpenFlights country database (csv)")
|
|
||||||
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateCountriesFlag)
|
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateCountriesFlag)
|
||||||
|
|
||||||
locodeGenerateCmd.Flags().StringVar(&locodeGenerateContinentsPath, locodeGenerateContinentsFlag, "",
|
flags.StringVar(&locodeGenerateContinentsPath, locodeGenerateContinentsFlag, "", "Path to continent polygons (GeoJSON)")
|
||||||
"Path to continent polygons (GeoJSON)")
|
|
||||||
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateContinentsFlag)
|
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateContinentsFlag)
|
||||||
|
|
||||||
locodeGenerateCmd.Flags().StringVar(&locodeGenerateOutPath, locodeGenerateOutputFlag, "",
|
flags.StringVar(&locodeGenerateOutPath, locodeGenerateOutputFlag, "", "Target path for generated database")
|
||||||
"Target path for generated database")
|
|
||||||
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateOutputFlag)
|
_ = locodeGenerateCmd.MarkFlagRequired(locodeGenerateOutputFlag)
|
||||||
|
}
|
||||||
|
|
||||||
locodeCmd.AddCommand(locodeInfoCmd)
|
func initUtilLocodeInfoCmd() {
|
||||||
|
flags := locodeInfoCmd.Flags()
|
||||||
|
|
||||||
locodeInfoCmd.Flags().StringVar(&locodeInfoDBPath, locodeInfoDBFlag, "",
|
flags.StringVar(&locodeInfoDBPath, locodeInfoDBFlag, "", "Path to NeoFS UN/LOCODE database")
|
||||||
"Path to NeoFS UN/LOCODE database")
|
_ = locodeInfoCmd.MarkFlagRequired(locodeInfoDBFlag)
|
||||||
_ = locodeGenerateCmd.MarkFlagRequired(locodeInfoDBFlag)
|
|
||||||
|
|
||||||
locodeInfoCmd.Flags().StringVar(&locodeInfoCode, locodeInfoCodeFlag, "",
|
flags.StringVar(&locodeInfoCode, locodeInfoCodeFlag, "", "UN/LOCODE")
|
||||||
"UN/LOCODE")
|
_ = locodeInfoCmd.MarkFlagRequired(locodeInfoCodeFlag)
|
||||||
_ = locodeGenerateCmd.MarkFlagRequired(locodeInfoCodeFlag)
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
rootCmd.AddCommand(utilCmd)
|
||||||
|
|
||||||
|
utilCmd.AddCommand(
|
||||||
|
signCmd,
|
||||||
|
convertCmd,
|
||||||
|
keyerCmd,
|
||||||
|
locodeCmd,
|
||||||
|
)
|
||||||
|
|
||||||
|
signCmd.AddCommand(signBearerCmd, signSessionCmd)
|
||||||
|
convertCmd.AddCommand(convertEACLCmd)
|
||||||
|
locodeCmd.AddCommand(locodeGenerateCmd, locodeInfoCmd)
|
||||||
|
|
||||||
|
initUtilKeyerCmd()
|
||||||
|
|
||||||
|
initUtilSignBearerCmd()
|
||||||
|
initUtilSignSessionCmd()
|
||||||
|
|
||||||
|
initUtilConvertEACLCmd()
|
||||||
|
|
||||||
|
initUtilLocodeInfoCmd()
|
||||||
|
initUtilLocodeGenerateCmd()
|
||||||
}
|
}
|
||||||
|
|
||||||
func signBearerToken(cmd *cobra.Command, _ []string) {
|
func signBearerToken(cmd *cobra.Command, _ []string) {
|
||||||
|
|
Loading…
Reference in a new issue