host_check

This commit is contained in:
Colin 2024-04-18 10:33:53 -04:00
commit a70263b446
3 changed files with 147 additions and 0 deletions

48
README.md Normal file
View File

@ -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 <hostname> '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 <hostname> '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!

41
build.sh Executable file
View File

@ -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

58
host_check.go Normal file
View File

@ -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))
}
}
}
}