Quellcode durchsuchen

Load lapi config for `config show output` (#2097)

This adds URL and login parameters as it was intended.
Also rewrite configShow and displayOneAlert to use an embedded text/template for shorter code.
mmetc vor 2 Jahren
Ursprung
Commit
9faa49c7e8
3 geänderte Dateien mit 175 neuen und 134 gelöschten Zeilen
  1. 27 16
      cmd/crowdsec-cli/alerts.go
  2. 137 118
      cmd/crowdsec-cli/config_show.go
  3. 11 0
      test/bats/01_cscli.bats

+ 27 - 16
cmd/crowdsec-cli/alerts.go

@@ -10,6 +10,7 @@ import (
 	"sort"
 	"strconv"
 	"strings"
+	"text/template"
 	"time"
 
 	"github.com/fatih/color"
@@ -135,25 +136,35 @@ func AlertsToTable(alerts *models.GetAlertsResponse, printMachine bool) error {
 	return nil
 }
 
+var alertTemplate = `
+################################################################################################
+
+ - ID           : {{.ID}}
+ - Date         : {{.CreatedAt}}
+ - Machine      : {{.MachineID}}
+ - Simulation   : {{.Simulated}}
+ - Reason       : {{.Scenario}}
+ - Events Count : {{.EventsCount}}
+ - Scope:Value  : {{.Source.Scope}}{{if .Source.Value}}:{{.Source.Value}}{{end}}
+ - Country      : {{.Source.Cn}}
+ - AS           : {{.Source.AsName}}
+ - Begin        : {{.StartAt}}
+ - End          : {{.StopAt}}
+ - UUID         : {{.UUID}}
+
+`
+
+
 func DisplayOneAlert(alert *models.Alert, withDetail bool) error {
 	if csConfig.Cscli.Output == "human" {
-		fmt.Printf("\n################################################################################################\n\n")
-		scopeAndValue := *alert.Source.Scope
-		if *alert.Source.Value != "" {
-			scopeAndValue += ":" + *alert.Source.Value
+		tmpl, err := template.New("alert").Parse(alertTemplate)
+		if err != nil {
+			return err
+		}
+		err = tmpl.Execute(os.Stdout, alert)
+		if err != nil {
+			return err
 		}
-		fmt.Printf(" - ID           : %d\n", alert.ID)
-		fmt.Printf(" - Date         : %s\n", alert.CreatedAt)
-		fmt.Printf(" - Machine      : %s\n", alert.MachineID)
-		fmt.Printf(" - Simulation   : %v\n", *alert.Simulated)
-		fmt.Printf(" - Reason       : %s\n", *alert.Scenario)
-		fmt.Printf(" - Events Count : %d\n", *alert.EventsCount)
-		fmt.Printf(" - Scope:Value  : %s\n", scopeAndValue)
-		fmt.Printf(" - Country      : %s\n", alert.Source.Cn)
-		fmt.Printf(" - AS           : %s\n", alert.Source.AsName)
-		fmt.Printf(" - Begin        : %s\n", *alert.StartAt)
-		fmt.Printf(" - End          : %s\n", *alert.StopAt)
-		fmt.Printf(" - UUID         : %s\n\n", alert.UUID)
 
 		alertDecisionsTable(color.Output, alert)
 

+ 137 - 118
cmd/crowdsec-cli/config_show.go

@@ -3,10 +3,13 @@ package main
 import (
 	"encoding/json"
 	"fmt"
+	"os"
+	"text/template"
 
 	"github.com/antonmedv/expr"
 	"github.com/spf13/cobra"
 	"gopkg.in/yaml.v2"
+	log "github.com/sirupsen/logrus"
 
 	"github.com/crowdsecurity/crowdsec/pkg/csconfig"
 )
@@ -47,9 +50,137 @@ func showConfigKey(key string) error {
 	return nil
 }
 
+
+var configShowTemplate = `Global:
+
+{{- if .ConfigPaths }}
+   - Configuration Folder   : {{.ConfigPaths.ConfigDir}}
+   - 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:
+  - 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}}
+  - Hub Folder              : {{.Cscli.HubDir}}
+{{- 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:
+  - Listen URL              : {{.API.Server.ListenURI}}
+  - 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.Flush }}
+{{- if .DbConfig.Flush.MaxAge }}
+      - Flush age           : {{.DbConfig.Flush.MaxAge}}
+{{- end }}
+{{- if .DbConfig.Flush.MaxItems }}
+      - Flush size          : {{.DbConfig.Flush.MaxItems}}
+{{- end }}
+{{- end }}
+{{- end }}
+`
+
+
 func runConfigShow(cmd *cobra.Command, args []string) error {
 	flags := cmd.Flags()
 
+	if err := csConfig.LoadAPIClient(); err != nil {
+		log.Errorf("failed to load API client configuration: %s", err)
+		// don't return, we can still show the configuration
+	}
+
 	key, err := flags.GetString("key")
 	if err != nil {
 		return err
@@ -61,125 +192,13 @@ func runConfigShow(cmd *cobra.Command, args []string) error {
 
 	switch csConfig.Cscli.Output {
 	case "human":
-		fmt.Printf("Global:\n")
-
-		if csConfig.ConfigPaths != nil {
-			fmt.Printf("   - Configuration Folder   : %s\n", csConfig.ConfigPaths.ConfigDir)
-			fmt.Printf("   - Data Folder            : %s\n", csConfig.ConfigPaths.DataDir)
-			fmt.Printf("   - Hub Folder             : %s\n", csConfig.ConfigPaths.HubDir)
-			fmt.Printf("   - Simulation File        : %s\n", csConfig.ConfigPaths.SimulationFilePath)
-		}
-
-		if csConfig.Common != nil {
-			fmt.Printf("   - Log Folder             : %s\n", csConfig.Common.LogDir)
-			fmt.Printf("   - Log level              : %s\n", csConfig.Common.LogLevel)
-			fmt.Printf("   - Log Media              : %s\n", csConfig.Common.LogMedia)
-		}
-
-		if csConfig.Crowdsec != nil {
-			fmt.Printf("Crowdsec:\n")
-			fmt.Printf("  - Acquisition File        : %s\n", csConfig.Crowdsec.AcquisitionFilePath)
-			fmt.Printf("  - Parsers routines        : %d\n", csConfig.Crowdsec.ParserRoutinesCount)
-			if csConfig.Crowdsec.AcquisitionDirPath != "" {
-				fmt.Printf("  - Acquisition Folder      : %s\n", csConfig.Crowdsec.AcquisitionDirPath)
-			}
-		}
-
-		if csConfig.Cscli != nil {
-			fmt.Printf("cscli:\n")
-			fmt.Printf("  - Output                  : %s\n", csConfig.Cscli.Output)
-			fmt.Printf("  - Hub Branch              : %s\n", csConfig.Cscli.HubBranch)
-			fmt.Printf("  - Hub Folder              : %s\n", csConfig.Cscli.HubDir)
-		}
-
-		if csConfig.API != nil {
-			if csConfig.API.Client != nil && csConfig.API.Client.Credentials != nil {
-				fmt.Printf("API Client:\n")
-				fmt.Printf("  - URL                     : %s\n", csConfig.API.Client.Credentials.URL)
-				fmt.Printf("  - Login                   : %s\n", csConfig.API.Client.Credentials.Login)
-				fmt.Printf("  - Credentials File        : %s\n", csConfig.API.Client.CredentialsFilePath)
-			}
-
-			if csConfig.API.Server != nil {
-				fmt.Printf("Local API Server:\n")
-				fmt.Printf("  - Listen URL              : %s\n", csConfig.API.Server.ListenURI)
-				fmt.Printf("  - Profile File            : %s\n", csConfig.API.Server.ProfilesPath)
-
-				if csConfig.API.Server.TLS != nil {
-					if csConfig.API.Server.TLS.CertFilePath != "" {
-						fmt.Printf("  - Cert File : %s\n", csConfig.API.Server.TLS.CertFilePath)
-					}
-
-					if csConfig.API.Server.TLS.KeyFilePath != "" {
-						fmt.Printf("  - Key File  : %s\n", csConfig.API.Server.TLS.KeyFilePath)
-					}
-
-					if csConfig.API.Server.TLS.CACertPath != "" {
-						fmt.Printf("  - CA Cert   : %s\n", csConfig.API.Server.TLS.CACertPath)
-					}
-
-					if csConfig.API.Server.TLS.CRLPath != "" {
-						fmt.Printf("  - CRL       : %s\n", csConfig.API.Server.TLS.CRLPath)
-					}
-
-					if csConfig.API.Server.TLS.CacheExpiration != nil {
-						fmt.Printf("  - Cache Expiration : %s\n", csConfig.API.Server.TLS.CacheExpiration)
-					}
-
-					if csConfig.API.Server.TLS.ClientVerification != "" {
-						fmt.Printf("  - Client Verification : %s\n", csConfig.API.Server.TLS.ClientVerification)
-					}
-
-					if csConfig.API.Server.TLS.AllowedAgentsOU != nil {
-						for _, ou := range csConfig.API.Server.TLS.AllowedAgentsOU {
-							fmt.Printf("      - Allowed Agents OU       : %s\n", ou)
-						}
-					}
-
-					if csConfig.API.Server.TLS.AllowedBouncersOU != nil {
-						for _, ou := range csConfig.API.Server.TLS.AllowedBouncersOU {
-							fmt.Printf("      - Allowed Bouncers OU       : %s\n", ou)
-						}
-					}
-				}
-
-				fmt.Printf("  - Trusted IPs: \n")
-
-				for _, ip := range csConfig.API.Server.TrustedIPs {
-					fmt.Printf("      - %s\n", ip)
-				}
-
-				if csConfig.API.Server.OnlineClient != nil && csConfig.API.Server.OnlineClient.Credentials != nil {
-					fmt.Printf("Central API:\n")
-					fmt.Printf("  - URL                     : %s\n", csConfig.API.Server.OnlineClient.Credentials.URL)
-					fmt.Printf("  - Login                   : %s\n", csConfig.API.Server.OnlineClient.Credentials.Login)
-					fmt.Printf("  - Credentials File        : %s\n", csConfig.API.Server.OnlineClient.CredentialsFilePath)
-				}
-			}
+		tmp, err := template.New("config").Parse(configShowTemplate)
+		if err != nil {
+			return err
 		}
-
-		if csConfig.DbConfig != nil {
-			fmt.Printf("  - Database:\n")
-			fmt.Printf("      - Type                : %s\n", csConfig.DbConfig.Type)
-
-			switch csConfig.DbConfig.Type {
-			case "sqlite":
-				fmt.Printf("      - Path                : %s\n", csConfig.DbConfig.DbPath)
-			default:
-				fmt.Printf("      - Host                : %s\n", csConfig.DbConfig.Host)
-				fmt.Printf("      - Port                : %d\n", csConfig.DbConfig.Port)
-				fmt.Printf("      - User                : %s\n", csConfig.DbConfig.User)
-				fmt.Printf("      - DB Name             : %s\n", csConfig.DbConfig.DbName)
-			}
-
-			if csConfig.DbConfig.Flush != nil {
-				if *csConfig.DbConfig.Flush.MaxAge != "" {
-					fmt.Printf("      - Flush age           : %s\n", *csConfig.DbConfig.Flush.MaxAge)
-				}
-				if *csConfig.DbConfig.Flush.MaxItems != 0 {
-					fmt.Printf("      - Flush size          : %d\n", *csConfig.DbConfig.Flush.MaxItems)
-				}
-			}
+		err = tmp.Execute(os.Stdout, csConfig)
+		if err != nil {
+			return err
 		}
 	case "json":
 		data, err := json.MarshalIndent(csConfig, "", "  ")

+ 11 - 0
test/bats/01_cscli.bats

@@ -97,6 +97,17 @@ teardown() {
 
     rune -0 cscli config show --key Config.API.Server.ListenURI
     assert_output "127.0.0.1:8080"
+
+    # check that LAPI configuration is loaded (human and json, not shows in raw)
+
+    rune -0 cscli config show -o human
+    assert_line --regexp ".*- URL\s+: http://127.0.0.1:8080/"
+    assert_line --regexp ".*- Login\s+: githubciXXXXXXXXXXXXXXXXXXXXXXXX"
+    assert_line --regexp ".*- Credentials File\s+: .*/local_api_credentials.yaml"
+
+    rune -0 cscli config show -o json
+    rune -0 jq -c '.API.Client.Credentials | [.url,.login]' <(output)
+    assert_output '["http://127.0.0.1:8080/","githubciXXXXXXXXXXXXXXXXXXXXXXXX"]'
 }
 
 @test "cscli config backup / restore" {