Conversation
This adds events, rule and settings page to the plugin. User can select the backend for the events. Default backend is file/volumes. They can easily configure redis as well and use that as backend. Signed-off-by: Kautilya Tripathi <ktripathi@microsoft.com>
| name: http | ||
| selector: | ||
| app: redis-rest-proxy | ||
|
|
There was a problem hiding this comment.
consider restricting to clusterIP or adding a network policy? currently i think anyone can read all events/inject fake events
illume
left a comment
There was a problem hiding this comment.
Thanks for these changes.
It looks like this PR has git conflicts. Can you please fix them?
There was a problem hiding this comment.
Pull request overview
Adds a new Falco Headlamp plugin to this plugins repository, providing UI pages for viewing Falco security events, exploring loaded rules, and configuring event storage (file vs Redis).
Changes:
- Introduces Falco plugin navigation/routes plus Events, Rules, and Settings pages.
- Adds services/utilities for pod exec, event parsing/formatting, and rule discovery/parsing from Falco configs.
- Adds Redis helper manifests + Falco Helm values and documents setup; registers the plugin in the repo README.
Reviewed changes
Copilot reviewed 34 out of 36 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| falco/tsconfig.json | Plugin TypeScript config extending Headlamp plugin defaults. |
| falco/src/utils/storageUtils.ts | LocalStorage settings model + load/save helpers. |
| falco/src/utils/falcoRulesUtils.ts | YAML parsing + rules file discovery utilities. |
| falco/src/utils/falcoPodUtils.ts | Detect Falco file output path from Pod spec. |
| falco/src/utils/falcoEventUtils.ts | Event field extraction, formatting, and UI helpers. |
| falco/src/utils/constants.ts | Shared Falco namespace/label selector constants. |
| falco/src/types/FalcoRule.ts | Rule and rule-display types. |
| falco/src/types/FalcoEvent.ts | Falco event type definition. |
| falco/src/storybook.test.tsx | Storyshots test bootstrap. |
| falco/src/settings/index.tsx | Settings page export barrel. |
| falco/src/settings/Settings.tsx | Settings UI for selecting backend and Redis URL. |
| falco/src/services/podExecService.ts | Pod exec wrapper for reading files / command output. |
| falco/src/services/falcoRulesService.ts | Fetch pods/configs and aggregate rules from the cluster. |
| falco/src/rules/index.tsx | Rules page export barrel. |
| falco/src/rules/FalcoRules.tsx | Rules list page with loading/error handling. |
| falco/src/index.tsx | Plugin entry: icons, sidebar entries, and routes registration. |
| falco/src/headlamp-plugin.d.ts | Headlamp plugin type reference. |
| falco/src/events/index.tsx | Events page export barrel. |
| falco/src/events/FalcoEvents.tsx | Events viewer: file stream via exec + Redis polling backend. |
| falco/src/components/TagsCell.tsx | Colored tag rendering for event table. |
| falco/src/components/SeverityColumn.tsx | Colored severity pill renderer. |
| falco/src/components/RedisConnectionTester.tsx | Redis REST proxy ping/test UI. |
| falco/src/components/MessageCell.tsx | Clickable message cell with tooltip and keyboard support. |
| falco/src/components/LoadingIndicator.tsx | Shared loading + error UI component. |
| falco/src/components/K8sSourceCell.tsx | Attempts to link events to Kubernetes resources. |
| falco/src/components/EventDetailDialog.tsx | Event detail modal view. |
| falco/src/common/Table.tsx | Thin wrapper around Headlamp table component types/props. |
| falco/src/common/RulesTable.tsx | Rules table column definitions and table wrapper. |
| falco/redis/redis-server.yaml | Example Redis Deployment/Service for the Redis backend. |
| falco/redis/redis-rest-proxy.yaml | Example Redis REST proxy deployment (Flask) for browser access. |
| falco/package.json | Plugin package metadata and scripts (incl. redis setup script). |
| falco/falco-values.yaml | Example Helm values enabling Falco outputs/plugins. |
| falco/README.md | Plugin documentation and setup instructions. |
| falco/.gitignore | Plugin-local ignores (node_modules, dist, etc.). |
| README.md | Adds Falco plugin entry to the repository plugin list. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot address open review comments |
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Agent-Logs-Url: https://github.com/headlamp-k8s/plugins/sessions/f37e2a66-7f0d-4912-84fe-550e61db55c0 Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Fixed the merge conflict in README.md in commit
All review comments addressed in individual atomic commits:
Also added:
|
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 46 out of 48 changed files in this pull request and generated 11 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot address open review comments |
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
…lco container name Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Agent-Logs-Url: https://github.com/headlamp-k8s/plugins/sessions/d4ccc1bc-0993-4000-8406-a019a52c3952 Co-authored-by: illume <9541+illume@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 46 out of 48 changed files in this pull request and generated 10 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@copilot Address open review comments |
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
Co-authored-by: illume <9541+illume@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 46 out of 48 changed files in this pull request and generated 7 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| - **Falco Events Viewer:** | ||
|
|
||
| - Real-time streaming and display of Falco security events from all cluster namespaces. | ||
| - Powerful search and filter UI for namespaces, pods, containers, and severity. |
There was a problem hiding this comment.
README claims a "search and filter UI for namespaces, pods, containers" but the current Events view uses SectionFilterHeader with noNamespaceFilter and there are no explicit pod/container filters in the UI (only free-text search). Please adjust the wording to match the current UX to avoid confusing users.
| - Powerful search and filter UI for namespaces, pods, containers, and severity. | |
| - Free-text search across events, with severity-based filtering in the current UI. |
| // Reconstruct without trailing slash on the path, preserving any query/hash. | ||
| const base = `${parsed.protocol}//${parsed.host}${parsed.pathname.replace(/\/+$/, '')}`; | ||
| return base + (parsed.search || '') + (parsed.hash || ''); |
There was a problem hiding this comment.
normalizeRedisUrl returns base + search + hash, but callers build endpoints by string-concatenating paths (e.g. ${normalized}/events). If the user enters a URL containing ?query or #hash, the resulting request URL becomes malformed (query/hash ends up before /events). Consider stripping search/hash in normalizeRedisUrl, or have callers use new URL('/events', normalizedUrlObject) so path joining is correct and predictable.
| it('should load stored settings', () => { | ||
| const stored: FalcoSettings = { backend: 'redis', redisUrl: 'http://localhost:8080' }; | ||
| localStorage.setItem('falco_event_storage_settings', JSON.stringify(stored)); | ||
| const settings = loadSettings(); | ||
| expect(settings).toEqual(stored); |
There was a problem hiding this comment.
Tests hardcode the localStorage key string in multiple places instead of using FALCO_SETTINGS_KEY. This makes the tests unnecessarily brittle if the key is ever renamed. Prefer importing and using the exported constant so production code and tests stay in sync.
| if ('rule' in obj) { | ||
| rules.push({ | ||
| name: String(obj.rule), | ||
| desc: obj.desc || '', | ||
| source, | ||
| }); |
There was a problem hiding this comment.
extractRulesFromYaml assigns desc: obj.desc || '', which can yield a non-string (e.g. number/object) and violates the FalcoRule.desc: string contract. Coerce to string (similar to name: String(obj.rule)) so the returned data is consistently typed.
| return await PodExecService.execCommand( | ||
| pod, | ||
| pod.spec?.containers?.[0]?.name || 'falco', | ||
| ['cat', filePath], | ||
| { tty: true } |
There was a problem hiding this comment.
readFile always execs in pod.spec.containers[0] (fallback 'falco'). If the Falco chart adds sidecars/init containers (e.g. falcoctl), the first container may not be the one that has /etc/falco/* mounted, causing reads to fail. Prefer selecting the container named falco when present (fall back to the first only when not found).
| console.error('Falco exec error:', msg); | ||
| }; | ||
| try { | ||
| const containerName = pod.spec?.containers?.[0]?.name || 'falco'; |
There was a problem hiding this comment.
The file-stream backend execs tail in pod.spec.containers[0] (fallback 'falco'), but the Falco daemonset can include sidecars (e.g. falcoctl). If the first container isn't the Falco one (or doesn't have the file mount), the stream will fail. Consider selecting the container named falco when present (similar to detectFalcoFileOutputPath).
| const containerName = pod.spec?.containers?.[0]?.name || 'falco'; | |
| const containers = pod.spec?.containers ?? []; | |
| const falcoContainer = containers.find(container => container?.name === 'falco'); | |
| const containerName = falcoContainer?.name || containers[0]?.name || 'falco'; |
| # If can't parse as JSON, try getting raw data | ||
| if data is None: | ||
| data = request.get_data(as_text=True) | ||
| # Log what we received | ||
| print(f"Received raw data: {data}", file=sys.stderr) | ||
| try: | ||
| # Try to parse it as JSON | ||
| data = json.loads(data) | ||
| except: | ||
| # If not valid JSON, store as is | ||
| _store_event(json.dumps({"rule":"Raw Event", "output":data})) | ||
| return jsonify(status='ok'), 201 | ||
|
|
||
| # Store proper JSON data | ||
| print(f"Storing JSON: {json.dumps(data)}", file=sys.stderr) | ||
| _store_event(json.dumps(data)) |
There was a problem hiding this comment.
The redis-rest-proxy container prints full received event payloads (Received raw data / Storing JSON) to stderr. Falco events can contain sensitive details (command lines, paths, usernames), so logging full payloads by default is a data exposure risk and can also bloat logs. Consider removing these prints or gating them behind an explicit debug env var.
Add plugin for Falco.
TODO
How to test
Screenshots