mirror of
https://github.com/fosrl/pangolin.git
synced 2025-05-13 13:50:40 +01:00
Merge branch 'dev' of https://github.com/fosrl/pangolin into dev
This commit is contained in:
commit
f5a3fd7202
5 changed files with 128 additions and 137 deletions
|
@ -9,6 +9,9 @@ services:
|
||||||
PARSERS: crowdsecurity/whitelists
|
PARSERS: crowdsecurity/whitelists
|
||||||
ENROLL_TAGS: docker
|
ENROLL_TAGS: docker
|
||||||
healthcheck:
|
healthcheck:
|
||||||
|
interval: 10s
|
||||||
|
retries: 15
|
||||||
|
timeout: 10s
|
||||||
test: ["CMD", "cscli", "capi", "status"]
|
test: ["CMD", "cscli", "capi", "status"]
|
||||||
labels:
|
labels:
|
||||||
- "traefik.enable=false" # Disable traefik for crowdsec
|
- "traefik.enable=false" # Disable traefik for crowdsec
|
||||||
|
|
|
@ -3,9 +3,12 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"gopkg.in/yaml.v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
func installCrowdsec(config Config) error {
|
func installCrowdsec(config Config) error {
|
||||||
|
@ -63,6 +66,12 @@ func installCrowdsec(config Config) error {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check and add the service dependency of crowdsec to traefik
|
||||||
|
if err := CheckAndAddCrowdsecDependency("docker-compose.yml"); err != nil {
|
||||||
|
fmt.Printf("Error adding crowdsec dependency to traefik: %v\n", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
if err := startContainers(); err != nil {
|
if err := startContainers(); err != nil {
|
||||||
return fmt.Errorf("failed to start containers: %v", err)
|
return fmt.Errorf("failed to start containers: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -135,3 +144,58 @@ func checkIfTextInFile(file, text string) bool {
|
||||||
// Check for text
|
// Check for text
|
||||||
return bytes.Contains(content, []byte(text))
|
return bytes.Contains(content, []byte(text))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CheckAndAddCrowdsecDependency(composePath string) error {
|
||||||
|
// Read the docker-compose.yml file
|
||||||
|
data, err := os.ReadFile(composePath)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error reading compose file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse YAML into a generic map
|
||||||
|
var compose map[string]interface{}
|
||||||
|
if err := yaml.Unmarshal(data, &compose); err != nil {
|
||||||
|
return fmt.Errorf("error parsing compose file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get services section
|
||||||
|
services, ok := compose["services"].(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("services section not found or invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get traefik service
|
||||||
|
traefik, ok := services["traefik"].(map[string]interface{})
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("traefik service not found or invalid")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get dependencies
|
||||||
|
dependsOn, ok := traefik["depends_on"].(map[string]interface{})
|
||||||
|
if ok {
|
||||||
|
// Append the new block for crowdsec
|
||||||
|
dependsOn["crowdsec"] = map[string]interface{}{
|
||||||
|
"condition": "service_healthy",
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// No dependencies exist, create it
|
||||||
|
traefik["depends_on"] = map[string]interface{}{
|
||||||
|
"crowdsec": map[string]interface{}{
|
||||||
|
"condition": "service_healthy",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Marshal the modified data back to YAML with indentation
|
||||||
|
modifiedData, err := MarshalYAMLWithIndent(compose, 2) // Set indentation to 2 spaces
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("error marshaling YAML: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := os.WriteFile(composePath, modifiedData, 0644); err != nil {
|
||||||
|
return fmt.Errorf("error writing updated compose file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Added dependency of crowdsec to traefik")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ module installer
|
||||||
go 1.23.0
|
go 1.23.0
|
||||||
|
|
||||||
require (
|
require (
|
||||||
golang.org/x/sys v0.29.0 // indirect
|
golang.org/x/term v0.28.0
|
||||||
golang.org/x/term v0.28.0 // indirect
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
require golang.org/x/sys v0.29.0 // indirect
|
||||||
|
|
|
@ -2,6 +2,7 @@ golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
|
||||||
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||||
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
golang.org/x/term v0.28.0 h1:/Ts8HFuMR2E6IP/jlo7QVLZHggjKQbhu/7H0LJFr3Gg=
|
||||||
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
golang.org/x/term v0.28.0/go.mod h1:Sw/lC2IAUZ92udQNf3WodGtn4k/XoLyZoh8v/8uiwek=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
|
168
install/main.go
168
install/main.go
|
@ -87,7 +87,15 @@ func main() {
|
||||||
|
|
||||||
if isDockerInstalled() {
|
if isDockerInstalled() {
|
||||||
if readBool(reader, "Would you like to install and start the containers?", true) {
|
if readBool(reader, "Would you like to install and start the containers?", true) {
|
||||||
pullAndStartContainers()
|
if err := pullContainers(); err != nil {
|
||||||
|
fmt.Println("Error: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := startContainers(); err != nil {
|
||||||
|
fmt.Println("Error: ", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -427,24 +435,24 @@ func installDocker() error {
|
||||||
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||||
`, dockerArch))
|
`, dockerArch))
|
||||||
case strings.Contains(osRelease, "ID=fedora"):
|
case strings.Contains(osRelease, "ID=fedora"):
|
||||||
installCmd = exec.Command("bash", "-c", fmt.Sprintf(`
|
installCmd = exec.Command("bash", "-c", `
|
||||||
dnf -y install dnf-plugins-core &&
|
dnf -y install dnf-plugins-core &&
|
||||||
dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo &&
|
dnf config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo &&
|
||||||
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
|
||||||
`))
|
`)
|
||||||
case strings.Contains(osRelease, "ID=opensuse") || strings.Contains(osRelease, "ID=\"opensuse-"):
|
case strings.Contains(osRelease, "ID=opensuse") || strings.Contains(osRelease, "ID=\"opensuse-"):
|
||||||
installCmd = exec.Command("bash", "-c", `
|
installCmd = exec.Command("bash", "-c", `
|
||||||
zypper install -y docker docker-compose &&
|
zypper install -y docker docker-compose &&
|
||||||
systemctl enable docker
|
systemctl enable docker
|
||||||
`)
|
`)
|
||||||
case strings.Contains(osRelease, "ID=rhel") || strings.Contains(osRelease, "ID=\"rhel"):
|
case strings.Contains(osRelease, "ID=rhel") || strings.Contains(osRelease, "ID=\"rhel"):
|
||||||
installCmd = exec.Command("bash", "-c", fmt.Sprintf(`
|
installCmd = exec.Command("bash", "-c", `
|
||||||
dnf remove -y runc &&
|
dnf remove -y runc &&
|
||||||
dnf -y install yum-utils &&
|
dnf -y install yum-utils &&
|
||||||
dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo &&
|
dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo &&
|
||||||
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin &&
|
dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin &&
|
||||||
systemctl enable docker
|
systemctl enable docker
|
||||||
`))
|
`)
|
||||||
case strings.Contains(osRelease, "ID=amzn"):
|
case strings.Contains(osRelease, "ID=amzn"):
|
||||||
installCmd = exec.Command("bash", "-c", `
|
installCmd = exec.Command("bash", "-c", `
|
||||||
yum update -y &&
|
yum update -y &&
|
||||||
|
@ -468,162 +476,76 @@ func isDockerInstalled() bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCommandString(useNewStyle bool) string {
|
// executeDockerComposeCommandWithArgs executes the appropriate docker command with arguments supplied
|
||||||
if useNewStyle {
|
func executeDockerComposeCommandWithArgs(args ...string) error {
|
||||||
return "'docker compose'"
|
var cmd *exec.Cmd
|
||||||
}
|
|
||||||
return "'docker-compose'"
|
|
||||||
}
|
|
||||||
|
|
||||||
func pullAndStartContainers() error {
|
|
||||||
fmt.Println("Starting containers...")
|
|
||||||
|
|
||||||
// Check which docker compose command is available
|
|
||||||
var useNewStyle bool
|
var useNewStyle bool
|
||||||
|
|
||||||
|
if !isDockerInstalled() {
|
||||||
|
return fmt.Errorf("docker is not installed")
|
||||||
|
}
|
||||||
|
|
||||||
checkCmd := exec.Command("docker", "compose", "version")
|
checkCmd := exec.Command("docker", "compose", "version")
|
||||||
if err := checkCmd.Run(); err == nil {
|
if err := checkCmd.Run(); err == nil {
|
||||||
useNewStyle = true
|
useNewStyle = true
|
||||||
} else {
|
} else {
|
||||||
// Check if docker-compose (old style) is available
|
|
||||||
checkCmd = exec.Command("docker-compose", "version")
|
checkCmd = exec.Command("docker-compose", "version")
|
||||||
if err := checkCmd.Run(); err != nil {
|
if err := checkCmd.Run(); err == nil {
|
||||||
return fmt.Errorf("neither 'docker compose' nor 'docker-compose' command is available: %v", err)
|
useNewStyle = false
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("neither 'docker compose' nor 'docker-compose' command is available")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to execute docker compose commands
|
|
||||||
executeCommand := func(args ...string) error {
|
|
||||||
var cmd *exec.Cmd
|
|
||||||
if useNewStyle {
|
if useNewStyle {
|
||||||
cmd = exec.Command("docker", append([]string{"compose"}, args...)...)
|
cmd = exec.Command("docker", append([]string{"compose"}, args...)...)
|
||||||
} else {
|
} else {
|
||||||
cmd = exec.Command("docker-compose", args...)
|
cmd = exec.Command("docker-compose", args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
cmd.Stderr = os.Stderr
|
cmd.Stderr = os.Stderr
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull containers
|
// pullContainers pulls the containers using the appropriate command.
|
||||||
fmt.Printf("Using %s command to pull containers...\n", getCommandString(useNewStyle))
|
func pullContainers() error {
|
||||||
if err := executeCommand("-f", "docker-compose.yml", "pull"); err != nil {
|
fmt.Println("Pulling the container images...")
|
||||||
return fmt.Errorf("failed to pull containers: %v", err)
|
|
||||||
|
if err := executeDockerComposeCommandWithArgs("-f", "docker-compose.yml", "pull", "--policy", "always"); err != nil {
|
||||||
|
return fmt.Errorf("failed to pull the containers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start containers
|
return nil
|
||||||
fmt.Printf("Using %s command to start containers...\n", getCommandString(useNewStyle))
|
}
|
||||||
if err := executeCommand("-f", "docker-compose.yml", "up", "-d"); err != nil {
|
|
||||||
|
// startContainers starts the containers using the appropriate command.
|
||||||
|
func startContainers() error {
|
||||||
|
fmt.Println("Starting containers...")
|
||||||
|
if err := executeDockerComposeCommandWithArgs("-f", "docker-compose.yml", "up", "-d", "--force-recreate"); err != nil {
|
||||||
return fmt.Errorf("failed to start containers: %v", err)
|
return fmt.Errorf("failed to start containers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// bring containers down
|
// stopContainers stops the containers using the appropriate command.
|
||||||
func stopContainers() error {
|
func stopContainers() error {
|
||||||
fmt.Println("Stopping containers...")
|
fmt.Println("Stopping containers...")
|
||||||
|
|
||||||
// Check which docker compose command is available
|
if err := executeDockerComposeCommandWithArgs("-f", "docker-compose.yml", "down"); err != nil {
|
||||||
var useNewStyle bool
|
|
||||||
checkCmd := exec.Command("docker", "compose", "version")
|
|
||||||
if err := checkCmd.Run(); err == nil {
|
|
||||||
useNewStyle = true
|
|
||||||
} else {
|
|
||||||
// Check if docker-compose (old style) is available
|
|
||||||
checkCmd = exec.Command("docker-compose", "version")
|
|
||||||
if err := checkCmd.Run(); err != nil {
|
|
||||||
return fmt.Errorf("neither 'docker compose' nor 'docker-compose' command is available: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to execute docker compose commands
|
|
||||||
executeCommand := func(args ...string) error {
|
|
||||||
var cmd *exec.Cmd
|
|
||||||
if useNewStyle {
|
|
||||||
cmd = exec.Command("docker", append([]string{"compose"}, args...)...)
|
|
||||||
} else {
|
|
||||||
cmd = exec.Command("docker-compose", args...)
|
|
||||||
}
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
return cmd.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := executeCommand("-f", "docker-compose.yml", "down"); err != nil {
|
|
||||||
return fmt.Errorf("failed to stop containers: %v", err)
|
return fmt.Errorf("failed to stop containers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// just start containers
|
// restartContainer restarts a specific container using the appropriate command.
|
||||||
func startContainers() error {
|
|
||||||
fmt.Println("Starting containers...")
|
|
||||||
|
|
||||||
// Check which docker compose command is available
|
|
||||||
var useNewStyle bool
|
|
||||||
checkCmd := exec.Command("docker", "compose", "version")
|
|
||||||
if err := checkCmd.Run(); err == nil {
|
|
||||||
useNewStyle = true
|
|
||||||
} else {
|
|
||||||
// Check if docker-compose (old style) is available
|
|
||||||
checkCmd = exec.Command("docker-compose", "version")
|
|
||||||
if err := checkCmd.Run(); err != nil {
|
|
||||||
return fmt.Errorf("neither 'docker compose' nor 'docker-compose' command is available: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to execute docker compose commands
|
|
||||||
executeCommand := func(args ...string) error {
|
|
||||||
var cmd *exec.Cmd
|
|
||||||
if useNewStyle {
|
|
||||||
cmd = exec.Command("docker", append([]string{"compose"}, args...)...)
|
|
||||||
} else {
|
|
||||||
cmd = exec.Command("docker-compose", args...)
|
|
||||||
}
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
return cmd.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := executeCommand("-f", "docker-compose.yml", "up", "-d"); err != nil {
|
|
||||||
return fmt.Errorf("failed to start containers: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func restartContainer(container string) error {
|
func restartContainer(container string) error {
|
||||||
fmt.Printf("Restarting %s container...\n", container)
|
fmt.Println("Restarting containers...")
|
||||||
|
|
||||||
// Check which docker compose command is available
|
if err := executeDockerComposeCommandWithArgs("-f", "docker-compose.yml", "restart", container); err != nil {
|
||||||
var useNewStyle bool
|
return fmt.Errorf("failed to stop the container \"%s\": %v", container, err)
|
||||||
checkCmd := exec.Command("docker", "compose", "version")
|
|
||||||
if err := checkCmd.Run(); err == nil {
|
|
||||||
useNewStyle = true
|
|
||||||
} else {
|
|
||||||
// Check if docker-compose (old style) is available
|
|
||||||
checkCmd = exec.Command("docker-compose", "version")
|
|
||||||
if err := checkCmd.Run(); err != nil {
|
|
||||||
return fmt.Errorf("neither 'docker compose' nor 'docker-compose' command is available: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper function to execute docker compose commands
|
|
||||||
executeCommand := func(args ...string) error {
|
|
||||||
var cmd *exec.Cmd
|
|
||||||
if useNewStyle {
|
|
||||||
cmd = exec.Command("docker", append([]string{"compose"}, args...)...)
|
|
||||||
} else {
|
|
||||||
cmd = exec.Command("docker-compose", args...)
|
|
||||||
}
|
|
||||||
cmd.Stdout = os.Stdout
|
|
||||||
cmd.Stderr = os.Stderr
|
|
||||||
return cmd.Run()
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := executeCommand("-f", "docker-compose.yml", "restart", container); err != nil {
|
|
||||||
return fmt.Errorf("failed to restart %s container: %v", container, err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
Loading…
Reference in a new issue