VM Tracker Client - Referenzdokumentation¶
Inhaltsverzeichnis¶
- Übersicht
- Datenstrukturen
- Interfaces
- Funktionen
- Kommandozeilen-Parameter
- Verwendungsbeispiele
- Fehlerbehandlung
- Integration
Übersicht¶
Der VM Tracker Client ist ein in Go geschriebener Dienst, der automatisch Informationen über virtuelle Maschinen (VMs) an einen zentralen API-Server sendet. Der Client überwacht kontinuierlich Hostname und IP-Adresse einer VM und registriert diese Informationen in regelmäßigen Intervallen.
Hauptfunktionen¶
- ✅ Automatische Erkennung von Hostname
- ✅ Erkennung von IPv4-Adressen auf spezifischen Netzwerk-Interfaces
- ✅ Periodische Registration bei einem API-Server
- ✅ Automatische Wiederholungsversuche bei Fehlern
- ✅ Graceful Shutdown bei SIGTERM/SIGINT
- ✅ Konfigurierbares Update-Intervall
Architektur¶
┌─────────────────────┐
│ VM Tracker Client │
│ │
│ ┌───────────────┐ │
│ │ Hostname │ │
│ │ Detection │ │
│ └───────────────┘ │
│ │
│ ┌───────────────┐ │
│ │ IP Address │ │
│ │ Detection │ │
│ └───────────────┘ │
│ │
│ ┌───────────────┐ │
│ │ HTTP Client │ │
│ │ Registration │ │
│ └───────────────┘ │
└─────────────────────┘
│
│ HTTP POST
│ /api/register
▼
┌─────────────────────┐
│ API Server │
└─────────────────────┘
Datenstrukturen¶
VMInfo¶
Die zentrale Datenstruktur, die Informationen über eine VM enthält.
Definition¶
type VMInfo struct {
Hostname string `json:"hostname"`
IPAddress string `json:"ip_address"`
Interface string `json:"interface"`
}
Felder¶
| Feld | Typ | JSON Tag | Beschreibung |
|---|---|---|---|
Hostname |
string |
hostname |
Der Hostname der VM (z.B. "web-server-01") |
IPAddress |
string |
ip_address |
Die IPv4-Adresse der VM (z.B. "192.168.1.100") |
Interface |
string |
interface |
Der Name des Netzwerk-Interfaces (z.B. "eth0", "enp0s1") |
JSON-Repräsentation¶
Verwendung¶
info := VMInfo{
Hostname: "my-vm",
IPAddress: "10.0.0.5",
Interface: "enp0s1",
}
// JSON Marshaling
jsonData, err := json.Marshal(info)
if err != nil {
log.Fatal(err)
}
// JSON Unmarshaling
var vmInfo VMInfo
err = json.Unmarshal(jsonData, &vmInfo)
if err != nil {
log.Fatal(err)
}
Validierung¶
- Hostname: Kann beliebige Zeichen enthalten, sollte aber einem gültigen Hostname-Format entsprechen
- IPAddress: Muss eine gültige IPv4-Adresse sein (wird durch
net.ParseIP()validiert) - Interface: Muss ein existierendes Netzwerk-Interface auf dem System sein
Interfaces¶
HTTPClient¶
Interface für HTTP-Operationen, ermöglicht Mocking und Testing.
Definition¶
type HTTPClient interface {
Post(url, contentType string, body *bytes.Buffer) (*http.Response, error)
}
Methoden¶
Post¶
Parameter:
- url (string): Die vollständige URL für den POST-Request
- contentType (string): MIME-Type des Request-Body (z.B. "application/json")
- body (*bytes.Buffer): Der Request-Body als Buffer
Rückgabewerte:
- *http.Response: Die HTTP-Response oder nil bei Fehler
- error: Fehler-Information oder nil bei Erfolg
Beispiel:
client := &DefaultHTTPClient{}
body := bytes.NewBufferString(`{"key":"value"}`)
resp, err := client.Post("http://api.example.com/data", "application/json", body)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
DefaultHTTPClient¶
Produktions-Implementation des HTTPClient Interface.
Definition¶
Methoden¶
func (c *DefaultHTTPClient) Post(url, contentType string, body *bytes.Buffer) (*http.Response, error)
Wrapper um die Standard-http.Post() Funktion.
Verwendung:
Funktionen¶
getHostname¶
Ermittelt den Hostnamen des Systems.
Signatur¶
Rückgabewerte¶
string: Der Hostname des Systems oder "unknown" bei Fehler
Beschreibung¶
Diese Funktion verwendet os.Hostname() um den Hostnamen zu ermitteln. Bei einem Fehler wird "unknown" zurückgegeben und der Fehler wird geloggt.
Beispiel¶
Fehlerbehandlung¶
- Bei Fehlern wird eine Warnung geloggt:
"Error getting hostname: <error>" - Rückgabewert ist immer ein gültiger String (nie leer)
Siehe auch¶
- Referenz: main.go:24
getIPAddress¶
Ermittelt die IPv4-Adresse eines spezifischen Netzwerk-Interfaces.
Signatur¶
Parameter¶
interfaceName(string): Name des Netzwerk-Interfaces (z.B. "eth0", "enp0s1", "en0")
Rückgabewerte¶
string: Die IPv4-Adresse des Interfaces oder leerer String bei Fehlererror: Fehler-Information odernilbei Erfolg
Beschreibung¶
Diese Funktion sucht nach dem angegebenen Netzwerk-Interface und gibt die erste gefundene nicht-Loopback IPv4-Adresse zurück.
Beispiel¶
ip, err := getIPAddress("eth0")
if err != nil {
log.Fatal(err)
}
fmt.Printf("IP Address: %s\n", ip)
// Output: IP Address: 192.168.1.100
Fehler¶
| Fehlertyp | Beschreibung |
|---|---|
"interface %s not found: %v" |
Das angegebene Interface existiert nicht |
"error getting addresses for %s: %v" |
Fehler beim Abrufen der Adressen |
"no IPv4 address found on interface %s" |
Keine IPv4-Adresse auf dem Interface gefunden |
Implementierungsdetails¶
- Sucht das Interface mit
net.InterfaceByName() - Ruft alle Adressen mit
iface.Addrs()ab - Filtert nach nicht-Loopback IPv4-Adressen
- Gibt die erste gefundene Adresse zurück
Siehe auch¶
- Referenz: main.go:33
sendRegistration¶
Sendet eine VM-Registration an den API-Server (Produktions-Wrapper).
Signatur¶
Parameter¶
apiURL(string): Basis-URL des API-Servers (z.B. "http://api.example.com:8080")info(VMInfo): VM-Informationen zum Senden
Rückgabewerte¶
error: Fehler-Information odernilbei Erfolg
Beschreibung¶
Diese Funktion ist ein Wrapper um sendRegistrationWithClient() und verwendet den DefaultHTTPClient für Produktionsumgebungen.
Beispiel¶
apiURL := "http://api.example.com:8080"
info := VMInfo{
Hostname: "web-01",
IPAddress: "192.168.1.100",
Interface: "eth0",
}
err := sendRegistration(apiURL, info)
if err != nil {
log.Printf("Registration failed: %v", err)
}
Siehe auch¶
sendRegistrationWithClient()für die detaillierte Implementation- Referenz: main.go:70
sendRegistrationWithClient¶
Sendet eine VM-Registration mit einem benutzerdefinierten HTTP-Client.
Signatur¶
Parameter¶
apiURL(string): Basis-URL des API-Serversinfo(VMInfo): VM-Informationen zum Sendenclient(HTTPClient): HTTP-Client für die Anfrage
Rückgabewerte¶
error: Fehler-Information odernilbei Erfolg
Beschreibung¶
Sendet einen HTTP POST-Request an <apiURL>/api/register mit den VM-Informationen als JSON-Body.
HTTP-Request¶
Endpoint: POST /api/register
Headers:
Body:
HTTP-Response¶
Erfolg:
- Status Code: 200 OK
Fehler:
- Status Code: != 200 (beliebiger Fehlercode)
Fehler¶
| Fehlertyp | Beschreibung |
|---|---|
"error marshaling JSON: %v" |
JSON-Serialisierung fehlgeschlagen |
"error sending request: %v" |
Netzwerkfehler beim Senden |
"server returned status %d" |
Server hat einen Nicht-200 Status Code zurückgegeben |
Beispiel mit Mock-Client¶
// Mock für Testing
mockClient := &MockHTTPClient{
PostFunc: func(url, contentType string, body *bytes.Buffer) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: io.NopCloser(bytes.NewBufferString("OK")),
}, nil
},
}
info := VMInfo{
Hostname: "test-vm",
IPAddress: "192.168.1.100",
Interface: "eth0",
}
err := sendRegistrationWithClient("http://api.example.com", info, mockClient)
if err != nil {
log.Fatal(err)
}
Implementierungsdetails¶
- Marshalt
VMInfozu JSON - Sendet POST-Request an
<apiURL>/api/register - Prüft HTTP-Status Code
- Schließt Response-Body ordnungsgemäß
Siehe auch¶
- Referenz: main.go:74
Kommandozeilen-Parameter¶
Der VM Tracker Client unterstützt folgende Kommandozeilen-Flags:
-api¶
Typ: string
Standard: "http://10.0.2.196:8080"
Beschreibung: URL des API-Servers
Verwendung:
./vm-tracker-client -api "http://api.example.com:8080"
./vm-tracker-client -api "https://secure-api.example.com"
Hinweise: - Trailing Slashes werden automatisch entfernt - Unterstützt HTTP und HTTPS - Port kann optional angegeben werden
-interface¶
Typ: string
Standard: "enp0s1"
Beschreibung: Name des zu überwachenden Netzwerk-Interfaces
Verwendung:
./vm-tracker-client -interface "eth0"
./vm-tracker-client -interface "en0"
./vm-tracker-client -interface "wlan0"
Gängige Interface-Namen:
| Betriebssystem | Übliche Namen |
|---|---|
| Linux | eth0, eth1, enp0s1, enp0s3 |
| macOS | en0, en1 |
| Windows | Ethernet, Wi-Fi |
-interval¶
Typ: int
Standard: 30
Einheit: Sekunden
Beschreibung: Intervall zwischen Updates
Verwendung:
./vm-tracker-client -interval 60 # Alle 60 Sekunden
./vm-tracker-client -interval 10 # Alle 10 Sekunden
./vm-tracker-client -interval 300 # Alle 5 Minuten
Empfohlene Werte: - Entwicklung: 10-30 Sekunden - Produktion: 60-300 Sekunden - Niedrige Last: 300+ Sekunden
-retry¶
Typ: int
Standard: 5
Einheit: Sekunden
Beschreibung: Wartezeit zwischen Wiederholungsversuchen bei Fehlern
Verwendung:
./vm-tracker-client -retry 10 # 10 Sekunden warten
./vm-tracker-client -retry 1 # Schnelle Wiederholung
-verbose¶
Typ: bool
Standard: false
Beschreibung: Aktiviert ausführliches Logging
Verwendung:
Output mit -verbose:
2025/11/04 12:00:00 Sending registration: {Hostname:web-01 IPAddress:192.168.1.100 Interface:eth0}
2025/11/04 12:00:00 Update sent successfully
2025/11/04 12:00:30 Sending update: {Hostname:web-01 IPAddress:192.168.1.100 Interface:eth0}
2025/11/04 12:00:30 Update sent successfully
Verwendungsbeispiele¶
Basis-Verwendung¶
# Einfachster Start mit Standardwerten
./vm-tracker-client
# Mit benutzerdefinierten Parametern
./vm-tracker-client \
-api "http://api.example.com:8080" \
-interface "eth0" \
-interval 60 \
-verbose
Docker-Container¶
docker run -d \
--name vm-tracker-client \
--network host \
vm-tracker-client:latest \
-api "http://api-server:8080" \
-interface "eth0" \
-interval 30
Systemd Service¶
[Unit]
Description=VM Tracker Client
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/vm-tracker-client \
-api "http://api.example.com:8080" \
-interface "eth0" \
-interval 60 \
-retry 5
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Kubernetes Deployment¶
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: vm-tracker-client
spec:
selector:
matchLabels:
app: vm-tracker-client
template:
metadata:
labels:
app: vm-tracker-client
spec:
hostNetwork: true
containers:
- name: client
image: vm-tracker-client:latest
args:
- "-api"
- "http://vm-tracker-api:8080"
- "-interface"
- "eth0"
- "-interval"
- "60"
- "-verbose"
Programmatische Verwendung¶
package main
import (
"log"
"time"
)
func main() {
apiURL := "http://api.example.com:8080"
interfaceName := "eth0"
// Initial registration
hostname := getHostname()
ipAddress, err := getIPAddress(interfaceName)
if err != nil {
log.Fatalf("Failed to get IP: %v", err)
}
info := VMInfo{
Hostname: hostname,
IPAddress: ipAddress,
Interface: interfaceName,
}
err = sendRegistration(apiURL, info)
if err != nil {
log.Fatalf("Failed to register: %v", err)
}
log.Printf("Successfully registered: %s @ %s", hostname, ipAddress)
// Periodic updates
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for range ticker.C {
// Update and send
ipAddress, err := getIPAddress(interfaceName)
if err != nil {
log.Printf("Error getting IP: %v", err)
continue
}
info.IPAddress = ipAddress
err = sendRegistration(apiURL, info)
if err != nil {
log.Printf("Failed to send update: %v", err)
}
}
}
Fehlerbehandlung¶
Retry-Mechanismus¶
Der Client implementiert automatische Wiederholungsversuche bei Fehlern:
Initial Registration¶
maxRetries := 3
retryCount := 0
for retryCount < maxRetries {
err := sendRegistration(apiURL, info)
if err == nil {
break // Erfolg
}
log.Printf("Failed to register: %v, retrying in %d seconds...", err, retryDelay)
time.Sleep(time.Duration(retryDelay) * time.Second)
retryCount++
}
if retryCount >= maxRetries {
log.Fatalf("Failed to register after %d attempts, exiting", maxRetries)
}
Periodische Updates¶
Bei periodischen Updates wird bei Fehlern nicht abgebrochen, sondern nur geloggt:
for {
select {
case <-ticker.C:
err := sendRegistration(apiURL, info)
if err != nil {
log.Printf("Failed to send update: %v", err)
// Wartet auf nächsten Tick
}
}
}
Fehlertypen¶
| Fehlertyp | Beschreibung | Behandlung |
|---|---|---|
| Network Error | Verbindung zum Server fehlgeschlagen | Retry mit exponentieller Backoff |
| HTTP 4xx | Client-Fehler (z.B. ungültige Daten) | Logging, eventuell Abbruch |
| HTTP 5xx | Server-Fehler | Retry mit Wartezeit |
| Interface Error | Netzwerk-Interface nicht gefunden | Logging, weiter versuchen |
| JSON Error | Serialisierungsfehler | Logging, kritischer Fehler |
Signal Handling¶
Graceful Shutdown bei SIGTERM/SIGINT:
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGTERM, syscall.SIGINT)
for {
select {
case sig := <-sigChan:
log.Printf("Received signal %v, shutting down...", sig)
return
case <-ticker.C:
// Normal operation
}
}
Unterstützte Signale:
- SIGTERM - Ordnungsgemäßer Shutdown
- SIGINT - Ctrl+C Interrupt
Integration¶
API-Server Requirements¶
Der Client erwartet einen kompatiblen API-Server mit folgendem Endpoint:
POST /api/register¶
Request:
POST /api/register HTTP/1.1
Host: api.example.com:8080
Content-Type: application/json
{
"hostname": "web-server-01",
"ip_address": "192.168.1.100",
"interface": "eth0"
}
Success Response:
HTTP/1.1 200 OK
Content-Type: application/json
{
"status": "registered",
"timestamp": "2025-11-04T12:00:00Z"
}
Error Response:
Monitoring & Logging¶
Der Client schreibt Logs nach stdout/stderr:
Log-Levels:
| Level | Beispiel | Beschreibung |
|---|---|---|
| INFO | VM Tracker Client starting... |
Normale Operationen |
| INFO | Successfully registered with API server |
Erfolgreiche Aktionen |
| WARNING | Warning: interface not found, retrying... |
Nicht-kritische Fehler |
| ERROR | Failed to register: connection refused |
Fehler mit Retry |
| FATAL | Failed to register after 3 attempts, exiting |
Kritische Fehler, Programm-Abbruch |
Log-Format:
Metriken¶
Für Monitoring können folgende Metriken erfasst werden:
- Registration Success Rate: Erfolgreiche vs. fehlgeschlagene Registrationen
- API Response Time: Zeit für /api/register Aufrufe
- Update Interval: Tatsächliches vs. konfiguriertes Intervall
- Retry Count: Anzahl der Wiederholungsversuche
- Uptime: Laufzeit des Clients
Health Checks¶
Für Container-Orchestrierung:
# Prüfen ob Prozess läuft
pgrep -f vm-tracker-client
# Prüfen ob Updates gesendet werden (Log-basiert)
timeout 65 tail -f /var/log/vm-tracker.log | grep -q "Update sent"
Anhang¶
Build-Anleitung¶
# Standard-Build
go build -o vm-tracker-client main.go
# Mit Optimierung
go build -ldflags="-s -w" -o vm-tracker-client main.go
# Cross-Compilation für Linux
GOOS=linux GOARCH=amd64 go build -o vm-tracker-client-linux main.go
# Mit Version-Info
go build -ldflags="-X main.Version=1.0.0" -o vm-tracker-client main.go
Testing¶
# Unit Tests
go test -v
# Mit Coverage
go test -v -cover -coverprofile=coverage.out
# Benchmarks
go test -bench=. -benchmem
Abhängigkeiten¶
Der Client verwendet nur Go Standard Library:
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"log"
"net"
"net/http"
"os"
"os/signal"
"strings"
"syscall"
"time"
)
Keine externen Abhängigkeiten erforderlich!
Performance¶
Ressourcen-Verbrauch: - CPU: < 1% idle, < 5% während Updates - Memory: ~5-10 MB RAM - Network: Minimal (~1-2 KB pro Update)
Skalierung: - Kann tausende Instanzen parallel betreiben - Netzwerk-Last: ~2 KB × (Anzahl VMs) / Intervall - Beispiel: 1000 VMs @ 60s Intervall = ~33 KB/s
Sicherheit¶
Empfehlungen:
- HTTPS verwenden:
-api "https://api.example.com" - Authentifizierung: Bei Bedarf erweitern mit API-Keys/Tokens
- Firewall: Nur ausgehende Verbindungen zum API-Server erlauben
- Least Privilege: Client mit minimalen Berechtigungen ausführen
- Log-Rotation: Logs regelmäßig rotieren und archivieren
Lizenz¶
Bitte beachten Sie die Lizenzbestimmungen des Projekts.
Support¶
Bei Fragen oder Problemen:
- Siehe unittests für Test-Dokumentation
- Erstellen Sie ein Issue im Repository
- Prüfen Sie die Logs mit -verbose Flag
Version: 1.0 Letzte Aktualisierung: 2025-11-04 Autor: VM Tracker Team