Skip to content

HYPERFLEET-1276 - refactor: simplify TSL v6 search helpers#249

Open
kuudori wants to merge 1 commit into
openshift-hyperfleet:mainfrom
kuudori:HYPERFLEET-1276
Open

HYPERFLEET-1276 - refactor: simplify TSL v6 search helpers#249
kuudori wants to merge 1 commit into
openshift-hyperfleet:mainfrom
kuudori:HYPERFLEET-1276

Conversation

@kuudori

@kuudori kuudori commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

Replace 100-line FieldNameWalk with IdentWalk + getField callback, extract wrapSpecNumericCasts, move properties into getField, delete NormalizeInSyntax (no consumers use old IN () syntax), add missing properties key validation, remove dead code.

Net: -670 lines.

Summary

  • HYPERFLEET-1276

Test Plan

  • Unit tests added/updated
  • make test-all passes
  • make lint passes
  • Helm chart changes validated with make test-helm (if applicable)
  • Deployed to a development cluster and verified (if Helm/config changes)
  • E2E tests passed (if cross-component or major changes)

@openshift-ci openshift-ci Bot requested review from crizzo71 and mbrudnoy June 24, 2026 15:00
@openshift-ci

openshift-ci Bot commented Jun 24, 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 rafabene 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

@coderabbitai

coderabbitai Bot commented Jun 24, 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: c3736011-fd71-48e2-9525-a7a382bbabb9

📥 Commits

Reviewing files that changed from the base of the PR and between 7fb3985 and 0223eb4.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum, !**/go.sum
📒 Files selected for processing (7)
  • go.mod
  • pkg/db/sql_helpers.go
  • pkg/db/sql_helpers_test.go
  • pkg/services/generic.go
  • pkg/services/generic_test.go
  • test/integration/clusters_test.go
  • test/integration/node_pools_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/db/sql_helpers_test.go
🚧 Files skipped from review as they are similar to previous changes (4)
  • go.mod
  • pkg/services/generic_test.go
  • pkg/services/generic.go
  • pkg/db/sql_helpers.go

📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes
    • Improved LIST search parsing and SQL translation for nested dot-style fields, including stronger validation for spec, labels, properties, and status.conditions.
    • Enhanced condition handling and correct operator semantics (including improved NOT/OR behavior).
    • Improved type-aware comparisons for spec subfields, including correct numeric casting, plus more consistent in query behavior.
  • Tests
    • Refreshed unit and integration coverage to align with tree-search-language v6 behavior and updated query syntax expectations.
  • Chores
    • Updated the underlying tree-search-language dependency to v6.

Walkthrough

This PR migrates tree-search-language usage to v6 in go.mod, pkg/db/sql_helpers.go, pkg/services/generic.go, and tests. It rewrites TSL parsing and SQL-walk entry points around pointer-based tsl.Node/tsl.TSLNode handling, updates condition extraction and field mapping, and changes search syntax coverage to v6 bracket in forms. CWE-20 and CWE-704-relevant validation and typed-node handling are changed.

Sequence Diagram(s)

sequenceDiagram
  participant GenericService
  participant tsl
  participant db
  participant SqlWalker
  GenericService->>tsl: ParseTSL(listCtx.args.Search)
  GenericService->>db: ExtractConditionQueries(tslTree)
  GenericService->>db: FieldNameWalk(tslTree, disallowedFields)
  GenericService->>SqlWalker: Walk(&tsl.TSLNode{Node: tslTree})
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 51.72% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (10 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: a refactor of TSL v6 search helpers.
Description check ✅ Passed The description is directly related to the TSL v6 helper refactor and dead-code cleanup.
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 PASS (CWE-532): no non-test slog/log/printf call uses token/password/credential/secret as a field or interpolated string; scans only hit comments/fmt.Errorf.
No Hardcoded Secrets ✅ Passed No hardcoded creds, user:pass URLs, or long base64 literals found in touched files; no CWE-798/CWE-321 issue evident.
No Weak Cryptography ✅ Passed No CWE-327/208 issues found: changed files contain no md5/des/rc4/SHA1-for-security or secret compares; only unrelated FNV hashing in advisory locks.
No Injection Vectors ✅ Passed No CWE-89/78/79/502 sinks introduced; SQL fmt.Sprintf sites use schema metadata or strict allowlist/regex validation, not raw untrusted input.
No Privileged Containers ✅ Passed No deployed manifest adds privileged flags; Dockerfile uses root only transiently with comment and switches back to non-root (CWE-250).
No Pii Or Sensitive Data In Logs ✅ Passed No CWE-532 issue: changed files have only generic size warnings; no logs expose PII, session IDs, raw bodies, or creds.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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.

@hyperfleet-ci-bot

hyperfleet-ci-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

Risk Score: 2 — risk/medium

Signal Detail Points
PR size 1530 lines (>500) +2
Sensitive paths none +0
Test coverage Tests cover changed packages +0

Computed by hyperfleet-risk-scorer

@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: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
pkg/db/sql_helpers.go (1)

365-392: 🎯 Functional Correctness | 🟠 Major

Reject mixed OR expressions containing condition predicates. ExtractConditionQueries replaces condition nodes with 1 = 1, and the extracted SQL is appended later with AND. That changes name='x' OR status.conditions.Available='True' into (name='x' OR 1=1) AND ..., which collapses the OR branch and mis-evaluates the query (CWE-682). Either keep condition SQL in the AST or reject mixed OR queries.

🤖 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/db/sql_helpers.go` around lines 365 - 392, ExtractConditionQueries in
sql_helpers.go must not rewrite condition predicates inside mixed OR expressions
to a always-true placeholder, because that changes the boolean logic. Update the
handling around hasCondition/conditionsNodeConverter so mixed OR queries
containing condition fields are either rejected with a BadRequest or preserved
in the AST without collapsing the OR branch. Use the existing unary NOT and
condition extraction logic in ExtractConditionQueries, conditionsNodeConverter,
and subtreeHasCondition as the place to enforce this rule.
pkg/services/generic.go (1)

333-355: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Skip mapped JSONB expressions before related-table dot splitting.

After FieldNameWalk, fields like labels->>'app.kubernetes.io/name' or properties ->> 'owner.name' can contain dots but are no longer relation paths. Splitting them here misclassifies the prefix as a related resource and returns a bad request. No CWE applies; this is deterministic query translation breakage.

Proposed fix
 	walkFn := func(field string) (string, error) {
+		if strings.Contains(field, "->") {
+			return field, nil
+		}
 		fieldParts := strings.Split(field, ".")
 		if len(fieldParts) > 1 && fieldParts[0] != resourceTable {
🤖 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/services/generic.go` around lines 333 - 355, Skip JSONB-mapped
expressions before relation-path handling in walkFn: after FieldNameWalk,
strings like labels->>'app.kubernetes.io/name' or properties ->> 'owner.name'
may contain dots but are not related-table references. Update the IdentWalk
logic in generic.go so it first detects mapped JSONB expressions and returns
them unchanged, and only then splits on "." and resolves joins via
listCtx.joins/GetTableRelation.
🤖 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/db/sql_helpers.go`:
- Around line 52-60: The properties.* branch in the field-building logic is
bypassing the shared disallowed-field validation, so a resource that forbids
properties can still be queried through a nested property key. Update the field
resolution flow in the helper that handles trimmed names so the disallowedFields
check applies before returning from the properties prefix path, or explicitly
validate the base “properties” field before constructing the SQL expression. Use
the existing symbols validateFieldKey, disallowedFields, and the properties.*
handling in sql_helpers.go to keep the check consistent with other field cases.
- Around line 271-279: Preserve sub-second precision when rebinding timestamp
literals in the SQL helper: in the `tsl.KindTimestampLiteral` handling inside
`sql_helpers.go`, change the formatting used for `n.Right.Value.(time.Time)`
from the current RFC3339-based conversion to a nanosecond-preserving one so
fractional seconds are not lost. Keep the existing type check and error path in
place, and update the `rightStr` assignment in this branch to use
`time.RFC3339Nano` so condition filters compare against the exact timestamp
value.

---

Outside diff comments:
In `@pkg/db/sql_helpers.go`:
- Around line 365-392: ExtractConditionQueries in sql_helpers.go must not
rewrite condition predicates inside mixed OR expressions to a always-true
placeholder, because that changes the boolean logic. Update the handling around
hasCondition/conditionsNodeConverter so mixed OR queries containing condition
fields are either rejected with a BadRequest or preserved in the AST without
collapsing the OR branch. Use the existing unary NOT and condition extraction
logic in ExtractConditionQueries, conditionsNodeConverter, and
subtreeHasCondition as the place to enforce this rule.

In `@pkg/services/generic.go`:
- Around line 333-355: Skip JSONB-mapped expressions before relation-path
handling in walkFn: after FieldNameWalk, strings like
labels->>'app.kubernetes.io/name' or properties ->> 'owner.name' may contain
dots but are not related-table references. Update the IdentWalk logic in
generic.go so it first detects mapped JSONB expressions and returns them
unchanged, and only then splits on "." and resolves joins via
listCtx.joins/GetTableRelation.
🪄 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: b558e419-641e-4759-91b1-c59da15e1075

📥 Commits

Reviewing files that changed from the base of the PR and between d8ca1a2 and 52f99e6.

⛔ Files ignored due to path filters (1)
  • go.sum is excluded by !**/*.sum, !**/go.sum
📒 Files selected for processing (5)
  • go.mod
  • pkg/db/sql_helpers.go
  • pkg/db/sql_helpers_test.go
  • pkg/services/generic.go
  • pkg/services/generic_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/db/sql_helpers.go
Comment thread pkg/db/sql_helpers.go Outdated
Comment thread pkg/db/sql_helpers.go
Replace 100-line FieldNameWalk with IdentWalk + getField callback,
extract wrapSpecNumericCasts, move properties into getField, delete
NormalizeInSyntax (no consumers use old IN () syntax), add missing
properties key validation, remove dead code.

Net: -670 lines.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant