/* 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" "slices" "codeberg.org/scip/esctl/pkg/cfg" "codeberg.org/scip/esctl/pkg/es" "github.com/urfave/cli/v3" ) func IndexTemplate(conf *cfg.Config) *cli.Command { return &cli.Command{ Name: "template", Aliases: []string{"tpl"}, Usage: "manage index templates", Commands: []*cli.Command{ IndexTemplateList(conf), IndexTemplateShow(conf), IndexTemplateCreate(conf, false), IndexTemplateCreate(conf, true), IndexTemplateDelete(conf), }, } } func IndexTemplateList(conf *cfg.Config) *cli.Command { return &cli.Command{ Name: "list", Aliases: []string{"ls"}, Usage: "list index templates", Flags: []cli.Flag{ &cli.StringSliceFlag{ Name: "filter-index-pattern", Usage: "show only index templates which use patterns, which match the filter", Destination: &conf.Filter, Aliases: []string{"F"}, }, &cli.BoolFlag{ Name: "hidden", Usage: "show hidden index templates as well", Destination: &conf.Hidden, Aliases: []string{"H"}, }, }, Action: func(ctx context.Context, cmd *cli.Command) error { return es.IndexTemplateList(conf, cmd.Args().Get(0)) }, } } func IndexTemplateShow(conf *cfg.Config) *cli.Command { return &cli.Command{ Name: "show", Aliases: []string{"sh"}, Usage: "show details about an index template", Action: func(ctx context.Context, cmd *cli.Command) error { index := cmd.Args().Get(0) if index == "" { return errors.New("no index template specified") } return es.IndexTemplateShow(conf, cmd.Args().Get(0)) }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { complete(conf, cmd, Cindextemplate) }, } } func IndexTemplateCreate(conf *cfg.Config, modify bool) *cli.Command { name := "create" alias := "+" required := true if modify { name = "update" alias = "upd" required = false } return &cli.Command{ Name: name, Aliases: []string{alias}, Usage: name + " a new index template", UsageText: name + ` ...`, CustomHelpTemplate: addReference( `Valid field mapping types: integer, text, date, keyword Doc for index settings: https://www.elastic.co/docs/reference/elasticsearch/index-settings `), Flags: []cli.Flag{ &cli.BoolFlag{ Name: "data-stream", Usage: "template creates a data stream", Destination: &conf.Stream, Aliases: []string{"S"}, }, &cli.BoolFlag{ Name: "allow-auto-create", Usage: "automatically create indices", Destination: &conf.AutoCreate, Aliases: []string{"a"}, }, &cli.BoolFlag{ Name: "rollover", Usage: "automatically rollover associated aliases", Destination: &conf.Rollover, Aliases: []string{"R"}, }, &cli.StringFlag{ Name: "mode", Usage: "index mode, one of: standard, timeseries, logsdb or lookup", Destination: &conf.Mode, Aliases: []string{"m"}, }, &cli.StringFlag{ Name: "retention", Usage: "data retention, e.g. -1 (infinitely), 30d, 3m or 1y (data stream only)", Destination: &conf.Retention, Aliases: []string{"r"}, Required: required, }, &cli.IntFlag{ Name: "priority", Usage: "index template priority", Destination: &conf.Priority, Aliases: []string{"p"}, }, &cli.StringSliceFlag{ Name: "index-pattern", Usage: "index matching pattern", Destination: &conf.Patterns, Aliases: []string{"i"}, Required: required, }, &cli.StringSliceFlag{ Name: "settings", Usage: "individual template settings, format: name:value, multiple possible", Destination: &conf.Settings, Aliases: []string{"s"}, }, &cli.StringSliceFlag{ Name: "component", Usage: "include component template, multiple possible", Destination: &conf.Components, Aliases: []string{"c"}, }, &cli.StringSliceFlag{ Name: "meta", Usage: "custom meta field, format: name:value, multiple possible", Destination: &conf.Meta, Aliases: []string{"M"}, }, &cli.StringSliceFlag{ Name: "aliases", Usage: "set up aliases to associate with indices", Destination: &conf.Aliases, Aliases: []string{"A"}, }, &cli.StringFlag{ Name: "ilm-policy", Usage: "ilm policy to apply", Destination: &conf.Policy, Aliases: []string{"p"}, }, }, Action: func(ctx context.Context, cmd *cli.Command) error { args := cmd.Args() if args.Len() == 0 { return errors.New("no name specified") } if conf.Mode != "" { if !slices.Contains([]string{"standard", "timeseries", "logsdb", "lookup"}, conf.Mode) { return errors.New("mode must be one of: standard, timeseries, logsdb or lookup") } } mappings := args.Slice()[1:] if modify { return es.IndexTemplateModify(conf, args.Get(0), mappings) } return es.IndexTemplateCreate(conf, args.Get(0), mappings) }, } } func IndexTemplateDelete(conf *cfg.Config) *cli.Command { return &cli.Command{ Name: "delete", Aliases: []string{"rm"}, Usage: "delete an index template", Action: func(ctx context.Context, cmd *cli.Command) error { index := cmd.Args().Get(0) if index == "" { return errors.New("no index template specified") } return es.IndexTemplateDelete(conf, cmd.Args().Get(0)) }, ShellComplete: func(ctx context.Context, cmd *cli.Command) { complete(conf, cmd, Cindextemplate) }, } }