-
Notifications
You must be signed in to change notification settings - Fork 138
Expand file tree
/
Copy pathMakefile
More file actions
324 lines (271 loc) · 12 KB
/
Copy pathMakefile
File metadata and controls
324 lines (271 loc) · 12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
.PHONY: build install clean dev frontend backend test test-e2e test-chart lint help restart restart-fe kill watch-backend watch-frontend
.PHONY: release release-binaries-dry docker docker-test docker-multiarch docker-push
.PHONY: desktop desktop-binary desktop-dev desktop-package-darwin desktop-package-windows desktop-package-linux
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
LDFLAGS := -X main.version=$(VERSION)
DOCKER_REPO ?= ghcr.io/skyhook-io/radar
RADAR_FLAGS ?=
PORT ?= 9280
## Quick in-cluster test deploy (full build: frontend + embed + Go binary)
# Usage: make deploy-test (or make deploy-test TEST_IMAGE=... CLUSTER_NS=... CLUSTER_DEPLOY=...)
TEST_IMAGE ?= gcr.io/koalabackend/radar:auth-rbac
CLUSTER_NS ?= radar
CLUSTER_DEPLOY ?= radar
deploy-test: frontend embed
@echo "=== Fast test deploy: Go build → push → rollout ==="
@echo "Building Go binary for linux/amd64..."
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o /tmp/radar-linux ./cmd/explorer
@echo "Building minimal Docker image..."
@echo 'FROM gcr.io/distroless/static-debian12:nonroot' > /tmp/Dockerfile.test
@echo 'COPY radar-linux /app/radar' >> /tmp/Dockerfile.test
@echo 'ENTRYPOINT ["/app/radar"]' >> /tmp/Dockerfile.test
docker build -t $(TEST_IMAGE) -f /tmp/Dockerfile.test /tmp
docker push $(TEST_IMAGE)
kubectl rollout restart deploy/$(CLUSTER_DEPLOY) -n $(CLUSTER_NS)
kubectl rollout status deploy/$(CLUSTER_DEPLOY) -n $(CLUSTER_NS) --timeout=60s
@echo "=== Done. Tail logs: kubectl logs -n $(CLUSTER_NS) -l app.kubernetes.io/name=$(CLUSTER_DEPLOY) -f ==="
# Build a probe image from the CURRENT code and load it into a kind cluster, for
# developing the in-cluster reachability probe. A -dirty local build's version is
# not a published tag, so the default image won't exist - load a local one and run
# radar with --reachability-image $(PROBE_IMAGE). Binary path /radar + ENTRYPOINT
# match the official image so the probe Job's `["/radar","probe",...]` command works.
KIND_CLUSTER ?= test
PROBE_IMAGE ?= radar-probe:dev
kind-load-probe:
@echo "Building probe binary for linux/$$(go env GOARCH)..."
GOOS=linux GOARCH=$$(go env GOARCH) CGO_ENABLED=0 go build -ldflags "$(LDFLAGS)" -o /tmp/radar-probe-bin ./cmd/explorer
@echo 'FROM gcr.io/distroless/static-debian12:nonroot' > /tmp/Dockerfile.probe
@echo 'COPY radar-probe-bin /radar' >> /tmp/Dockerfile.probe
@echo 'ENTRYPOINT ["/radar"]' >> /tmp/Dockerfile.probe
docker build -t $(PROBE_IMAGE) -f /tmp/Dockerfile.probe /tmp
kind load docker-image $(PROBE_IMAGE) --name $(KIND_CLUSTER)
@echo "Loaded $(PROBE_IMAGE) into kind/$(KIND_CLUSTER). Run radar with: --reachability-image $(PROBE_IMAGE)"
## Build targets
# Build the complete application (frontend + embedded binary)
build: frontend embed backend
@echo "Build complete: ./radar"
# Build and install to /usr/local/bin
install: build
@echo "Installing to /usr/local/bin/kubectl-radar..."
@cp radar /usr/local/bin/kubectl-radar || sudo cp radar /usr/local/bin/kubectl-radar
@echo "Installed! Run 'kubectl radar' or 'kubectl-radar'"
# Build Go backend with embedded frontend
backend:
@echo "Building Go backend..."
go build -ldflags "$(LDFLAGS)" -o radar ./cmd/explorer
# Build frontend (auto-installs deps if needed)
frontend:
@echo "Building frontend..."
@test -d web/node_modules || (echo "Installing npm dependencies..." && cd web && npm install)
cd web && npm run build
# Copy built frontend to embed directory
embed:
@echo "Copying frontend to static..."
rm -rf internal/static/dist
@mkdir -p internal/static/dist
cp -r web/dist/* internal/static/dist/
## Development targets
# Quick rebuild and restart
restart: frontend embed backend kill
@sleep 1
./radar --kubeconfig ~/.kube/config --no-browser --port $(PORT) $(RADAR_FLAGS) &
@sleep 4
@echo "Server running at http://localhost:$(PORT)"
# Frontend-only rebuild and restart (faster - no Go recompile, serves from web/dist via --dev)
restart-fe: frontend kill
@sleep 1
./radar --dev --kubeconfig ~/.kube/config --no-browser --port $(PORT) $(RADAR_FLAGS) &
@sleep 4
@echo "Server running at http://localhost:$(PORT)"
# Hot reload development (run both in separate terminals)
# Terminal 1: make watch-frontend
# Terminal 2: make watch-backend
dev:
@echo "=== Development Mode ==="
@echo ""
@echo "Run these in separate terminals:"
@echo " Terminal 1: make watch-frontend (Vite dev server on :9273)"
@echo " Terminal 2: make watch-backend (Go with air on :9280)"
@echo ""
@echo "Frontend proxies API calls to backend automatically."
# Frontend with Vite hot reload
watch-frontend:
cd web && npm run dev
# Backend with air hot reload
# Pass extra flags: make watch-backend RADAR_FLAGS="--fake-in-cluster"
watch-backend:
@command -v air >/dev/null 2>&1 || { echo "Installing air..."; go install github.com/air-verse/air@latest; }
air -- $(RADAR_FLAGS)
# Run built binary
run:
./radar --kubeconfig ~/.kube/config
# Run in dev mode (serve frontend from web/dist instead of embedded)
run-dev:
./radar --kubeconfig ~/.kube/config --dev
## Utility targets
# Kill any running radar process (on configured port and by process name)
kill:
@lsof -ti:$(PORT) | xargs kill -9 2>/dev/null || true
@pkill -9 -f './radar' 2>/dev/null || true
# Install all dependencies
deps:
go mod download
go mod tidy
cd web && npm install
# Install dev tools
install-tools:
go install github.com/air-verse/air@latest
cd web && npm install
# Clean build artifacts
clean:
rm -f radar radar-desktop
rm -rf web/dist
rm -f internal/static/dist/index.html
rm -rf internal/static/dist/assets
# Run tests
test:
go test -v ./...
# Run e2e tests against the current kubeconfig cluster (on-demand, not in CI)
test-e2e:
go test -tags e2e -v -timeout 5m ./internal/k8s/
# Smoke-test the Helm chart's template rendering (requires `helm` on PATH)
test-chart:
./scripts/test-chart.sh
# Bootstrap a kind cluster pre-loaded with curated GitOps scenarios
# (Argo CD + Flux + healthy/suspended/app-of-apps/ApplicationSet/etc).
# Useful for visual-testing GitOps UI changes against realistic state.
# See scripts/gitops-demo/README.md for the full coverage matrix.
gitops-demo:
./scripts/gitops-demo.sh up
gitops-demo-down:
./scripts/gitops-demo.sh down
gitops-demo-status:
./scripts/gitops-demo.sh status
gitops-demo-drift:
./scripts/gitops-demo.sh drift
# Bootstrap a kind cluster pre-loaded with curated Crossplane fixtures
# (core + provider-kubernetes + function-patch-and-transform + XRD/Composition/XRs).
# Useful for visual-testing Crossplane UI changes against realistic state.
# See scripts/crossplane-demo/README.md for the full coverage matrix.
crossplane-demo:
./scripts/crossplane-demo.sh up
crossplane-demo-down:
./scripts/crossplane-demo.sh down
crossplane-demo-status:
./scripts/crossplane-demo.sh status
# Run linter
lint:
go vet ./...
# Type check frontend
tsc:
cd web && npm run tsc
# Format code
fmt:
go fmt ./...
# ============================================================================
# Docker & Helm
# ============================================================================
# Docker build (single arch, for local testing)
# Uses --target full to build from source (the default 'release' target requires pre-built binaries)
docker:
docker build --target full -t $(DOCKER_REPO):$(VERSION) -t $(DOCKER_REPO):latest .
# Test Docker image with read-only filesystem (simulates in-cluster with readOnlyRootFilesystem)
# Requires ~/.kube/config for cluster access; runs on port 9280
docker-test: docker
@echo "Starting Radar with read-only filesystem (simulating in-cluster)..."
@echo "Press Ctrl+C to stop"
docker run --rm \
--read-only \
--tmpfs /tmp \
-e HELM_CACHE_HOME=/tmp/helm/cache \
-e HELM_CONFIG_HOME=/tmp/helm/config \
-e HELM_DATA_HOME=/tmp/helm/data \
-v $(HOME)/.kube/config:/home/nonroot/.kube/config:ro \
-p 9280:9280 \
$(DOCKER_REPO):$(VERSION) --no-browser
# Docker build multi-arch (amd64 + arm64, for production)
docker-multiarch:
@docker buildx inspect radar-builder &>/dev/null || docker buildx create --name radar-builder --use
docker buildx use radar-builder
docker buildx build \
--platform linux/amd64,linux/arm64 \
--build-arg VERSION=$(VERSION) \
-t $(DOCKER_REPO):$(VERSION) \
-t $(DOCKER_REPO):latest \
--push \
.
docker-push:
docker push $(DOCKER_REPO):$(VERSION)
docker push $(DOCKER_REPO):latest
# ============================================================================
# Desktop (Wails) Targets
# ============================================================================
# Build desktop app: frontend + Go desktop binary
desktop: frontend embed desktop-binary
@echo "Desktop build complete: ./radar-desktop"
# Build desktop binary only (assumes frontend is already in internal/static/dist)
desktop-binary:
@echo "Building desktop binary..."
CGO_ENABLED=1 CGO_LDFLAGS="-framework UniformTypeIdentifiers" go build -tags production -ldflags "$(LDFLAGS)" -o radar-desktop ./cmd/desktop
# Run desktop app in Wails dev mode with Go hot reload.
# wails.json lives in cmd/desktop/ (Wails requires it next to the main package).
# Requires wails CLI: go install github.com/wailsapp/wails/v2/cmd/wails@latest
desktop-dev:
@command -v wails >/dev/null 2>&1 || { echo "Error: wails CLI not found. Install with: go install github.com/wailsapp/wails/v2/cmd/wails@latest"; exit 1; }
cd cmd/desktop && wails dev -ldflags "$(LDFLAGS)"
# Package macOS .app bundle
desktop-package-darwin:
@command -v wails >/dev/null 2>&1 || { echo "Error: wails CLI not found"; exit 1; }
cd cmd/desktop && wails build -platform darwin/universal -ldflags "$(LDFLAGS)"
# Package Windows .exe
desktop-package-windows:
@command -v wails >/dev/null 2>&1 || { echo "Error: wails CLI not found"; exit 1; }
cd cmd/desktop && wails build -platform windows/amd64 -ldflags "$(LDFLAGS)"
# Package Linux binary
desktop-package-linux:
@command -v wails >/dev/null 2>&1 || { echo "Error: wails CLI not found"; exit 1; }
cd cmd/desktop && wails build -platform linux/amd64 -ldflags "$(LDFLAGS)"
# ============================================================================
# Release Targets
# ============================================================================
# Dry run goreleaser (no publish)
release-binaries-dry:
@command -v goreleaser >/dev/null 2>&1 || { echo "Error: goreleaser not found"; exit 1; }
goreleaser release --snapshot --clean
# Interactive release (remote via CI or local)
release:
./scripts/release.sh
# ============================================================================
# Help
# ============================================================================
help:
@echo "Radar - Kubernetes Cluster Visualization"
@echo ""
@echo "Development:"
@echo " make build - Build CLI binary (frontend + embedded)"
@echo " make watch-frontend - Vite dev server with HMR (port 9273)"
@echo " make watch-backend - Go with air hot reload (port 9280)"
@echo " make run - Run built binary"
@echo " make test - Run tests"
@echo ""
@echo "Desktop:"
@echo " make desktop - Build desktop app (frontend + Wails binary)"
@echo " make desktop-binary - Build desktop binary only"
@echo " make desktop-dev - Run desktop in Wails dev mode"
@echo " make desktop-package-darwin - Package macOS .app bundle"
@echo ""
@echo "Docker & In-Cluster:"
@echo " make docker - Build Docker image (local arch)"
@echo " make docker-test - Build and run with read-only filesystem (simulates in-cluster)"
@echo " make docker-multiarch - Build multi-arch image (amd64+arm64) and push"
@echo " make docker-push - Push to GHCR"
@echo ""
@echo "Release:"
@echo " make release - Interactive release (remote via CI or local)"
@echo " make release-binaries-dry - Dry run goreleaser (no publish)"
@echo ""
@echo "Utility:"
@echo " make deps - Install all dependencies"
@echo " make install - Install CLI to /usr/local/bin"
@echo " make clean - Clean build artifacts"
@echo " make kill - Kill running server"