mirror of
https://codeberg.org/scip/esctl.git
synced 2026-08-24 16:04:18 +02:00
Compare commits
5 Commits
internal/g
...
internal/r
| Author | SHA1 | Date | |
|---|---|---|---|
| 3abe8b62a2 | |||
| 86f17329b0 | |||
| 2d8ecae73b | |||
| 033dd0ccd1 | |||
| 0d81e5c3bc |
@@ -2,7 +2,7 @@ matrix:
|
||||
platform:
|
||||
- linux/amd64
|
||||
goversion:
|
||||
- 1.26.4
|
||||
- 1.25.8
|
||||
|
||||
labels:
|
||||
platform: ${platform}
|
||||
@@ -21,6 +21,6 @@ steps:
|
||||
event: [push,manual]
|
||||
image: golang:${goversion}
|
||||
commands:
|
||||
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.12.2
|
||||
- curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s -- -b $(go env GOPATH)/bin v2.5.0
|
||||
- golangci-lint --version
|
||||
- golangci-lint run ./...
|
||||
|
||||
@@ -536,6 +536,7 @@ index - manage indicies
|
||||
update - update an index
|
||||
delete - delete an index
|
||||
close - close an index
|
||||
allocation - explain index allocation
|
||||
fields - show info about field capabilities
|
||||
ilm - show ilm status
|
||||
alias - manage index aliases
|
||||
@@ -563,7 +564,6 @@ search - search within an index
|
||||
shard - manage shards
|
||||
list - list shards
|
||||
show - show details about a shard
|
||||
allocation - explain shard allocation
|
||||
snapshot - manage snapshots
|
||||
list - list snapshots
|
||||
show - show details about a snapshot
|
||||
|
||||
6
TODO.md
6
TODO.md
@@ -3,7 +3,13 @@
|
||||
|
||||
- index show: add more details, see screenshots
|
||||
|
||||
- add shard explain, aka:
|
||||
get /_cluster/allocation/explain {"index":"yourindex", "primary": true, "shard":0}
|
||||
|
||||
|
||||
- add datastream support:
|
||||
https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-get-data-stream
|
||||
|
||||
also exclude data stream backing indices from index ls
|
||||
|
||||
- table any2string
|
||||
|
||||
33
cmd/index.go
33
cmd/index.go
@@ -40,6 +40,7 @@ func Index(conf *cfg.Config) *cli.Command {
|
||||
IndexCreate(conf, true),
|
||||
IndexDelete(conf),
|
||||
IndexClose(conf),
|
||||
IndexAllocation(conf),
|
||||
IndexFields(conf),
|
||||
IndexIlm(conf),
|
||||
|
||||
@@ -95,6 +96,38 @@ func IndexList(conf *cfg.Config) *cli.Command {
|
||||
}
|
||||
}
|
||||
|
||||
func IndexAllocation(conf *cfg.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "allocation",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "explain index allocation",
|
||||
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{
|
||||
Name: "shard",
|
||||
Usage: "shard number to explain for",
|
||||
Destination: &conf.Shards,
|
||||
Aliases: []string{"s"},
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "primary",
|
||||
Usage: "explain primary allocation (default true)",
|
||||
Destination: &conf.Primary,
|
||||
Aliases: []string{"p"},
|
||||
},
|
||||
},
|
||||
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
index := cmd.Args().Get(0)
|
||||
if index == "" {
|
||||
return errors.New("no index specified")
|
||||
}
|
||||
|
||||
return es.IndexAllocation(conf, cmd.Args().Get(0))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func IndexShow(conf *cfg.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "show",
|
||||
|
||||
@@ -35,7 +35,6 @@ func Shard(conf *cfg.Config) *cli.Command {
|
||||
Commands: []*cli.Command{
|
||||
ShardList(conf),
|
||||
ShardShow(conf),
|
||||
ShardAllocation(conf),
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -95,41 +94,3 @@ func ShardShow(conf *cfg.Config) *cli.Command {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func ShardAllocation(conf *cfg.Config) *cli.Command {
|
||||
return &cli.Command{
|
||||
Name: "allocation",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "explain shard allocation",
|
||||
|
||||
Flags: []cli.Flag{
|
||||
&cli.IntFlag{
|
||||
Name: "shard",
|
||||
Usage: "shard number to explain for",
|
||||
Destination: &conf.Shards,
|
||||
Aliases: []string{"s"},
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "primary",
|
||||
Usage: "explain primary allocation (default true)",
|
||||
Destination: &conf.Primary,
|
||||
Aliases: []string{"p"},
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "node",
|
||||
Usage: "explain a shard only if it is currently located on the specified node name or node ID",
|
||||
Destination: &conf.FromNode,
|
||||
Aliases: []string{"n"},
|
||||
},
|
||||
},
|
||||
|
||||
Action: func(ctx context.Context, cmd *cli.Command) error {
|
||||
index := cmd.Args().Get(0)
|
||||
if index == "" {
|
||||
return errors.New("no index specified")
|
||||
}
|
||||
|
||||
return es.ShardAllocation(conf, cmd.Args().Get(0))
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
func addReference(ref string) string {
|
||||
indentedRef := []string{}
|
||||
|
||||
for line := range strings.SplitSeq(ref, "\n") {
|
||||
for _, line := range strings.Split(ref, "\n") {
|
||||
indentedRef = append(indentedRef, " "+line)
|
||||
}
|
||||
return fmt.Sprintf("%s\nREFERENCE:\n%s\n",
|
||||
|
||||
2
go.mod
2
go.mod
@@ -14,7 +14,7 @@
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
module codeberg.org/scip/esctl
|
||||
|
||||
go 1.26.4
|
||||
go 1.25.8
|
||||
|
||||
require (
|
||||
github.com/MichaelMure/go-term-markdown v0.1.4
|
||||
|
||||
@@ -45,7 +45,7 @@ func (t *DebugTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
var pretty bytes.Buffer
|
||||
err = json.Indent(&pretty, buf.Bytes(), "", "\t")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("json parse error: %w", err)
|
||||
return nil, fmt.Errorf("json parse error: %s", err)
|
||||
}
|
||||
|
||||
content = pretty.String()
|
||||
|
||||
@@ -94,7 +94,7 @@ func ApiRepl(conf *cfg.Config) error {
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to initialize readline lib: %w", err)
|
||||
return fmt.Errorf("failed to initialize readline lib: %s", err)
|
||||
}
|
||||
|
||||
for {
|
||||
@@ -237,7 +237,7 @@ func CallAPI(conf *cfg.Config, verb, path, data string) ([]byte, error) {
|
||||
// Read and print response
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response body: %w", err)
|
||||
return nil, fmt.Errorf("failed to read response body: %s", err)
|
||||
}
|
||||
|
||||
return body, nil
|
||||
@@ -261,7 +261,7 @@ func prettyfiJson(conf *cfg.Config, raw []byte) (string, error) {
|
||||
var pretty bytes.Buffer
|
||||
err := json.Indent(&pretty, raw, "", "\t")
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("json parse error: %w", err)
|
||||
return "", fmt.Errorf("json parse error: %s", err)
|
||||
}
|
||||
|
||||
return pretty.String(), nil
|
||||
@@ -295,7 +295,7 @@ func readJSON(input string) (string, error) {
|
||||
check := map[string]any{}
|
||||
err := json.Unmarshal([]byte(data), &check)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error: input data is not proper JSON: %w", err)
|
||||
return "", fmt.Errorf("error: input data is not proper JSON: %s", err)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ func CcrStatus(conf *cfg.Config, leader, follower string) error {
|
||||
res, err := conf.Clusters[alias].ES().Cat.Indices().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get indicies on %s: %w", alias, esErrorString(err))
|
||||
return fmt.Errorf("failed to get indicies on %s: %s", alias, esErrorString(err))
|
||||
}
|
||||
|
||||
indices[alias] = make(map[string]*types.IndicesRecord, len(res))
|
||||
@@ -87,7 +87,7 @@ func CcrRemoteInfo(conf *cfg.Config, index string) error {
|
||||
res, err := conf.DefaultCluster.ES().Cluster.RemoteInfo().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve follower info: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to retrieve follower info: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ccr remote info", "info", res)
|
||||
|
||||
@@ -29,7 +29,7 @@ func getRemoteName(conf *cfg.Config) (string, error) {
|
||||
res, err := conf.DefaultCluster.ES().Cluster.RemoteInfo().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to retrieve follower info: %w", esErrorString(err))
|
||||
return "", fmt.Errorf("failed to retrieve follower info: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
remote := ""
|
||||
@@ -91,7 +91,7 @@ func CcrFollowerResume(conf *cfg.Config, index string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resume ccr following: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to resume ccr following: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -102,7 +102,7 @@ func CcrFollowerPause(conf *cfg.Config, index string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to pause ccr following: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to pause ccr following: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -113,7 +113,7 @@ func CcrFollowerUnfollow(conf *cfg.Config, index string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to unfollow index: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to unfollow index: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -136,7 +136,7 @@ func CcrFollowerAdd(conf *cfg.Config, index string) error {
|
||||
_, err = create.Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create follower index: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to create follower index: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -146,7 +146,7 @@ func CcrFollowerShow(conf *cfg.Config, index string) error {
|
||||
res, err := conf.DefaultCluster.ES().Ccr.FollowStats(index).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve follower index info: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to retrieve follower index info: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "follower stats", res.Indices)
|
||||
|
||||
@@ -44,14 +44,16 @@ func ClusterList(conf *cfg.Config) error {
|
||||
|
||||
// check endpoints in parallel to speed things up
|
||||
for name, cluster := range conf.Clusters {
|
||||
wg.Add(1)
|
||||
|
||||
wg.Go(func() {
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
online, err := cluster.IsReachable()
|
||||
|
||||
mu.Lock()
|
||||
reachable[name] = clusterReachable{reachable: online, err: err}
|
||||
mu.Unlock()
|
||||
})
|
||||
}()
|
||||
}
|
||||
|
||||
wg.Wait()
|
||||
|
||||
@@ -35,7 +35,7 @@ func ClusterSettingsList(conf *cfg.Config) error {
|
||||
FlatSettings(true).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get cluster settings: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get cluster settings: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
table := printer.NewTable(conf, 2, 0)
|
||||
@@ -75,7 +75,7 @@ func ClusterSettingsSet(conf *cfg.Config, args cli.Args) error {
|
||||
case conf.Transient:
|
||||
message, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshall transient value <%v> to valid JSON: %w", value, err)
|
||||
return fmt.Errorf("failed to marshall transient value <%v> to valid JSON: %s", value, err)
|
||||
}
|
||||
put.AddTransient(setting, message)
|
||||
case conf.Persistent:
|
||||
@@ -83,7 +83,7 @@ func ClusterSettingsSet(conf *cfg.Config, args cli.Args) error {
|
||||
default:
|
||||
message, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshall persistent value <%v> to valid JSON: %w", value, err)
|
||||
return fmt.Errorf("failed to marshall persistent value <%v> to valid JSON: %s", value, err)
|
||||
}
|
||||
put.AddPersistent(setting, message)
|
||||
}
|
||||
@@ -91,7 +91,7 @@ func ClusterSettingsSet(conf *cfg.Config, args cli.Args) error {
|
||||
|
||||
_, err := put.Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set settings: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to set settings: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -100,7 +100,7 @@ func ClusterSettingsSet(conf *cfg.Config, args cli.Args) error {
|
||||
func ClusterSettingsSetSingle(conf *cfg.Config, setting, value string) error {
|
||||
message, err := json.Marshal(value)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshall persistent value <%v> to valid JSON: %w", value, err)
|
||||
return fmt.Errorf("failed to marshall persistent value <%v> to valid JSON: %s", value, err)
|
||||
}
|
||||
|
||||
_, err = conf.DefaultCluster.ES().Cluster.PutSettings().
|
||||
@@ -108,7 +108,7 @@ func ClusterSettingsSetSingle(conf *cfg.Config, setting, value string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to set %s: %w", setting, esErrorString(err))
|
||||
return fmt.Errorf("failed to set %s: %s", setting, esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -32,7 +32,7 @@ func DatastreamNames(conf *cfg.Config) ([]string, error) {
|
||||
res, err := conf.DefaultCluster.ES().Indices.GetDataStream().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get data streams: %w", esErrorString(err))
|
||||
return nil, fmt.Errorf("failed to get data streams: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
dss := make([]string, len(res.DataStreams))
|
||||
@@ -47,7 +47,7 @@ func DatastreamList(conf *cfg.Config) error {
|
||||
res, err := conf.DefaultCluster.ES().Indices.GetDataStream().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get data streams: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get data streams: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "data streams", res)
|
||||
@@ -128,7 +128,7 @@ func DatastreamShow(conf *cfg.Config, dsname string) error {
|
||||
Name(dsname).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get data stream: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get data stream: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "data stream", res)
|
||||
@@ -141,7 +141,7 @@ func DatastreamShow(conf *cfg.Config, dsname string) error {
|
||||
Name(dsname).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get data stream stats: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get data stream stats: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
table := printer.NewTable(conf, 11, 2)
|
||||
@@ -208,7 +208,7 @@ func DatastreamCreate(conf *cfg.Config, dsname string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create datastream: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to create datastream: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -219,7 +219,7 @@ func DatastreamDelete(conf *cfg.Config, dsname string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete datastream: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to delete datastream: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -229,7 +229,7 @@ func DatastreamRollover(conf *cfg.Config, ds string) error {
|
||||
res, err := RolloverAlias(conf, ds)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to rollover data stream: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to rollover data stream: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
table := printer.NewTable(conf, 2, 5)
|
||||
|
||||
@@ -42,7 +42,7 @@ func DocAdd(conf *cfg.Config, jsondoc string) error {
|
||||
|
||||
err := json.Unmarshal([]byte(jsondoc), &data)
|
||||
if err != nil {
|
||||
return fmt.Errorf("supplied document was not valid JSON: %w", err)
|
||||
return fmt.Errorf("supplied document was not valid JSON: %s", err)
|
||||
}
|
||||
|
||||
now := fmt.Sprintf("%d", rand.Int64())
|
||||
@@ -51,7 +51,7 @@ func DocAdd(conf *cfg.Config, jsondoc string) error {
|
||||
Document(data).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create new doc in index %s: %w", conf.Index, esErrorString(err))
|
||||
return fmt.Errorf("failed to create new doc in index %s: %s", conf.Index, esErrorString(err))
|
||||
}
|
||||
|
||||
fmt.Println(res.Id_)
|
||||
@@ -63,7 +63,7 @@ func DocShow(conf *cfg.Config, id string) error {
|
||||
res, err := conf.DefaultCluster.ES().Get(conf.Index, id).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve doc in index %s: %w", conf.Index, esErrorString(err))
|
||||
return fmt.Errorf("failed to retrieve doc in index %s: %s", conf.Index, esErrorString(err))
|
||||
}
|
||||
|
||||
if !res.Found {
|
||||
@@ -94,7 +94,7 @@ func DocDelete(conf *cfg.Config, queries []string) error {
|
||||
_, err := conf.DefaultCluster.ES().Delete(conf.Index, id).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete doc in index %s: %w", conf.Index, esErrorString(err))
|
||||
return fmt.Errorf("failed to delete doc in index %s: %s", conf.Index, esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -117,7 +117,7 @@ func DocDelete(conf *cfg.Config, queries []string) error {
|
||||
Request(req).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete docs in index %s: %w", conf.Index, esErrorString(err))
|
||||
return fmt.Errorf("failed to delete docs in index %s: %s", conf.Index, esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -17,33 +17,29 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
package es
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/elastic/go-elasticsearch/v9/typedapi/types"
|
||||
)
|
||||
|
||||
func esErrorString(err error) error {
|
||||
func esErrorString(err error) string {
|
||||
msg := err.Error()
|
||||
|
||||
switch e := err.(type) {
|
||||
case *types.ElasticsearchError:
|
||||
var causes strings.Builder
|
||||
causes := ""
|
||||
|
||||
for _, cause := range e.ErrorCause.RootCause {
|
||||
// FIXME: re-activate linter here, see https://github.com/golangci/golangci-lint/issues/6662
|
||||
//nolint:staticcheck
|
||||
causes.WriteString(fmt.Sprintf("%s\n", *cause.Reason))
|
||||
causes += fmt.Sprintf("%s\n", *cause.Reason)
|
||||
}
|
||||
|
||||
if e.ErrorCause.Reason != nil {
|
||||
msg = *e.ErrorCause.Reason + ": " + causes.String()
|
||||
msg = *e.ErrorCause.Reason + ": " + causes
|
||||
} else {
|
||||
msg = fmt.Sprintf("http status %d: ", e.Status)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return errors.New(msg)
|
||||
return msg
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func IlmRetry(conf *cfg.Config, index string) error {
|
||||
_, err := conf.DefaultCluster.ES().Ilm.Retry(index).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retry ilm: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to retry ilm: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -47,7 +47,7 @@ func IlmStatus(conf *cfg.Config) error {
|
||||
res, err := conf.DefaultCluster.ES().Ilm.GetStatus().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get ilm status: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get ilm status: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
fmt.Println(res.OperationMode.Name)
|
||||
@@ -59,7 +59,7 @@ func IlmNames(conf *cfg.Config) ([]string, error) {
|
||||
res, err := conf.DefaultCluster.ES().Ilm.GetLifecycle().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get ilm policies: %w", esErrorString(err))
|
||||
return nil, fmt.Errorf("failed to get ilm policies: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
names := make([]string, len(res))
|
||||
@@ -82,7 +82,7 @@ func IlmList(conf *cfg.Config, pattern string) error {
|
||||
|
||||
res, err := ilm.Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get ilm policies: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get ilm policies: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
if conf.Debug {
|
||||
@@ -110,7 +110,7 @@ func IlmShow(conf *cfg.Config, policy string) error {
|
||||
Policy(policy).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get ilm status: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get ilm status: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
if conf.Debug {
|
||||
@@ -270,7 +270,7 @@ func IlmExplain(conf *cfg.Config, index string) error {
|
||||
res, err := conf.DefaultCluster.ES().Ilm.ExplainLifecycle(index).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get ilm state: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get ilm state: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ilm status", "ilm", res)
|
||||
@@ -523,7 +523,7 @@ func IlmCreate(conf *cfg.Config, policyname string) error {
|
||||
|
||||
_, err = ilm.Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed create ilm policy: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed create ilm policy: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -157,7 +157,11 @@ func IlmForecastShow(conf *cfg.Config) error {
|
||||
var toBeFreed int64 = 0
|
||||
|
||||
for _, phase := range phaseData {
|
||||
age := max(virtualAge(&phase), phase.age)
|
||||
age := virtualAge(&phase)
|
||||
|
||||
if age < phase.age {
|
||||
age = phase.age
|
||||
}
|
||||
|
||||
if age+within >= phase.minage {
|
||||
toBeFreed += phase.size
|
||||
@@ -196,7 +200,7 @@ func getIlmPhaseData(conf *cfg.Config) ([]PhaseData, error) {
|
||||
var indicesres *indices.Response
|
||||
var ilmpolicies getlifecycle.Response
|
||||
|
||||
for range 3 {
|
||||
for i := 0; i < 3; i++ {
|
||||
r := <-responses
|
||||
|
||||
if r.error != nil {
|
||||
|
||||
@@ -39,7 +39,7 @@ func IndexNames(conf *cfg.Config) ([]string, error) {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get indicies: %w", esErrorString(err))
|
||||
return nil, fmt.Errorf("failed to get indicies: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
indices := make([]string, len(res))
|
||||
@@ -97,7 +97,7 @@ func IndexList(conf *cfg.Config) error {
|
||||
|
||||
res, err := cat.Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get indicies: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get indicies: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "indicies", res)
|
||||
@@ -133,7 +133,7 @@ func IndexShow(conf *cfg.Config, indexpattern string) error {
|
||||
res, err := conf.DefaultCluster.ES().Indices.Get(indexpattern).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get index: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get index: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("index show", "index", res)
|
||||
@@ -234,7 +234,7 @@ func IndexCreate(conf *cfg.Config, index string, mappings []string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create index: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to create index: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -244,7 +244,7 @@ func IndexDelete(conf *cfg.Config, index string) error {
|
||||
_, err := conf.DefaultCluster.ES().Indices.Delete(index).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete index: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to delete index: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -255,19 +255,77 @@ func IndexClose(conf *cfg.Config, index string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to close index: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to close index: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func IndexAllocation(conf *cfg.Config, index string) error {
|
||||
res, err := conf.DefaultCluster.ES().Cluster.AllocationExplain().
|
||||
Index(index).
|
||||
Primary(conf.Primary).
|
||||
Shard(conf.Shards).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get index allocation explain: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "index", res)
|
||||
|
||||
currentNode := res.CurrentNode
|
||||
|
||||
table := printer.NewTable(conf, 2, 10)
|
||||
table.Addheaders("index allocation setting", "value")
|
||||
|
||||
roles := make([]string, len(currentNode.Roles))
|
||||
for idx, role := range currentNode.Roles {
|
||||
roles[idx] = role.Name
|
||||
}
|
||||
|
||||
table.Entries = [][]any{
|
||||
{"Index", index},
|
||||
{"Current node", currentNode.Name},
|
||||
{"Current k8s node", currentNode.Attributes["k8s_node_name"]},
|
||||
{"Current node address", currentNode.TransportAddress},
|
||||
{"Current node id", currentNode.Id},
|
||||
{"Current node weight", currentNode.WeightRanking},
|
||||
{"Current node roles", roles},
|
||||
{"Can rebalance cluster", res.CanRebalanceCluster.Name},
|
||||
{"Can rebalance to another node", res.CanRebalanceToOtherNode.Name},
|
||||
{"Can remain on current node", res.CanRemainOnCurrentNode.Name},
|
||||
}
|
||||
|
||||
if err := table.Print(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
func IndexModify(conf *cfg.Config, index string) error {
|
||||
settings := esdsl.NewIndexSettings().NumberOfReplicas(strconv.Itoa(conf.Replicas))
|
||||
|
||||
_, err := conf.DefaultCluster.ES().Indices.PutSettings().
|
||||
Indices(index).
|
||||
Index(settings).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to modify index settings: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
func IndexFields(conf *cfg.Config, index string) error {
|
||||
res, err := conf.DefaultCluster.ES().FieldCaps().
|
||||
Index(index).
|
||||
Fields("*").
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve field capabilties: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to retrieve field capabilties: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
table := printer.NewTable(conf, 5, 0)
|
||||
|
||||
@@ -35,7 +35,7 @@ func IndexAliasCreate(conf *cfg.Config, index, alias string) error {
|
||||
slog.Debug("create alias", "result", res)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create index alias: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to create index alias: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -54,7 +54,7 @@ func IndexAliasList(conf *cfg.Config) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to list index aliases: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to list index aliases: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("aliases list", "result", res)
|
||||
@@ -102,7 +102,7 @@ func IndexAliasDelete(conf *cfg.Config, index, alias string) error {
|
||||
slog.Debug("delete alias", "result", res)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete index alias: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to delete index alias: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -112,7 +112,7 @@ func IndexAliasRollover(conf *cfg.Config, alias string) error {
|
||||
res, err := RolloverAlias(conf, alias)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to rollover index alias: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to rollover index alias: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
table := printer.NewTable(conf, 2, 5)
|
||||
|
||||
@@ -22,7 +22,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"maps"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -38,7 +37,7 @@ func IndexTemplateList(conf *cfg.Config) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get index templates: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get index templates: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("res", "index templates", res)
|
||||
@@ -65,7 +64,7 @@ func IndexTemplateShow(conf *cfg.Config, tplname string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get index template: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get index template: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("res", "index template", res)
|
||||
@@ -226,7 +225,7 @@ func IndexTemplateCreate(conf *cfg.Config, name string, mappings []string) error
|
||||
_, err := create.Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create index template: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to create index template: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -243,7 +242,7 @@ func IndexTemplateModify(conf *cfg.Config, name string, mappings []string) error
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get index template: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get index template: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("res", "index template", res)
|
||||
@@ -337,7 +336,7 @@ func IndexTemplateModify(conf *cfg.Config, name string, mappings []string) error
|
||||
_, err = modify.Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to modify index template: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to modify index template: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
if conf.Rollover {
|
||||
@@ -353,7 +352,7 @@ func IndexTemplateDelete(conf *cfg.Config, name string) error {
|
||||
_, err := conf.DefaultCluster.ES().Indices.DeleteIndexTemplate(name).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to delete index template: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to delete index template: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -368,7 +367,7 @@ func rolloverAliasIndexTemplate(conf *cfg.Config, name string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get index template: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get index template: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("res", "index template", res)
|
||||
@@ -385,7 +384,7 @@ func rolloverAliasIndexTemplate(conf *cfg.Config, name string) error {
|
||||
res, err := conf.DefaultCluster.ES().Indices.ResolveIndex(pattern).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to resolve index pattern: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to resolve index pattern: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
for _, index := range res.Indices {
|
||||
@@ -449,7 +448,9 @@ func modMappings(mappings []string) (types.TypeMappingVariant, error) {
|
||||
func modMeta(conf *cfg.Config, meta types.Metadata) (map[string]json.RawMessage, error) {
|
||||
metadata := map[string]json.RawMessage{}
|
||||
|
||||
maps.Copy(metadata, meta)
|
||||
for key, value := range meta {
|
||||
metadata[key] = value
|
||||
}
|
||||
|
||||
for _, meta := range conf.Meta {
|
||||
parts := strings.Split(meta, ":")
|
||||
|
||||
@@ -29,7 +29,7 @@ func LicenseShow(conf *cfg.Config) error {
|
||||
res, err := conf.DefaultCluster.ES().License.Get().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get license: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get license: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("license show", "license", res)
|
||||
|
||||
@@ -32,7 +32,7 @@ func NodeList(conf *cfg.Config) error {
|
||||
// get nodes
|
||||
nodes, err := conf.DefaultCluster.ES().Cat.Nodes().Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get nodes: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get nodes: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "nodes", nodes)
|
||||
@@ -64,7 +64,7 @@ func NodeNames(conf *cfg.Config) ([]string, error) {
|
||||
nodes, err := conf.DefaultCluster.ES().Cat.Nodes().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get nodes: %w", esErrorString(err))
|
||||
return nil, fmt.Errorf("failed to get nodes: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "nodes", nodes)
|
||||
@@ -86,7 +86,7 @@ func NodeShow(conf *cfg.Config, nodename string) error {
|
||||
Metric("os, jvm, thread_pool, remote_cluster_server").
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get node info: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get node info: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "node", res)
|
||||
@@ -95,7 +95,7 @@ func NodeShow(conf *cfg.Config, nodename string) error {
|
||||
NodeId(nodename).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get node stats: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get node stats: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "stat", stats)
|
||||
@@ -159,7 +159,7 @@ func NodeClients(conf *cfg.Config, nodename string) error {
|
||||
NodeId(nodename).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get node stats: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get node stats: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "stat", stats)
|
||||
|
||||
@@ -158,7 +158,7 @@ func getApiData(
|
||||
}
|
||||
|
||||
if arerr != nil {
|
||||
ar.error = fmt.Errorf("failed to get data from API: %w", arerr)
|
||||
ar.error = fmt.Errorf("failed to get data from API: %s", arerr)
|
||||
}
|
||||
|
||||
reschan <- ar
|
||||
|
||||
@@ -30,7 +30,7 @@ func RoleNames(conf *cfg.Config) ([]string, error) {
|
||||
res, err := conf.DefaultCluster.ES().Security.GetRole().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get roles: %w", esErrorString(err))
|
||||
return nil, fmt.Errorf("failed to get roles: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
roles := make([]string, len(res))
|
||||
@@ -47,7 +47,7 @@ func RoleList(conf *cfg.Config) error {
|
||||
res, err := conf.DefaultCluster.ES().Security.GetRole().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get roles: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get roles: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "roles", res)
|
||||
@@ -74,7 +74,7 @@ func RoleShow(conf *cfg.Config, rolename string) error {
|
||||
Name(rolename).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get role: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get role: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "role", res)
|
||||
|
||||
@@ -75,7 +75,7 @@ type Register struct {
|
||||
func getCsvRecords(conf *cfg.Config, csvfile string) (map[string]Record, error) {
|
||||
data, err := os.ReadFile(csvfile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read CSV file: %w", err)
|
||||
return nil, fmt.Errorf("failed to read CSV file: %s", err)
|
||||
}
|
||||
|
||||
csvreader := csv.NewReader(bytes.NewReader(data))
|
||||
@@ -85,7 +85,7 @@ func getCsvRecords(conf *cfg.Config, csvfile string) (map[string]Record, error)
|
||||
|
||||
rows, err := csvreader.ReadAll()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse CSV: %w", err)
|
||||
return nil, fmt.Errorf("failed to parse CSV: %s", err)
|
||||
}
|
||||
|
||||
records := make(map[string]Record, len(rows)-1)
|
||||
@@ -118,7 +118,7 @@ func getCsvRecords(conf *cfg.Config, csvfile string) (map[string]Record, error)
|
||||
func getCsvRecord(conf *cfg.Config, csvfile, rolename string) (*Record, error) {
|
||||
fd, err := os.Open(csvfile)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to open CSV file: %w", err)
|
||||
return nil, fmt.Errorf("failed to open CSV file: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
if err := fd.Close(); err != nil {
|
||||
@@ -210,7 +210,7 @@ func RoleDiff(conf *cfg.Config, csvfile, role string) error {
|
||||
res, err := conf.DefaultCluster.ES().Security.GetRole().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get roles: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get roles: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
rows := diffRoles(conf, records, res)
|
||||
@@ -245,7 +245,7 @@ func getRoleMappingGroups(conf *cfg.Config, rolename string) ([]string, error) {
|
||||
mappings, err := conf.DefaultCluster.ES().Security.GetRoleMapping().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get role mappings: %w", esErrorString(err))
|
||||
return nil, fmt.Errorf("failed to get role mappings: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
groups := []string{}
|
||||
@@ -279,7 +279,7 @@ func RoleDiffSingle(conf *cfg.Config, csvfile, rolename string) error {
|
||||
Name(rolename).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get role: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get role: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
record, err := getCsvRecord(conf, csvfile, rolename)
|
||||
|
||||
@@ -82,13 +82,13 @@ func explainSearch(conf *cfg.Config, search *search.Search) error {
|
||||
Size(1). // one's enough for explain
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to call explain search (esdsl): %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to call explain search (esdsl): %s", esErrorString(err))
|
||||
}
|
||||
|
||||
if conf.Debug {
|
||||
raw, err := json.Marshal(res)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to marshal explain result: %w", err)
|
||||
return fmt.Errorf("failed to marshal explain result: %s", err)
|
||||
}
|
||||
|
||||
value := gjson.Get(string(raw), "hits.hits.0._explanation")
|
||||
@@ -134,7 +134,7 @@ func validateSearch(conf *cfg.Config, queries []string) error {
|
||||
res, err := validate.
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to validate search (esdsl): %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to validate search (esdsl): %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "search", res)
|
||||
@@ -154,7 +154,7 @@ func searchOnce(conf *cfg.Config, search *search.Search) error {
|
||||
Size(conf.To).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to run search (esdsl): %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to run search (esdsl): %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "search", res)
|
||||
@@ -169,7 +169,7 @@ func searchPit(conf *cfg.Config, req *search.Request) error {
|
||||
ctx := context.Background()
|
||||
pit, err := conf.DefaultCluster.ES().OpenPointInTime(conf.Index).KeepAlive("1m").Do(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open point-in-time request for search: %w", err)
|
||||
return fmt.Errorf("failed to open point-in-time request for search: %s", err)
|
||||
}
|
||||
defer func() {
|
||||
_, err := conf.DefaultCluster.ES().ClosePointInTime().Id(pit.Id).Do(ctx)
|
||||
@@ -192,7 +192,7 @@ func searchPit(conf *cfg.Config, req *search.Request) error {
|
||||
for {
|
||||
res, err := search.Do(ctx)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to run search (esdsl pit): %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to run search (esdsl pit): %s", esErrorString(err))
|
||||
}
|
||||
|
||||
if len(res.Hits.Hits) == 0 {
|
||||
@@ -222,7 +222,7 @@ func searchTail(conf *cfg.Config, search *search.Search) error {
|
||||
for {
|
||||
res, err := search.Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to run search (esdsl): %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to run search (esdsl): %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "search", res)
|
||||
|
||||
@@ -86,7 +86,7 @@ func ShardList(conf *cfg.Config) error {
|
||||
res, err := conf.DefaultCluster.ES().Cat.Shards().
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get shards: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get shards: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
shardlist := filterShards(conf, res)
|
||||
@@ -136,7 +136,7 @@ func ShardShow(conf *cfg.Config, index string) error {
|
||||
res, err := conf.DefaultCluster.ES().Cat.Shards().Index(index).
|
||||
Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get shards: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get shards: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "shards", res)
|
||||
@@ -145,63 +145,3 @@ func ShardShow(conf *cfg.Config, index string) error {
|
||||
|
||||
return printShards(conf, res)
|
||||
}
|
||||
|
||||
func ShardAllocation(conf *cfg.Config, index string) error {
|
||||
explain := conf.DefaultCluster.ES().Cluster.AllocationExplain().
|
||||
Index(index).
|
||||
Primary(conf.Primary).
|
||||
Shard(conf.Shards)
|
||||
|
||||
if conf.FromNode != "" {
|
||||
explain.CurrentNode(conf.FromNode)
|
||||
}
|
||||
|
||||
res, err := explain.Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get shard allocation explain: %w", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "explain", res)
|
||||
|
||||
currentNode := res.CurrentNode
|
||||
|
||||
table := printer.NewTable(conf, 2, 10)
|
||||
table.Addheaders("shard allocation setting", "value")
|
||||
|
||||
roles := make([]string, len(currentNode.Roles))
|
||||
for idx, role := range currentNode.Roles {
|
||||
roles[idx] = role.Name
|
||||
}
|
||||
|
||||
table.Entries = [][]any{
|
||||
{"Index", index},
|
||||
{"Current state", res.CurrentState},
|
||||
{"Current node", currentNode.Name},
|
||||
{"Current k8s node", currentNode.Attributes["k8s_node_name"]},
|
||||
{"Current node address", currentNode.TransportAddress},
|
||||
{"Current node id", currentNode.Id},
|
||||
{"Current node weight", currentNode.WeightRanking},
|
||||
{"Current node roles", roles},
|
||||
{"Can rebalance cluster", res.CanRebalanceCluster.Name},
|
||||
{"Can rebalance to another node", res.CanRebalanceToOtherNode.Name},
|
||||
{"Can remain on current node", res.CanRemainOnCurrentNode.Name},
|
||||
}
|
||||
|
||||
if res.CurrentState == "unassigned" {
|
||||
table.AddRow("Unassignment reason", res.UnassignedInfo.Reason.String()+" at "+res.UnassignedInfo.At.(string))
|
||||
}
|
||||
|
||||
for _, nodeDecision := range res.NodeAllocationDecisions {
|
||||
for _, decider := range nodeDecision.Deciders {
|
||||
table.AddRow("Allocation decider", decider.Decider)
|
||||
table.AddRow(" -> decision", decider.Decision.String())
|
||||
table.AddRow(" -> explanation", decider.Explanation)
|
||||
}
|
||||
}
|
||||
|
||||
if err := table.Print(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ func SnapshotList(conf *cfg.Config) error {
|
||||
// get partial indicies
|
||||
ires, err := conf.DefaultCluster.ES().Cat.Indices().Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get indicies: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get indicies: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
indicies := map[string]int{}
|
||||
@@ -58,7 +58,7 @@ func SnapshotList(conf *cfg.Config) error {
|
||||
// get snapshots
|
||||
sres, err := conf.DefaultCluster.ES().Cat.Snapshots().Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get snapshots: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get snapshots: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "indicies", sres)
|
||||
@@ -108,7 +108,7 @@ func SnapshotList(conf *cfg.Config) error {
|
||||
func SnapshotShow(conf *cfg.Config, snapshot string) error {
|
||||
res, err := conf.DefaultCluster.ES().Snapshot.Get("*", snapshot).Do(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get snapshot: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get snapshot: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("ES result", "snapshot", res)
|
||||
|
||||
@@ -32,7 +32,7 @@ func TaskList(conf *cfg.Config) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get index templates: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to get index templates: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
slog.Debug("res", "tasks", res)
|
||||
@@ -68,7 +68,7 @@ func TaskCancel(conf *cfg.Config, taskid string) error {
|
||||
Do(context.Background())
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to cancel task: %w", esErrorString(err))
|
||||
return fmt.Errorf("failed to cancel task: %s", esErrorString(err))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -115,6 +115,13 @@ func (m model) footerView() string {
|
||||
return lipgloss.JoinHorizontal(lipgloss.Center, line, info)
|
||||
}
|
||||
|
||||
func max(a, b int) int {
|
||||
if a > b {
|
||||
return a
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
func Pager(title, message string) {
|
||||
p := tea.NewProgram(
|
||||
model{content: message, title: title},
|
||||
|
||||
@@ -104,7 +104,7 @@ func (data *Table) PrintYAML() error {
|
||||
|
||||
body, err := yaml.Marshal(raw)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to produce YAML output: %w", err)
|
||||
return fmt.Errorf("failed to produce YAML output: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println(string(body))
|
||||
@@ -117,7 +117,7 @@ func (data *Table) PrintJSON() error {
|
||||
|
||||
body, err := json.MarshalIndent(raw, "", " ")
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to produce JSON output: %w", err)
|
||||
return fmt.Errorf("failed to produce JSON output: %s", err)
|
||||
}
|
||||
|
||||
fmt.Println(string(body))
|
||||
|
||||
Reference in New Issue
Block a user