mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-02-14 18:09:51 +00:00
* Add MCP (Model Context Protocol) server command Implement `kubeshark mcp` command that runs an MCP server over stdio, enabling AI assistants to query Kubeshark's network visibility data. Features: - MCP protocol implementation (JSON-RPC 2.0 over stdio) - Dynamic tool discovery from Hub's /api/mcp endpoint - Local cluster management tools (check_kubeshark_status, start_kubeshark, stop_kubeshark) - --url flag for direct connection to existing Kubeshark deployment - --kubeconfig flag for proxy mode with kubectl - --allow-destructive flag to enable start/stop operations (safe by default) - --list-tools flag to display available tools - --mcp-config flag to generate MCP client configuration - 5-minute cache TTL for Hub tools/prompts - Prompts for common analysis tasks * Address code review comments for MCP implementation - Add 30s timeout to HTTP client to prevent hanging requests - Add scanner.Err() check after stdin processing loop - Close HTTP response bodies to prevent resource leaks - Add goroutine to wait on started process to prevent zombies - Simplify polling loop by removing ineffective context check - Advertise check_kubeshark_status in URL mode (was callable but hidden) - Update documentation to clarify URL mode only disables start/stop * Fix lint errors in mcpRunner.go - Use type conversion instead of struct literals for hubMCPTool -> mcpTool and hubMCPPromptArg -> mcpPromptArg (S1016 gosimple) - Lowercase error string to follow Go conventions (ST1005 staticcheck) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add MCP server unit tests Comprehensive unit tests for the MCP server implementation: - Protocol tests (initialize, tools/list, tools/call, prompts/list, prompts/get) - Tool tests (check_kubeshark_status, start_kubeshark, stop_kubeshark) - Hub integration tests (tool fetching, caching, prompt handling) - Error handling tests - Edge case tests * Fix MCP unit tests to use correct /tools/call endpoint - Update all Hub tool tests to use POST /tools/call endpoint instead of individual paths like /workloads, /calls, /stats - Verify arguments in POST body instead of URL query parameters - Add newMockHubHandler helper for proper Hub endpoint mocking - Split TestMCP_ToolsList into three tests: - TestMCP_ToolsList_CLIOnly: Tests without Hub backend - TestMCP_ToolsList_WithDestructive: Tests with destructive flag - TestMCP_ToolsList_WithHubBackend: Tests with mock Hub providing tools - Fix TestMCP_FullConversation to mock Hub MCP endpoint correctly - Rename URL encoding tests for clarity - All tests now correctly reflect the implementation 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Simplify MCP unit tests - Remove section header comments (10 headers) - Consolidate similar tests using table-driven patterns - Simplify test assertions with more concise checks - Combine edge case tests into single test function - Reduce verbose test structures Total reduction: 1477 → 495 lines (66%) All 24 tests still pass. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add MCP integration test framework Add integration tests that run against a real Kubernetes cluster: - MCP protocol tests (initialize, tools/list, prompts/list) - Cluster management tests (check_kubeshark_status, start_kubeshark, stop_kubeshark) - Full lifecycle test (check -> start -> check -> stop -> check) - API tools tests (list_workloads, list_api_calls, get_api_stats) Also includes: - Makefile targets for running integration tests - Test helper functions (startMCPSession, cleanupKubeshark, etc.) - Documentation (README.md, TEMPLATE.md, ISSUE_TEMPLATE.md) * Address review comments on integration tests Makefile: - Use unique temporary files (mktemp) instead of shared /tmp/integration-test.log to prevent race conditions when multiple test targets run concurrently - Remove redundant test-integration-verbose target (test-integration already uses -v) - Add cleanup (rm -f) for temporary log files integration/mcp_test.go: - Capture stderr from MCP server for debugging failures - Add getStderr() method to mcpSession for accessing captured stderr - Fix potential goroutine leak by adding return statements after t.Fatalf - Remove t.Run subtests in TestMCP_APIToolsRequireKubeshark to clarify sequential execution with shared session - Fix benchmark to use getKubesharkBinary helper for consistency - Add Kubernetes cluster check to benchmark (graceful skip) - Add proper error handling for pipe creation in benchmark - Remove unnecessary bytes import workaround (now actually used for stderr) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Simplify and clean up MCP integration tests - Remove unrelated L4 viewer files (1239 lines) - Remove template/issue documentation files (419 lines) - Trim README to essential content only - Remove TEMPLATE comments from common_test.go - Add initialize() helper to reduce test boilerplate - Add hasKubernetesCluster() helper for benchmarks - Simplify all test functions with consistent patterns Total reduction: 2964 → 866 lines (71%) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> * Add MCP registry metadata for official registry submission Add metadata files for submitting Kubeshark MCP server to the official MCP registry at registry.modelcontextprotocol.io: - mcp/server.json: Registry metadata with tools, prompts, and configuration - mcp/README.md: MCP server documentation and usage guide --------- Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
284 lines
11 KiB
Makefile
284 lines
11 KiB
Makefile
SHELL=/bin/bash
|
|
|
|
.PHONY: help
|
|
.DEFAULT_GOAL := build
|
|
.ONESHELL:
|
|
|
|
SUFFIX=$(GOOS)_$(GOARCH)
|
|
COMMIT_HASH=$(shell git rev-parse HEAD)
|
|
GIT_BRANCH=$(shell git branch --show-current | tr '[:upper:]' '[:lower:]')
|
|
GIT_VERSION=$(shell git branch --show-current | tr '[:upper:]' '[:lower:]')
|
|
BUILD_TIMESTAMP=$(shell date +%s)
|
|
export VER?=0.0.0
|
|
|
|
help: ## Print this help message.
|
|
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
|
|
|
build-debug: ## Build for debugging.
|
|
export CGO_ENABLED=1
|
|
export GCLFAGS='-gcflags="all=-N -l"'
|
|
${MAKE} build-base
|
|
|
|
build: ## Build.
|
|
export CGO_ENABLED=0
|
|
export LDFLAGS_EXT='-extldflags=-static -s -w'
|
|
${MAKE} build-base
|
|
|
|
build-race: ## Build with -race flag.
|
|
export CGO_ENABLED=1
|
|
export GCLFAGS='-race'
|
|
export LDFLAGS_EXT='-extldflags=-static -s -w'
|
|
${MAKE} build-base
|
|
|
|
build-base: ## Build binary (select the platform via GOOS / GOARCH env variables).
|
|
go build ${GCLFAGS} -ldflags="${LDFLAGS_EXT} \
|
|
-X 'github.com/kubeshark/kubeshark/misc.GitCommitHash=$(COMMIT_HASH)' \
|
|
-X 'github.com/kubeshark/kubeshark/misc.Branch=$(GIT_BRANCH)' \
|
|
-X 'github.com/kubeshark/kubeshark/misc.BuildTimestamp=$(BUILD_TIMESTAMP)' \
|
|
-X 'github.com/kubeshark/kubeshark/misc.Platform=$(SUFFIX)' \
|
|
-X 'github.com/kubeshark/kubeshark/misc.Ver=$(VER)'" \
|
|
-o bin/kubeshark_$(SUFFIX) kubeshark.go && \
|
|
cd bin && shasum -a 256 kubeshark_${SUFFIX} > kubeshark_${SUFFIX}.sha256
|
|
|
|
build-brew: ## Build binary for brew/core CI
|
|
go build ${GCLFAGS} -ldflags="${LDFLAGS_EXT} \
|
|
-X 'github.com/kubeshark/kubeshark/misc.GitCommitHash=$(COMMIT_HASH)' \
|
|
-X 'github.com/kubeshark/kubeshark/misc.Branch=$(GIT_BRANCH)' \
|
|
-X 'github.com/kubeshark/kubeshark/misc.BuildTimestamp=$(BUILD_TIMESTAMP)' \
|
|
-X 'github.com/kubeshark/kubeshark/misc.Platform=$(SUFFIX)' \
|
|
-X 'github.com/kubeshark/kubeshark/misc.Ver=$(VER)'" \
|
|
-o kubeshark kubeshark.go
|
|
|
|
build-windows-amd64:
|
|
$(MAKE) build GOOS=windows GOARCH=amd64 && \
|
|
mv ./bin/kubeshark_windows_amd64 ./bin/kubeshark.exe && \
|
|
rm bin/kubeshark_windows_amd64.sha256 && \
|
|
cd bin && shasum -a 256 kubeshark.exe > kubeshark.exe.sha256
|
|
|
|
build-all: ## Build for all supported platforms.
|
|
export CGO_ENABLED=0
|
|
echo "Compiling for every OS and Platform" && \
|
|
mkdir -p bin && sed s/_VER_/$(VER)/g RELEASE.md.TEMPLATE > bin/README.md && \
|
|
$(MAKE) build GOOS=linux GOARCH=amd64 && \
|
|
$(MAKE) build GOOS=linux GOARCH=arm64 && \
|
|
$(MAKE) build GOOS=darwin GOARCH=amd64 && \
|
|
$(MAKE) build GOOS=darwin GOARCH=arm64 && \
|
|
$(MAKE) build-windows-amd64 && \
|
|
echo "---------" && \
|
|
find ./bin -ls
|
|
|
|
clean: ## Clean all build artifacts.
|
|
go clean
|
|
rm -rf ./bin/*
|
|
|
|
test: ## Run cli tests.
|
|
@go test ./... -coverpkg=./... -race -coverprofile=coverage.out -covermode=atomic
|
|
|
|
test-integration: ## Run integration tests (requires Kubernetes cluster).
|
|
@echo "Running integration tests..."
|
|
@LOG_FILE=$$(mktemp /tmp/integration-test.XXXXXX.log); \
|
|
go test -tags=integration -timeout $${INTEGRATION_TIMEOUT:-5m} -v ./integration/... 2>&1 | tee $$LOG_FILE; \
|
|
status=$$?; \
|
|
echo ""; \
|
|
echo "========================================"; \
|
|
echo " INTEGRATION TEST SUMMARY"; \
|
|
echo "========================================"; \
|
|
grep -E "^(--- PASS|--- FAIL|--- SKIP)" $$LOG_FILE || true; \
|
|
echo "----------------------------------------"; \
|
|
pass=$$(grep -c "^--- PASS" $$LOG_FILE 2>/dev/null || true); \
|
|
fail=$$(grep -c "^--- FAIL" $$LOG_FILE 2>/dev/null || true); \
|
|
skip=$$(grep -c "^--- SKIP" $$LOG_FILE 2>/dev/null || true); \
|
|
echo "PASSED: $${pass:-0}"; \
|
|
echo "FAILED: $${fail:-0}"; \
|
|
echo "SKIPPED: $${skip:-0}"; \
|
|
echo "========================================"; \
|
|
rm -f $$LOG_FILE; \
|
|
exit $$status
|
|
|
|
test-integration-mcp: ## Run only MCP integration tests.
|
|
@echo "Running MCP integration tests..."
|
|
@LOG_FILE=$$(mktemp /tmp/integration-test.XXXXXX.log); \
|
|
go test -tags=integration -timeout $${INTEGRATION_TIMEOUT:-5m} -v ./integration/ -run "MCP" 2>&1 | tee $$LOG_FILE; \
|
|
status=$$?; \
|
|
echo ""; \
|
|
echo "========================================"; \
|
|
echo " INTEGRATION TEST SUMMARY"; \
|
|
echo "========================================"; \
|
|
grep -E "^(--- PASS|--- FAIL|--- SKIP)" $$LOG_FILE || true; \
|
|
echo "----------------------------------------"; \
|
|
pass=$$(grep -c "^--- PASS" $$LOG_FILE 2>/dev/null || true); \
|
|
fail=$$(grep -c "^--- FAIL" $$LOG_FILE 2>/dev/null || true); \
|
|
skip=$$(grep -c "^--- SKIP" $$LOG_FILE 2>/dev/null || true); \
|
|
echo "PASSED: $${pass:-0}"; \
|
|
echo "FAILED: $${fail:-0}"; \
|
|
echo "SKIPPED: $${skip:-0}"; \
|
|
echo "========================================"; \
|
|
rm -f $$LOG_FILE; \
|
|
exit $$status
|
|
|
|
test-integration-short: ## Run quick integration tests (skips long-running tests).
|
|
@echo "Running quick integration tests..."
|
|
@LOG_FILE=$$(mktemp /tmp/integration-test.XXXXXX.log); \
|
|
go test -tags=integration -timeout $${INTEGRATION_TIMEOUT:-2m} -short -v ./integration/... 2>&1 | tee $$LOG_FILE; \
|
|
status=$$?; \
|
|
echo ""; \
|
|
echo "========================================"; \
|
|
echo " INTEGRATION TEST SUMMARY"; \
|
|
echo "========================================"; \
|
|
grep -E "^(--- PASS|--- FAIL|--- SKIP)" $$LOG_FILE || true; \
|
|
echo "----------------------------------------"; \
|
|
pass=$$(grep -c "^--- PASS" $$LOG_FILE 2>/dev/null || true); \
|
|
fail=$$(grep -c "^--- FAIL" $$LOG_FILE 2>/dev/null || true); \
|
|
skip=$$(grep -c "^--- SKIP" $$LOG_FILE 2>/dev/null || true); \
|
|
echo "PASSED: $${pass:-0}"; \
|
|
echo "FAILED: $${fail:-0}"; \
|
|
echo "SKIPPED: $${skip:-0}"; \
|
|
echo "========================================"; \
|
|
rm -f $$LOG_FILE; \
|
|
exit $$status
|
|
|
|
lint: ## Lint the source code.
|
|
golangci-lint run
|
|
|
|
kubectl-view-all-resources: ## This command outputs all Kubernetes resources using YAML format and pipes it to VS Code
|
|
./kubectl.sh view-all-resources
|
|
|
|
kubectl-view-kubeshark-resources: ## This command outputs all Kubernetes resources in "kubeshark" namespace using YAML format and pipes it to VS Code
|
|
./kubectl.sh view-kubeshark-resources
|
|
|
|
generate-helm-values: ## Generate the Helm values from config.yaml
|
|
# [ -f ~/.kubeshark/config.yaml ] && mv ~/.kubeshark/config.yaml ~/.kubeshark/config.yaml.old
|
|
bin/kubeshark__ config>helm-chart/values.yaml
|
|
# [ -f ~/.kubeshark/config.yaml.old ] && mv ~/.kubeshark/config.yaml.old ~/.kubeshark/config.yaml
|
|
# sed -i 's/^license:.*/license: ""/' helm-chart/values.yaml && sed -i '1i # find a detailed description here: https://github.com/kubeshark/kubeshark/blob/master/helm-chart/README.md' helm-chart/values.yaml
|
|
|
|
generate-manifests: ## Generate the manifests from the Helm chart using default configuration
|
|
helm template kubeshark -n default ./helm-chart > ./manifests/complete.yaml
|
|
|
|
logs-sniffer:
|
|
export LOGS_POD_PREFIX=kubeshark-worker-
|
|
export LOGS_CONTAINER='-c sniffer'
|
|
export LOGS_FOLLOW=
|
|
${MAKE} logs
|
|
|
|
logs-sniffer-follow:
|
|
export LOGS_POD_PREFIX=kubeshark-worker-
|
|
export LOGS_CONTAINER='-c sniffer'
|
|
export LOGS_FOLLOW=--follow
|
|
${MAKE} logs
|
|
|
|
logs-tracer:
|
|
export LOGS_POD_PREFIX=kubeshark-worker-
|
|
export LOGS_CONTAINER='-c tracer'
|
|
export LOGS_FOLLOW=
|
|
${MAKE} logs
|
|
|
|
logs-tracer-follow:
|
|
export LOGS_POD_PREFIX=kubeshark-worker-
|
|
export LOGS_CONTAINER='-c tracer'
|
|
export LOGS_FOLLOW=--follow
|
|
${MAKE} logs
|
|
|
|
logs-worker: logs-sniffer
|
|
|
|
logs-worker-follow: logs-sniffer-follow
|
|
|
|
logs-hub:
|
|
export LOGS_POD_PREFIX=kubeshark-hub
|
|
export LOGS_FOLLOW=
|
|
${MAKE} logs
|
|
|
|
logs-hub-follow:
|
|
export LOGS_POD_PREFIX=kubeshark-hub
|
|
export LOGS_FOLLOW=--follow
|
|
${MAKE} logs
|
|
|
|
logs-front:
|
|
export LOGS_POD_PREFIX=kubeshark-front
|
|
export LOGS_FOLLOW=
|
|
${MAKE} logs
|
|
|
|
logs-front-follow:
|
|
export LOGS_POD_PREFIX=kubeshark-front
|
|
export LOGS_FOLLOW=--follow
|
|
${MAKE} logs
|
|
|
|
logs:
|
|
kubectl logs $$(kubectl get pods | awk '$$1 ~ /^$(LOGS_POD_PREFIX)/' | awk 'END {print $$1}') $(LOGS_CONTAINER) $(LOGS_FOLLOW)
|
|
|
|
ssh-node:
|
|
kubectl ssh node $$(kubectl get nodes | awk 'END {print $$1}')
|
|
|
|
exec-worker:
|
|
export EXEC_POD_PREFIX=kubeshark-worker-
|
|
${MAKE} exec
|
|
|
|
exec-hub:
|
|
export EXEC_POD_PREFIX=kubeshark-hub
|
|
${MAKE} exec
|
|
|
|
exec-front:
|
|
export EXEC_POD_PREFIX=kubeshark-front
|
|
${MAKE} exec
|
|
|
|
exec:
|
|
kubectl exec --stdin --tty $$(kubectl get pods | awk '$$1 ~ /^$(EXEC_POD_PREFIX)/' | awk 'END {print $$1}') -- /bin/sh
|
|
|
|
helm-install:
|
|
cd helm-chart && helm install kubeshark . --set tap.docker.tag=$(TAG) && cd ..
|
|
|
|
helm-install-debug:
|
|
cd helm-chart && helm install kubeshark . --set tap.docker.tag=$(TAG) --set tap.debug=true && cd ..
|
|
|
|
helm-install-profile:
|
|
cd helm-chart && helm install kubeshark . --set tap.docker.tag=$(TAG) --set tap.pprof.enabled=true && cd ..
|
|
|
|
helm-uninstall:
|
|
helm uninstall kubeshark
|
|
|
|
proxy:
|
|
kubeshark proxy
|
|
|
|
port-forward:
|
|
kubectl port-forward $$(kubectl get pods | awk '$$1 ~ /^$(POD_PREFIX)/' | awk 'END {print $$1}') $(SRC_PORT):$(DST_PORT)
|
|
|
|
release:
|
|
@cd ../worker && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
|
|
@cd ../tracer && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
|
|
@cd ../hub && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
|
|
@cd ../front && git checkout master && git pull && git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
|
|
@cd ../kubeshark && git checkout master && git pull && sed -i "s/^version:.*/version: \"$(shell echo $(VERSION) | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+)\..*/\1/')\"/" helm-chart/Chart.yaml && make
|
|
@if [ "$(shell uname)" = "Darwin" ]; then \
|
|
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime ./bin/kubeshark__; \
|
|
fi
|
|
@make generate-helm-values && make generate-manifests
|
|
@git add -A . && git commit -m ":bookmark: Bump the Helm chart version to $(VERSION)" && git push
|
|
@git tag -d v$(VERSION); git tag v$(VERSION) && git push origin --tags
|
|
@rm -rf ../kubeshark.github.io/charts/chart && mkdir ../kubeshark.github.io/charts/chart && cp -r helm-chart/ ../kubeshark.github.io/charts/chart/
|
|
@cd ../kubeshark.github.io/ && git add -A . && git commit -m ":sparkles: Update the Helm chart" && git push
|
|
@cd ../kubeshark
|
|
|
|
release-dry-run:
|
|
@cd ../worker && git checkout master && git pull
|
|
@cd ../tracer && git checkout master && git pull
|
|
@cd ../hub && git checkout master && git pull
|
|
@cd ../front && git checkout master && git pull
|
|
@cd ../kubeshark && sed -i "s/^version:.*/version: \"$(shell echo $(VERSION) | sed -E 's/^([0-9]+\.[0-9]+\.[0-9]+)\..*/\1/')\"/" helm-chart/Chart.yaml && make
|
|
@if [ "$(shell uname)" = "Darwin" ]; then \
|
|
codesign --sign - --force --preserve-metadata=entitlements,requirements,flags,runtime ./bin/kubeshark__; \
|
|
fi
|
|
@make generate-helm-values && make generate-manifests
|
|
@rm -rf ../kubeshark.github.io/charts/chart && mkdir ../kubeshark.github.io/charts/chart && cp -r helm-chart/ ../kubeshark.github.io/charts/chart/
|
|
@cd ../kubeshark.github.io/
|
|
@cd ../kubeshark
|
|
|
|
branch:
|
|
@cd ../worker && git checkout master && git pull && git checkout -b $(name); git push --set-upstream origin $(name)
|
|
@cd ../hub && git checkout master && git pull && git checkout -b $(name); git push --set-upstream origin $(name)
|
|
@cd ../front && git checkout master && git pull && git checkout -b $(name); git push --set-upstream origin $(name)
|
|
|
|
switch-to-branch:
|
|
@cd ../worker && git checkout $(name)
|
|
@cd ../hub && git checkout $(name)
|
|
@cd ../front && git checkout $(name)
|