mirror of
https://codeberg.org/scip/esctl.git
synced 2026-08-24 03:24:19 +02:00
add support for config file and multiple clusters config (#1)
This commit is contained in:
25
cmd/root.go
25
cmd/root.go
@@ -37,10 +37,7 @@ func Finish(err error) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Main() int {
|
func Main() int {
|
||||||
conf, err := cfg.Init()
|
conf := cfg.NewConfig()
|
||||||
if err != nil {
|
|
||||||
return Finish(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd := &cli.Command{
|
cmd := &cli.Command{
|
||||||
Name: "esctl",
|
Name: "esctl",
|
||||||
@@ -57,6 +54,21 @@ func Main() int {
|
|||||||
Sources: cli.EnvVars("ES_DEBUG"),
|
Sources: cli.EnvVars("ES_DEBUG"),
|
||||||
Destination: &conf.Debug,
|
Destination: &conf.Debug,
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "config",
|
||||||
|
Aliases: []string{"c"},
|
||||||
|
Value: "",
|
||||||
|
Usage: "config file",
|
||||||
|
Sources: cli.EnvVars("ES_CONFIG"),
|
||||||
|
Destination: &conf.ConfigFile,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "cluster",
|
||||||
|
Aliases: []string{"C"},
|
||||||
|
Value: "",
|
||||||
|
Usage: "cluster alias to work with",
|
||||||
|
Destination: &conf.CurrentCluster,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
Commands: []*cli.Command{
|
Commands: []*cli.Command{
|
||||||
@@ -67,7 +79,12 @@ func Main() int {
|
|||||||
},
|
},
|
||||||
|
|
||||||
Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
|
Before: func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
|
||||||
|
if err := conf.Init(); err != nil {
|
||||||
|
Finish(err)
|
||||||
|
}
|
||||||
|
|
||||||
log.Init(conf)
|
log.Init(conf)
|
||||||
|
|
||||||
return nil, nil
|
return nil, nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,56 +19,147 @@ package cfg
|
|||||||
import (
|
import (
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"errors"
|
"errors"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/alecthomas/repr"
|
||||||
"github.com/elastic/elastic-transport-go/v8/elastictransport"
|
"github.com/elastic/elastic-transport-go/v8/elastictransport"
|
||||||
"github.com/elastic/go-elasticsearch/v9"
|
"github.com/elastic/go-elasticsearch/v9"
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
Version string = `v0.0.1`
|
Version string = `v0.0.2`
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Cluster struct {
|
||||||
|
Uri, User, Pass string
|
||||||
|
ES *elasticsearch.TypedClient
|
||||||
|
}
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
Uri, User, Pass string
|
ConfigFile string // -c
|
||||||
ES *elasticsearch.TypedClient
|
CurrentCluster string // -C
|
||||||
Debug bool
|
Debug bool // -d
|
||||||
|
Clusters map[string]*Cluster
|
||||||
|
DefaultCluster *Cluster
|
||||||
From, To, MaxItems int
|
From, To, MaxItems int
|
||||||
Index string
|
Index string
|
||||||
Filter []string
|
Filter []string
|
||||||
Failed, Partials bool
|
Failed, Partials bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func Init() (*Config, error) {
|
func NewConfig() *Config {
|
||||||
cfg := Config{
|
return &Config{Clusters: map[string]*Cluster{}}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conf *Config) Init() error {
|
||||||
|
if conf.ConfigFile != "" {
|
||||||
|
if err := conf.LoadConfig(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err := conf.LoadEnv(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.CurrentCluster != "" {
|
||||||
|
current, exists := conf.Clusters[conf.CurrentCluster]
|
||||||
|
if !exists {
|
||||||
|
return fmt.Errorf("no cluster with alias %s configured", conf.CurrentCluster)
|
||||||
|
} else {
|
||||||
|
conf.DefaultCluster = current
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if conf.Debug {
|
||||||
|
repr.Println(conf)
|
||||||
|
}
|
||||||
|
|
||||||
|
conf.SetupES()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conf *Config) LoadEnv() error {
|
||||||
|
cluster := Cluster{
|
||||||
Uri: os.Getenv("ES_URI"),
|
Uri: os.Getenv("ES_URI"),
|
||||||
User: os.Getenv("ES_USER"),
|
User: os.Getenv("ES_USER"),
|
||||||
Pass: os.Getenv("ES_PASS"),
|
Pass: os.Getenv("ES_PASS"),
|
||||||
}
|
}
|
||||||
|
|
||||||
switch {
|
switch {
|
||||||
case cfg.Uri == "":
|
case cluster.Uri == "":
|
||||||
return nil, errors.New("ES_URI unset")
|
return errors.New("ES_URI unset")
|
||||||
case cfg.User == "":
|
case cluster.User == "":
|
||||||
return nil, errors.New("ES_USER unset")
|
return errors.New("ES_USER unset")
|
||||||
case cfg.Pass == "":
|
case cluster.Pass == "":
|
||||||
return nil, errors.New("ES_PASS unset")
|
return errors.New("ES_PASS unset")
|
||||||
}
|
}
|
||||||
|
|
||||||
es, _ := elasticsearch.NewTyped(
|
conf.Clusters["default"] = &cluster
|
||||||
elasticsearch.WithAddresses(cfg.Uri),
|
conf.DefaultCluster = &cluster
|
||||||
elasticsearch.WithBasicAuth(cfg.User, cfg.Pass),
|
|
||||||
elasticsearch.WithTransportOptions(
|
|
||||||
elastictransport.WithTransport(
|
|
||||||
&http.Transport{
|
|
||||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
||||||
},
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
|
|
||||||
cfg.ES = es
|
return nil
|
||||||
|
}
|
||||||
return &cfg, nil
|
|
||||||
|
func (conf *Config) LoadConfig() error {
|
||||||
|
if conf.ConfigFile == "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := os.ReadFile(conf.ConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to read config file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
newconf := &Config{}
|
||||||
|
|
||||||
|
err = yaml.Unmarshal(data, newconf)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to unmarshal config file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(newconf.Clusters) > 0 {
|
||||||
|
conf.Clusters = newconf.Clusters
|
||||||
|
|
||||||
|
_, exists := conf.Clusters["default"]
|
||||||
|
if !exists {
|
||||||
|
// no "default", just use the first we stumble upon
|
||||||
|
for _, cluster := range conf.Clusters {
|
||||||
|
conf.DefaultCluster = cluster
|
||||||
|
break
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
conf.DefaultCluster = newconf.Clusters["default"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (conf *Config) SetupES() error {
|
||||||
|
for _, cluster := range conf.Clusters {
|
||||||
|
es, err := elasticsearch.NewTyped(
|
||||||
|
elasticsearch.WithAddresses(cluster.Uri),
|
||||||
|
elasticsearch.WithBasicAuth(cluster.User, cluster.Pass),
|
||||||
|
elasticsearch.WithTransportOptions(
|
||||||
|
elastictransport.WithTransport(
|
||||||
|
&http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to setup elasticsearch connection: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cluster.ES = es
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func Health(conf *cfg.Config) error {
|
func Health(conf *cfg.Config) error {
|
||||||
res, err := conf.ES.Cluster.Health().Do(context.Background())
|
res, err := conf.DefaultCluster.ES.Cluster.Health().Do(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error getting health: %s", err)
|
log.Fatalf("Error getting health: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func IndexList(conf *cfg.Config) error {
|
func IndexList(conf *cfg.Config) error {
|
||||||
cat := conf.ES.Cat.Indices()
|
cat := conf.DefaultCluster.ES.Cat.Indices()
|
||||||
|
|
||||||
if conf.Failed {
|
if conf.Failed {
|
||||||
cat = cat.Health(healthstatus.Red)
|
cat = cat.Health(healthstatus.Red)
|
||||||
@@ -67,7 +67,7 @@ func IndexList(conf *cfg.Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IndexShow(conf *cfg.Config, index string) error {
|
func IndexShow(conf *cfg.Config, index string) error {
|
||||||
res, err := conf.ES.Indices.Get(index).Do(context.Background())
|
res, err := conf.DefaultCluster.ES.Indices.Get(index).Do(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get index: %s", err)
|
return fmt.Errorf("failed to get index: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ func Search(conf *cfg.Config, q string) error {
|
|||||||
query.Filter(filters...)
|
query.Filter(filters...)
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := conf.ES.Search().
|
res, err := conf.DefaultCluster.ES.Search().
|
||||||
Index(conf.Index).
|
Index(conf.Index).
|
||||||
Request(&search.Request{
|
Request(&search.Request{
|
||||||
Query: query.QueryCaster(),
|
Query: query.QueryCaster(),
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ type Snapshot struct {
|
|||||||
|
|
||||||
func SnapshotList(conf *cfg.Config) error {
|
func SnapshotList(conf *cfg.Config) error {
|
||||||
// get partial indicies
|
// get partial indicies
|
||||||
ires, err := conf.ES.Cat.Indices().Do(context.Background())
|
ires, err := conf.DefaultCluster.ES.Cat.Indices().Do(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting indicies: %s", err)
|
return fmt.Errorf("Error getting indicies: %s", err)
|
||||||
}
|
}
|
||||||
@@ -55,7 +55,7 @@ func SnapshotList(conf *cfg.Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get snapshots
|
// get snapshots
|
||||||
sres, err := conf.ES.Cat.Snapshots().Do(context.Background())
|
sres, err := conf.DefaultCluster.ES.Cat.Snapshots().Do(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting snapshots: %s", err)
|
return fmt.Errorf("Error getting snapshots: %s", err)
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ func SnapshotList(conf *cfg.Config) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SnapshotShow(conf *cfg.Config, snapshot string) error {
|
func SnapshotShow(conf *cfg.Config, snapshot string) error {
|
||||||
res, err := conf.ES.Snapshot.Get("*", snapshot).Do(context.Background())
|
res, err := conf.DefaultCluster.ES.Snapshot.Get("*", snapshot).Do(context.Background())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get snapshot: %s", err)
|
return fmt.Errorf("failed to get snapshot: %s", err)
|
||||||
}
|
}
|
||||||
|
|||||||
9
sample-2-clusters.yaml
Normal file
9
sample-2-clusters.yaml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
clusters:
|
||||||
|
default:
|
||||||
|
uri: https://es.foo.bar:9200/
|
||||||
|
user: elastic
|
||||||
|
pass: 123456
|
||||||
|
other:
|
||||||
|
uri: https://myes.foo:9200/
|
||||||
|
user: elastic
|
||||||
|
pass: asdasdasd
|
||||||
Reference in New Issue
Block a user