KGO is a comprehensive Go-based Kubernetes dashboard that provides REST API and Advanced Terminal User Interface (TUI) for managing Kubernetes resources with enterprise-grade features.
- 🚀 Asynchronous Data Loading: Non-blocking UI with concurrent resource fetching
- 🎨 Advanced TUI: Feature-rich terminal interface with theming, filtering, and multi-view support
- 📊 Full Resource Support: Pods, Deployments, Services, ConfigMaps, and Namespaces
- 🔄 Real-time Updates: WebSocket streaming and background data refresh
- 🏗️ Modular Design: Clean architecture with separate concerns for API and TUI interfaces
- ⚡ Performance Optimized: Concurrent operations and efficient Kubernetes API usage
- Connect to any Kubernetes cluster using kubeconfig
- Dual Interface: REST API and Terminal UI
- Full Resource Support: Pods, Deployments, Services, and ConfigMaps
- Asynchronous Data Loading: Non-blocking UI with concurrent resource fetching
- CRUD operations on all supported resources
- Real-time event streaming via WebSocket
- REST API with Gin
- Advanced TUI: Interactive terminal interface with filtering, theming, and multi-view support
- Proper error handling and logging with klog
- Modular structure
k8s-dashboard/
├── cmd/server/main.go # Main application with TUI mode
├── pkg/
│ ├── api/ # REST API handlers for all resources
│ ├── k8s/client.go # Kubernetes client operations
│ ├── tui/tui.go # Advanced Terminal User Interface
│ ├── config/ # Configuration management
│ ├── metrics/ # Metrics and monitoring
│ └── grpc/ # gRPC support (optional)
├── proto/ # Protocol buffer definitions
├── go.mod # Dependencies
├── test_integration.sh # Integration tests
└── README.md # This file
-
Ensure you have Go installed and a Kubernetes cluster accessible.
-
Clone or navigate to the project directory.
-
Run
go mod tidyto install dependencies. -
Run the server:
go run cmd/server/main.go -kubeconfig=/path/to/kubeconfig
If running in-cluster, omit the
-kubeconfigflag. -
The server will start on port 8080.
./bin/server -tui -kubeconfig=/path/to/kubeconfig- Asynchronous Data Loading: Non-blocking UI with concurrent resource fetching
- Multi-Resource Support: Pods, Deployments, Services, ConfigMaps, and Namespaces
- Advanced Filtering: Regex support, case-sensitive/insensitive, inverse filtering
- Multiple View Modes: List, Details, YAML, Logs, and Relationships views
- Theming: Multiple color themes with customizable appearance (Default, Dark, Light, Solarized, Dracula, Nord, Gruvbox, Monokai, Cyberpunk)
- Split-Pane Layout: Horizontal/vertical split views for detailed inspection
- Real-time Updates: Background data refresh without UI freezing
- Interactive Navigation: Tab-based resource switching, keyboard shortcuts
- Resource Relationships: Visual representation of resource connections
- ↑↓/←→ Navigate through resources
- Enter Show resource details
- Tab Switch between resource types (Pods/Deployments/Services/ConfigMaps/Namespaces)
- r/F5 Refresh data asynchronously
- d Delete resource (with confirmation)
- n Change namespace
- / Advanced search/filtering
- f Clear filters
- v Cycle through view modes (List/Details/YAML/Logs/Relationships)
- y Toggle YAML view in details mode
- j Show logs for pods
- s Toggle split-pane view
- S Switch split layout (horizontal/vertical)
- 1-5 Quick switch to resource types (1: Pods, 2: Deployments, 3: Services, 4: ConfigMaps, 5: Namespaces)
- c Create new pod (basic)
- t/T Cycle through color themes
- h/? Show help
- q Quit
Use the REST API directly for automation and integration:
# List pods
curl http://localhost:8080/api/v1/pods?namespace=default
# Create pod
curl -X POST -H "Content-Type: application/json" \
-d '{"apiVersion":"v1","kind":"Pod","metadata":{"name":"test-pod"},"spec":{"containers":[{"name":"nginx","image":"nginx"}]}}' \
http://localhost:8080/api/v1/pods/default- Real-time pod status display
- Interactive pod details view
- Namespace switching
- Pod deletion with confirmation
- Color-coded interface
GET /api/v1/pods?namespace=default- List pods in namespacePOST /api/v1/pods/:namespace- Create a pod in namespacePUT /api/v1/pods/:namespace/:name- Update a podDELETE /api/v1/pods/:namespace/:name- Delete a podGET /api/v1/pods/watch?namespace=default- Watch pod changes (WebSocket)GET /api/v1/pods/:namespace/:name/logs- Get pod logsGET /api/v1/pods/:namespace/:name/exec- Execute commands in pod
GET /api/v1/deployments?namespace=default- List deployments in namespacePOST /api/v1/deployments/:namespace- Create a deployment in namespacePUT /api/v1/deployments/:namespace/:name- Update a deploymentDELETE /api/v1/deployments/:namespace/:name- Delete a deployment
GET /api/v1/services?namespace=default- List services in namespacePOST /api/v1/services/:namespace- Create a service in namespacePUT /api/v1/services/:namespace/:name- Update a serviceDELETE /api/v1/services/:namespace/:name- Delete a service
GET /api/v1/configmaps?namespace=default- List configmaps in namespacePOST /api/v1/configmaps/:namespace- Create a configmap in namespacePUT /api/v1/configmaps/:namespace/:name- Update a configmapDELETE /api/v1/configmaps/:namespace/:name- Delete a configmap
GET /api/v1/namespaces- List all namespaces (gRPC only, TUI supported)
GET /api/v1/metrics/cluster- Get cluster-wide metricsGET /api/v1/metrics/namespace/:namespace- Get namespace-specific metrics
Use fetch for REST API calls:
// List pods
fetch('/api/v1/pods?namespace=default')
.then(res => res.json())
.then(data => setPods(data.pods));
// Create pod
const podSpec = {
apiVersion: 'v1',
kind: 'Pod',
metadata: { name: 'my-pod' },
spec: {
containers: [{
name: 'my-container',
image: 'nginx'
}]
}
};
fetch('/api/v1/pods/default', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(podSpec)
});
// Update pod
fetch('/api/v1/pods/default/my-pod', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(updatedPodSpec)
});
// Delete pod
fetch('/api/v1/pods/default/my-pod', {
method: 'DELETE'
});Use WebSocket for real-time updates:
const ws = new WebSocket('ws://localhost:8080/api/v1/pods/watch?namespace=default');
ws.onopen = () => {
console.log('Connected to pod watcher');
};
ws.onmessage = (event) => {
const change = JSON.parse(event.data);
console.log('Pod change:', change.type, change.object.metadata.name);
// Update UI based on change.type (ADDED, MODIFIED, DELETED)
};
ws.onclose = () => {
console.log('Disconnected from pod watcher');
};The TUI implements a sophisticated asynchronous data loading system to prevent UI freezing:
- Concurrent Goroutines: Each resource type loads in parallel goroutines
- Channel Communication: Thread-safe data updates via Go channels
- Background Processing: Dedicated goroutine handles data updates
- Loading State Management: Counter-based tracking of completion
- Non-blocking UI: User interactions remain responsive during data loading
- Responsive Interface: UI never freezes during data operations
- Concurrent Loading: All resources load simultaneously for faster overall loading
- Error Resilience: Individual failures don't block other resource loading
- Real-time Updates: Data refreshes in background without user intervention
The application already supports Pods, Deployments, Services, and ConfigMaps. To add support for additional resources (e.g., StatefulSets, Jobs, etc.):
- Add corresponding functions in
pkg/k8s/client.go(e.g.,ListStatefulSets,CreateStatefulSet) - Add handlers in
pkg/api/directory - Add routes in
cmd/server/main.go - Update TUI in
pkg/tui/tui.goto handle the new resource type - Update protobuf definitions in
proto/k8s.protoif using gRPC
Currently supports kubeconfig-based authentication. For production:
- Use Kubernetes service account tokens
- Implement JWT authentication
- Add middleware for authorization
Run unit tests with mocked Kubernetes client:
go test ./... -vFor full integration testing with a real Kubernetes cluster:
-
Start the server:
./bin/server -kubeconfig=/path/to/kubeconfig
-
Run the integration test script:
chmod +x test_integration.sh ./test_integration.sh
The integration script tests all CRUD operations and verifies responses.
# List resources
curl http://localhost:8080/api/v1/pods?namespace=default
curl http://localhost:8080/api/v1/deployments?namespace=default
curl http://localhost:8080/api/v1/services?namespace=default
curl http://localhost:8080/api/v1/configmaps?namespace=default
# Create resources
curl -X POST -H "Content-Type: application/json" \
-d '{"apiVersion":"v1","kind":"Pod","metadata":{"name":"test-pod"},"spec":{"containers":[{"name":"nginx","image":"nginx"}]}}' \
http://localhost:8080/api/v1/pods/default
curl -X POST -H "Content-Type: application/json" \
-d '{"apiVersion":"v1","kind":"ConfigMap","metadata":{"name":"test-config"},"data":{"key":"value"}}' \
http://localhost:8080/api/v1/configmaps/default
# Update resources
curl -X PUT -H "Content-Type: application/json" \
-d '{"apiVersion":"v1","kind":"Pod","metadata":{"name":"test-pod","labels":{"app":"test"}},"spec":{"containers":[{"name":"nginx","image":"nginx"}]}}' \
http://localhost:8080/api/v1/pods/default/test-pod
# Delete resources
curl -X DELETE http://localhost:8080/api/v1/pods/default/test-pod
curl -X DELETE http://localhost:8080/api/v1/configmaps/default/test-configTest real-time pod watching:
const ws = new WebSocket('ws://localhost:8080/api/v1/pods/watch?namespace=default');
ws.onmessage = (event) => console.log('Pod change:', JSON.parse(event.data));✅ FULLY FUNCTIONAL - The gRPC implementation has been completed and tested.
- ✅ Missing Conversion Functions: Added
convertProtoToPod,convertProtoToDeployment,convertProtoToService,convertProtoToConfigMap - ✅ Type Consistency: All client methods now return Kubernetes types instead of protobuf types
- ✅ Import Dependencies: Added required imports (
appsv1,metav1) - ✅ Protobuf Generation: Regenerated fresh protobuf Go files with correct type definitions
- ✅ Compilation: All gRPC packages now compile successfully
The project now supports two architectural approaches:
- Uses goroutines + channels for async UI
- No network overhead
- Simpler deployment
- Status: ✅ Active
- Distributed architecture support
- Network-enabled operations
- Multi-server scalability
- Status: ✅ Ready for use
To use gRPC instead of direct client calls:
-
Modify
cmd/server/main.go:// Start gRPC server grpcServer := grpc.NewServer(clientset) go grpcServer.Start(":50051") // Use gRPC client in TUI grpcClient, _ := grpc.NewClient("localhost:50051") tui, _ := tui.NewTUI(grpcClient)
-
Benefits of gRPC mode:
- Separate TUI and API server processes
- Load balancing across multiple API servers
- Network-based architecture
- Better for microservices deployments
- Asynchronous Architecture: Non-blocking data loading prevents UI freezing under load
- Resource Scaling: Support for multiple resource types with efficient concurrent loading
- Add TLS/HTTPS for secure communication
- Implement rate limiting for API endpoints
- Add comprehensive error handling and logging with klog
- Use structured logging with appropriate log levels
- Add metrics and monitoring (already partially implemented in
pkg/metrics/) - Implement graceful shutdown handling
- Consider connection pooling for Kubernetes API calls
- Add caching layer for frequently accessed resources
- Implement authentication and authorization middleware