Skip to content

HYPERFLEET-1328 - refactor: simplify resource handlers and add registry cycle detection#286

Open
kuudori wants to merge 1 commit into
openshift-hyperfleet:mainfrom
kuudori:HYPERFLEET-1328-refactor-resource-handler-validation
Open

HYPERFLEET-1328 - refactor: simplify resource handlers and add registry cycle detection#286
kuudori wants to merge 1 commit into
openshift-hyperfleet:mainfrom
kuudori:HYPERFLEET-1328-refactor-resource-handler-validation

Conversation

@kuudori

@kuudori kuudori commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Simplify parent-kind checks in ResourceHandler and RootResourceHandler with actionable error messages that point to the exact nested route (e.g. create it via /channels/{id}/versions)
  • Add ParentKind cycle detection to registry.Validate() so misconfigured ownership chains are caught at startup instead of causing infinite recursion at runtime
  • Harden schema validation path matching in middleware

Test plan

  • Registry cycle detection test (TestValidate_ParentKindCycle_Panics)
  • All existing registry, handler, and service unit tests pass
  • go vet clean across all modified packages

@openshift-ci openshift-ci Bot requested a review from rh-amarin July 7, 2026 23:23
@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign ruclo for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci Bot requested a review from Ruclo July 7, 2026 23:23
@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 340757bc-a6fe-4ee2-88ca-c382f688d308

📥 Commits

Reviewing files that changed from the base of the PR and between 1cba700 and 2fe4a11.

📒 Files selected for processing (8)
  • pkg/handlers/resource_handler.go
  • pkg/handlers/resource_handler_test.go
  • pkg/handlers/root_resource_handler.go
  • pkg/middleware/schema_validation.go
  • pkg/middleware/schema_validation_match_test.go
  • pkg/registry/registry.go
  • pkg/registry/registry_test.go
  • test/integration/root_resources_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)
✅ Files skipped from review due to trivial changes (1)
  • pkg/middleware/schema_validation.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • pkg/handlers/root_resource_handler.go
  • pkg/registry/registry.go
  • pkg/middleware/schema_validation_match_test.go
  • pkg/registry/registry_test.go
  • pkg/handlers/resource_handler_test.go
  • pkg/handlers/resource_handler.go

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Creating a child resource without a parent now returns a clear 400 Bad Request with guidance on the correct nested route.
    • Error responses for invalid child resource creation have been standardized across related endpoints.
    • Resource ownership validation now detects circular parent relationships and fails fast with an error.

Walkthrough

Resource handlers now branch on parent_id presence for flat versus nested routes, and child-kind creation without parent context returns a direct validation error with parent-route guidance. Root resource creation uses the parent descriptor to format the required nested path. Registry validation now walks ParentKind chains and panics on ownership cycles. Middleware matcher comments and tests were updated for /resources POST and PATCH handling.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ResourceHandler
  participant RootResourceHandler
  participant Registry

  Client->>ResourceHandler: POST /versions without parent_id
  ResourceHandler->>ResourceHandler: extract parentID, hasParent=false
  ResourceHandler->>RootResourceHandler: create child-kind request
  RootResourceHandler->>Registry: MustGet(parent kind)
  Registry-->>RootResourceHandler: parent descriptor
  RootResourceHandler-->>Client: errors.Validation with parent route guidance
Loading

Related issues: None identified from provided data.

Related PRs: None identified from provided data.

Suggested labels: security, validation, routing

Suggested reviewers: None identified from provided data.

Compact metadata: repo openshift-hyperfleet/hyperfleet-api, PR #286.

CWE-863, CWE-284.

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main changes: resource handler refactors and registry ParentKind cycle detection.
Description check ✅ Passed The description tracks the implemented handler, registry, and middleware changes and the test plan.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Sec-02: Secrets In Log Output ✅ Passed No non-test/example log statements with token/password/credential/secret were found; no CWE-532 log leakage in the changed Go files.
No Hardcoded Secrets ✅ Passed No CWE-798/CWE-259 indicators: touched files contain only route strings, UUIDs, and test fixtures; no API keys, tokens, passwords, private keys.
No Weak Cryptography ✅ Passed No banned crypto APIs, custom crypto, ECB, or secret-compare code in the touched files/repo scan; only routing/validation changes. CWE-327/328 not implicated.
No Injection Vectors ✅ Passed PASS: No CWE-89/78/79/502 sink in changed code; the only fmt.Sprintf uses registry-loaded descriptor.Kind (trusted config), not raw user input.
No Privileged Containers ✅ Passed PASS: HEAD only changes Go source/tests; no Kubernetes/OpenShift manifests, Helm templates, or Dockerfiles were touched, so no privileged-container flags are present.
No Pii Or Sensitive Data In Logs ✅ Passed No new slog/logr/zap/fmt.Print* calls or body dumps in the diff; no CWE-532/CWE-200 exposure found.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
pkg/registry/registry.go (1)

109-131: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Merge duplicate ParentKind != "" guards and extract cycle check.

Two separate if d.ParentKind != "" blocks run back-to-back (Lines 109 and 118). Combine them and extract the traversal into a helper (e.g. checkParentKindCycle(d, descriptors)) — Validate() is now ~66 lines with well over 5 independent panic branches, exceeding the decomposition threshold.

♻️ Proposed refactor
-		if d.ParentKind != "" {
-			if _, ok := descriptors[d.ParentKind]; !ok {
-				panic(fmt.Sprintf(
-					"entity kind %q references unregistered parent kind %q",
-					d.Kind, d.ParentKind,
-				))
-			}
-		}
-
-		if d.ParentKind != "" {
-			visited := map[string]bool{d.Kind: true}
-			for cur := d.ParentKind; cur != ""; {
-				if visited[cur] {
-					panic(fmt.Sprintf(
-						"ownership cycle detected: kind %q participates in a ParentKind cycle",
-						d.Kind,
-					))
-				}
-				visited[cur] = true
-				cur = descriptors[cur].ParentKind
-			}
-		}
+		if d.ParentKind != "" {
+			if _, ok := descriptors[d.ParentKind]; !ok {
+				panic(fmt.Sprintf(
+					"entity kind %q references unregistered parent kind %q",
+					d.Kind, d.ParentKind,
+				))
+			}
+			checkParentKindCycle(d, descriptors)
+		}

As per path instructions, "Functions >50 lines or >5 branching paths — flag for decomposition."

🤖 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 `@pkg/registry/registry.go` around lines 109 - 131, In Validate, merge the
duplicated ParentKind presence checks into a single guard and move the ancestry
traversal into a helper such as checkParentKindCycle. Use the existing
descriptors map and d.Kind/d.ParentKind in the helper to preserve the same panic
behavior, but keep Validate focused by delegating the cycle detection logic
instead of having two back-to-back branches.

Source: Path instructions

🤖 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 `@pkg/handlers/resource_handler.go`:
- Around line 45-63: The child-kind create rejection is currently using
errors.Validation(), which maps to 400 instead of the expected 422 response.
Update the shared child-create validation logic used by ResourceHandler and
RootResourceHandler so both the flat and nested create paths return
Unprocessable Entity for invalid child-kind creates, preserving the API contract
expected by the root_resources integration tests. Locate the duplicated
rejection code in ResourceHandler and RootResourceHandler and route both through
the same helper that produces the 422 response.

In `@pkg/handlers/root_resource_handler.go`:
- Around line 92-97: The child-kind root create path in rootResourceHandler
should return the dedicated 422 contract instead of the generic validation
status. In the branch that checks descriptor.ParentKind and builds the “create
it via /{id}/...” message, either set the HTTPCode explicitly to 422 on the
returned error or switch to the existing child-create error helper so POST
/api/hyperfleet/v1/resources preserves the child-create behavior.

---

Nitpick comments:
In `@pkg/registry/registry.go`:
- Around line 109-131: In Validate, merge the duplicated ParentKind presence
checks into a single guard and move the ancestry traversal into a helper such as
checkParentKindCycle. Use the existing descriptors map and d.Kind/d.ParentKind
in the helper to preserve the same panic behavior, but keep Validate focused by
delegating the cycle detection logic instead of having two back-to-back
branches.
🪄 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: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 992f9348-4315-439a-9194-d319079ce1e2

📥 Commits

Reviewing files that changed from the base of the PR and between 089114e and 1cba700.

📒 Files selected for processing (7)
  • pkg/handlers/resource_handler.go
  • pkg/handlers/resource_handler_test.go
  • pkg/handlers/root_resource_handler.go
  • pkg/middleware/schema_validation.go
  • pkg/middleware/schema_validation_match_test.go
  • pkg/registry/registry.go
  • pkg/registry/registry_test.go
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • openshift-hyperfleet/architecture (manual)
  • openshift-hyperfleet/hyperfleet-api (manual)
  • openshift-hyperfleet/hyperfleet-sentinel (manual)
  • openshift-hyperfleet/hyperfleet-adapter (manual)
  • openshift-hyperfleet/hyperfleet-broker (manual)

Comment thread pkg/handlers/resource_handler.go
Comment thread pkg/handlers/root_resource_handler.go
@hyperfleet-ci-bot

hyperfleet-ci-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

Risk Score: 0 — risk/low

Signal Detail Points
PR size 170 lines +0
Sensitive paths none +0
Test coverage Tests cover changed packages +0

Computed by hyperfleet-risk-scorer

…ry cycle detection

Consolidate parent-kind checks in resource handlers with actionable error
messages, add ParentKind cycle detection to registry startup validation,
and harden schema validation path matching.
@kuudori kuudori force-pushed the HYPERFLEET-1328-refactor-resource-handler-validation branch from 1cba700 to 2fe4a11 Compare July 8, 2026 00:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant