2025-02-12 21:56:13 -05:00
package main
2025-02-09 16:14:29 -05:00
import (
"bytes"
"fmt"
"os"
"os/exec"
"strings"
)
2025-02-13 22:16:52 -05:00
func installCrowdsec ( config Config ) error {
2025-02-18 21:41:23 -05:00
if err := stopContainers ( ) ; err != nil {
return fmt . Errorf ( "failed to stop containers: %v" , err )
}
2025-02-09 16:14:29 -05:00
// Run installation steps
if err := backupConfig ( ) ; err != nil {
return fmt . Errorf ( "backup failed: %v" , err )
}
2025-02-13 22:16:52 -05:00
if err := createConfigFiles ( config ) ; err != nil {
fmt . Printf ( "Error creating config files: %v\n" , err )
os . Exit ( 1 )
2025-02-09 16:14:29 -05:00
}
2025-02-18 21:41:23 -05:00
os . MkdirAll ( "config/crowdsec/db" , 0755 )
2025-04-05 17:47:37 +02:00
os . MkdirAll ( "config/crowdsec/acquis.d" , 0755 )
2025-02-18 21:41:23 -05:00
os . MkdirAll ( "config/traefik/logs" , 0755 )
2025-02-16 11:26:45 -05:00
if err := copyDockerService ( "config/crowdsec/docker-compose.yml" , "docker-compose.yml" , "crowdsec" ) ; err != nil {
fmt . Printf ( "Error copying docker service: %v\n" , err )
os . Exit ( 1 )
}
2025-02-23 21:44:02 -05:00
if err := MergeYAML ( "config/traefik/traefik_config.yml" , "config/crowdsec/traefik_config.yml" ) ; err != nil {
2025-02-16 11:26:45 -05:00
fmt . Printf ( "Error copying entry points: %v\n" , err )
os . Exit ( 1 )
}
2025-02-23 21:44:02 -05:00
// delete the 2nd file
if err := os . Remove ( "config/crowdsec/traefik_config.yml" ) ; err != nil {
fmt . Printf ( "Error removing file: %v\n" , err )
2025-02-16 11:26:45 -05:00
os . Exit ( 1 )
}
2025-02-23 21:44:02 -05:00
if err := MergeYAML ( "config/traefik/dynamic_config.yml" , "config/crowdsec/dynamic_config.yml" ) ; err != nil {
fmt . Printf ( "Error copying entry points: %v\n" , err )
2025-02-16 11:26:45 -05:00
os . Exit ( 1 )
}
2025-02-23 21:44:02 -05:00
// delete the 2nd file
if err := os . Remove ( "config/crowdsec/dynamic_config.yml" ) ; err != nil {
fmt . Printf ( "Error removing file: %v\n" , err )
2025-02-16 11:26:45 -05:00
os . Exit ( 1 )
}
if err := os . Remove ( "config/crowdsec/docker-compose.yml" ) ; err != nil {
fmt . Printf ( "Error removing file: %v\n" , err )
os . Exit ( 1 )
}
2025-02-09 16:14:29 -05:00
2025-02-19 21:42:42 -05:00
if err := CheckAndAddTraefikLogVolume ( "docker-compose.yml" ) ; err != nil {
fmt . Printf ( "Error checking and adding Traefik log volume: %v\n" , err )
os . Exit ( 1 )
2025-02-09 16:14:29 -05:00
}
2025-02-19 21:42:42 -05:00
if err := startContainers ( ) ; err != nil {
return fmt . Errorf ( "failed to start containers: %v" , err )
}
2025-02-18 21:41:23 -05:00
2025-02-19 21:42:42 -05:00
// get API key
apiKey , err := GetCrowdSecAPIKey ( )
2025-02-09 16:14:29 -05:00
if err != nil {
2025-02-19 21:42:42 -05:00
return fmt . Errorf ( "failed to get API key: %v" , err )
2025-02-09 16:14:29 -05:00
}
2025-02-19 21:42:42 -05:00
config . TraefikBouncerKey = apiKey
2025-02-09 16:14:29 -05:00
2025-02-19 21:42:42 -05:00
if err := replaceInFile ( "config/traefik/dynamic_config.yml" , "PUT_YOUR_BOUNCER_KEY_HERE_OR_IT_WILL_NOT_WORK" , config . TraefikBouncerKey ) ; err != nil {
return fmt . Errorf ( "failed to replace bouncer key: %v" , err )
2025-02-09 16:14:29 -05:00
}
2025-02-19 21:42:42 -05:00
if err := restartContainer ( "traefik" ) ; err != nil {
return fmt . Errorf ( "failed to restart containers: %v" , err )
2025-02-18 21:41:23 -05:00
}
2025-03-03 15:43:26 -05:00
if checkIfTextInFile ( "config/traefik/dynamic_config.yml" , "PUT_YOUR_BOUNCER_KEY_HERE_OR_IT_WILL_NOT_WORK" ) {
fmt . Println ( "Failed to replace bouncer key! Please retrieve the key and replace it in the config/traefik/dynamic_config.yml file using the following command:" )
fmt . Println ( " docker exec crowdsec cscli bouncers add traefik-bouncer" )
}
2025-02-09 16:14:29 -05:00
return nil
}
2025-02-13 22:16:52 -05:00
func checkIsCrowdsecInstalledInCompose ( ) bool {
// Read docker-compose.yml
content , err := os . ReadFile ( "docker-compose.yml" )
2025-02-12 21:56:13 -05:00
if err != nil {
2025-02-13 22:16:52 -05:00
return false
2025-02-12 21:56:13 -05:00
}
2025-02-13 22:16:52 -05:00
// Check for crowdsec service
return bytes . Contains ( content , [ ] byte ( "crowdsec:" ) )
2025-02-12 21:56:13 -05:00
}
2025-02-19 21:42:42 -05:00
func GetCrowdSecAPIKey ( ) ( string , error ) {
// First, ensure the container is running
if err := waitForContainer ( "crowdsec" ) ; err != nil {
return "" , fmt . Errorf ( "waiting for container: %w" , err )
}
// Execute the command to get the API key
cmd := exec . Command ( "docker" , "exec" , "crowdsec" , "cscli" , "bouncers" , "add" , "traefik-bouncer" , "-o" , "raw" )
var out bytes . Buffer
cmd . Stdout = & out
if err := cmd . Run ( ) ; err != nil {
return "" , fmt . Errorf ( "executing command: %w" , err )
}
// Trim any whitespace from the output
apiKey := strings . TrimSpace ( out . String ( ) )
if apiKey == "" {
return "" , fmt . Errorf ( "empty API key returned" )
}
return apiKey , nil
}
2025-03-03 15:43:26 -05:00
func checkIfTextInFile ( file , text string ) bool {
// Read file
content , err := os . ReadFile ( file )
if err != nil {
return false
}
// Check for text
return bytes . Contains ( content , [ ] byte ( text ) )
}