feat(endpoints): add inodes introspection endpoint#1273
Conversation
Adds an "/inodes" endpoint that returns the contents of the userspace inode map for inspection. This will be useful in tests that need to look into the internal state after operations that don't emit events or during development to validate what is currently being tracked. The new endpoint is disabled by default and can be enabled with the new `endpoint.introspection` configuration value, that should gate any future introspection endpoints we decide to add in the future. This configuration value is not hotreloadable, it can only be set at start up, this is meant to make it harder for the endpoint to come online on production environments.
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yml Review profile: CHILL Plan: Enterprise Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughChangesThe PR adds configurable endpoint introspection, exposes a Inode introspection
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant Server
participant HostScanner
Client->>Server: GET /inodes
Server->>HostScanner: send oneshot response sender
HostScanner->>HostScanner: serialize inode map
HostScanner-->>Server: JSON result
Server-->>Client: HTTP response
Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1273 +/- ##
==========================================
+ Coverage 32.73% 38.35% +5.61%
==========================================
Files 22 22
Lines 3174 3455 +281
Branches 3174 3455 +281
==========================================
+ Hits 1039 1325 +286
+ Misses 2131 2126 -5
Partials 4 4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@fact/src/config/tests.rs`:
- Around line 300-325: Update the configuration tests to assert
EndpointConfig::introspection() directly rather than relying only on FactConfig
equality. In fact/src/config/tests.rs:300-325, compare the parsed effective
value in the parsing loop; at 1512-1565, assert the updated value and add an
introspection: false update input; at 2409-2421, assert the environment-derived
value; and at 2644-2657, assert the environment-overrides-YAML value.
In `@fact/src/endpoints.rs`:
- Around line 158-172: Update the host-scanner request flow around
host_scanner_intro to use try_send, returning HTTP 503 when the channel is
saturated or unavailable instead of awaiting indefinitely. Wrap rx.await in a
bounded timeout and return an appropriate 503 response when the scanner does not
respond before it expires, while preserving the existing success and
scanner-error responses.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Enterprise
Run ID: 82d61e0c-05b2-4af2-a25b-96743e92d407
📒 Files selected for processing (5)
fact/src/config/mod.rsfact/src/config/tests.rsfact/src/endpoints.rsfact/src/host_scanner.rsfact/src/lib.rs
262673f to
a142db9
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@fact/src/config/reloader.rs`:
- Around line 189-192: Update the endpoint reload branch around
Reloader::endpoint_should_reload so it applies only reloadable endpoint fields
and preserves the existing old.introspection value, rather than replacing old
with new.endpoint.clone(). Add or extend regression coverage for an
introspection-only change followed by a reloadable endpoint change, ensuring
introspection remains unchanged until restart.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Enterprise
Run ID: 0163c873-533a-44c7-a1be-af9dac47f696
📒 Files selected for processing (2)
fact/src/config/mod.rsfact/src/config/reloader.rs
Added unit tests for additional validation.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
fact/src/config/reloader.rs (1)
177-180: 🎯 Functional Correctness | 🔴 Critical | ⚡ Quick winClone
new.endpointbefore using struct-update syntax.Line 179 moves
EndpointConfigout of&FactConfig; this does not compile becauseEndpointConfigisClone, notCopy.Proposed fix
*old = EndpointConfig { introspection: old.introspection, - ..new.endpoint + ..new.endpoint.clone() };#!/usr/bin/env bash set -euo pipefail rg -n -C 3 'derive\(.*(Clone|Copy)|struct EndpointConfig|\.{2}new\.endpoint' \ fact/src/config/mod.rs fact/src/config/reloader.rs🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@fact/src/config/reloader.rs` around lines 177 - 180, Update the EndpointConfig struct update in the reloader logic to clone new.endpoint before spreading it, since new is borrowed and EndpointConfig is not Copy. Preserve the existing introspection override from old while ensuring the assignment does not move out of the borrowed FactConfig.
🧹 Nitpick comments (1)
fact/src/config/reloader.rs (1)
499-505: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winAssert the watch notification state too. Add a per-case expected notification flag and check
endpoint.has_changed().unwrap()aftersend_updates(); otherwise an unconditional send could still leave this test green.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@fact/src/config/reloader.rs` around lines 499 - 505, Extend the test cases iterated by the reloader test to include an expected notification flag, then update the loop around Reloader::from and send_updates to assert endpoint.has_changed().unwrap() against that per-case expectation. Preserve the existing endpoint value assertion while ensuring each case verifies both state and notification behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@fact/src/config/reloader.rs`:
- Around line 177-180: Update the EndpointConfig struct update in the reloader
logic to clone new.endpoint before spreading it, since new is borrowed and
EndpointConfig is not Copy. Preserve the existing introspection override from
old while ensuring the assignment does not move out of the borrowed FactConfig.
---
Nitpick comments:
In `@fact/src/config/reloader.rs`:
- Around line 499-505: Extend the test cases iterated by the reloader test to
include an expected notification flag, then update the loop around
Reloader::from and send_updates to assert endpoint.has_changed().unwrap()
against that per-case expectation. Preserve the existing endpoint value
assertion while ensuring each case verifies both state and notification
behavior.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yml
Review profile: CHILL
Plan: Enterprise
Run ID: ed55f6e3-23b4-46a8-b9aa-fdc48ab9a94f
📒 Files selected for processing (1)
fact/src/config/reloader.rs
Description
Adds an "/inodes" endpoint that returns the contents of the userspace inode map for inspection. This will be useful in tests that need to look into the internal state after operations that don't emit events or during development to validate what is currently being tracked.
The new endpoint is disabled by default and can be enabled with the new
endpoint.introspectionconfiguration value, that should gate any future introspection endpoints we decide to add in the future. This configuration value is not hotreloadable, it can only be set at start up, this is meant to make it harder for the endpoint to come online on production environments.Fixes #1079
Checklist
Automated testing
If any of these don't apply, please comment below.
Testing Performed
The responses are formatted with
jqfor better visibility, the endpoint returns minified JSON.Introspection endpoint enabled:
{ "39:228583982": "/etc/sensitive-files/seq", "39:200442630": "/etc/sensitive-files/my-dir/something", "39:227290637": "/etc/sensitive-files/private/super-private/something", "39:196873539": "/etc/sensitive-files/test", "39:194573419": "/etc/sensitive-files/my-dir/nested/something", "39:194396170": "/etc/sensitive-files/my-dir", "39:228288758": "/etc/sensitive-files/mount", "39:217415897": "/etc/sensitive-files/other", "39:228583961": "/etc/sensitive-files/sequence", "39:202489561": "/etc/sensitive-files/something", "39:194573388": "/etc/sensitive-files/my-dir/nested", "39:227290085": "/etc/sensitive-files/private", "39:227290591": "/etc/sensitive-files/private/super-private", "39:227290457": "/etc/sensitive-files/private/something", "39:126382982": "/etc/sensitive-files" }Introspection endpoint disabled, metrics endpoint enabled:
No endpoint enabled:
Summary by CodeRabbit
--introspectionCLI option orFACT_ENDPOINT_INTROSPECTIONenvironment variable (default: disabled;--no-introspectionavailable).GET /inodesendpoint that returns the current inode-to-path mapping as JSON when introspection is enabled.endpoint.introspection(boolean), including type validation and environment-variable override precedence.