package tree import ( "crypto/sha256" "strings" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/commonflags" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-cli/internal/key" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/tree" cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id" objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object" "github.com/spf13/cobra" ) var getByPathCmd = &cobra.Command{ Use: "get-by-path", Short: "Get a node by its path", Run: getByPath, PersistentPreRun: func(cmd *cobra.Command, _ []string) { commonflags.Bind(cmd) }, } func initGetByPathCmd() { commonflags.Init(getByPathCmd) initCTID(getByPathCmd) ff := getByPathCmd.Flags() // tree service does not allow any attribute except // the 'FileName' but that's a limitation of the // current implementation, not the rule // ff.String(pathAttributeFlagKey, "", "Path attribute") ff.String(pathFlagKey, "", "Path to a node") ff.Bool(latestOnlyFlagKey, false, "Look only for the latest version of a node") _ = cobra.MarkFlagRequired(ff, commonflags.RPC) } func getByPath(cmd *cobra.Command, _ []string) { pk := key.GetOrGenerate(cmd) cidRaw, _ := cmd.Flags().GetString(commonflags.CIDFlag) var cnr cid.ID err := cnr.DecodeString(cidRaw) commonCmd.ExitOnErr(cmd, "decode container ID string: %w", err) tid, _ := cmd.Flags().GetString(treeIDFlagKey) ctx := cmd.Context() cli, err := _client(ctx) commonCmd.ExitOnErr(cmd, "failed to create client: %w", err) rawCID := make([]byte, sha256.Size) cnr.Encode(rawCID) latestOnly, _ := cmd.Flags().GetBool(latestOnlyFlagKey) path, _ := cmd.Flags().GetString(pathFlagKey) var bt []byte if t := common.ReadBearerToken(cmd, bearerFlagKey); t != nil { bt = t.Marshal() } req := new(tree.GetNodeByPathRequest) req.Body = &tree.GetNodeByPathRequest_Body{ ContainerId: rawCID, TreeId: tid, PathAttribute: objectSDK.AttributeFileName, // PathAttribute: pAttr, Path: strings.Split(path, "/"), LatestOnly: latestOnly, AllAttributes: true, BearerToken: bt, } commonCmd.ExitOnErr(cmd, "signing message: %w", tree.SignMessage(req, pk)) resp, err := cli.GetNodeByPath(ctx, req) commonCmd.ExitOnErr(cmd, "failed to call getNodeByPath: %w", err) nn := resp.GetBody().GetNodes() if len(nn) == 0 { common.PrintVerbose(cmd, "The node is not found") return } for _, n := range nn { cmd.Printf("%d:\n", n.GetNodeId()) cmd.Println("\tParent ID: ", n.GetParentId()) cmd.Println("\tTimestamp: ", n.GetTimestamp()) cmd.Println("\tMeta pairs: ") for _, kv := range n.GetMeta() { cmd.Printf("\t\t%s: %s\n", kv.GetKey(), string(kv.GetValue())) } } }