Skip to content

ROSAENG-1089: ensure unique hash4 DNS slug per cluster name - #308

Merged
openshift-merge-bot[bot] merged 1 commit into
openshift-online:mainfrom
typeid:avoid_dns_collision
Aug 11, 2026
Merged

ROSAENG-1089: ensure unique hash4 DNS slug per cluster name#308
openshift-merge-bot[bot] merged 1 commit into
openshift-online:mainfrom
typeid:avoid_dns_collision

Conversation

@typeid

@typeid typeid commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add ListClustersByName to the platform-api's hyperfleetdb client wrapper to query clusters by name across all accounts (uses field selector pushdown to SQL)
  • Add HasHash4Collision helper to check whether any existing cluster shares a 4-char UUID prefix
  • Add collision check + retry loop (max 5 attempts) in the Create handler, after UUID generation
  • Update cluster-controller docs to document the uniqueness guarantee

Test plan

  • TestClient_ListClustersByName — cross-account listing by name
  • TestHasHash4Collision — table-driven tests for collision detection (match, no match, empty list, short/empty InternalID)
  • TestClusterHandler_Create_Hash4NoCollision — handler-level test with pre-existing cluster
  • Existing Create handler tests updated with field indexer for metadata.name
  • make test-api — all tests pass
  • make lint — 0 issues

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Cluster DNS identifiers are now guaranteed to be unique among active clusters.
    • Cluster creation automatically retries when a DNS identifier collision occurs.
    • Concurrent cluster creation requests are handled safely, allowing only valid unique identifiers.
  • Bug Fixes

    • Persistent identifier collisions now return a clear internal error instead of an incorrect conflict response.
  • Documentation

    • Updated cluster DNS documentation to explain identifier generation, uniqueness validation, collision retries, and available identifier limits.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Aug 11, 2026
@openshift-ci-robot

openshift-ci-robot commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

@typeid: This pull request references ROSAENG-1089 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the sub-task to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Add ListClustersByName to the platform-api's hyperfleetdb client wrapper to query clusters by name across all accounts (uses field selector pushdown to SQL)
  • Add HasHash4Collision helper to check whether any existing cluster shares a 4-char UUID prefix
  • Add collision check + retry loop (max 5 attempts) in the Create handler, after UUID generation
  • Update cluster-controller docs to document the uniqueness guarantee

Test plan

  • TestClient_ListClustersByName — cross-account listing by name
  • TestHasHash4Collision — table-driven tests for collision detection (match, no match, empty list, short/empty InternalID)
  • TestClusterHandler_Create_Hash4NoCollision — handler-level test with pre-existing cluster
  • Existing Create handler tests updated with field indexer for metadata.name
  • make test-api — all tests pass
  • make lint — 0 issues

🤖 Generated with Claude Code

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: openshift-online/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: a9412432-3d27-4c48-9d44-bfc740dce824

📥 Commits

Reviewing files that changed from the base of the PR and between 6be81a0 and c9df088.

📒 Files selected for processing (3)
  • hyperfleet-operator/docs/cluster-controller.md
  • platform-api/pkg/handlers/cluster.go
  • platform-api/pkg/handlers/cluster_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • hyperfleet-operator/docs/cluster-controller.md
  • platform-api/pkg/handlers/cluster.go

Walkthrough

Cluster creation now derives DNS prefixes from UUIDs, enforces active-cluster uniqueness in PostgreSQL, retries prefix collisions up to five times, and documents and tests the behavior, including concurrent creation.

Changes

Cluster DNS uniqueness

Layer / File(s) Summary
Active cluster uniqueness constraint
hyperfleet-db/internal/schema/migrations/002_cluster_dns_uniqueness.sql, hyperfleet-db/internal/schema/schema.go
Adds and registers a partial unique index for active clusters using the name and first four InternalID characters.
Cluster creation retry flow
platform-api/pkg/handlers/cluster.go
Adds injectable UUID generation and retries creation up to five times after AlreadyExists errors. Exhausted retries return CLUSTERS-MGMT-CREATE-007.
Collision validation and documentation
platform-api/pkg/handlers/cluster_test.go, hyperfleet-operator/docs/cluster-controller.md
Tests successful retries, exhausted retries, and concurrent collisions. Documents UUID-derived hash4 uniqueness and retry limits.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: cdoan1

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant ClusterHandler
  participant Database
  Client->>ClusterHandler: Submit cluster creation
  ClusterHandler->>ClusterHandler: Generate UUID
  ClusterHandler->>Database: Create cluster
  Database-->>ClusterHandler: Success or AlreadyExists
  ClusterHandler->>ClusterHandler: Retry with new UUID up to five times
  ClusterHandler-->>Client: Return creation result
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error The changed Create path logs user-supplied req.Name as cluster_name and accountID in production; retries repeat these customer identifiers in logs. Remove cluster_name and account_id from this log, or use approved redacted identifiers. Do not log user-supplied customer names.
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Ai-Attribution ⚠️ Warning AI use is stated in the PR, but HEAD has only Co-Authored-By: Claude Opus 4.6 and no Assisted-by or Generated-by trailer. Replace the AI Co-Authored-By trailer with the required Assisted-by or Generated-by trailer.
✅ Passed checks (8 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enforcing unique hash4 DNS slugs for cluster names.
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.
No-Weak-Crypto ✅ Passed Changed files add no MD5, SHA1, DES, RC4, Blowfish, ECB, custom crypto, or secret comparisons; UUID v4 uses crypto/rand and comparisons cover names/UUID prefixes.
Container-Privileges ✅ Passed The PR changes only Go, SQL, and Markdown files. No container or Kubernetes manifest changed, and scans found no forbidden privilege, host namespace, SYS_ADMIN, or root settings.
No-Hardcoded-Secrets ✅ Passed No hardcoded secrets, API keys, tokens, passwords, private keys, base64 strings >32 chars, or embedded credentials found in any PR files.
No-Injection-Vectors ✅ Passed No injection vectors detected. SQL migrations embedded as static files without concatenation. All user inputs (cluster name, ID) properly handled via Kubernetes client API, not raw SQL. Error messa...
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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)
platform-api/pkg/handlers/cluster_test.go (1)

565-593: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift

Add deterministic coverage for hash4 collisions.

Line 565 only verifies the no-collision path. The direct uuid.New() call prevents this test from forcing a collision. Inject an ID generator into ClusterHandler. Test one collision followed by a unique prefix. Test five collisions and verify CLUSTERS-MGMT-CREATE-007.

🤖 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 `@platform-api/pkg/handlers/cluster_test.go` around lines 565 - 593, Add an
injectable ID generator to ClusterHandler and replace the direct uuid.New() call
in the create flow with it. Extend TestClusterHandler_Create_Hash4NoCollision
with deterministic generator values, then add coverage for one hash4 collision
followed by a unique ID and for five consecutive collisions, asserting the
latter returns CLUSTERS-MGMT-CREATE-007.
🤖 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 `@platform-api/pkg/handlers/cluster.go`:
- Around line 141-159: Make cluster creation enforce (name, hash4) uniqueness
atomically in the persistence operation rather than relying on the preflight
ListClustersByName check in the cluster handler; retry UUID generation only when
that atomic create operation reports a uniqueness conflict, while preserving
non-conflict errors. Update hyperfleet-operator/docs/cluster-controller.md:75 to
claim the uniqueness guarantee only after the persistence layer provides this
atomic enforcement.
- Around line 141-155: Remove the request-derived cluster_name field from both
logger.Error calls in the cluster creation flow around ListClustersByName and
the hash4 retry loop. Keep the existing error messages and other non-sensitive
fields unchanged, without introducing another request-provided identifier.

---

Nitpick comments:
In `@platform-api/pkg/handlers/cluster_test.go`:
- Around line 565-593: Add an injectable ID generator to ClusterHandler and
replace the direct uuid.New() call in the create flow with it. Extend
TestClusterHandler_Create_Hash4NoCollision with deterministic generator values,
then add coverage for one hash4 collision followed by a unique ID and for five
consecutive collisions, asserting the latter returns CLUSTERS-MGMT-CREATE-007.
🪄 Autofix

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: Repository: openshift-online/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 84f23557-b47f-4b05-8e98-31aa90968ce1

📥 Commits

Reviewing files that changed from the base of the PR and between fd74585 and 4ffe943.

📒 Files selected for processing (5)
  • hyperfleet-operator/docs/cluster-controller.md
  • platform-api/pkg/clients/hyperfleetdb/client.go
  • platform-api/pkg/clients/hyperfleetdb/client_test.go
  • platform-api/pkg/handlers/cluster.go
  • platform-api/pkg/handlers/cluster_test.go

Comment thread platform-api/pkg/handlers/cluster.go Outdated
Comment thread platform-api/pkg/handlers/cluster.go Outdated
@typeid
typeid force-pushed the avoid_dns_collision branch from 4ffe943 to 3e52602 Compare August 11, 2026 08:18

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 `@platform-api/pkg/handlers/cluster_test.go`:
- Around line 604-680: Add a coordinated concurrent-create test around
ClusterHandler.Create that submits same-name requests producing the same hash4
and verifies only one succeeds while the other receives the established conflict
response. Enforce this through an atomic shared-store reservation or datastore
unique constraint in the create path, using the persistent store as the source
of truth rather than a process-local lock; preserve the existing retry behavior
for collisions.
🪄 Autofix

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: Repository: openshift-online/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: e36e7a73-898a-4057-9764-c582a369d2e0

📥 Commits

Reviewing files that changed from the base of the PR and between 4ffe943 and 3e52602.

📒 Files selected for processing (2)
  • platform-api/pkg/handlers/cluster.go
  • platform-api/pkg/handlers/cluster_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • platform-api/pkg/handlers/cluster.go

Comment thread platform-api/pkg/handlers/cluster_test.go
@typeid
typeid force-pushed the avoid_dns_collision branch from 3e52602 to 1bf4bd2 Compare August 11, 2026 08:40

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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 `@hyperfleet-db/internal/schema/migrations/002_cluster_dns_uniqueness.sql`:
- Around line 6-10: Update the index definition in the migration by changing
CREATE UNIQUE INDEX to CREATE UNIQUE INDEX CONCURRENTLY for
idx_cluster_name_hash4, preserving the existing table, expressions, and WHERE
conditions.

In `@platform-api/pkg/handlers/cluster_test.go`:
- Around line 593-596: Handle all serialization and deserialization errors in
the cluster handler tests: check json.Marshal at
platform-api/pkg/handlers/cluster_test.go lines 593-596, 623-626, 665-668, and
742-745, and check response decode errors at lines 638-640 and 680-683. Fail
each test immediately when an error occurs, without ignoring any error returns.
🪄 Autofix

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: Repository: openshift-online/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 5ee39efc-aaff-4f9d-bc5f-4e15f633617a

📥 Commits

Reviewing files that changed from the base of the PR and between 3e52602 and 1bf4bd2.

📒 Files selected for processing (3)
  • hyperfleet-db/internal/schema/migrations/002_cluster_dns_uniqueness.sql
  • hyperfleet-db/internal/schema/schema.go
  • platform-api/pkg/handlers/cluster_test.go

Comment thread platform-api/pkg/handlers/cluster_test.go Outdated
@typeid
typeid force-pushed the avoid_dns_collision branch from 1bf4bd2 to 6be81a0 Compare August 11, 2026 09:14
Add a cross-account collision check in the platform-api Create handler
that queries all clusters sharing the same name and verifies no existing
cluster has a matching 4-character UUID prefix. On collision, the UUID
is regenerated (up to 5 attempts). UUID generation is injectable for
deterministic testing of collision and retry paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@cdoan1

cdoan1 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

/lgtm

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Aug 11, 2026
@openshift-ci

openshift-ci Bot commented Aug 11, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cdoan1, typeid

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 0e12a93 into openshift-online:main Aug 11, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. review-ready

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants