cmd: set-bans: allow banning from fpath

e.g., given a `bans.csv`

	104.248.45.80,2400h
	104.248.45.81,2400h
	104.248.45.83,2400h
	104.248.45.84,2400h

one can ban all those 4 hosts via

	$ monero daemon set-bans -f ./bans.csv

Signed-off-by: Ciro S. Costa <utxobr@protonmail.com>
This commit is contained in:
Ciro S. Costa 2021-07-21 18:56:33 -04:00
parent bc7c6484cd
commit 44b1bdf069

View file

@ -1,8 +1,10 @@
package daemon
import (
"encoding/csv"
"fmt"
"net"
"os"
"time"
"github.com/spf13/cobra"
@ -15,6 +17,7 @@ import (
type setBansCommand struct {
Host net.IP
Duration time.Duration
Filepath string
JSON bool
}
@ -30,7 +33,10 @@ func (c *setBansCommand) Cmd() *cobra.Command {
false, "whether or not to output the result as json")
cmd.Flags().IPVar(&c.Host, "host",
nil, "ip address (string format) of the host to ban")
_ = cmd.MarkFlagRequired("host")
cmd.Flags().StringVarP(&c.Filepath, "filepath", "f",
"", "location of a csv file containing <host>,<period> "+
"entries to ban")
cmd.Flags().DurationVar(&c.Duration, "duration",
24*time.Hour, "for how long this host should be banned for")
@ -48,14 +54,26 @@ func (c *setBansCommand) RunE(_ *cobra.Command, _ []string) error {
}
params := daemon.SetBansRequestParameters{
Bans: []daemon.SetBansBan{
{
Host: c.Host.String(),
Ban: true,
Seconds: int64(c.Duration.Seconds()),
},
},
Bans: []daemon.SetBansBan{},
}
if c.Host != nil {
params.Bans = append(params.Bans, daemon.SetBansBan{
Host: c.Host.String(),
Ban: true,
Seconds: int64(c.Duration.Seconds()),
})
}
if c.Filepath != "" {
bansFromFile, err := c.bansFromFilepath()
if err != nil {
return fmt.Errorf("bans from file: %w", err)
}
params.Bans = append(params.Bans, bansFromFile...)
}
resp, err := client.SetBans(ctx, params)
if err != nil {
return fmt.Errorf("set bans: %w", err)
@ -69,6 +87,43 @@ func (c *setBansCommand) RunE(_ *cobra.Command, _ []string) error {
return nil
}
func (c *setBansCommand) bansFromFilepath() ([]daemon.SetBansBan, error) {
f, err := os.Open(c.Filepath)
if err != nil {
return nil, fmt.Errorf("open: %w", err)
}
defer f.Close()
entries, err := csv.NewReader(f).ReadAll()
if err != nil {
return nil, fmt.Errorf("csv read all: %w", err)
}
bans := []daemon.SetBansBan{}
for _, entry := range entries {
if len(entry) != 2 {
return nil, fmt.Errorf(
"expected 2 fields in entry, got %d",
len(entry),
)
}
host, durationStr := entry[0], entry[1]
duration, err := time.ParseDuration(durationStr)
if err != nil {
return nil, fmt.Errorf("parse duration: %w", err)
}
bans = append(bans, daemon.SetBansBan{
Host: host,
Seconds: int64(duration.Seconds()),
Ban: true,
})
}
return bans, nil
}
// nolint:forbidigo
func (c *setBansCommand) pretty(v *daemon.SetBansResult) {
fmt.Println(v.Status)