/* 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, false), IlmCreate(conf, true), IlmForecast(conf), IlmExplain(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 IlmExplain(conf *cfg.Config) *cli.Command { return &cli.Command{ Name: "explain", Usage: "explain ilm condition of an index", UsageText: "explain ", Action: func(ctx context.Context, cmd *cli.Command) error { index := cmd.Args().Get(0) if index == "" { return errors.New("no index specified") } return es.IlmExplain(conf, index) }, } } 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 ", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "tree", Usage: "display policy as a tree", Destination: &conf.Ilm.Tree, Aliases: []string{"t"}, }, }, 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) }, } } func IlmCreate(conf *cfg.Config, modify bool) *cli.Command { name := "create" alias := "+" usage := "create a new lifecycle policy" if modify { name = "update" usage = "update an lifecycle policy" alias = "upd" } return &cli.Command{ Name: name, Aliases: []string{alias}, Usage: usage, UsageText: name + " [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.StringFlag{ 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, }, &cli.StringFlag{ Name: "frozen-searchable-snapshot-repo", Usage: "frozen phase: searchable snapshot repo", Destination: &conf.Ilm.FrozenSearchableSnapshotRepo, }, // 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)) }, } }