/*
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 .
*/
package cmd
import (
"context"
"errors"
"codeberg.org/scip/esctl/pkg/cfg"
"codeberg.org/scip/esctl/pkg/es"
"github.com/urfave/cli/v3"
)
func Ilm(conf *cfg.Config) *cli.Command {
return &cli.Command{
Name: "ilm",
Usage: "manage index lifecycle",
Commands: []*cli.Command{
IlmRetry(conf),
IlmStatus(conf),
IlmList(conf),
IlmShow(conf),
IlmCreate(conf),
},
}
}
func IlmRetry(conf *cfg.Config) *cli.Command {
return &cli.Command{
Name: "retry",
Usage: "retry applying an ILM profile to an index",
UsageText: "retry ",
Action: func(ctx context.Context, cmd *cli.Command) error {
return es.IlmRetry(conf, cmd.Args().Get(0))
},
}
}
func IlmStatus(conf *cfg.Config) *cli.Command {
return &cli.Command{
Name: "status",
Usage: "get the current index lifecycle management status",
Action: func(ctx context.Context, cmd *cli.Command) error {
return es.IlmStatus(conf)
},
}
}
func IlmList(conf *cfg.Config) *cli.Command {
return &cli.Command{
Name: "list",
Aliases: []string{"ls"},
Usage: "list index lifecycle policies",
UsageText: "list []",
Action: func(ctx context.Context, cmd *cli.Command) error {
return es.IlmList(conf, cmd.Args().Get(0))
},
}
}
func IlmShow(conf *cfg.Config) *cli.Command {
return &cli.Command{
Name: "show",
Aliases: []string{"sh"},
Usage: "show details about an index lifecycle policy",
UsageText: "show ",
Action: func(ctx context.Context, cmd *cli.Command) error {
policy := cmd.Args().Get(0)
if policy == "" {
return errors.New("no policy specified")
}
return es.IlmShow(conf, cmd.Args().Get(0))
},
ShellComplete: func(ctx context.Context, cmd *cli.Command) {
complete(cmd, Cilm)
},
}
}
/*
*
{
"policy": {
"phases": {
"hot": {
"min_age": "0ms",
"actions": {
"rollover": {
"max_primary_shard_size": "50gb",
"max_age": "1d",
"max_docs": 100000000
},
"set_priority": {
"priority": 100
}
}
},
"warm": {
"min_age": "7d",
"actions": {
"migrate": {},
"shrink": {
"number_of_shards": 1
},
"forcemerge": {
"max_num_segments": 1
},
"set_priority": {
"priority": 50
}
}
},
"cold": {
"min_age": "30d",
"actions": {
"migrate": {},
"searchable_snapshot": {
"snapshot_repository": "s3-logs-archive",
"force_merge_index": true
},
"set_priority": {
"priority": 0
}
}
},
"delete": {
"min_age": "90d",
"actions": {
"delete": {
"delete_searchable_snapshot": true
}
}
}
}
}
}
*/
func IlmCreate(conf *cfg.Config) *cli.Command {
return &cli.Command{
Name: "create",
Aliases: []string{"+"},
Usage: "create a index lifecycle policy",
UsageText: "create [options] ",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "description",
Usage: "policy description",
Destination: &conf.Ilm.Description,
Aliases: []string{"D"},
},
// hot
&cli.StringFlag{
Name: "hot-min-age",
Usage: "hot phase: min age",
Destination: &conf.Ilm.HotMinAge,
},
&cli.StringFlag{
Name: "hot-rollover-max-age",
Usage: "hot phase: rollover after",
Destination: &conf.Ilm.HotRolloverMaxAge,
},
&cli.Int64Flag{
Name: "hot-rollover-max-primary-shard-size",
Usage: "hot phase: max primary shard size",
Destination: &conf.Ilm.HotRolloverMaxPrimaryShardSize,
},
&cli.Int64Flag{
Name: "hot-rollover-max-docs",
Usage: "hot phase: max docs",
Destination: &conf.Ilm.HotRolloverMaxDocs,
},
&cli.BoolFlag{
Name: "hot-readonly",
Usage: "hot phase: make index ro before rollover",
Destination: &conf.Ilm.HotReadonly,
},
// warm
&cli.StringFlag{
Name: "warm-min-age",
Usage: "warm phase: min age",
Destination: &conf.Ilm.WarmMinAge,
},
&cli.IntFlag{
Name: "warm-force-merge-segments",
Usage: "warm phase: force merge segments per shard",
Destination: &conf.Ilm.WarmForceMerge,
},
&cli.IntFlag{
Name: "warm-shrink-shards",
Usage: "warm phase: shrink on number of shards",
Destination: &conf.Ilm.WarmShrinkShards,
},
&cli.IntFlag{
Name: "warm-priority",
Usage: "warm phase: priority",
Destination: &conf.Ilm.WarmPriority,
},
// cold
&cli.StringFlag{
Name: "cold-min-age",
Usage: "cold phase: min age",
Destination: &conf.Ilm.ColdMinAge,
},
&cli.StringFlag{
Name: "cold-searchable-snapshot-repo",
Usage: "cold phase: searchable snapshot repo",
Destination: &conf.Ilm.ColdSearchableSnapshotRepo,
},
&cli.IntFlag{
Name: "cold-force-merge-segments",
Usage: "cold phase: force merge segments per shard",
Destination: &conf.Ilm.ColdForceMerge,
},
&cli.IntFlag{
Name: "cold-priority",
Usage: "cold phase: priority",
Destination: &conf.Ilm.ColdPriority,
},
// frozen
&cli.StringFlag{
Name: "frozen-min-age",
Usage: "frozen phase: min age",
Destination: &conf.Ilm.FrozenMinAge,
},
// delete
&cli.StringFlag{
Name: "delete-min-age",
Usage: "delete phase: min age",
Destination: &conf.Ilm.DeleteMinAge,
},
&cli.BoolFlag{
Name: "delete-searchable-snapshots",
Usage: "delete phase: delete searchable snapshots",
Destination: &conf.Ilm.DeleteSearchableSnapshots,
},
},
Action: func(ctx context.Context, cmd *cli.Command) error {
policy := cmd.Args().Get(0)
if policy == "" {
return errors.New("no policy name specified")
}
return es.IlmCreate(conf, cmd.Args().Get(0))
},
}
}