crowdsec/cmd/crowdsec-cli/config_show.go
mmetc c64332d30a
cscli config show: avoid globals, use yaml v3 (#2863)
* cscli config show: avoid globals, use yaml v3

* lint (whitespace/errors)
2024-04-23 12:28:38 +02:00

259 lines
6.7 KiB
Go

package main
import (
"encoding/json"
"fmt"
"os"
"text/template"
"github.com/antonmedv/expr"
"github.com/sanity-io/litter"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
"github.com/crowdsecurity/crowdsec/pkg/csconfig"
"github.com/crowdsecurity/crowdsec/pkg/exprhelpers"
)
func (cli *cliConfig) showKey(key string) error {
cfg := cli.cfg()
type Env struct {
Config *csconfig.Config
}
opts := []expr.Option{}
opts = append(opts, exprhelpers.GetExprOptions(map[string]interface{}{})...)
opts = append(opts, expr.Env(Env{}))
program, err := expr.Compile(key, opts...)
if err != nil {
return err
}
output, err := expr.Run(program, Env{Config: cfg})
if err != nil {
return err
}
switch cfg.Cscli.Output {
case "human", "raw":
// Don't use litter for strings, it adds quotes
// that would break compatibility with previous versions
switch output.(type) {
case string:
fmt.Println(output)
default:
litter.Dump(output)
}
case "json":
data, err := json.MarshalIndent(output, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal configuration: %w", err)
}
fmt.Println(string(data))
}
return nil
}
func (cli *cliConfig) template() string {
return `Global:
{{- if .ConfigPaths }}
- Configuration Folder : {{.ConfigPaths.ConfigDir}}
- Data Folder : {{.ConfigPaths.DataDir}}
- Hub Folder : {{.ConfigPaths.HubDir}}
- Simulation File : {{.ConfigPaths.SimulationFilePath}}
{{- end }}
{{- if .Common }}
- Log Folder : {{.Common.LogDir}}
- Log level : {{.Common.LogLevel}}
- Log Media : {{.Common.LogMedia}}
{{- end }}
{{- if .Crowdsec }}
Crowdsec{{if and .Crowdsec.Enable (not (ValueBool .Crowdsec.Enable))}} (disabled){{end}}:
- Acquisition File : {{.Crowdsec.AcquisitionFilePath}}
- Parsers routines : {{.Crowdsec.ParserRoutinesCount}}
{{- if .Crowdsec.AcquisitionDirPath }}
- Acquisition Folder : {{.Crowdsec.AcquisitionDirPath}}
{{- end }}
{{- end }}
{{- if .Cscli }}
cscli:
- Output : {{.Cscli.Output}}
- Hub Branch : {{.Cscli.HubBranch}}
{{- end }}
{{- if .API }}
{{- if .API.Client }}
API Client:
{{- if .API.Client.Credentials }}
- URL : {{.API.Client.Credentials.URL}}
- Login : {{.API.Client.Credentials.Login}}
{{- end }}
- Credentials File : {{.API.Client.CredentialsFilePath}}
{{- end }}
{{- if .API.Server }}
Local API Server{{if and .API.Server.Enable (not (ValueBool .API.Server.Enable))}} (disabled){{end}}:
- Listen URL : {{.API.Server.ListenURI}}
- Listen Socket : {{.API.Server.ListenSocket}}
- Profile File : {{.API.Server.ProfilesPath}}
{{- if .API.Server.TLS }}
{{- if .API.Server.TLS.CertFilePath }}
- Cert File : {{.API.Server.TLS.CertFilePath}}
{{- end }}
{{- if .API.Server.TLS.KeyFilePath }}
- Key File : {{.API.Server.TLS.KeyFilePath}}
{{- end }}
{{- if .API.Server.TLS.CACertPath }}
- CA Cert : {{.API.Server.TLS.CACertPath}}
{{- end }}
{{- if .API.Server.TLS.CRLPath }}
- CRL : {{.API.Server.TLS.CRLPath}}
{{- end }}
{{- if .API.Server.TLS.CacheExpiration }}
- Cache Expiration : {{.API.Server.TLS.CacheExpiration}}
{{- end }}
{{- if .API.Server.TLS.ClientVerification }}
- Client Verification : {{.API.Server.TLS.ClientVerification}}
{{- end }}
{{- if .API.Server.TLS.AllowedAgentsOU }}
{{- range .API.Server.TLS.AllowedAgentsOU }}
- Allowed Agents OU : {{.}}
{{- end }}
{{- end }}
{{- if .API.Server.TLS.AllowedBouncersOU }}
{{- range .API.Server.TLS.AllowedBouncersOU }}
- Allowed Bouncers OU : {{.}}
{{- end }}
{{- end }}
{{- end }}
- Trusted IPs:
{{- range .API.Server.TrustedIPs }}
- {{.}}
{{- end }}
{{- if and .API.Server.OnlineClient .API.Server.OnlineClient.Credentials }}
Central API:
- URL : {{.API.Server.OnlineClient.Credentials.URL}}
- Login : {{.API.Server.OnlineClient.Credentials.Login}}
- Credentials File : {{.API.Server.OnlineClient.CredentialsFilePath}}
{{- end }}
{{- end }}
{{- end }}
{{- if .DbConfig }}
- Database:
- Type : {{.DbConfig.Type}}
{{- if eq .DbConfig.Type "sqlite" }}
- Path : {{.DbConfig.DbPath}}
{{- else}}
- Host : {{.DbConfig.Host}}
- Port : {{.DbConfig.Port}}
- User : {{.DbConfig.User}}
- DB Name : {{.DbConfig.DbName}}
{{- end }}
{{- if .DbConfig.MaxOpenConns }}
- Max Open Conns : {{.DbConfig.MaxOpenConns}}
{{- end }}
{{- if ne .DbConfig.DecisionBulkSize 0 }}
- Decision Bulk Size : {{.DbConfig.DecisionBulkSize}}
{{- end }}
{{- if .DbConfig.Flush }}
{{- if .DbConfig.Flush.MaxAge }}
- Flush age : {{.DbConfig.Flush.MaxAge}}
{{- end }}
{{- if .DbConfig.Flush.MaxItems }}
- Flush size : {{.DbConfig.Flush.MaxItems}}
{{- end }}
{{- end }}
{{- end }}
`
}
func (cli *cliConfig) show() error {
cfg := cli.cfg()
switch cfg.Cscli.Output {
case "human":
// The tests on .Enable look funny because the option has a true default which has
// not been set yet (we don't really load the LAPI) and go templates don't dereference
// pointers in boolean tests. Prefix notation is the cherry on top.
funcs := template.FuncMap{
// can't use generics here
"ValueBool": func(b *bool) bool { return b != nil && *b },
}
tmp, err := template.New("config").Funcs(funcs).Parse(cli.template())
if err != nil {
return err
}
err = tmp.Execute(os.Stdout, cfg)
if err != nil {
return err
}
case "json":
data, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal configuration: %w", err)
}
fmt.Println(string(data))
case "raw":
data, err := yaml.Marshal(cfg)
if err != nil {
return fmt.Errorf("failed to marshal configuration: %w", err)
}
fmt.Println(string(data))
}
return nil
}
func (cli *cliConfig) newShowCmd() *cobra.Command {
var key string
cmd := &cobra.Command{
Use: "show",
Short: "Displays current config",
Long: `Displays the current cli configuration.`,
Args: cobra.ExactArgs(0),
DisableAutoGenTag: true,
RunE: func(_ *cobra.Command, _ []string) error {
if err := cli.cfg().LoadAPIClient(); err != nil {
log.Errorf("failed to load API client configuration: %s", err)
// don't return, we can still show the configuration
}
if key != "" {
return cli.showKey(key)
}
return cli.show()
},
}
flags := cmd.Flags()
flags.StringVarP(&key, "key", "", "", "Display only this value (Config.API.Server.ListenURI)")
return cmd
}