Skip to content

Conversation

@yasun1
Copy link
Contributor

@yasun1 yasun1 commented Dec 9, 2025

Close HYPERFLEET-22

Summary by CodeRabbit

  • Breaking Changes

    • Removed the /api/hyperfleet/v1/compatibility endpoint
    • Cluster names now require a minimum of 3 characters
    • Kind field is now required for clusters and node pools
  • Improvements

    • Enhanced input validation for cluster and node pool names (alphanumeric and hyphens only)
    • Improved error responses with clearer validation failure messages
    • Updated API documentation to production endpoint

✏️ Tip: You can customize this high-level summary in your review settings.

I still leave securitySchemes here; otherwise, we need to make a significant change to remove auth, and we actually want authorization in the future, and currently, setting EnableJWT=false is met the MVP requirement.

@coderabbitai
Copy link

coderabbitai bot commented Dec 9, 2025

Walkthrough

This pull request removes the compatibility API endpoint and modifies Kind field handling from auto-defaulting to explicit preservation. Input validation is enhanced for cluster and node pool names (enforcing 3-63 character length, lowercase alphanumeric with hyphens) and Kind fields (requiring "Cluster" or "NodePool" respectively). The OpenAPI specification is updated with Apache 2.0 license information, HTTP bearer authentication scheme, production server URL, and tightened cluster name constraints (minLength 1 to 3). Integration tests are updated to expect 400 Bad Request responses for validation failures, and new contract tests verify synchronization between domain and OpenAPI constants. Test client configuration now targets the local test server environment.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20–30 minutes

Areas requiring attention:

  • Kind field handling shift: Verify that removal of auto-defaulting in pkg/api/cluster_types.go and pkg/api/node_pool_types.go aligns with the new validation requirements in handlers and doesn't introduce regressions with existing data or workflows.
  • Validation logic robustness: Review the regex pattern in pkg/handlers/validation.go for correctness and confirm validateName and validateKind helpers handle edge cases (null pointers, reflection operations) safely.
  • Compatibility endpoint removal: Ensure complete removal across routes.go, handler file deletion, and integration test cleanup with no dangling references.
  • OpenAPI specification changes: Validate production server URL, minLength constraint change for cluster names (1→3), and bearer auth scheme integration.
  • Test expectations: Confirm that updated integration tests in clusters_test.go and node_pools_test.go properly reflect new 400 error behaviors and error message assertions.

Suggested labels

lgtm

Suggested reviewers

  • rh-amarin
  • yingzhanredhat

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.76% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: adding cluster/nodepool name and kind validation, and removing the unused compatibility endpoint.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (7)
pkg/handlers/validation.go (1)

10-11: Consider stricter pattern to disallow leading/trailing hyphens.

The current pattern ^[a-z0-9-]+$ allows names that start or end with hyphens (e.g., -cluster, cluster-, ---), which typically violates Kubernetes DNS-1123 naming conventions. If this API follows Kubernetes naming standards, consider using a pattern like ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ to require alphanumeric start/end.

-// Cluster/NodePool name pattern: lowercase alphanumeric and hyphens
-var namePattern = regexp.MustCompile(`^[a-z0-9-]+$`)
+// Cluster/NodePool name pattern: lowercase alphanumeric and hyphens
+// Must start and end with alphanumeric character (Kubernetes DNS-1123 label convention)
+var namePattern = regexp.MustCompile(`^[a-z0-9]([a-z0-9-]*[a-z0-9])?$`)
openapi/openapi.yaml (1)

35-36: 400 responses are missing error schema references.

The 400 Bad Request responses added throughout the spec don't include a response body schema. For consistency with the default error responses and to help clients handle validation errors, consider adding the Error schema reference.

         '400':
           description: The server could not understand the request due to invalid syntax.
+          content:
+            application/json:
+              schema:
+                $ref: '#/components/schemas/Error'
pkg/handlers/cluster_nodepools.go (1)

124-161: NodePool Create validation is sensible; consider centralizing name length constraints

Using validateName(&req, "Name", "name", 1, 255) and validateKind(&req, "Kind", "kind", "NodePool") brings NodePool creation in line with the new validation approach and happens before any conversion or DB operations, which is good.

If cluster/nodepool name limits are meant to stay in sync with OpenAPI/DB constraints long‑term, consider extracting these min/max values into shared constants (e.g., ClusterNameMinLen, ClusterNameMaxLen, NodePoolNameMaxLen) to avoid silent drift between handlers, schema, and tests.

test/integration/node_pools_test.go (2)

210-247: Empty kind integration test correctly validates 400 behavior

TestNodePoolPost_EmptyKind cleanly exercises the handler by:

  • Creating a real cluster,
  • Sending raw JSON with \"kind\": \"\" under an authenticated context, and
  • Asserting a 400 plus an error reason containing “kind is required”.

This is a good end‑to‑end coverage of the new Kind validation path.

You could factor the repeated “POST raw JSON and parse error.reason” logic (here and in WrongKind) into a small helper to keep these tests DRY, but it’s not required.


249-286: Wrong kind integration test robustly checks specific validation messaging

TestNodePoolPost_WrongKind mirrors the empty‑kind test for the “wrong kind value” case, confirming 400 and a reason containing “kind must be 'NodePool'”. This gives good regression protection for both status code and user‑facing error text.

test/integration/clusters_test.go (2)

621-654: Empty kind cluster test accurately validates 400 and message content

TestClusterPost_EmptyKind:

  • Authenticates via JWT,
  • Sends raw JSON with \"kind\": \"\" to bypass client struct constraints, and
  • Verifies 400 plus an error reason containing “kind is required”.

This is a solid end‑to‑end check of the new Kind validation for clusters.

As with the nodepool tests, you might consider a small helper for “POST invalid payload and assert error.reason substring” to reduce repetition, but current code is clear enough.


656-689: Wrong kind cluster test mirrors nodepool coverage and looks good

TestClusterPost_WrongKind complements the empty‑kind case by asserting a 400 and a reason containing “kind must be 'Cluster'” when an incorrect kind is supplied. Together, these tests meaningfully lock in the new Kind API contract.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc5c73e and 6524faa.

📒 Files selected for processing (25)
  • cmd/hyperfleet-api/server/routes.go (0 hunks)
  • openapi/openapi.yaml (14 hunks)
  • pkg/api/cluster_types.go (0 hunks)
  • pkg/api/cluster_types_test.go (2 hunks)
  • pkg/api/node_pool_types.go (0 hunks)
  • pkg/api/node_pool_types_test.go (2 hunks)
  • pkg/api/openapi_embed.go (0 hunks)
  • pkg/api/presenters/adapter_status_test.go (2 hunks)
  • pkg/auth/auth_middleware.go (0 hunks)
  • pkg/dao/mocks/generic.go (1 hunks)
  • pkg/handlers/cluster.go (1 hunks)
  • pkg/handlers/cluster_nodepools.go (2 hunks)
  • pkg/handlers/compatibility.go (0 hunks)
  • pkg/handlers/node_pool.go (1 hunks)
  • pkg/handlers/validation.go (2 hunks)
  • pkg/handlers/validation_test.go (1 hunks)
  • pkg/logger/logger.go (1 hunks)
  • plugins/clusters/plugin.go (0 hunks)
  • plugins/nodePools/plugin.go (0 hunks)
  • test/helper.go (1 hunks)
  • test/integration/api_contract_test.go (1 hunks)
  • test/integration/clusters_test.go (7 hunks)
  • test/integration/compatibility_test.go (0 hunks)
  • test/integration/integration_test.go (1 hunks)
  • test/integration/node_pools_test.go (4 hunks)
💤 Files with no reviewable changes (9)
  • cmd/hyperfleet-api/server/routes.go
  • plugins/clusters/plugin.go
  • pkg/handlers/compatibility.go
  • pkg/auth/auth_middleware.go
  • pkg/api/openapi_embed.go
  • plugins/nodePools/plugin.go
  • pkg/api/node_pool_types.go
  • pkg/api/cluster_types.go
  • test/integration/compatibility_test.go
🧰 Additional context used
📓 Path-based instructions (9)
**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use Go 1.24.9 with FIPS-compliant crypto enabled (CGO_ENABLED=1, GOEXPERIMENT=boringcrypto)

Files:

  • pkg/handlers/cluster.go
  • pkg/handlers/node_pool.go
  • test/integration/api_contract_test.go
  • test/integration/node_pools_test.go
  • pkg/api/presenters/adapter_status_test.go
  • test/helper.go
  • pkg/handlers/validation.go
  • pkg/api/cluster_types_test.go
  • pkg/dao/mocks/generic.go
  • test/integration/clusters_test.go
  • pkg/handlers/validation_test.go
  • pkg/api/node_pool_types_test.go
  • test/integration/integration_test.go
  • pkg/handlers/cluster_nodepools.go
  • pkg/logger/logger.go
pkg/{handlers,services}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Always retrieve database session from context via db.NewContext() instead of creating new connections

Files:

  • pkg/handlers/cluster.go
  • pkg/handlers/node_pool.go
  • pkg/handlers/validation.go
  • pkg/handlers/validation_test.go
  • pkg/handlers/cluster_nodepools.go
pkg/handlers/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Implement all HTTP handlers following the pattern: parse request → call service/DAO → handle errors → send response

Files:

  • pkg/handlers/cluster.go
  • pkg/handlers/node_pool.go
  • pkg/handlers/validation.go
  • pkg/handlers/validation_test.go
  • pkg/handlers/cluster_nodepools.go
pkg/{handlers,services,dao}/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/{handlers,services,dao}/**/*.go: Use structured logging via pkg/logger/logger.go with context propagation including opid, accountID, and tx_id
Return errors using the structured ServiceError type from pkg/errors/ with HttpCode, Code, and Reason fields

Files:

  • pkg/handlers/cluster.go
  • pkg/handlers/node_pool.go
  • pkg/handlers/validation.go
  • pkg/dao/mocks/generic.go
  • pkg/handlers/validation_test.go
  • pkg/handlers/cluster_nodepools.go
pkg/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Implement JWT authentication middleware that validates tokens and extracts account ID and username from claims

Files:

  • pkg/handlers/cluster.go
  • pkg/handlers/node_pool.go
  • pkg/api/presenters/adapter_status_test.go
  • pkg/handlers/validation.go
  • pkg/api/cluster_types_test.go
  • pkg/dao/mocks/generic.go
  • pkg/handlers/validation_test.go
  • pkg/api/node_pool_types_test.go
  • pkg/handlers/cluster_nodepools.go
  • pkg/logger/logger.go
test/integration/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

test/integration/**/*.go: Create integration tests using Testcontainers for isolated PostgreSQL instances per test
All API endpoints must be integrated tested in test/integration/ covering CRUD operations, pagination, search, and error cases

Files:

  • test/integration/api_contract_test.go
  • test/integration/node_pools_test.go
  • test/integration/clusters_test.go
  • test/integration/integration_test.go
pkg/api/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

Use //go:embed directive to embed the OpenAPI specification at compile time from pkg/api/openapi/api/openapi.yaml

Files:

  • pkg/api/presenters/adapter_status_test.go
  • pkg/api/cluster_types_test.go
  • pkg/api/node_pool_types_test.go
pkg/dao/**/*.go

📄 CodeRabbit inference engine (CLAUDE.md)

pkg/dao/**/*.go: Use context.Context as the first parameter in all DAO methods for transaction propagation
Increment generation field on each spec update to enable optimistic concurrency control
All DAO methods must support context-based session access for transaction participation

Files:

  • pkg/dao/mocks/generic.go
openapi/openapi.yaml

📄 CodeRabbit inference engine (CLAUDE.md)

TypeSpec definitions are maintained separately in hyperfleet-api-spec repository; only edit openapi/openapi.yaml in this repository for spec changes

Files:

  • openapi/openapi.yaml
🧠 Learnings (12)
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to pkg/db/migrations/**/*.go : Store cluster and nodepool specifications as JSONB in PostgreSQL schema, never as separate columns

Applied to files:

  • pkg/handlers/node_pool.go
  • test/integration/node_pools_test.go
  • pkg/handlers/cluster_nodepools.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to test/integration/**/*.go : All API endpoints must be integrated tested in test/integration/ covering CRUD operations, pagination, search, and error cases

Applied to files:

  • test/integration/api_contract_test.go
  • test/integration/node_pools_test.go
  • test/integration/clusters_test.go
  • test/integration/integration_test.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to pkg/api/**/*.go : Use //go:embed directive to embed the OpenAPI specification at compile time from pkg/api/openapi/api/openapi.yaml

Applied to files:

  • test/integration/api_contract_test.go
  • test/integration/node_pools_test.go
  • test/integration/integration_test.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to test/integration/**/*.go : Create integration tests using Testcontainers for isolated PostgreSQL instances per test

Applied to files:

  • test/integration/api_contract_test.go
  • test/integration/node_pools_test.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to test/factories/**/*.go : Use test data factories in test/factories/ to provide consistent test data instead of hardcoding values

Applied to files:

  • test/integration/api_contract_test.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to pkg/**/*.go : Implement JWT authentication middleware that validates tokens and extracts account ID and username from claims

Applied to files:

  • test/integration/node_pools_test.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to pkg/db/migrations/**/*.go : Use polymorphic adapter_statuses table with owner_type and owner_id columns instead of separate status tables per resource type

Applied to files:

  • pkg/api/presenters/adapter_status_test.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to pkg/services/**/*.go : Implement adapter status aggregation: phase is Ready if all adapters report Ready=True, Failed if any report Ready=False, NotReady otherwise

Applied to files:

  • pkg/api/presenters/adapter_status_test.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to pkg/dao/**/*.go : Increment generation field on each spec update to enable optimistic concurrency control

Applied to files:

  • pkg/dao/mocks/generic.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to pkg/dao/**/*.go : Use context.Context as the first parameter in all DAO methods for transaction propagation

Applied to files:

  • pkg/dao/mocks/generic.go
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: Applies to openapi/openapi.yaml : TypeSpec definitions are maintained separately in hyperfleet-api-spec repository; only edit openapi/openapi.yaml in this repository for spec changes

Applied to files:

  • openapi/openapi.yaml
📚 Learning: 2025-12-03T15:47:39.989Z
Learnt from: CR
Repo: openshift-hyperfleet/hyperfleet-api PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-03T15:47:39.989Z
Learning: HyperFleet API contains no business logic and creates no events; it is purely a data persistence and retrieval service

Applied to files:

  • openapi/openapi.yaml
🧬 Code graph analysis (6)
test/integration/api_contract_test.go (1)
pkg/api/status_types.go (6)
  • PhaseNotReady (10-10)
  • PhaseReady (11-11)
  • PhaseFailed (12-12)
  • ConditionTrue (20-20)
  • ConditionFalse (21-21)
  • ConditionUnknown (22-22)
test/integration/node_pools_test.go (1)
test/registration.go (1)
  • RegisterIntegration (13-24)
pkg/handlers/validation.go (1)
pkg/errors/errors.go (2)
  • ServiceError (100-109)
  • Validation (214-216)
pkg/api/cluster_types_test.go (1)
pkg/api/cluster_types.go (1)
  • Cluster (11-34)
test/integration/clusters_test.go (1)
test/registration.go (1)
  • RegisterIntegration (13-24)
pkg/api/node_pool_types_test.go (1)
pkg/api/node_pool_types.go (1)
  • NodePool (12-40)
🔇 Additional comments (27)
pkg/api/presenters/adapter_status_test.go (2)

197-197: ****


364-364: ****

pkg/dao/mocks/generic.go (1)

26-76: Update mock methods to include context.Context as the first parameter per DAO guidelines.

The coding guidelines require "context.Context as the first parameter in all DAO methods for transaction propagation." This mock currently implements Fetch, Count, Validate, Preload, OrderBy, Joins, Group, Where, GetTableName, and GetTableRelation without context parameters. Only GetInstanceDao includes context. Update these methods to accept context.Context as the first parameter to comply with the documented guidelines and enable transaction propagation through the mock.

test/integration/integration_test.go (1)

30-32: LGTM!

Comment alignment adjustments only; the path computation logic remains correct.

test/helper.go (1)

244-255: LGTM!

The API client configuration now explicitly targets the local test server, consistent with the pattern used in RestURL(). This ensures integration tests properly route requests to the test server.

pkg/handlers/validation.go (2)

45-80: LGTM!

The validateName function properly handles pointer dereferencing and validates in the correct order: nil → empty → min length → max length → pattern. Error messages are clear and informative.


82-107: LGTM!

The validateKind function correctly validates that the kind field matches the expected value, with proper pointer handling and clear error messages.

openapi/openapi.yaml (4)

7-9: LGTM!

Proper license information added to the API specification.


710-714: LGTM!

The minLength: 3 constraint aligns with the validateName function in Go code that enforces a minimum of 3 characters for cluster names.


1204-1206: Verify that removing the development server URL is intentional.

The server configuration was changed from a localhost development URL to a production URL. This may affect local development and testing workflows that rely on the OpenAPI spec for client generation or documentation.


364-368: BearerAuth security scheme is defined but not applied to operations.

The BearerAuth security scheme is added under components.securitySchemes, but it's not applied to any operations via security requirements (either globally or per-operation). If authentication is intended to be enforced, you'll need to add a global security section or per-operation security requirements.

pkg/handlers/node_pool.go (1)

118-130: LGTM!

Formatting alignment adjustments only; the struct definition and response logic remain unchanged.

pkg/handlers/cluster.go (1)

30-55: Create handler validation for Name/Kind looks correct and consistent

Adding validateName(&req, "Name", "name", 3, 63) and validateKind(&req, "Kind", "kind", "Cluster") in the Create handler cleanly enforces the new constraints before conversion and service calls, and matches the documented 3–63 length and specific kind requirement. No issues from the handler side.

pkg/handlers/cluster_nodepools.go (1)

64-76: List response struct change is cosmetic only

The nodePoolList struct alignment changes are whitespace-only; JSON tags and field types are unchanged, so behavior remains identical.

pkg/api/cluster_types_test.go (2)

70-83: Kind preservation tests correctly reflect new BeforeCreate semantics

TestCluster_BeforeCreate_KindPreservation now asserts that a pre‑set Kind: "Cluster" survives BeforeCreate unchanged, which matches the intent of removing Kind defaulting logic. The test is focused and clear.


191-202: Complete defaults test now properly includes explicit Kind

Updating TestCluster_BeforeCreate_Complete to set Kind: "Cluster" and assert that it’s preserved (instead of auto‑set) keeps this “all defaults” test consistent with the new Kind behavior while still checking the other defaulted fields.

test/integration/node_pools_test.go (2)

3-4: encoding/json import is appropriate and used

The added encoding/json import is required for the new error‑response parsing and has no unused‑import risk.


60-73: Adding Kind to NodePool create requests aligns tests with API requirements

Setting Kind: openapi.PtrString("NodePool") in both TestNodePoolPost and TestGetNodePoolByClusterIdAndNodePoolId ensures the happy‑path tests respect the new Kind requirement and still verify the returned Kind field.

pkg/handlers/validation_test.go (1)

1-147: Validation tests provide solid coverage of name and kind edge cases

These tests thoroughly exercise validateName and validateKind:

  • Valid and invalid patterns,
  • Min/max length boundaries,
  • Distinguishing “required” from “too short/too long” and “wrong kind”.

They should give good confidence that handler‑level validations behave as intended; no issues spotted.

test/integration/api_contract_test.go (1)

1-40: API contract tests are a good guardrail against constant drift

Both TestAPIContract_ResourcePhaseConstants and TestAPIContract_ConditionStatusConstants succinctly assert that domain constants match the generated OpenAPI enums. This is a low‑maintenance way to detect spec/code divergence early.

pkg/api/node_pool_types_test.go (2)

71-85: NodePool Kind preservation tests correctly reflect new behavior

TestNodePool_BeforeCreate_KindPreservation now verifies that a pre‑set Kind: "NodePool" is left untouched by BeforeCreate, which aligns with the removal of defaulting logic and the expectation that handlers validate/set Kind before persistence.


231-243: Complete NodePool defaults test now properly treats Kind as input, not default

In TestNodePool_BeforeCreate_Complete, explicitly setting Kind: "NodePool" and asserting it’s preserved (while other defaults are applied) keeps this aggregate test consistent with the new Kind semantics without weakening existing coverage of OwnerKind, StatusPhase, Href, etc.

test/integration/clusters_test.go (5)

225-247: Cluster name boundary tests now correctly assert 400 responses

Updating the “too long” and “empty” name cases in TestClusterBoundaryValues to expect http.StatusBadRequest (and an error for empty) matches the new handler‑level validation and OpenAPI constraints on cluster name length and non‑emptiness. This is the right behavior shift away from 5xxs.


269-279: Unicode name rejection test aligns with stricter name pattern

The new Unicode test case in TestClusterBoundaryValues asserting a 400 for names outside [a-z0-9-]+ gives good coverage for the pattern enforcement and ensures non‑ASCII names don’t slip through inadvertently.


483-485: Lowercasing ID prefix stabilizes name-based sorting tests

Using strings.ToLower(h.NewID()) in TestClusterList_DefaultSorting ensures the randomly generated ID fragment doesn’t introduce case‑sensitivity quirks into lexicographic ordering, making the name‑based assertions more robust.


531-538: OrderBy name test prefix change improves determinism

The testPrefix := fmt.Sprintf("name-sort-%s", strings.ToLower(h.NewID())) change in TestClusterList_OrderByName follows the same idea: consistently lowercased prefixes reduce the chance of flaky ordering tests due to mixed case.


581-586: Descending name sort test benefits from lowercased prefix as well

Similarly, in TestClusterList_OrderByNameDesc, using a lowercased random suffix for testPrefix keeps the desc‑ordering assertions deterministic across runs.

Comment on lines 30 to +32
// TODO username is unused, should we be logging it? Could be pii
username string
extra extra
username string
extra extra
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Remove the unused username field or resolve its TODO.

The username field is never populated in NewOCMLogger(), copied but unused in the logging logic, and has a TODO questioning whether it should be logged due to PII concerns. Either remove this dead code or implement proper username handling if it's genuinely needed.

Consider removing the unused field:

 type logger struct {
 	context   context.Context
 	level     int32
 	accountID string
-	// TODO username is unused, should we be logging it? Could be pii
-	username string
 	extra    extra
 }

And remove it from the V() method:

 func (l *logger) V(level int32) OCMLogger {
 	return &logger{
 		context:   l.context,
 		accountID: l.accountID,
-		username:  l.username,
 		level:     level,
 	}
 }

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In pkg/logger/logger.go around lines 30-32, the struct field `username` is
unused and flagged by a TODO; remove the dead `username string` field from the
logger struct, delete any references or assignments to it (including in
NewOCMLogger and any copy/clone logic), and update the V() method
signature/implementation to omit handling of username so the code compiles
cleanly; if username must be retained later, replace the field with an explicit,
documented decision (e.g., a nullable/scrubbed identity or a separate opt-in
metadata map) and adjust NewOCMLogger and V() to properly populate/handle it
with PII safeguards, but for now remove the unused field and associated code and
run `go build`/tests to ensure nothing else references it.

)

// Cluster/NodePool name pattern: lowercase alphanumeric and hyphens
var namePattern = regexp.MustCompile(`^[a-z0-9-]+$`)
Copy link
Contributor

Choose a reason for hiding this comment

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

CodeRabbit suggest to use a stricter regex to have names compatible with Kubernetes.
Even though we will use Ids as kubernetes object names, I think it makes sense to have that stricter rule.
And change it also in the spec.
wdyt?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Agree with that. Let us make it stricter to comply with the RFC 1123 guidelines.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fix in #16

@openshift-ci
Copy link

openshift-ci bot commented Dec 9, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: rh-amarin, yasun1

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

The pull request process is described 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-merge-bot openshift-merge-bot bot merged commit 9ffd6d0 into openshift-hyperfleet:main Dec 9, 2025
7 checks passed
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.

2 participants