xmr-remote-nodes/cmd/server/probers.go

173 lines
4 KiB
Go

package server
import (
"bufio"
"fmt"
"log/slog"
"os"
"strconv"
"strings"
"text/tabwriter"
"time"
"xmr-remote-nodes/internal/database"
"xmr-remote-nodes/internal/monero"
"github.com/spf13/cobra"
)
var probersCmd = &cobra.Command{
Use: "probers",
Short: "Add, edit, delete, and show registered probers",
Long: `Command to administer prober machines.
This command should only be run on the server which directly connect to the MySQL database.
`,
Run: func(cmd *cobra.Command, _ []string) {
if err := cmd.Help(); err != nil {
slog.Error(err.Error())
os.Exit(1)
}
},
}
var listProbersCmd = &cobra.Command{
Use: "list [search]",
Short: "Print registered probers",
Long: `Print list of registered prober machines.
Use [search] args to filter results by name or api key.
"sort-by" flag can be "id" or "last_submit_ts"
"sort-dir" flag can be "asc" or "desc"`,
Example: `# To sort probers by last submit time in ascending order that contains "sin1":
xmr-nodes probers list -s last_submit_ts -d asc sin1`,
Run: func(cmd *cobra.Command, args []string) {
if err := database.ConnectDB(); err != nil {
panic(err)
}
sortBy, _ := cmd.Flags().GetString("sort-by")
sortDir, _ := cmd.Flags().GetString("sort-dir")
probersRepo := monero.NewProber()
probers, err := probersRepo.Probers(monero.QueryProbers{
Search: strings.Join(args, " "),
SortBy: sortBy,
SortDirection: sortDir,
})
if err != nil {
fmt.Println(err)
return
}
if len(probers) == 0 {
fmt.Println("No probers found")
return
}
w := tabwriter.NewWriter(os.Stdout, 1, 1, 1, ' ', 0)
fmt.Fprintf(w, "ID\t| Name\t| Last Submit\t| API Key\n")
for _, prober := range probers {
fmt.Fprintf(w, "%d\t| %s\t| %s\t| %s\n",
prober.ID,
prober.Name,
time.Unix(prober.LastSubmitTs, 0).Format(time.RFC3339),
prober.ApiKey,
)
}
w.Flush()
},
}
func stringPrompt(label string) string {
var s string
r := bufio.NewReader(os.Stdin)
for {
fmt.Fprint(os.Stderr, label+" ")
s, _ = r.ReadString('\n')
if s != "" {
break
}
}
return strings.TrimSpace(s)
}
var addProbersCmd = &cobra.Command{
Use: "add [name]",
Short: "Add new prober",
Long: `Create new prober identified by [name] (if provided) along with an API key.
This command will display the prober name and API key when successfully executed.`,
Run: func(_ *cobra.Command, args []string) {
if err := database.ConnectDB(); err != nil {
fmt.Println(err)
return
}
proberName := ""
if len(args) > 0 {
proberName = strings.Join(args, " ")
} else {
proberName = stringPrompt("Prober Name:")
}
proberRepo := monero.NewProber()
prober, err := proberRepo.Add(proberName)
if err != nil {
fmt.Println(err)
return
}
fmt.Printf("Name: %s\nAPI Key: %s\n", prober.Name, prober.ApiKey)
},
}
var editProbersCmd = &cobra.Command{
Use: "edit",
Short: "Edit prober",
Long: `Edit prober name by id.`,
Run: func(cmd *cobra.Command, _ []string) {
if err := database.ConnectDB(); err != nil {
fmt.Println(err)
return
}
proberId, err := strconv.Atoi(stringPrompt("Prober ID:"))
if err != nil {
fmt.Println("Invalid ID:", err)
return
}
proberName := stringPrompt("Prober Name:")
proberRepo := monero.NewProber()
err = proberRepo.Edit(proberId, proberName)
if err != nil {
fmt.Println("Failed to update prober:", err)
return
}
fmt.Printf("Prober ID %d updated\n", proberId)
},
}
var deleteProbersCmd = &cobra.Command{
Use: "delete",
Short: "Delete prober",
Long: `Delete prober identified by id.`,
Run: func(_ *cobra.Command, _ []string) {
if err := database.ConnectDB(); err != nil {
fmt.Println(err)
return
}
proberId, err := strconv.Atoi(stringPrompt("Prober ID:"))
if err != nil {
fmt.Println("Invalid ID:", err)
return
}
proberRepo := monero.NewProber()
err = proberRepo.Delete(proberId)
if err != nil {
fmt.Println("Failed to delete prober:", err)
return
}
fmt.Printf("Prober ID %d deleted\n", proberId)
},
}