package nns import ( "errors" "math/big" "strings" "git.frostfs.info/TrueCloudLab/frostfs-contract/nns" "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags" commonCmd "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/internal/common" "github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/spf13/cobra" ) func initAddRecordCmd() { Cmd.AddCommand(addRecordCmd) addRecordCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) addRecordCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc) addRecordCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc) addRecordCmd.Flags().String(nnsRecordTypeFlag, "", nnsRecordTypeFlagDesc) addRecordCmd.Flags().String(nnsRecordDataFlag, "", nnsRecordDataFlagDesc) _ = cobra.MarkFlagRequired(addRecordCmd.Flags(), nnsNameFlag) _ = cobra.MarkFlagRequired(addRecordCmd.Flags(), nnsRecordTypeFlag) _ = cobra.MarkFlagRequired(addRecordCmd.Flags(), nnsRecordDataFlag) } func initGetRecordsCmd() { Cmd.AddCommand(getRecordsCmd) getRecordsCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) getRecordsCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc) getRecordsCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc) getRecordsCmd.Flags().String(nnsRecordTypeFlag, "", nnsRecordTypeFlagDesc) _ = cobra.MarkFlagRequired(getRecordsCmd.Flags(), nnsNameFlag) } func initDelRecordsCmd() { Cmd.AddCommand(delRecordsCmd) delRecordsCmd.Flags().StringP(commonflags.EndpointFlag, commonflags.EndpointFlagShort, "", commonflags.EndpointFlagDesc) delRecordsCmd.Flags().String(commonflags.AlphabetWalletsFlag, "", commonflags.AlphabetWalletsFlagDesc) delRecordsCmd.Flags().String(nnsNameFlag, "", nnsNameFlagDesc) delRecordsCmd.Flags().String(nnsRecordTypeFlag, "", nnsRecordTypeFlagDesc) _ = cobra.MarkFlagRequired(delRecordsCmd.Flags(), nnsNameFlag) _ = cobra.MarkFlagRequired(delRecordsCmd.Flags(), nnsRecordTypeFlag) } func addRecord(cmd *cobra.Command, _ []string) { c, actor, _ := getRPCClient(cmd) name, _ := cmd.Flags().GetString(nnsNameFlag) data, _ := cmd.Flags().GetString(nnsRecordDataFlag) recordType, _ := cmd.Flags().GetString(nnsRecordTypeFlag) typ, err := getRecordType(recordType) commonCmd.ExitOnErr(cmd, "unable to parse record type: %w", err) h, vub, err := c.AddRecord(name, typ, data) commonCmd.ExitOnErr(cmd, "unable to add record: %w", err) cmd.Println("Waiting for transaction to persist...") _, err = actor.Wait(h, vub, err) commonCmd.ExitOnErr(cmd, "renew domain error: %w", err) cmd.Println("Record added successfully") } func getRecords(cmd *cobra.Command, _ []string) { c, act, hash := getRPCClient(cmd) name, _ := cmd.Flags().GetString(nnsNameFlag) recordType, _ := cmd.Flags().GetString(nnsRecordTypeFlag) if recordType == "" { sid, r, err := unwrap.SessionIterator(act.Invoker.Call(hash, "getAllRecords", name)) commonCmd.ExitOnErr(cmd, "unable to get records: %w", err) defer func() { _ = act.Invoker.TerminateSession(sid) }() items, err := act.Invoker.TraverseIterator(sid, &r, 0) commonCmd.ExitOnErr(cmd, "unable to get records: %w", err) for len(items) != 0 { for j := range items { rs := items[j].Value().([]stackitem.Item) bs, err := rs[2].TryBytes() commonCmd.ExitOnErr(cmd, "unable to parse record state: %w", err) cmd.Printf("%s %s\n", recordTypeToString(nns.RecordType(rs[1].Value().(*big.Int).Int64())), string(bs)) } items, err = act.Invoker.TraverseIterator(sid, &r, 0) commonCmd.ExitOnErr(cmd, "unable to get records: %w", err) } } else { typ, err := getRecordType(recordType) commonCmd.ExitOnErr(cmd, "unable to parse record type: %w", err) items, err := c.GetRecords(name, typ) commonCmd.ExitOnErr(cmd, "unable to get records: %w", err) for _, item := range items { record, err := item.TryBytes() commonCmd.ExitOnErr(cmd, "unable to parse response: %w", err) cmd.Println(string(record)) } } } func delRecords(cmd *cobra.Command, _ []string) { c, actor, _ := getRPCClient(cmd) name, _ := cmd.Flags().GetString(nnsNameFlag) recordType, _ := cmd.Flags().GetString(nnsRecordTypeFlag) typ, err := getRecordType(recordType) commonCmd.ExitOnErr(cmd, "unable to parse record type: %w", err) h, vub, err := c.DeleteRecords(name, typ) commonCmd.ExitOnErr(cmd, "unable to delete records: %w", err) cmd.Println("Waiting for transaction to persist...") _, err = actor.Wait(h, vub, err) commonCmd.ExitOnErr(cmd, "delete records error: %w", err) cmd.Println("Records removed successfully") } func getRecordType(recordType string) (*big.Int, error) { switch strings.ToUpper(recordType) { case "A": return big.NewInt(int64(nns.A)), nil case "CNAME": return big.NewInt(int64(nns.CNAME)), nil case "SOA": return big.NewInt(int64(nns.SOA)), nil case "TXT": return big.NewInt(int64(nns.TXT)), nil case "AAAA": return big.NewInt(int64(nns.AAAA)), nil } return nil, errors.New("unsupported record type") } func recordTypeToString(rt nns.RecordType) string { switch rt { case nns.A: return "A" case nns.CNAME: return "CNAME" case nns.SOA: return "SOA" case nns.TXT: return "TXT" case nns.AAAA: return "AAAA" } return "" }