diff --git a/cmd/index.go b/cmd/index.go index 7ccf28a..4e3d471 100644 --- a/cmd/index.go +++ b/cmd/index.go @@ -38,6 +38,7 @@ func Index(conf *cfg.Config) *cli.Command { IndexCreate(conf), IndexDelete(conf), IndexClose(conf), + IndexAllocation(conf), }, } } @@ -75,6 +76,33 @@ 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 { + return es.IndexAllocation(conf, cmd.Args().Get(0)) + }, + } +} + func IndexShow(conf *cfg.Config) *cli.Command { return &cli.Command{ Name: "show", diff --git a/pkg/cfg/config.go b/pkg/cfg/config.go index b08dbcc..4e084de 100644 --- a/pkg/cfg/config.go +++ b/pkg/cfg/config.go @@ -47,8 +47,9 @@ type Config struct { DefaultCluster *Cluster Index string // index: -i Failed, Partials bool // index: flags - Shards, Replicas int // index create: -s -r + Shards, Replicas int // index create+allocation: -s -r Wait bool // index create: -w + Primary bool // index allocation: -p From, To, MaxItems int // search: flags Filter []string // search: -F Exclude string // cluster compare: -e (regexp) diff --git a/pkg/es/ccr.go b/pkg/es/ccr.go index 8a14464..a28e03d 100644 --- a/pkg/es/ccr.go +++ b/pkg/es/ccr.go @@ -116,7 +116,7 @@ func CcrRemoteInfo(conf *cfg.Config, index string) error { } table := NewTable(2, 5) - table.Addheaders("field", "value") + table.Addheaders("ccr remote property", "value") table.entries = [][]string{ {"Remote Cluster", remote}, diff --git a/pkg/es/ccr_follower.go b/pkg/es/ccr_follower.go index f4357fe..20ac745 100644 --- a/pkg/es/ccr_follower.go +++ b/pkg/es/ccr_follower.go @@ -176,7 +176,7 @@ func CcrFollowerShow(conf *cfg.Config, index string) error { follower := res.Indices[0].Shards[0] table := NewTable(2, 9) - table.Addheaders("field", "value") + table.Addheaders("ccr follower property", "value") table.entries = [][]string{ {"name", index}, diff --git a/pkg/es/index.go b/pkg/es/index.go index 0b4f76a..34574fb 100644 --- a/pkg/es/index.go +++ b/pkg/es/index.go @@ -111,7 +111,7 @@ func IndexShow(conf *cfg.Config, index string) error { slog.Debug("ES result", "index", res) table := NewTable(2, 5) - table.Addheaders("field", "value") + table.Addheaders("index property", "value") ts, err := strconv.ParseInt(res[index].Settings.Index.CreationDate.(string), 10, 64) if err != nil { @@ -216,3 +216,52 @@ func IndexClose(conf *cfg.Config, index string) error { return nil } + +func IndexAllocation(conf *cfg.Config, index string) error { + if index == "" { + return fmt.Errorf("no index specified") + } + + alloc := conf.DefaultCluster.ES.Cluster.AllocationExplain(). + Index(index). + Primary(conf.Primary). + Shard(conf.Shards) + + res, err := alloc.Header("content-type", "application/json"). + Header("accept", "application/json"). + Do(context.Background()) + if err != nil { + return fmt.Errorf("failed to get index allocation explain: %s", err) + } + + slog.Debug("ES result", "index", res) + + currentNode := res.CurrentNode + + table := NewTable(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 = [][]string{ + {"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", fmt.Sprintf("%d", currentNode.WeightRanking)}, + {"Current node roles", strings.Join(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.PrintMarkdown(); err != nil { + return err + } + + return nil +} diff --git a/pkg/es/snapshot.go b/pkg/es/snapshot.go index 2ccb499..4149e2d 100644 --- a/pkg/es/snapshot.go +++ b/pkg/es/snapshot.go @@ -117,7 +117,7 @@ func SnapshotShow(conf *cfg.Config, snapshot string) error { } table := NewTable(2, 17) - table.Addheaders("field", "value") + table.Addheaders("snapshot property", "value") snap := res.Snapshots[0]