Skip to content

HYPERFLEET-1490 - feat: add hyperfleet.resource_id span attribute to service layer - #328

Open
Ruclo wants to merge 1 commit into
openshift-hyperfleet:mainfrom
Ruclo:HYPERFLEET-1490
Open

HYPERFLEET-1490 - feat: add hyperfleet.resource_id span attribute to service layer#328
Ruclo wants to merge 1 commit into
openshift-hyperfleet:mainfrom
Ruclo:HYPERFLEET-1490

Conversation

@Ruclo

@Ruclo Ruclo commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Set hyperfleet.resource_id and hyperfleet.resource_type span attributes on Get, Create, Patch, and Delete operations in pkg/services/resource.go
  • Enables resource-level trace correlation in Tempo — operators can query traces by resource ID to find the API request that created or mutated a specific cluster or nodepool
  • Add unit tests using tracetest.InMemoryExporter verifying span attributes are set for all 4 CRUD methods

Test plan

  • make lint passes (0 issues)
  • make test passes (1428 tests)
  • 4 new span attribute tests pass (Get, Create, Patch, Delete)

🤖 Generated with Claude Code

@openshift-ci
openshift-ci Bot requested review from pnguyen44 and sherine-k August 6, 2026 13:19
@openshift-ci

openshift-ci Bot commented Aug 6, 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 rh-amarin 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 Aug 6, 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: 470605be-1b72-42ad-8a7c-63daed8d80e6

📥 Commits

Reviewing files that changed from the base of the PR and between c746c38 and abeabd3.

📒 Files selected for processing (1)
  • pkg/services/resource.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 as they are similar to previous changes (1)
  • pkg/services/resource.go

📝 Walkthrough

Summary by CodeRabbit

  • Observability

    • Resource operations now include resource IDs and types in OpenTelemetry traces, improving monitoring and troubleshooting.
  • Tests

    • Expanded coverage to verify tracing attributes across resource retrieval, creation, updates, deletion, ownership queries, forced deletion, and adapter status processing.

Walkthrough

The resource service now records hyperfleet.resource_id and hyperfleet.resource_type on OpenTelemetry spans. Coverage includes creation, retrieval, update, deletion, owner lookup, adapter status processing, and force deletion. Tests use an in-memory exporter and cover successful and failed operations.

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

Suggested reviewers: sherine-k

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding the hyperfleet.resource_id span attribute to the service layer.
Description check ✅ Passed The description accurately covers the span attributes, affected operations, trace correlation use case, and test coverage.
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 eligible log call includes a token, password, credential, or secret field/value; request headers are masked and DB strings are redacted. No CWE-532 finding.
No Hardcoded Secrets ✅ Passed The patch changes only two Go files. Added-line scans found no API keys, tokens, passwords, embedded URL credentials, private-key markers, or secret base64 strings; no CWE-798 finding.
No Weak Cryptography ✅ Passed PR changes only tracing and test code; no crypto/md5, crypto/des, crypto/rc4, SHA-1, ECB, custom crypto, or secret comparisons were found (CWE-327/CWE- timing risks absent).
No Injection Vectors ✅ Passed The production diff adds only OpenTelemetry attributes and validation. It adds no fmt.Sprintf query, command, YAML, template.HTML, or raw SQL sink; existing query formatting is unchanged.
No Privileged Containers ✅ Passed No CWE-250 finding: only Go files changed; Helm defaults use runAsNonRoot, UID 65532, dropped ALL capabilities, and allowPrivilegeEscalation false. Dockerfile root use is documented for make instal...
No Pii Or Sensitive Data In Logs ✅ Passed The PR adds only OpenTelemetry span attributes and tests; no slog, logr, zap, log, or fmt.Print* logging statements were added.
✨ 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: 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 `@pkg/services/resource_test.go`:
- Around line 3160-3163: Update the t.Cleanup callback around tp.Shutdown to
check and report its error, and ensure all four ForceFlush results are checked
and reported rather than ignored. Use the test’s existing error-reporting
mechanism so incomplete span export or shutdown failures fail the test.
🪄 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: Central YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 30542a9b-4b85-44d4-9812-6fa69da75e45

📥 Commits

Reviewing files that changed from the base of the PR and between cf39733 and 6117674.

📒 Files selected for processing (2)
  • pkg/services/resource.go
  • pkg/services/resource_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/services/resource_test.go
@hyperfleet-ci-bot

hyperfleet-ci-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

Risk Score: 1 — risk/low

Signal Detail Points
PR size 274 lines (>200) +1
Sensitive paths none +0
Test coverage Tests cover changed packages +0

Computed by hyperfleet-risk-scorer

@Ruclo
Ruclo force-pushed the HYPERFLEET-1490 branch from 6117674 to fbc5598 Compare August 6, 2026 13:31
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

Comment thread pkg/services/resource.go
Comment on lines +70 to +73
trace.SpanFromContext(ctx).SetAttributes(
attribute.String("hyperfleet.resource_id", id),
attribute.String("hyperfleet.resource_type", kind),
)

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.

hyperfleet.resource_type is set to the Kind (e.g. "Cluster") here and at the other three call sites, but the Tracing Standard and Sentinel's existing spans use the plural form (e.g. "clusters"). This mismatch means a TraceQL query on resource_type won't match across API and Sentinel spans for the same resource. Consider using the descriptor's plural form instead.

Comment on lines +3151 to +3166
func setupTestTracer(t *testing.T) (*sdktrace.TracerProvider, *tracetest.InMemoryExporter) {
t.Helper()
exporter := tracetest.NewInMemoryExporter()
tp := sdktrace.NewTracerProvider(
sdktrace.WithSampler(sdktrace.AlwaysSample()),
sdktrace.WithSyncer(exporter),
)
prev := otel.GetTracerProvider()
otel.SetTracerProvider(tp)
t.Cleanup(func() {
if err := tp.Shutdown(context.Background()); err != nil {
t.Errorf("failed to shutdown tracer: %v", err)
}
otel.SetTracerProvider(prev)
})
return tp, exporter

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.

setupTestTracer swaps the global otel TracerProvider for the test, then each test starts its span via the global otel.Tracer rather than the tp returned by this helper. Using tp.Tracer(...) directly would avoid touching process-global state, which would remove a potential source of flakiness if t.Parallel() is ever added to these tests.

@pnguyen44

pnguyen44 commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

A few service methods aren't instrumented with these span attributes and would miss tracing coverage:

  • GetByID — used by GET /resources/{id}, ForceDelete, ListStatuses, and CreateStatus
  • ProcessAdapterStatus — used when adapters report status back to the API

Comment thread pkg/services/resource_test.go Outdated
Comment thread pkg/services/resource_test.go Outdated
Comment thread pkg/services/resource.go Outdated
Comment thread pkg/services/resource_test.go Outdated
@Ruclo
Ruclo force-pushed the HYPERFLEET-1490 branch from fbc5598 to c746c38 Compare August 7, 2026 10:21
…service layer

Set hyperfleet.resource_id and hyperfleet.resource_type span attributes
on Get, Create, Patch, and Delete operations for resource-level trace
correlation in Tempo.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@Ruclo
Ruclo force-pushed the HYPERFLEET-1490 branch from c746c38 to abeabd3 Compare August 7, 2026 10:56
@Ruclo
Ruclo requested a review from pnguyen44 August 7, 2026 11:19
Comment thread pkg/services/resource.go
Comment on lines 67 to 76
if svcErr := validateKind(kind); svcErr != nil {
return nil, svcErr
}
trace.SpanFromContext(ctx).SetAttributes(
attribute.String("hyperfleet.resource_id", id),
attribute.String("hyperfleet.resource_type", registry.MustGet(kind).Plural),
)
resource, err := s.resourceDao.Get(ctx, kind, id)
if err != nil {
return nil, handleGetError(kind, "id", id, err)

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.

The same two attributes end up getting set in four different orderings across the 8 instrumented methods here (Get/Patch/Delete tag both together after validateKind, Create splits type-early/id-late, GetByOwner/ProcessAdapterStatus/ForceDelete tag id before validateKind, GetByID tags id before the DAO call). None of these are unsafe, but on an invalid kind, some methods leave the span fully untagged while others still tag resource_id. Worth picking one ordering convention and applying it everywhere for consistency.

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.

2 participants