VM Tracker API - API Reference¶
Overview¶
The VM Tracker API is a lightweight REST API for managing and monitoring virtual machines. It enables the registration, listing, and deletion of VM information as well as downloading installation scripts.
Base URL: http://localhost:8080 (default, configurable via PORT environment variable)
Framework: Go Standard Library (net/http)
Data Format: JSON
Endpoints¶
1. Register VM¶
Registers or updates information about a virtual machine.
Endpoint: POST /api/register
Content-Type: application/json
Request Body¶
| Field | Type | Required | Description |
|---|---|---|---|
hostname |
string | Yes | Hostname of the VM |
ip_address |
string | Yes | IP address of the VM |
interface |
string | No | Network interface (default: "unknown") |
Example Request¶
curl -X POST http://localhost:8080/api/register \
-H "Content-Type: application/json" \
-d '{
"hostname": "cp1",
"ip_address": "10.0.0.12",
"interface": "eth0"
}'
Response¶
Status Code: 200 OK
Error Responses¶
| Status Code | Description |
|---|---|
400 Bad Request |
Invalid JSON or missing required fields (hostname, ip_address) |
405 Method Not Allowed |
Wrong HTTP method used |
Implementation: main.go:152-175
2. List VMs¶
Returns a list of all registered virtual machines.
Endpoint: GET /api/vms
Content-Type: application/json
Example Request¶
Response¶
Status Code: 200 OK
[
{
"hostname": "cp1",
"ip_address": "10.0.0.12",
"last_seen": "2025-11-03T12:34:56.789Z",
"status": "online",
"interface": "eth0"
},
{
"hostname": "worker1",
"ip_address": "10.0.0.13",
"last_seen": "2025-11-03T12:30:00.123Z",
"status": "offline",
"interface": "eth0"
}
]
Response Fields¶
| Field | Type | Description |
|---|---|---|
hostname |
string | Hostname of the VM |
ip_address |
string | IP address of the VM |
last_seen |
string (ISO 8601) | Timestamp of last contact |
status |
string | VM status: "online", "offline" or "waiting" |
interface |
string | Network interface |
Status Logic¶
- online: VM has checked in within the last 60 seconds
- offline: VM has not checked in for more than 60 seconds
- waiting: VM was registered but doesn't have a
last_seentimestamp yet
Notes¶
- Returns an empty array
[]if no VMs are registered - Status is automatically updated by a background process (every 30 seconds)
Error Responses¶
| Status Code | Description |
|---|---|
405 Method Not Allowed |
Wrong HTTP method used |
Implementation: main.go:177-185
3. Delete VM¶
Deletes a specific virtual machine by its hostname.
Endpoint: DELETE /api/vms/{hostname}
URL Parameters:
- {hostname}: The hostname of the VM to delete
Example Request¶
Response (Success)¶
Status Code: 200 OK
Error Responses¶
| Status Code | Description |
|---|---|
400 Bad Request |
Hostname is missing or invalid |
404 Not Found |
VM with this hostname was not found |
405 Method Not Allowed |
Wrong HTTP method used |
Security¶
The hostname is sanitized with path.Clean() to prevent path traversal attacks.
Implementation: main.go:187-207
4. Download Installation Script¶
Downloads a pre-configured installation script for the VM Tracker Client.
Endpoint: GET /download/install
Content-Type: text/x-shellscript; charset=utf-8
Example Request¶
or in browser:
Response¶
Status Code: 200 OK
Headers:
- Content-Type: text/x-shellscript; charset=utf-8
- Content-Disposition: attachment; filename="vm-tracker-install.sh"
The script contains: - Automatic detection of OS and architecture (Linux, Darwin, Windows) - Download of the appropriate client binary (arm64, amd64, armv7, armv6, 386) - Automatic systemd service configuration (for Linux) - Configuration with API endpoints
Error Responses¶
| Status Code | Description |
|---|---|
500 Internal Server Error |
Template error when generating the script |
Implementation: main.go:224-241
Template: templates/install.sh
5. Web Dashboard¶
Displays an interactive HTML dashboard with all registered VMs.
Endpoint: GET /
Content-Type: text/html; charset=utf-8
Example Request¶
Open in browser:
Features¶
- Real-time display of all registered VMs
- Auto-refresh every 10 seconds
- Live clock
- Status indicators (online/offline/waiting)
- Delete button with confirmation for each VM
- Responsive design
Error Responses¶
| Status Code | Description |
|---|---|
500 Internal Server Error |
Template error when rendering the page |
Implementation: main.go:243-255
Template: templates/index.html
Data Models¶
VMInfo¶
Represents the information of a virtual machine.
type VMInfo struct {
Hostname string `json:"hostname"` // Hostname of the VM
IPAddress string `json:"ip_address"` // IP address
LastSeen time.Time `json:"last_seen"` // Last contact timestamp
Status string `json:"status"` // Status: "online", "offline", "waiting"
Interface string `json:"interface"` // Network interface
}
Config¶
Configuration structure for the API.
type Config struct {
Title string // Application title
BaseURL string // Base URL for UI and API
RegisterURL string // URL for registration endpoint
ListURL string // URL for list endpoint
DeleteBaseURL string // Base URL for delete endpoint
}
Configuration¶
The API can be configured via the following environment variables:
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 8080 |
APP_TITLE |
Application title | "VM Tracker" |
BASE_URL |
Base URL for UI and API | "http://localhost" |
API_BASE_URL |
Base URL for API endpoints | Value of BASE_URL |
REGISTER_URL |
URL for registration endpoint | /api/register |
LIST_URL |
URL for list endpoint | /api/vms |
DELETE_BASE_URL |
Base URL for delete endpoint | /api/vms/ |
Example¶
export PORT=9090
export APP_TITLE="My VM Tracker"
export BASE_URL="https://vmtracker.example.com"
./vm-tracker-api
Status Management¶
Automatic Offline Detection¶
A background process checks the status of all VMs every 30 seconds:
- VMs that have not checked in for more than 60 seconds are marked as
"offline" - VMs that have checked in within the last 60 seconds are
"online"
Implementation: main.go:70-83 (CheckOffline() method)
Status Values¶
| Status | Description |
|---|---|
online |
VM has checked in within the last 60 seconds |
offline |
VM has not checked in for more than 60 seconds |
waiting |
VM was registered but doesn't have a last_seen timestamp yet |
Architecture¶
Thread Safety¶
The API uses sync.RWMutex for thread-safe operations on the VM registry:
- Read Lock: For
GetAll()operations - Write Lock: For
Update()andDelete()operations
Implementation: main.go:30-32
Data Storage¶
- In-Memory: All VM data is stored in RAM
- Non-persistent: Data is lost on restart
- Structure:
map[string]VMInfo(hostname as key)
Error Handling¶
HTTP Status Codes¶
The API uses the following HTTP status codes:
| Status Code | Usage |
|---|---|
200 OK |
Successful request |
400 Bad Request |
Invalid request (missing/invalid JSON, missing required fields) |
404 Not Found |
Resource not found (VM doesn't exist) |
405 Method Not Allowed |
Wrong HTTP method used |
500 Internal Server Error |
Internal server error (template error) |
Error Response Format¶
Errors are returned as plain text:
or
Logging¶
The API logs the following events:
- Startup: Server port, web UI URL and available endpoints
- VM Updates: Registrations and deletions are not logged by default
Example Log on Startup¶
2025/11/03 12:00:00 VM Tracker API starting on port 8080
2025/11/03 12:00:00 Web UI: http://localhost:8080
2025/11/03 12:00:00 API endpoints:
2025/11/03 12:00:00 POST /api/register
2025/11/03 12:00:00 GET /api/vms
2025/11/03 12:00:00 DELETE /api/vms/{hostname}
2025/11/03 12:00:00 GET /download/install
2025/11/03 12:00:00 GET /
Client Installation¶
Automatic Installation¶
-
Download installation script:
-
Make executable and install:
Supported Platforms¶
Operating Systems: - Linux - Darwin (macOS) - Windows
Architectures: - amd64 (x86_64) - arm64 (ARM 64-bit) - armv7 (ARM 32-bit v7) - armv6 (ARM 32-bit v6) - 386 (x86 32-bit)
Systemd Service (Linux)¶
The client is automatically installed as a systemd service:
Service File: /etc/systemd/system/vm-tracker.service
Commands:
# Check status
sudo systemctl status vm-tracker
# Start
sudo systemctl start vm-tracker
# Stop
sudo systemctl stop vm-tracker
# Restart
sudo systemctl restart vm-tracker
# View logs
sudo journalctl -u vm-tracker -f
Example Workflows¶
1. Register VM and Check Status¶
# Register VM
curl -X POST http://localhost:8080/api/register \
-H "Content-Type: application/json" \
-d '{
"hostname": "webserver01",
"ip_address": "192.168.1.100",
"interface": "eth0"
}'
# Check status after 5 seconds
sleep 5
curl http://localhost:8080/api/vms | jq '.[] | select(.hostname=="webserver01")'
2. Find All Offline VMs¶
3. Delete VM¶
# Delete VM
curl -X DELETE http://localhost:8080/api/vms/webserver01
# Verify it's gone
curl http://localhost:8080/api/vms | jq '.[] | select(.hostname=="webserver01")'
4. Install Client on Remote VM¶
# On remote VM via SSH
ssh user@remote-vm
# Download and execute installation script
curl -o vm-tracker-install.sh http://api-server:8080/download/install
chmod +x vm-tracker-install.sh
sudo ./vm-tracker-install.sh
# Check service status
sudo systemctl status vm-tracker
Security Notes¶
Current Security Measures¶
- Path Traversal Protection: Hostnames are sanitized with
path.Clean() - JSON Validation: Inputs are validated
- Required Field Check:
hostnameandip_addressare required
Recommended Additional Measures¶
⚠️ Important: The API currently has no authentication or encryption implemented.
For production environments, it is recommended:
- HTTPS/TLS: Use of a reverse proxy (nginx, Traefik, Caddy)
- Authentication: Implement API keys, JWT tokens or OAuth
- Rate Limiting: Protection against DoS attacks
- CORS: Configure Cross-Origin Resource Sharing
- Input Validation: Additional validation for IP addresses and hostnames
- Persistence: Data storage in database for production use
Example: Nginx Reverse Proxy with TLS¶
server {
listen 443 ssl http2;
server_name vmtracker.example.com;
ssl_certificate /etc/ssl/certs/vmtracker.crt;
ssl_certificate_key /etc/ssl/private/vmtracker.key;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Performance¶
Memory Requirements¶
- Base: ~10 MB for the API itself
- Per VM: ~200 bytes (depending on hostname and IP length)
- Example: 10,000 VMs ≈ 2 MB additional
Latency¶
- Registration: < 1 ms (in-memory operation)
- Listing: < 5 ms for 10,000 VMs
- Deletion: < 1 ms (in-memory operation)
Scaling¶
The current implementation is optimized for small to medium deployments:
- ✅ Good for: 1-10,000 VMs
- ⚠️ Limited for: 10,000-100,000 VMs (in-memory limit)
- ❌ Not suitable for: > 100,000 VMs without database connection
Development¶
Build¶
Build for Different Platforms¶
# Linux amd64
GOOS=linux GOARCH=amd64 go build -o vm-tracker-api main.go
# Linux arm64
GOOS=linux GOARCH=arm64 go build -o vm-tracker-api-arm64 main.go
# macOS
GOOS=darwin GOARCH=amd64 go build -o vm-tracker-api-darwin main.go
# Windows
GOOS=windows GOARCH=amd64 go build -o vm-tracker-api.exe main.go
Tests¶
Overview¶
This test suite provides comprehensive unit tests for the VM Tracker API with a code coverage of 66.4%.
Test Files¶
main_test.go- Complete test suite with unit tests and benchmarks
Running Tests¶
Run All Tests¶
Tests with Coverage¶
Detailed Coverage Report¶
HTML Coverage Report¶
Run Benchmarks¶
Run Specific Tests¶
# Only VMRegistry tests
go test -run TestVMRegistry -v
# Only handler tests
go test -run TestRegisterHandler -v
go test -run TestListHandler -v
go test -run TestDeleteHandler -v
# Only helper function tests
go test -run TestGetenv -v
go test -run TestFirstSet -v
go test -run TestJoinURL -v
go test -run TestLoadConfig -v
Test Categories¶
1. VMRegistry Tests¶
Tests for the thread-safe VM registry:
- TestVMRegistry_Update - Register/update VM
- TestVMRegistry_Update_SetsDefaults - Default values are set
- TestVMRegistry_Update_UpdatesExisting - Update existing VMs
- TestVMRegistry_GetAll_Empty - Empty registry
- TestVMRegistry_GetAll_ReturnsAllVMs - Retrieve all VMs
- TestVMRegistry_GetAll_MarksOffline - Offline status for old VMs
- TestVMRegistry_GetAll_KeepsOnline - Online status for current VMs
- TestVMRegistry_Delete_Success - Successfully delete VM
- TestVMRegistry_Delete_NotFound - Delete non-existent VM
- TestVMRegistry_ThreadSafety - Test concurrency
Coverage: 100% for Update, GetAll, Delete
2. HTTP Handler Tests¶
Tests for all API endpoints:
POST /api/register¶
- TestRegisterHandler_Success - Successful registration
- TestRegisterHandler_DefaultInterface - Default interface is set
- TestRegisterHandler_InvalidJSON - Invalid JSON
- TestRegisterHandler_MissingHostname - Missing hostname
- TestRegisterHandler_MissingIPAddress - Missing IP address
- TestRegisterHandler_WrongMethod - Wrong HTTP method
Coverage: 100%
GET /api/vms¶
- TestListHandler_Success - Successfully list VMs
- TestListHandler_Empty - Empty VM list
- TestListHandler_WrongMethod - Wrong HTTP method
Coverage: 100%
DELETE /api/vms/{hostname}¶
- TestDeleteHandler_Success - Successfully delete VM
- TestDeleteHandler_NotFound - VM not found
- TestDeleteHandler_MissingHostname - Missing hostname
- TestDeleteHandler_PathTraversal - Path traversal protection
- TestDeleteHandler_WrongMethod - Wrong HTTP method
Coverage: 100%
3. Helper Function Tests¶
Tests for helper functions:
- TestGetenv - Environment variables with defaults
- TestFirstSet - Find first non-empty string
- TestJoinURL - Join URL paths
- TestLoadConfig - Load configuration
Coverage: 100%
4. Benchmark Tests¶
Performance tests for critical operations:
- BenchmarkVMRegistry_Update - VM update performance
- BenchmarkVMRegistry_GetAll - VM listing performance (1000 VMs)
- BenchmarkVMRegistry_Delete - VM deletion performance
- BenchmarkRegisterHandler - HTTP register handler performance
- BenchmarkListHandler - HTTP list handler performance (100 VMs)
Coverage Report¶
Function Coverage
----------------------------------------
Update 100.0%
GetAll 100.0%
Delete 100.0%
CheckOffline 0.0% (Background goroutine)
loadConfig 100.0%
getenv 100.0%
firstSet 100.0%
joinURL 100.0%
registerHandler 100.0%
listHandler 100.0%
deleteHandler 100.0%
installScriptHandler 0.0% (Template rendering)
statusHandler 0.0% (Template rendering)
main 0.0% (Entry point)
----------------------------------------
TOTAL 66.4%
Untested Functions¶
The following functions are not tested as they are difficult to test or not critical:
- CheckOffline() - Background goroutine for offline detection
- installScriptHandler() - Template rendering
- statusHandler() - Template rendering
- main() - Main entry point
Test Structure¶
Setup/Teardown¶
Each test initializes a new registry:
Test Conventions¶
- Arrange - Prepare test data
- Act - Call function/handler
- Assert - Verify results
Example Test¶
func TestRegisterHandler_Success(t *testing.T) {
// Arrange
registry = &VMRegistry{vms: make(map[string]*VMInfo)}
reqBody := `{"hostname": "test-vm", "ip_address": "192.168.1.100"}`
req := httptest.NewRequest(http.MethodPost, "/api/register", strings.NewReader(reqBody))
w := httptest.NewRecorder()
// Act
registerHandler(w, req)
// Assert
if w.Code != http.StatusOK {
t.Errorf("Expected status 200, got %d", w.Code)
}
// ... more assertions
}
Benchmark Results¶
Example output (Apple M3):
BenchmarkVMRegistry_Update-8 1000000 1234 ns/op 256 B/op 5 allocs/op
BenchmarkVMRegistry_GetAll-8 50000 34567 ns/op 16384 B/op 10 allocs/op
BenchmarkVMRegistry_Delete-8 2000000 678 ns/op 32 B/op 2 allocs/op
BenchmarkRegisterHandler-8 100000 12345 ns/op 2048 B/op 25 allocs/op
BenchmarkListHandler-8 30000 45678 ns/op 32768 B/op 15 allocs/op
Test Scenarios¶
Edge Cases¶
The tests cover the following edge cases:
- Empty Inputs - Empty registry, empty requests
- Invalid Inputs - Malformed JSON, missing fields
- Security - Path traversal attempts
- Concurrency - Parallel updates/reads/deletes
- Status Transitions - Online/offline based on timestamps
- HTTP Methods - Wrong methods are rejected
Integration Tests¶
Although these are unit tests, some tests cover integration between components:
- Handler → Registry integration
- Configuration → Handler integration
- JSON encoding/decoding
Continuous Integration (CI)¶
GitHub Actions Example¶
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-go@v4
with:
go-version: '1.25'
- run: go test -v -cover ./...
- run: go test -bench=. -benchmem
GitLab CI Example¶
test:
image: golang:1.25
script:
- go test -v -cover ./...
- go test -bench=. -benchmem
coverage: '/coverage: \d+.\d+% of statements/'
Best Practices¶
Test Isolation¶
Each test is isolated and doesn't affect other tests:
Meaningful Error Messages¶
Table-Driven Tests¶
Multiple test cases in one test:
testCases := []struct {
name string
input string
expected string
}{
{"case1", "input1", "expected1"},
{"case2", "input2", "expected2"},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Execute test
})
}
Troubleshooting¶
Tests Fail¶
- Coverage too low: Check environment variables
- Race Conditions: Test with
-raceflag: - Timeout: Set longer timeout:
Verbose Output¶
For detailed output:
The -count=1 flag disables test caching.
Extensions¶
Adding New Tests¶
- Implement function/feature in
main.go - Add test function in
main_test.go - Run test and check coverage
- Add benchmark if needed
Template Handler Tests¶
For installScriptHandler and statusHandler:
func TestInstallScriptHandler(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/download/install", nil)
w := httptest.NewRecorder()
installScriptHandler(w, req)
// Check Content-Type, status, body content
}
Integration with Test Coverage Tools¶
Codecov.io integration:
Summary¶
The test suite provides:
- ✅ 28 Unit Tests for all critical functions
- ✅ 66.4% Code Coverage
- ✅ 100% Coverage for business logic (handlers, registry, helpers)
- ✅ 5 Benchmark Tests for performance monitoring
- ✅ Thread Safety Tests for concurrency
- ✅ Security Tests for path traversal protection
- ✅ Edge Case Tests for robustness
The tests are:
- 🚀 Fast - All tests run in < 100ms
- 🔒 Isolated - No mutual dependencies
- 📊 Measurable - Coverage and benchmarks available
- 🛡️ Secure - Security edge cases covered
- 🔧 Maintainable - Clear structure and conventions
Contact & Support¶
For questions or problems with the tests:
- Check coverage report:
go test -cover - Activate verbose output:
go test -v - Use race detector:
go test -race
Last Updated: 2025-11-03 Test Framework: Go testing package Minimum Go Version: 1.25.2
Version Information¶
- Go Version: 1.25.2 (minimum)
- Dependencies: Only Go Standard Library
- Module:
github.com/rk/vm-tracker-api
Support & Further Information¶
Project Structure¶
vm-tracker-api/
├── main.go # Main application and all handlers
├── go.mod # Go module definition
├── templates/
│ ├── index.html # Web dashboard
│ └── install.sh # Installation script template
└── apiref.md # This API reference
Code References¶
- Main Logic:
main.go - Registration:
main.go:152-175 - Listing:
main.go:177-185 - Deletion:
main.go:187-207 - Installation Script:
main.go:224-241 - Dashboard:
main.go:243-255 - Status Monitor:
main.go:70-83 - Configuration:
main.go:95-114
Changelog¶
Version 1.0.0 (Current)¶
Features: - VM registration and management - Automatic offline detection - Web dashboard with auto-refresh - Multi-platform client installation - Thread-safe in-memory storage
Known Limitations: - No persistence (in-memory only) - No authentication - No TLS/HTTPS - No API versioning - No pagination for large VM lists
Documentation generated on 2025-11-03