From cd4055d0b7d192281a0652342aeb9e50e3dbb5eb Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Thu, 14 Jan 2021 21:32:14 +0300 Subject: [PATCH] [#168] cmd/cli: Add snapshot command to netmap section Signed-off-by: Leonard Lyubich --- cmd/neofs-cli/modules/control.go | 39 ++++++++------ cmd/neofs-cli/modules/netmap.go | 88 ++++++++++++++++++++++++++------ 2 files changed, 97 insertions(+), 30 deletions(-) diff --git a/cmd/neofs-cli/modules/control.go b/cmd/neofs-cli/modules/control.go index be98e58f9..4cf21e629 100644 --- a/cmd/neofs-cli/modules/control.go +++ b/cmd/neofs-cli/modules/control.go @@ -27,6 +27,29 @@ func init() { rootCmd.AddCommand(controlCmd) controlCmd.AddCommand(healthCheckCmd) + + controlCmd.AddCommand(snapshotCmd) +} + +func getControlServiceClient() (control.ControlServiceClient, error) { + netAddr, err := getEndpointAddress() + if err != nil { + return nil, err + } + + ipAddr, err := netAddr.IPAddrString() + if err != nil { + return nil, errInvalidEndpoint + } + + con, err := client.NewGRPCClientConn( + client.WithNetworkAddress(ipAddr), + ) + if err != nil { + return nil, err + } + + return control.NewControlServiceClient(con), nil } func healthCheck(cmd *cobra.Command, _ []string) error { @@ -43,25 +66,11 @@ func healthCheck(cmd *cobra.Command, _ []string) error { return err } - netAddr, err := getEndpointAddress() + cli, err := getControlServiceClient() if err != nil { return err } - ipAddr, err := netAddr.IPAddrString() - if err != nil { - return errInvalidEndpoint - } - - con, err := client.NewGRPCClientConn( - client.WithNetworkAddress(ipAddr), - ) - if err != nil { - return err - } - - cli := control.NewControlServiceClient(con) - resp, err := cli.HealthCheck(context.Background(), req) if err != nil { return err diff --git a/cmd/neofs-cli/modules/netmap.go b/cmd/neofs-cli/modules/netmap.go index e0949ebcb..faf8675ab 100644 --- a/cmd/neofs-cli/modules/netmap.go +++ b/cmd/neofs-cli/modules/netmap.go @@ -1,18 +1,22 @@ package cmd import ( - "bytes" "context" "encoding/hex" - "encoding/json" "fmt" + "github.com/mr-tron/base58" "github.com/nspcc-dev/neofs-api-go/pkg/netmap" + "github.com/nspcc-dev/neofs-api-go/util/signature" + "github.com/nspcc-dev/neofs-node/pkg/services/control" + controlSvc "github.com/nspcc-dev/neofs-node/pkg/services/control/server" "github.com/spf13/cobra" ) var ( nodeInfoJSON bool + + netmapSnapshotJSON bool ) // netmapCmd represents the netmap command @@ -31,9 +35,13 @@ func init() { netmapCmd.AddCommand( getEpochCmd, localNodeInfoCmd, + snapshotCmd, ) localNodeInfoCmd.Flags().BoolVar(&nodeInfoJSON, "json", false, "print node info in JSON format") + + snapshotCmd.Flags().BoolVar(&netmapSnapshotJSON, "json", false, + "print netmap structure in JSON format") } var getEpochCmd = &cobra.Command{ @@ -78,21 +86,50 @@ var localNodeInfoCmd = &cobra.Command{ }, } +var snapshotCmd = &cobra.Command{ + Use: "snapshot", + Short: "Get network map snapshot", + Long: "Get network map snapshot", + RunE: func(cmd *cobra.Command, args []string) error { + key, err := getKey() + if err != nil { + return err + } + + req := new(control.NetmapSnapshotRequest) + req.SetBody(new(control.NetmapSnapshotRequest_Body)) + + if err := controlSvc.SignMessage(key, req); err != nil { + return err + } + + cli, err := getControlServiceClient() + if err != nil { + return err + } + + resp, err := cli.NetmapSnapshot(context.Background(), req) + if err != nil { + return err + } + + sign := resp.GetSignature() + + if err := signature.VerifyDataWithSource(resp, func() ([]byte, []byte) { + return sign.GetKey(), sign.GetSign() + }); err != nil { + return err + } + + prettyPrintNetmap(resp.GetBody().GetNetmap(), netmapSnapshotJSON) + + return nil + }, +} + func prettyPrintNodeInfo(i *netmap.NodeInfo, jsonEncoding bool) { if jsonEncoding { - data, err := i.MarshalJSON() - if err != nil { - printVerbose("Can't convert container to json: %w", err) - return - } - - buf := new(bytes.Buffer) - if err := json.Indent(buf, data, "", " "); err != nil { - printVerbose("Can't pretty print json: %w", err) - } - - fmt.Println(buf) - + printJSONMarshaler(i, "node info") return } @@ -104,3 +141,24 @@ func prettyPrintNodeInfo(i *netmap.NodeInfo, jsonEncoding bool) { fmt.Printf("attribute: %s=%s\n", attribute.Key(), attribute.Value()) } } + +func prettyPrintNetmap(nm *control.Netmap, jsonEncoding bool) { + if jsonEncoding { + fmt.Println("JSON encoding is not implemented") + return + } + + fmt.Println("Epoch:", nm.GetEpoch()) + + for i, node := range nm.GetNodes() { + fmt.Printf("Node %d: %s %s %s\n", i+1, + base58.Encode(node.GetPublicKey()), + node.GetAddress(), + node.GetState(), + ) + + for _, attr := range node.GetAttributes() { + fmt.Printf("\t%s: %s\n", attr.GetKey(), attr.GetValue()) + } + } +}