package main import ( "bytes" "fmt" "os" "os/exec" "strings" "time" ) func installCrowdsec(config Config) error { if err := stopContainers(); err != nil { return fmt.Errorf("failed to stop containers: %v", err) } // Run installation steps if err := backupConfig(); err != nil { return fmt.Errorf("backup failed: %v", err) } if err := createConfigFiles(config); err != nil { fmt.Printf("Error creating config files: %v\n", err) os.Exit(1) } os.MkdirAll("config/crowdsec/db", 0755) os.MkdirAll("config/crowdsec_logs/syslog", 0755) os.MkdirAll("config/traefik/logs", 0755) 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) } if err := copyWebsecureEntryPoint("config/crowdsec/traefik_config.yml", "config/traefik/traefik_config.yml"); err != nil { fmt.Printf("Error copying entry points: %v\n", err) os.Exit(1) } if err := copyEntryPoints("config/traefik/traefik_config.yml", "config/crowdsec/traefik_config.yml"); err != nil { fmt.Printf("Error copying entry points: %v\n", err) os.Exit(1) } if err := moveFile("config/crowdsec/traefik_config.yml", "config/traefik/traefik_config.yml"); err != nil { fmt.Printf("Error moving file: %v\n", err) os.Exit(1) } if err := moveFile("config/crowdsec/dynamic_config.yml", "config/traefik/dynamic_config.yml"); err != nil { fmt.Printf("Error moving file: %v\n", err) 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) } if err := retrieveBouncerKey(config); err != nil { return fmt.Errorf("bouncer key retrieval failed: %v", err) } // if err := startContainers(); err != nil { // return fmt.Errorf("failed to start containers: %v", err) // } return nil } func retrieveBouncerKey(config Config) error { fmt.Println("Retrieving bouncer key. Please be patient...") // Start crowdsec container cmd := exec.Command("docker", "compose", "up", "-d", "crowdsec") if err := cmd.Run(); err != nil { return fmt.Errorf("failed to start crowdsec: %v", err) } // verify that the container is running if not keep waiting for 10 more seconds then return an error count := 0 for { cmd := exec.Command("docker", "inspect", "-f", "{{.State.Running}}", "crowdsec") output, err := cmd.Output() if err != nil { return fmt.Errorf("failed to inspect crowdsec container: %v", err) } if strings.TrimSpace(string(output)) == "true" { break } time.Sleep(10 * time.Second) count++ if count > 4 { return fmt.Errorf("crowdsec container is not running") } } // Get bouncer key output, err := exec.Command("docker", "exec", "crowdsec", "cscli", "bouncers", "add", "traefik-bouncer").Output() if err != nil { return fmt.Errorf("failed to get bouncer key: %v", err) } // Parse key from output lines := strings.Split(string(output), "\n") for _, line := range lines { if strings.Contains(line, "key:") { config.TraefikBouncerKey = strings.TrimSpace(strings.Split(line, ":")[1]) fmt.Println("Bouncer key:", config.TraefikBouncerKey) break } } // Stop crowdsec container cmd = exec.Command("docker", "compose", "down") if err := cmd.Run(); err != nil { return fmt.Errorf("failed to stop crowdsec: %v", err) } fmt.Println("Bouncer key retrieved successfully.") return nil } func checkIsCrowdsecInstalledInCompose() bool { // Read docker-compose.yml content, err := os.ReadFile("docker-compose.yml") if err != nil { return false } // Check for crowdsec service return bytes.Contains(content, []byte("crowdsec:")) }