Skip to content

ROSAENG-62444: feat: replace DynamoDB Streams informer with EventBridge Pipes for specs and status paths - #291

Open
rrp-bot wants to merge 4 commits into
openshift-online:mainfrom
rrp-bot:feature/eventbridge-pipes
Open

ROSAENG-62444: feat: replace DynamoDB Streams informer with EventBridge Pipes for specs and status paths#291
rrp-bot wants to merge 4 commits into
openshift-online:mainfrom
rrp-bot:feature/eventbridge-pipes

Conversation

@rrp-bot

@rrp-bot rrp-bot commented Aug 7, 2026

Copy link
Copy Markdown

Summary

Remove the DynamoDB Streams-based status polling from the hyperfleet-operator and replace with EventBridge Pipes → SQS delivery. Introduces statussqsconsumer for per-replica SQS queue polling.

Why: The previous approach required the operator to poll DynamoDB Streams directly for status change events, which is complex to manage across replicas and requires stream-level IAM access. EventBridge Pipes now reads INSERT/MODIFY events from the RC status DynamoDB Streams and delivers documentIDs to per-replica SQS queues. Each operator replica polls its own queue (index derived from pod name suffix).

Commits

  • feat: replace DynamoDB Streams informer with EventBridge Pipes for specs and status paths — deletes dynamo/snspublisher package, deletes dynamo/statusstream package, introduces dynamo/statussqsconsumer, wires into manager startup
  • fix: detect unresolved EventBridge JSONPath placeholders in status consumer — guards against literal <$.path> placeholder documentIDs, updates StatusNotification comment

Related PRs

Testing

Unit tests cover the consumer happy path and placeholder guard. Integration tests exercise the full operator stack.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Summary by CodeRabbit

  • New Features

    • Status notifications now use dedicated SQS queues instead of DynamoDB Streams.
    • Added Helm configuration for SQS queue URL prefixes, including per-replica queue support.
    • The operator processes valid status messages and removes them after handling.
  • Bug Fixes

    • Improved handling of malformed, empty, unresolved, or temporarily unavailable status messages.
    • Enhanced test-resource cleanup to retry during concurrent operations.

@openshift-ci

openshift-ci Bot commented Aug 7, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: rrp-bot
Once this PR has been reviewed and has the lgtm label, please assign slopezz 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 added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Aug 7, 2026
@openshift-ci

openshift-ci Bot commented Aug 7, 2026

Copy link
Copy Markdown

Hi @rrp-bot. Thanks for your PR.

I'm waiting for a openshift-online member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work.

Tip

We noticed you've done this a few times! Consider joining the org to skip this step and gain /lgtm and other bot rights. We recommend asking approvers on your previous PRs to sponsor you.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

Details

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 kubernetes-sigs/prow repository.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

The operator replaces DynamoDB Streams status watching with per-replica SQS consumption. Helm and manager configuration resolve queue URLs. Integration simulators dispatch events after successful status writes.

Changes

SQS status migration

Layer / File(s) Summary
Queue configuration and consumer contract
hyperfleet-operator/charts/..., hyperfleet-operator/cmd/manager/main.go, hyperfleet-operator/internal/dynamo/statussqsconsumer/consumer.go, hyperfleet-operator/go.mod
Helm defines the queue URL prefix. The manager validates and resolves the queue URL, creates an SQS client, and starts the consumer. The consumer defines its notification contract and client interface.
SQS polling and event dispatch
hyperfleet-operator/internal/dynamo/statussqsconsumer/*, hyperfleet-operator/cmd/manager/main.go
The consumer polls SQS, validates notifications, dispatches document IDs, deletes messages, retries receive errors, and stops on cancellation. Tests cover dispatch, deletion ordering, invalid messages, retries, and shutdown.
Status writes and integration validation
hyperfleet-operator/internal/dynamo/client.go, hyperfleet-operator/test/suite_test.go, hyperfleet-operator/test/helpers_test.go
DynamoDB upsert methods propagate results and errors. Simulators dispatch events after successful writes. Resource cleanup retries list, update, and delete failures.

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

Sequence Diagram(s)

sequenceDiagram
  participant StatefulSet
  participant Manager
  participant SQS
  participant StatusSQSConsumer
  participant EventRouter
  StatefulSet->>Manager: Provide SQS queue URL prefix
  Manager->>Manager: Resolve queue URL from pod ordinal
  Manager->>SQS: Create SQS client
  Manager->>StatusSQSConsumer: Start consumer
  SQS->>StatusSQSConsumer: Return status notification
  StatusSQSConsumer->>EventRouter: Dispatch document ID
  StatusSQSConsumer->>SQS: Delete processed message
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 consumer.go logs the raw SQS receiptHandle on DeleteMessage errors and logs documentID and queueURL, which may expose token-like credentials and customer or infrastructure identifiers. Do not log receiptHandle, documentID, or full queueURL. Log only a redacted/hash identifier or static context, plus the error.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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 explicit, but all three feature commits use Co-Authored-By: Claude Sonnet 4.6; no Assisted-by or Generated-by trailer is present. Replace the AI Co-Authored-By trailers with the repository-approved Assisted-by or Generated-by Red Hat attribution trailer.
✅ Passed checks (8 passed)
Check name Status Explanation
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 The full PR diff adds no MD5, SHA-1, DES, 3DES, RC4, Blowfish, ECB, custom crypto, or secret/token comparisons.
Container-Privileges ✅ Passed Workload manifests set runAsNonRoot=true, allowPrivilegeEscalation=false, RuntimeDefault, and drop ALL capabilities; no privileged, host PID/network/IPC, or SYS_ADMIN settings are present.
No-Hardcoded-Secrets ✅ Passed No hardcoded secrets were added; queue values are empty or non-credential URLs, test values are placeholders, and only added base64-like strings are go.sum module checksums.
No-Injection-Vectors ✅ Passed No listed injection APIs appear in the PR changes. SQS data is JSON-decoded and passed only as an EventRouter map key; DynamoDB uses typed SDK inputs, not SQL.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: replacing DynamoDB Streams with EventBridge Pipes for specification and status delivery.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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: 5

🤖 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-operator/cmd/manager/main.go`:
- Around line 100-105: Update the pod ordinal handling around podOrdinal() so
Atoi parse failures are propagated instead of treating the returned zero as
valid. Ensure the manager exits or returns the error before constructing
sqsStatusQueueURL, while preserving normal prefix URL construction for valid
ordinals.
- Around line 219-226: Delay starting statusConsumer.Run until
mgr.Start(signalCtx) has completed initial route registration, or otherwise
buffer messages until EventRouter can accept them; update the startup flow
around EventRouter.Dispatch and statusConsumer.Run while preserving cancellation
via watchCtx and watchCancel.
- Around line 224-226: Update the watch context initialization near
statusConsumer.Run to derive watchCtx from signalCtx instead of
context.Background(), while retaining its cancellation cleanup. This ensures the
consumer stops when manager shutdown begins through signalCtx.

In `@hyperfleet-operator/internal/dynamo/statussqsconsumer/consumer.go`:
- Around line 117-120: Update the JSON unmarshal error handling in the SQS
consumer to stop logging the complete message body. Keep logging the decode
error and include only safe metadata, such as the message identifier or receipt
context, while preserving deletion through deleteMessage.

In `@hyperfleet-operator/test/helpers_test.go`:
- Around line 39-62: Update the cleanup retry callback in Eventually to return
the first error from any c.List, SetFinalizers-related c.Update, or c.Delete
operation instead of discarding errors. Propagate each failure immediately so
retries report the failed Kubernetes operation, and return the success value
only after all ClusterList, NodePoolList, and ManifestList cleanup completes.
🪄 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: Pro Plus

Run ID: 2469c074-dbd7-45b4-8a7b-1c49f11e1bf0

📥 Commits

Reviewing files that changed from the base of the PR and between f659207 and b00a2bf.

⛔ Files ignored due to path filters (1)
  • hyperfleet-operator/go.sum is excluded by !**/*.sum
📒 Files selected for processing (12)
  • hyperfleet-operator/charts/templates/statefulset.yaml
  • hyperfleet-operator/charts/values.yaml
  • hyperfleet-operator/cmd/manager/main.go
  • hyperfleet-operator/go.mod
  • hyperfleet-operator/internal/dynamo/client.go
  • hyperfleet-operator/internal/dynamo/statussqsconsumer/consumer.go
  • hyperfleet-operator/internal/dynamo/statussqsconsumer/consumer_test.go
  • hyperfleet-operator/internal/dynamo/statusstream/manager.go
  • hyperfleet-operator/internal/dynamo/statusstream/watcher.go
  • hyperfleet-operator/internal/dynamo/statusstream/watcher_test.go
  • hyperfleet-operator/test/helpers_test.go
  • hyperfleet-operator/test/suite_test.go
💤 Files with no reviewable changes (3)
  • hyperfleet-operator/internal/dynamo/statusstream/watcher.go
  • hyperfleet-operator/internal/dynamo/statusstream/manager.go
  • hyperfleet-operator/internal/dynamo/statusstream/watcher_test.go

Comment on lines +100 to +105
// If a prefix was given, construct the full queue URL by appending the
// pod ordinal — matching the queue naming convention:
// <prefix><ordinal> e.g. https://sqs…/regional-hyperfleet-operator-2
if sqsStatusQueueURLPrefix != "" {
sqsStatusQueueURL = fmt.Sprintf("%s%d", sqsStatusQueueURLPrefix, ordinal)
}

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Fail when the pod ordinal is invalid.

podOrdinal() returns (0, nil) when strconv.Atoi fails. This prefix path then consumes replica 0's queue. Return the parse error so an invalid hostname cannot create competing consumers for the same queue.

🤖 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 `@hyperfleet-operator/cmd/manager/main.go` around lines 100 - 105, Update the
pod ordinal handling around podOrdinal() so Atoi parse failures are propagated
instead of treating the returned zero as valid. Ensure the manager exits or
returns the error before constructing sqsStatusQueueURL, while preserving normal
prefix URL construction for valid ordinals.

Comment thread hyperfleet-operator/cmd/manager/main.go Outdated
Comment thread hyperfleet-operator/cmd/manager/main.go Outdated
Comment thread hyperfleet-operator/internal/dynamo/statussqsconsumer/consumer.go
Comment thread hyperfleet-operator/test/helpers_test.go Outdated
@rrp-bot
rrp-bot force-pushed the feature/eventbridge-pipes branch from 8172b92 to 6848565 Compare August 11, 2026 09:03
@psav psav changed the title feat: replace DynamoDB Streams informer with EventBridge Pipes for specs and status paths ROSAENG-62444: feat: replace DynamoDB Streams informer with EventBridge Pipes for specs and status paths Aug 12, 2026
@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 12, 2026
@openshift-ci-robot

openshift-ci-robot commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

@rrp-bot: This pull request references ROSAENG-62444 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 story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

Remove the DynamoDB Streams-based status polling from the hyperfleet-operator and replace with EventBridge Pipes → SQS delivery. Introduces statussqsconsumer for per-replica SQS queue polling.

Why: The previous approach required the operator to poll DynamoDB Streams directly for status change events, which is complex to manage across replicas and requires stream-level IAM access. EventBridge Pipes now reads INSERT/MODIFY events from the RC status DynamoDB Streams and delivers documentIDs to per-replica SQS queues. Each operator replica polls its own queue (index derived from pod name suffix).

Commits

  • feat: replace DynamoDB Streams informer with EventBridge Pipes for specs and status paths — deletes dynamo/snspublisher package, deletes dynamo/statusstream package, introduces dynamo/statussqsconsumer, wires into manager startup
  • fix: detect unresolved EventBridge JSONPath placeholders in status consumer — guards against literal <$.path> placeholder documentIDs, updates StatusNotification comment

Related PRs

Testing

Unit tests cover the consumer happy path and placeholder guard. Integration tests exercise the full operator stack.

Co-Authored-By: Claude Sonnet 4.6 noreply@anthropic.com

Summary by CodeRabbit

  • New Features

  • Status notifications now use dedicated SQS queues instead of DynamoDB Streams.

  • Added Helm configuration for SQS queue URL prefixes, including per-replica queue support.

  • The operator processes valid status messages and removes them after handling.

  • Bug Fixes

  • Improved handling of malformed, empty, unresolved, or temporarily unavailable status messages.

  • Enhanced test-resource cleanup to retry during concurrent operations.

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.

rrp-bot and others added 4 commits August 12, 2026 14:42
…ecs and status paths

Remove the dynamo stream-based polling from the hyperfleet-operator entirely.
The operator previously relied on DynamoDB Streams informers for desire-write
notifications on the specs path, and kube-applier published status updates
back. Both paths are now driven by EventBridge Pipes reading directly from
DynamoDB Streams and delivering to SQS queues.

Changes:
- Delete hyperfleet-operator/internal/dynamo/snspublisher/ package entirely
- Remove SNSPublisher interface and NewClientWithSNS constructor from dynamo client
- Remove --sns-status-topic-arn flag from operator options
- Add statussqsconsumer package: polls per-replica SQS queue for status
  documentID notifications delivered by EventBridge Pipes
- Wire statussqsconsumer into manager startup; consumer index derived from
  pod name suffix for deterministic queue assignment
- go.mod/go.sum: add aws-sdk-go-v2/service/sqs dependency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…nsumer

Add a guard in handleMessage that detects when documentID is a literal
<$.path> placeholder — caused by jsonencode() in the pipe's input_template.
Previously these messages would pass the empty-string check and be dispatched
to EventRouter with a nonsense key, silently dropped with no error logged.

Also update StatusNotification comment to reflect the SQS delivery path and
import strings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- consumer.go: remove SQS message body from error log to avoid
  leaking customer data in log output
- main.go: derive consumer context from signalCtx so the consumer
  shuts down cleanly on manager termination; delay consumer start
  until mgr.GetCache().WaitForCacheSync() so all controllers have
  registered their EventRouter routes before messages are dispatched
  (messages dispatched before route registration are silently dropped
  and deleted, losing the notification)
- test/helpers_test.go: return errors from c.List, c.Update, c.Delete
  in the Eventually cleanup callback instead of discarding them, so
  test retries report the failing Kubernetes operation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@rrp-bot
rrp-bot force-pushed the feature/eventbridge-pipes branch from 3dba255 to dbac28c Compare August 12, 2026 14:42
@cdoan1

cdoan1 commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

/ok-to-test

@openshift-ci openshift-ci Bot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Aug 12, 2026
@openshift-ci

openshift-ci Bot commented Aug 12, 2026

Copy link
Copy Markdown

@rrp-bot: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/lint dbac28c link true /test lint

Full PR test history. Your PR dashboard.

Details

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 kubernetes-sigs/prow repository. I understand the commands that are listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. ok-to-test Indicates a non-member PR verified by an org member that is safe to test.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants