Skip to content

VM Tracker Client - Referenzdokumentation

Inhaltsverzeichnis

  1. Übersicht
  2. Datenstrukturen
  3. Interfaces
  4. Funktionen
  5. Kommandozeilen-Parameter
  6. Verwendungsbeispiele
  7. Fehlerbehandlung
  8. 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

{
  "hostname": "web-server-01",
  "ip_address": "192.168.1.100",
  "interface": "eth0"
}

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
Post(url, contentType string, body *bytes.Buffer) (*http.Response, error)

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

type DefaultHTTPClient struct{}

Methoden

func (c *DefaultHTTPClient) Post(url, contentType string, body *bytes.Buffer) (*http.Response, error)

Wrapper um die Standard-http.Post() Funktion.

Verwendung:

client := &DefaultHTTPClient{}
// Verwenden wie HTTPClient Interface

Funktionen

getHostname

Ermittelt den Hostnamen des Systems.

Signatur

func getHostname() string

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

hostname := getHostname()
fmt.Printf("Hostname: %s\n", hostname)
// Output: Hostname: web-server-01

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

func getIPAddress(interfaceName string) (string, error)

Parameter

  • interfaceName (string): Name des Netzwerk-Interfaces (z.B. "eth0", "enp0s1", "en0")

Rückgabewerte

  • string: Die IPv4-Adresse des Interfaces oder leerer String bei Fehler
  • error: Fehler-Information oder nil bei 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

  1. Sucht das Interface mit net.InterfaceByName()
  2. Ruft alle Adressen mit iface.Addrs() ab
  3. Filtert nach nicht-Loopback IPv4-Adressen
  4. 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

func sendRegistration(apiURL string, info VMInfo) error

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 oder nil bei 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

func sendRegistrationWithClient(apiURL string, info VMInfo, client HTTPClient) error

Parameter

  • apiURL (string): Basis-URL des API-Servers
  • info (VMInfo): VM-Informationen zum Senden
  • client (HTTPClient): HTTP-Client für die Anfrage

Rückgabewerte

  • error: Fehler-Information oder nil bei 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:

Content-Type: application/json

Body:

{
  "hostname": "web-server-01",
  "ip_address": "192.168.1.100",
  "interface": "eth0"
}

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

  1. Marshalt VMInfo zu JSON
  2. Sendet POST-Request an <apiURL>/api/register
  3. Prüft HTTP-Status Code
  4. 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:

./vm-tracker-client -verbose
./vm-tracker-client -verbose=true

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:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "error": "Invalid request data"
}

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:

2025/11/04 12:00:00 <Message>

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:

  1. HTTPS verwenden: -api "https://api.example.com"
  2. Authentifizierung: Bei Bedarf erweitern mit API-Keys/Tokens
  3. Firewall: Nur ausgehende Verbindungen zum API-Server erlauben
  4. Least Privilege: Client mit minimalen Berechtigungen ausführen
  5. 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