This guide walks through setting up a local development environment for SubNetree.
- Go 1.25+ -- Download
- Git -- Download
- Make -- Included on Linux/macOS; on Windows, use MSYS2 or WSL
- protoc (optional) -- Only needed if modifying gRPC definitions
Verify your Go installation:
go version
# Expected: go1.25.x or latergit clone https://github.com/HerbHall/subnetree.git
cd subnetree
make buildThis produces two binaries in bin/:
subnetree-- the serverscout-- the lightweight agent
cmd/
subnetree/ # Server entry point
scout/ # Agent entry point
internal/
config/ # Viper-backed Config implementation
event/ # In-memory EventBus
registry/ # Plugin lifecycle management
recon/ # Network discovery module
pulse/ # Monitoring module
dispatch/ # Agent management module
vault/ # Credential storage module
gateway/ # Remote access module
scout/ # Agent runtime
server/ # HTTP server and config loading
version/ # Build-time version injection
pkg/
plugin/ # Public plugin SDK (Apache 2.0)
models/ # Shared data types
api/
proto/v1/ # gRPC service definitions
docs/
adr/ # Architecture Decision Records
guides/ # Developer guides (this file)
requirements/ # Split requirement specifications
# With defaults (port 8080, SQLite in ./data/)
make run-server
# Or directly
./bin/subnetree
# With a config file
./bin/subnetree --config ./configs/subnetree.yaml
# Print version
./bin/subnetree --version# With defaults (connects to localhost:9090)
make run-scout
# Or with options
./bin/scout --server localhost:9090 --interval 30SubNetree uses Viper for configuration. Sources (in priority order):
- Environment variables with
NV_prefix (e.g.,NV_SERVER_PORT=9090) - Config file (
subnetree.yamlin current dir,./configs/, or/etc/subnetree/) - Built-in defaults
Example config file:
server:
host: 0.0.0.0
port: 8080
data_dir: ./data
logging:
level: info
format: json
plugins:
recon:
enabled: true
pulse:
enabled: true
dispatch:
enabled: true
vault:
enabled: true
gateway:
enabled: false # Requires Apache Guacamole# Run all tests
make test
# Run with race detector (requires CGo / Linux)
make test-race
# Run with coverage report
make test-coverage
# Run linter (go vet)
make lintAll plugins implement the plugin.Plugin interface from pkg/plugin/:
import "github.com/HerbHall/subnetree/pkg/plugin"
type MyPlugin struct{}
func (p *MyPlugin) Info() plugin.PluginInfo {
return plugin.PluginInfo{
Name: "myplugin",
Version: "0.1.0",
APIVersion: plugin.APIVersionCurrent,
}
}
func (p *MyPlugin) Init(ctx context.Context, deps plugin.Dependencies) error { ... }
func (p *MyPlugin) Start(ctx context.Context) error { ... }
func (p *MyPlugin) Stop(ctx context.Context) error { ... }Optional interfaces (implement only what you need):
plugin.HTTPProvider-- expose REST routesplugin.HealthChecker-- report health statusplugin.EventSubscriber-- declare event subscriptionsplugin.Validator-- validate config post-initplugin.Reloadable-- support hot config reload
Register plugins in cmd/subnetree/main.go.
- Run
gofmtbefore committing - Follow standard Go conventions
- Use
context.Contextfor cancellation - Return errors; do not panic
- Use table-driven tests
- Conventional commits:
feat:,fix:,refactor:,docs:,test:,chore:
| Target | Description |
|---|---|
make build |
Build server and agent |
make build-server |
Build server only |
make build-scout |
Build agent only |
make test |
Run all tests |
make test-race |
Run tests with race detector |
make test-coverage |
Run tests with coverage report |
make lint |
Run go vet |
make run-server |
Build and run server |
make run-scout |
Build and run agent |
make proto |
Regenerate protobuf code |
make clean |
Remove build artifacts |
make license-check |
Verify dependency licenses |