1
0
Fork 0
mirror of https://github.com/eosswedenorg/thalos synced 2026-06-18 04:40:03 +02:00

refactor cli to use cobra.

This commit is contained in:
Henrik Hautakoski 2024-02-17 13:45:05 +01:00
parent fad70e19b9
commit 59480533d3
11 changed files with 236 additions and 289 deletions

View file

@ -7,7 +7,7 @@ import (
"os/signal"
"time"
"github.com/urfave/cli/v2"
"github.com/spf13/cobra"
"github.com/eosswedenorg/thalos/api"
"github.com/eosswedenorg/thalos/api/message"
@ -18,44 +18,38 @@ import (
log "github.com/sirupsen/logrus"
)
var benchCmd = &cli.Command{
Name: "bench",
Usage: "Run a benchmark against a thalos node",
Flags: []cli.Flag{
redisUrlFlag,
redisUserFlag,
redisPasswordFlag,
redisDbFlag,
prefixFlag,
chainIdFlag,
&cli.DurationFlag{
Name: "interval",
Aliases: []string{"i"},
Value: time.Minute,
Usage: "How often the benchmark results should be displayed.",
},
},
Action: func(ctx *cli.Context) error {
var benchCmd = &cobra.Command{
Use: "bench",
Short: "Run a benchmark against a thalos node",
Run: func(cmd *cobra.Command, args []string) {
var counter int = 0
interval := ctx.Duration("interval")
interval, _ := cmd.Flags().GetDuration("interval")
url, _ := cmd.Flags().GetString("redis-url")
user, _ := cmd.Flags().GetString("redis-user")
pw, _ := cmd.Flags().GetString("redis-pw")
prefix, _ := cmd.Flags().GetString("prefix")
chain_id, _ := cmd.Flags().GetString("chain_id")
db, _ := cmd.Flags().GetInt("redis-db")
log.WithFields(log.Fields{
"url": ctx.String("redis-url"),
"prefix": ctx.String("prefix"),
"chain_id": ctx.String("chain_id"),
"database": ctx.Int("redis-db"),
"url": url,
"prefix": prefix,
"chain_id": chain_id,
"database": db,
}).Info("Connecting to redis")
// Create redis client
rdb := redis.NewClient(&redis.Options{
Addr: ctx.String("redis-url"),
Username: ctx.String("redis-user"),
Password: ctx.String("redis-pw"),
DB: ctx.Int("redis-db"),
Addr: url,
Username: user,
Password: pw,
DB: db,
})
if err := rdb.Ping(context.Background()).Err(); err != nil {
return err
log.WithError(err).Fatal("Failed to connect to redis")
return
}
log.Println("Connected to redis")
@ -65,20 +59,22 @@ var benchCmd = &cli.Command{
}).Info("Starting benchmark")
sub := api_redis.NewSubscriber(context.Background(), rdb, api_redis.Namespace{
Prefix: ctx.String("prefix"),
ChainID: ctx.String("chain_id"),
Prefix: prefix,
ChainID: chain_id,
})
codec, err := message.GetCodec("json")
if err != nil {
return err
log.WithError(err).Fatal("Failed to get codec")
return
}
client := api.NewClient(sub, codec.Decoder)
// Subscribe to all actions
if err = client.Subscribe(api.ActionChannel{}.Channel()); err != nil {
return err
log.WithError(err).Fatal("Failed to subscribe to channels")
return
}
go func() {
@ -102,7 +98,7 @@ var benchCmd = &cli.Command{
case <-sig:
fmt.Println("Got interrupt")
client.Close()
return nil
return
case now := <-time.After(interval):
elapsed := now.Sub(t)
t = now

View file

@ -1,37 +0,0 @@
package main
import (
"github.com/urfave/cli/v2"
)
var redisUrlFlag = &cli.StringFlag{
Name: "redis-url",
Value: "127.0.0.1:6379",
Usage: "host:port to the redis server",
}
var redisUserFlag = &cli.StringFlag{
Name: "redis-user",
Usage: "User to use when authenticating to the server",
}
var redisPasswordFlag = &cli.StringFlag{
Name: "redis-pw",
Usage: "Password to use when authenticating to the server",
}
var redisDbFlag = &cli.IntFlag{
Name: "redis-db",
Value: 0,
Usage: "What redis database we should connect to.",
}
var prefixFlag = &cli.StringFlag{
Name: "prefix",
Value: "ship",
}
var chainIdFlag = &cli.StringFlag{
Name: "chain_id",
Value: "1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4",
}

View file

@ -1,29 +1,63 @@
package main
import (
"os"
"github.com/urfave/cli/v2"
"time"
_ "github.com/eosswedenorg/thalos/app/log"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
)
var VersionString string = "dev"
func main() {
app := &cli.App{
Usage: "Collection of tools for dealing with the thalos application",
Version: VersionString,
Commands: []*cli.Command{
validateCmd,
benchCmd,
RedisACLCmd,
MockPublisherCmd,
var rootCmd *cobra.Command
func init() {
redisFlags := pflag.FlagSet{}
redisFlags.String("redis-url", "127.0.0.1:6379", "host:port to the redis server")
redisFlags.String("redis-user", "", "User to use when authenticating to the server")
redisFlags.String("redis-pw", "", "Password to use when authenticating to the server")
redisFlags.Int("redis-db", 0, "What redis database we should connect to.")
redisFlags.String("prefix", "ship", "redis prefix")
redisFlags.String("chain_id", "1064487b3cd1a897ce03ae5b6a865651747e2e152090f99c1d19d44e01aea5a4", "chain id")
rootCmd = &cobra.Command{
Use: "thalos-tools",
Short: "Collection of tools for dealing with the thalos application",
FParseErrWhitelist: cobra.FParseErrWhitelist{
UnknownFlags: true,
},
Version: VersionString,
}
if err := app.Run(os.Args); err != nil {
log.WithError(err).Fatal("Application error")
benchCmd.Flags().AddFlagSet(&redisFlags)
benchCmd.Flags().DurationP("interval", "i", time.Minute, "How often the benchmark results should be displayed.")
validateCmd.Flags().AddFlagSet(&redisFlags)
MockPublisherCmd.Flags().AddFlagSet(&redisFlags)
MockPublisherCmd.Flags().String("codec", "json", "codec to use")
RedisACLCmd.Flags().String("default-pw", "", "Password to use for the default account, if not provided a random one will be generated")
RedisACLCmd.Flags().String("client", "thalos-client", "Thalos client account name")
RedisACLCmd.Flags().String("client-pw", "", "Password to use for the thalos client account, if not provided a random one will be generated")
RedisACLCmd.Flags().String("server", "thalos", "Thalos account name")
RedisACLCmd.Flags().String("server-pw", "", "Password to use for the thalos server account, if not provided a random one will be generated")
RedisACLCmd.Flags().String("prefix", "ship", "Redis key prefix")
RedisACLCmd.Flags().Bool("cleartext", false, "If passwords should be hashed or left in cleartext.")
RedisACLCmd.Flags().String("file", "", "Where the config should be written to (default: standard out)")
rootCmd.AddCommand(
validateCmd,
benchCmd,
RedisACLCmd,
MockPublisherCmd,
)
}
func main() {
if err := rootCmd.Execute(); err != nil {
log.Fatal(err)
}
}

View file

@ -4,7 +4,7 @@ import (
"context"
"time"
"github.com/urfave/cli/v2"
"github.com/spf13/cobra"
"github.com/eosswedenorg/thalos/api"
"github.com/eosswedenorg/thalos/api/message"
@ -16,45 +16,43 @@ import (
log "github.com/sirupsen/logrus"
)
var MockPublisherCmd = &cli.Command{
Name: "mock_publisher",
Usage: "Run a publisher that mocks messages to a redis server. tries to send as many messages as possible",
Flags: []cli.Flag{
redisUrlFlag,
redisUserFlag,
redisPasswordFlag,
redisDbFlag,
prefixFlag,
chainIdFlag,
&cli.StringFlag{
Name: "codec",
Value: "json",
},
},
Action: func(ctx *cli.Context) error {
var MockPublisherCmd = &cobra.Command{
Use: "mock_publisher",
Short: "Run a publisher that mocks messages to a redis server. tries to send as many messages as possible",
Run: func(cmd *cobra.Command, args []string) {
url, _ := cmd.Flags().GetString("redis-url")
user, _ := cmd.Flags().GetString("redis-user")
pw, _ := cmd.Flags().GetString("redis-pw")
prefix, _ := cmd.Flags().GetString("prefix")
chain_id, _ := cmd.Flags().GetString("chain_id")
db, _ := cmd.Flags().GetInt("redis-db")
// Create redis client
rdb := redis.NewClient(&redis.Options{
Addr: ctx.String("redis-url"),
Username: ctx.String("redis-user"),
Password: ctx.String("redis-pw"),
DB: ctx.Int("redis-db"),
Addr: url,
Username: user,
Password: pw,
DB: db,
})
codec, err := message.GetCodec(ctx.String("codec"))
codecArg, _ := cmd.Flags().GetString("codec")
codec, err := message.GetCodec(codecArg)
if err != nil {
return err
log.WithError(err).Fatal("Failed to get codec")
return
}
log.WithFields(log.Fields{
"url": ctx.String("redis-url"),
"prefix": ctx.String("prefix"),
"chain_id": ctx.String("chain_id"),
"database": ctx.Int("redis-db"),
"url": url,
"prefix": prefix,
"chain_id": chain_id,
"database": db,
}).Info("Starting mock publisher")
ns := api_redis.Namespace{
Prefix: ctx.String("prefix"),
ChainID: ctx.String("chain_id"),
Prefix: prefix,
ChainID: chain_id,
}
publisher := redis_driver.NewPublisher(context.Background(), rdb, ns)
@ -104,7 +102,8 @@ var MockPublisherCmd = &cli.Command{
payload, err := codec.Encoder(msg)
if err != nil {
return err
log.WithError(err).Fatal("Failed to encode message")
return
}
channel := api.ActionChannel{}.Channel()

View file

@ -10,7 +10,8 @@ import (
"text/template"
"time"
"github.com/urfave/cli/v2"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)
var rnd *rand.Rand
@ -90,60 +91,30 @@ user {{.client}} on {{.clientpw}} resetchannels &{{.prefix}}::* -@all +subscribe
})
}
var RedisACLCmd = &cli.Command{
Name: "redis-acl",
Usage: "create a users.acl file",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "default-pw",
Usage: "Password to use for the default account, if not provided a random one will be generated",
},
&cli.StringFlag{
Name: "client",
Value: "thalos-client",
Usage: "Thalos client account name",
},
&cli.StringFlag{
Name: "client-pw",
Usage: "Password to use for the thalos client account, if not provided a random one will be generated",
},
&cli.StringFlag{
Name: "server",
Value: "thalos",
Usage: "Thalos account name",
},
&cli.StringFlag{
Name: "server-pw",
Usage: "Password to use for the thalos server account, if not provided a random one will be generated",
},
&cli.StringFlag{
Name: "prefix",
Value: "ship",
Usage: "Redis key prefix",
},
&cli.BoolFlag{
Name: "cleartext",
Usage: "If passwords should be hashed or left in cleartext.",
},
&cli.StringFlag{
Name: "file",
DefaultText: "Standard out",
Usage: "Where the config should be written to",
},
},
Action: func(ctx *cli.Context) error {
var RedisACLCmd = &cobra.Command{
Use: "redis-acl",
Short: "create a users.acl file",
Run: func(cmd *cobra.Command, args []string) {
var err error
var out *os.File = os.Stdout
rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
defaultUser := NewUser("default", ctx.String("default-pw"))
serverUser := NewUser(ctx.String("server"), ctx.String("server-pw"))
clientUser := NewUser(ctx.String("client"), ctx.String("client-pw"))
flagDefUserPw, _ := cmd.Flags().GetString("default-pw")
flagServer, _ := cmd.Flags().GetString("server")
flagServerPw, _ := cmd.Flags().GetString("server-pw")
flagClient, _ := cmd.Flags().GetString("client")
flagClientPw, _ := cmd.Flags().GetString("client-pw")
flagPrefix, _ := cmd.Flags().GetString("prefix")
defaultUser := NewUser("default", flagDefUserPw)
serverUser := NewUser(flagServer, flagServerPw)
clientUser := NewUser(flagClient, flagClientPw)
atleastOneGeneratedPw := defaultUser.Generated || serverUser.Generated || clientUser.Generated
if !ctx.Bool("cleartext") {
cleartext, _ := cmd.Flags().GetBool("cleartext")
if !cleartext {
if atleastOneGeneratedPw {
println("Passwords")
}
@ -157,17 +128,22 @@ var RedisACLCmd = &cli.Command{
clientUser.Hash()
}
filename := ctx.String("file")
filename, _ := cmd.Flags().GetString("file")
if len(filename) > 0 {
out, err = os.Create(filename)
if err != nil {
return err
log.WithError(err).Fatal("Failed to create output file")
return
}
defer out.Close()
} else if !ctx.Bool("cleartext") && atleastOneGeneratedPw {
} else if !cleartext && atleastOneGeneratedPw {
fmt.Println()
}
return writeTemplate(out, defaultUser, serverUser, clientUser, ctx.String("prefix"))
err = writeTemplate(out, defaultUser, serverUser, clientUser, flagPrefix)
if err != nil {
log.WithError(err).Fatal("Failed to writte config")
return
}
},
}

View file

@ -7,7 +7,7 @@ import (
"os/signal"
"time"
"github.com/urfave/cli/v2"
"github.com/spf13/cobra"
"github.com/eosswedenorg/thalos/api"
"github.com/eosswedenorg/thalos/api/message"
@ -18,33 +18,33 @@ import (
log "github.com/sirupsen/logrus"
)
var validateCmd = &cli.Command{
Name: "validate",
Usage: "Validate a thalos server by following action traces and makes sure that blocks arrive in order.",
Flags: []cli.Flag{
redisUrlFlag,
redisDbFlag,
prefixFlag,
chainIdFlag,
},
Action: func(ctx *cli.Context) error {
var validateCmd = &cobra.Command{
Use: "validate",
Short: "Validate a thalos server by following action traces and makes sure that blocks arrive in order.",
Run: func(cmd *cobra.Command, args []string) {
status_duration := time.Second * 10
url, _ := cmd.Flags().GetString("redis-url")
prefix, _ := cmd.Flags().GetString("prefix")
chain_id, _ := cmd.Flags().GetString("chain_id")
db, _ := cmd.Flags().GetInt("redis-db")
log.WithFields(log.Fields{
"url": ctx.String("redis-url"),
"prefix": ctx.String("prefix"),
"chain_id": ctx.String("chain_id"),
"database": ctx.Int("redis-db"),
"url": url,
"prefix": prefix,
"chain_id": chain_id,
"database": db,
}).Info("Connecting to redis")
// Create redis client
rdb := redis.NewClient(&redis.Options{
Addr: ctx.String("redis-url"),
DB: ctx.Int("redis-db"),
Addr: url,
DB: db,
})
if err := rdb.Ping(context.Background()).Err(); err != nil {
return err
log.WithError(err).Fatal("Failed to connect to redis")
return
}
log.Println("Connected to redis")
@ -52,20 +52,22 @@ var validateCmd = &cli.Command{
log.Info("Starting validation, following the stream")
sub := api_redis.NewSubscriber(context.Background(), rdb, api_redis.Namespace{
Prefix: ctx.String("prefix"),
ChainID: ctx.String("chain_id"),
Prefix: prefix,
ChainID: chain_id,
})
codec, err := message.GetCodec("json")
if err != nil {
return err
log.WithError(err).Fatal("Failed to get codec")
return
}
client := api.NewClient(sub, codec.Decoder)
// Subscribe to all actions
if err = client.Subscribe(api.ActionChannel{}.Channel()); err != nil {
return err
log.WithError(err).Fatal("Failed to subscribe to channels")
return
}
block_num := uint32(0)
@ -102,7 +104,7 @@ var validateCmd = &cli.Command{
case <-sig:
fmt.Println("Got interrupt")
client.Close()
return nil
return
case <-timer.C:
log.WithField("duration", timeout).
Warn("Did not get any messages during the defined duration")