Files
esctl/pkg/es/index.go

184 lines
4.3 KiB
Go
Raw Normal View History

/*
Copyright © 2026 Thomas von Dein
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package es
import (
"context"
2026-04-22 13:38:02 +02:00
"fmt"
"log/slog"
"strconv"
"time"
"codeberg.org/scip/esctl/pkg/cfg"
"github.com/elastic/go-elasticsearch/v9/typedapi/esdsl"
2026-04-22 13:38:02 +02:00
"github.com/elastic/go-elasticsearch/v9/typedapi/types/enums/healthstatus"
)
// used for completion
func IndexNames(conf *cfg.Config) ([]string, error) {
res, err := conf.DefaultCluster.ES.Cat.Indices().
Header("content-type", "application/json").
Header("accept", "application/json").
Do(context.Background())
if err != nil {
return nil, fmt.Errorf("failed to get indicies: %s", err)
}
indices := make([]string, len(res))
for idx, index := range res {
indices[idx] = *index.Index
}
return indices, nil
}
func IndexList(conf *cfg.Config) error {
cat := conf.DefaultCluster.ES.Cat.Indices().
// we need to add custom request headers, required for older ES instances
Header("content-type", "application/json").
Header("accept", "application/json")
2026-04-22 13:38:02 +02:00
if conf.Failed {
cat = cat.Health(healthstatus.Red)
}
res, err := cat.Do(context.Background())
if err != nil {
return fmt.Errorf("failed to get indicies: %s", err)
}
slog.Debug("ES result", "indicies", res)
size := len(res)
if conf.MaxItems > 0 {
if size > conf.MaxItems {
size = conf.MaxItems
}
}
2026-04-22 13:38:02 +02:00
table := NewTable(3, size)
table.Addheaders("name", "size", "docscount")
for idx, index := range res {
name := Colorize(*index.Health, *index.Index)
table.entries[idx] = []string{name, *index.DatasetSize, *index.DocsCount}
if idx == size-1 {
break
}
}
table.Sort()
if err := table.PrintMarkdown(); err != nil {
return err
}
return nil
}
2026-04-22 13:38:02 +02:00
func IndexShow(conf *cfg.Config, index string) error {
if index == "" {
return fmt.Errorf("no index specified")
}
res, err := conf.DefaultCluster.ES.Indices.Get(index).
// we need to add custom request headers, required for older ES instances
Header("content-type", "application/json").
Header("accept", "application/json").
Do(context.Background())
2026-04-22 13:38:02 +02:00
if err != nil {
return fmt.Errorf("failed to get index: %s", err)
}
slog.Debug("ES result", "index", res)
table := NewTable(2, 5)
table.Addheaders("field", "value")
ts, err := strconv.ParseInt(res[index].Settings.Index.CreationDate.(string), 10, 64)
if err != nil {
ts = 0
}
created := time.Unix(ts/1000, 0)
table.entries = [][]string{
{"name", index},
{"replicas", *res[index].Settings.Index.NumberOfReplicas},
{"shards", *res[index].Settings.Index.NumberOfShards},
{"created", created.Format("2006-01-02 15:04:05")},
{"uuid", *res[index].Settings.Index.Uuid},
}
if err := table.PrintMarkdown(); err != nil {
return err
}
return nil
}
func IndexCreate(conf *cfg.Config, index string) error {
if index == "" {
return fmt.Errorf("no index specified")
}
settings := esdsl.NewIndexSettings()
create := conf.DefaultCluster.ES.Indices.Create(index).
Header("content-type", "application/json").
Header("accept", "application/json")
if conf.Wait {
create.WaitForActiveShards("all")
}
if conf.Shards > 0 {
settings = settings.NumberOfShards(strconv.Itoa(conf.Shards))
}
if conf.Replicas > 0 {
settings = settings.NumberOfReplicas(strconv.Itoa(conf.Replicas))
}
_, err := create.Settings(settings).
Do(context.Background())
if err != nil {
return fmt.Errorf("failed to create index: %s", err)
}
return nil
}
func IndexDelete(conf *cfg.Config, index string) error {
if index == "" {
return fmt.Errorf("no index specified")
}
_, err := conf.DefaultCluster.ES.Indices.Delete(index).
Header("content-type", "application/json").
Header("accept", "application/json").
Do(context.Background())
if err != nil {
return fmt.Errorf("failed to delete index: %s", err)
}
2026-04-22 13:38:02 +02:00
return nil
}