Files
esctl/pkg/es/cluster_settings.go

142 lines
3.3 KiB
Go
Raw Normal View History

2026-05-11 10:28:25 +02:00
/*
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"
"encoding/json"
"fmt"
"log/slog"
"codeberg.org/scip/esctl/pkg/cfg"
"github.com/urfave/cli/v3"
)
// recursively traverse the raw settings hash and build a flat map
// consisting of the translated path and its value.
//
// e.g.
// logger:
//
// org:
// elasticsearch:
// transport:
// OutboundHandler: "ERROR"
//
// gets:
//
// logger.org.elasticsearch.transport.OutboundHandler: "ERROR"
func getJsonPath(raw map[string]any, topic string) map[string]string {
paths := map[string]string{}
for name, data := range raw {
path := topic + "." + name
switch value := data.(type) {
case string:
paths[path] = value
case map[string]any:
paths = getJsonPath(value, path)
}
}
return paths
}
func ClusterSettingsList(conf *cfg.Config) error {
res, err := conf.DefaultCluster.ES.Cluster.GetSettings().
Header("content-type", "application/json").
Header("accept", "application/json").
Do(context.Background())
if err != nil {
return fmt.Errorf("failed to get cluster settings: %s", err)
}
table := NewTable(2, 0)
table.Addheaders("setting", "value")
entries := [][]string{}
settingshash := res.Persistent // == map[string]json.RawMessage
switch {
case conf.Transient:
settingshash = res.Transient
case conf.Default:
settingshash = res.Defaults
}
for topic, val := range settingshash {
data := map[string]any{}
err := json.Unmarshal(val, &data)
if err != nil {
return fmt.Errorf("failed to unmarshall setting for topic %s: %s", topic, err)
}
paths := getJsonPath(data, topic)
slog.Debug("settings", topic, paths)
for setting, value := range paths {
2026-05-11 10:46:17 +02:00
entries = append(entries, []string{setting, fmt.Sprintf("%v", value)})
2026-05-11 10:28:25 +02:00
}
}
table.entries = entries
table.Sort()
if err := table.PrintMarkdown(); err != nil {
return err
}
return nil
}
func ClusterSettingsSet(conf *cfg.Config, args cli.Args) error {
put := conf.Clusters[conf.CurrentCluster].ES.Cluster.PutSettings()
for _, arg := range args.Slice() {
setting, value := splitArg(arg)
switch {
case conf.Transient:
message, err := json.Marshal(value)
if err != nil {
return fmt.Errorf("failed to marshall transient value <%v> to valid JSON: %s", value, err)
}
put.AddTransient(setting, message)
case conf.Persistent:
fallthrough
default:
message, err := json.Marshal(value)
if err != nil {
return fmt.Errorf("failed to marshall persistent value <%v> to valid JSON: %s", value, err)
}
put.AddPersistent(setting, message)
}
}
_, err := put.
Header("content-type", "application/json").
Header("accept", "application/json").
Do(context.Background())
if err != nil {
return fmt.Errorf("failed to set settings: %s", err)
}
return nil
}