commit a70263b4465456b93a111e0e10f958780238f968 Author: Colin Date: Thu Apr 18 10:33:53 2024 -0400 host_check diff --git a/README.md b/README.md new file mode 100644 index 0000000..ad7304e --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +# Purpose + +This Go binary performs basic network diagnostics on a set of hostnames, useful for checking connectivity to dependency containers. + +## Usage + +1. **Build:** + ```bash + ./build.sh + ``` + +2. **Set Environment Variables:** + * **HOSTNAMES:** Comma-separated list of hostnames to check (e.g., `database,redis-server,api.example.com`) + * **FAIL_ON_ERROR** (optional): Set to "true" to exit the program immediately upon the first ping failure. + * **COMMAND** (optional): Set to "entrypoint.sh" to execute an additional script on each host. + * **ERROR_COMMAND** (optional): A command to execute if a ping failure occurs, useful for automated error reporting (e.g., `go-glitch report-error 'Ping failed'`). + +3. **Run:** + ```bash + ./host_check + ``` + +## Output + +For each hostname: + +* **DNS Resolution:** Success or failure, with resolved IPs if successful. +* **Ping:** Success or failure, with ping statistics if successful. +* **Custom Script:** Output of the `entrypoint.sh` script, if executed. +* **Error Reporting:** Output of the `ERROR_COMMAND`, if set and a ping failure occurs. + +## Example + +To check connectivity to "db-container" and "webserver", execute an `entrypoint.sh` script, and report errors to go-glitch: + +```bash +export HOSTNAMES="db-container,webserver" +export COMMAND="entrypoint.sh" +export ERROR_COMMAND="go-glitch report-error 'Ping failed'" +./host_check +``` + +**Important:** +* Make sure you have a `build.sh` script in your project directory to handle the Go compilation process. +* You'll need an `entrypoint.sh` script if you want to leverage the `COMMAND` functionality. + +Let me know if you'd like any other adjustments to your README! + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..e1cde39 --- /dev/null +++ b/build.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +# Default architecture +DEFAULT_ARCH="linux/amd64" + +# Supported architectures (adjust as needed) +ARCHITECTURES=("linux/amd64" "linux/arm64" "linux/arm/v7") + +# Build function (Updated) +build_binary() { + os=$1 + arch=$2 + output_name="host_check" + + if [[ "$os/$arch" != "$DEFAULT_ARCH" ]]; then + output_name="${output_name}_${os}_${arch}" + fi + + # Create the dist folder if it doesn't exist + mkdir -p dist + + echo "Building for ${os}/${arch} -> dist/${output_name}" + GOOS=${os} GOARCH=${arch} go build -o dist/${output_name} . +} + +# Main Build Process (Updated) +for arch in "${ARCHITECTURES[@]}"; do + IFS='/' read -r -a parts <<< "$arch" + os=${parts[0]} + arch=${parts[1]} + + # Ensure module files are present in the current directory + if [ ! -f "go.mod" ] || [ ! -f "go.sum" ]; then + echo "Error: 'go.mod' and/or 'go.sum' not found in the current directory." + echo "Make sure you're in the root of your Go module before running the build." + exit 1 + fi + + build_binary $os $arch +done + diff --git a/host_check.go b/host_check.go new file mode 100644 index 0000000..9ce96f7 --- /dev/null +++ b/host_check.go @@ -0,0 +1,58 @@ +package main + +import ( + "fmt" + "net" + "os" + "os/exec" + "strings" +) + +func main() { + // ... (Hostname handling as before) ... + + failOnError := os.Getenv("FAIL_ON_ERROR") == "true" + commandStr := os.Getenv("COMMAND") + errorCommandStr := os.Getenv("ERROR_COMMAND") // Fetch error command + + for _, host := range hosts { + // ... (DNS Resolution as before) ... + + // Ping + pingCmd := exec.Command("ping", "-c", "3", host) + pingOutput, err := pingCmd.Output() + if err != nil { + fmt.Println("Ping Failed:", err) + if failOnError { + os.Exit(1) // Exit with error code + } + + // Execute error command if specified + if errorCommandStr != "" { + cmdParts := strings.Fields(errorCommandStr) + cmd := exec.Command(cmdParts[0], cmdParts[1:]...) + cmdOutput, cmdErr := cmd.Output() + if cmdErr != nil { + fmt.Println("Error Command Execution Failed:", errorCommandStr, cmdErr) + } else { + fmt.Println("Error Command Output:\n", string(cmdOutput)) + } + } + } else { + fmt.Println("Ping Output:\n", string(pingOutput)) + } + + // Execute additional command if specified + if commandStr != "" { + cmdParts := strings.Fields(commandStr) // Split on spaces + cmd := exec.Command(cmdParts[0], cmdParts[1:]...) + cmdOutput, err := cmd.Output() + if err != nil { + fmt.Println("Command Execution Failed:", cmdStr, err) + } else { + fmt.Println("Command Output:\n", string(cmdOutput)) + } + } + } +} +