Skip to content

fix: Use pointer-to-struct for fields with json omitempty#1063

Merged
openshift-merge-bot[bot] merged 1 commit into
rhobs:mainfrom
alanconway:go-api-fixes
May 14, 2026
Merged

fix: Use pointer-to-struct for fields with json omitempty#1063
openshift-merge-bot[bot] merged 1 commit into
rhobs:mainfrom
alanconway:go-api-fixes

Conversation

@alanconway
Copy link
Copy Markdown
Contributor

@alanconway alanconway commented Apr 20, 2026

Use pointers for API struct fields marked "omitempty".

"omitempty" does not work on non-pointer struct fields.
A zero valued struct will serialize at least as "{}" and may contain zero valued fields
if any fields are not "omitempty".
This can cause problems with default values and round-trip (de)serialization
and break even if the kubebuilder "+optional" comment is applied.

Additional fixes:

  • Rename TracingObjectStorageSpec.GCSSTSSpec to GCSWIF to match its type and json tag
  • Update CEL validation rule to handle nil storage/objectStorage with has() guards
  • Add nil guards for Tracing, Storage, ObjectStorageSpec, and Operators in controller code
  • Remove spurious omitempty from required S3Spec.AccessKeySecret field
  • Fix ConfigMapKeySelector doc comments that incorrectly referenced "Secret"

@openshift-ci openshift-ci Bot requested review from pavolloffay and slashpai April 20, 2026 20:19
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 20, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 0da7a399-0aca-4822-95ac-899781ad6ce6

📥 Commits

Reviewing files that changed from the base of the PR and between 2ea3caf and 63ad9f6.

📒 Files selected for processing (11)
  • bundle/manifests/observability.openshift.io_observabilityinstallers.yaml
  • deploy/crds/common/observability.openshift.io_observabilityinstallers.yaml
  • docs/api.md
  • pkg/apis/observability/v1alpha1/tracing.go
  • pkg/apis/observability/v1alpha1/tracing_test.go
  • pkg/apis/observability/v1alpha1/types.go
  • pkg/apis/observability/v1alpha1/zz_generated.deepcopy.go
  • pkg/controllers/observability/reconcilers.go
  • pkg/controllers/observability/reconcilers_test.go
  • pkg/controllers/observability/tempo_components.go
  • test/e2e/observability_installer_test.go
✅ Files skipped from review due to trivial changes (2)
  • docs/api.md
  • pkg/apis/observability/v1alpha1/zz_generated.deepcopy.go
🚧 Files skipped from review as they are similar to previous changes (9)
  • bundle/manifests/observability.openshift.io_observabilityinstallers.yaml
  • deploy/crds/common/observability.openshift.io_observabilityinstallers.yaml
  • pkg/controllers/observability/reconcilers.go
  • test/e2e/observability_installer_test.go
  • pkg/apis/observability/v1alpha1/tracing.go
  • pkg/apis/observability/v1alpha1/types.go
  • pkg/controllers/observability/reconcilers_test.go
  • pkg/apis/observability/v1alpha1/tracing_test.go
  • pkg/controllers/observability/tempo_components.go

📝 Walkthrough

Walkthrough

This pull request refactors optional tracing and capability configuration fields from value types to pointers throughout the API, adds safe getter methods to prevent nil dereferences, and renames the GCS Workload Identity Federation field from GCSSTSSpec to GCSWIF. The validation rule for tracing storage is updated to guard against nil pointer access. All corresponding changes are propagated through autogenerated deepcopy methods, test fixtures, CRD schemas, documentation, and controller implementations that consume these fields.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 10.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main change: converting API struct fields marked with json omitempty to use pointers instead of value types.
Description check ✅ Passed The description clearly explains the rationale for using pointers for fields with json omitempty and lists all additional fixes made in the changeset.
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.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

Error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions
The command is terminated due to an error: can't load config: unsupported version of the configuration: "" See https://golangci-lint.run/docs/product/migration-guide for migration instructions


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 and usage tips.

Copy link
Copy Markdown

@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

Caution

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

⚠️ Outside diff range comments (2)
pkg/controllers/observability/observability_controller.go (1)

207-233: ⚠️ Potential issue | 🟠 Major

Clear tracing status when tracing is nil or disabled.

Line 209 avoids the nil dereference, but the else still only runs when Capabilities is nil. If users remove spec.capabilities.tracing or set tracing disabled, stale Tempo/OpenTelemetry status can remain.

Proposed fix
-	if instance.Spec.Capabilities != nil {
-		capabilities := instance.Spec.Capabilities
-		if capabilities.Tracing != nil && capabilities.Tracing.Enabled {
+	capabilities := instance.Spec.Capabilities
+	if capabilities != nil && capabilities.Tracing != nil && capabilities.Tracing.Enabled {
 			otelcol := &otelv1beta1.OpenTelemetryCollector{}
 			err := o.client.Get(ctx, types.NamespacedName{
 				Namespace: instance.Namespace,
 				Name:      otelCollectorName(instance.Name),
 			}, otelcol)
@@
 
 			instance.Status.Tempo = fmt.Sprintf("%s/%s (%s)", instance.Namespace, tempoName(instance.Name), tempo.Status.TempoVersion)
 			instance.Status.OpenTelemetry = fmt.Sprintf("%s/%s (%s)", instance.Namespace, otelCollectorName(instance.Name), otelcol.Status.Version)
-		}
 	} else {
 		instance.Status.Tempo = ""
 		instance.Status.OpenTelemetry = ""
 	}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controllers/observability/observability_controller.go` around lines 207 -
233, The code only clears instance.Status.Tempo and
instance.Status.OpenTelemetry when instance.Spec.Capabilities is nil, leaving
stale values when Capabilities exists but capabilities.Tracing is nil or
capabilities.Tracing.Enabled is false; update the logic in the reconciliation
block (around the otelcol/tempo retrieval) so that when capabilities.Tracing ==
nil or capabilities.Tracing.Enabled == false you explicitly set
instance.Status.Tempo = "" and instance.Status.OpenTelemetry = "" (i.e., add an
else branch for the capabilities.Tracing check that clears those status fields),
leaving the existing nil Capabilities branch as-is.
pkg/controllers/observability/tempo_components.go (1)

63-78: ⚠️ Potential issue | 🟠 Major

Create the TLS secret under the name referenced by TempoStack.

Line 74 configures Tempo to read the cert from tempoStorageSecretName(instance.Name), but Line 156 creates the TLS Secret as tempoSecretName(instance.Name). That leaves Tempo pointing at a non-existent cert Secret and can collide with the object storage credentials Secret.

🐛 Proposed fix
 			objectStorageTLSSecret = &corev1.Secret{
 				TypeMeta: metav1.TypeMeta{
 					Kind:       "Secret",
 					APIVersion: corev1.SchemeGroupVersion.String(),
 				},
 				ObjectMeta: metav1.ObjectMeta{
-					Name:      tempoSecretName(instance.Name),
+					Name:      tempoStorageSecretName(instance.Name),
 					Namespace: instance.Namespace,
 				},
 			}

Also applies to: 150-156

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pkg/controllers/observability/tempo_components.go` around lines 63 - 78,
Tempo's TLS cert Secret is being referenced as
tempoStorageSecretName(instance.Name) in tempo.Spec.Storage.TLS.Cert but the
code that creates the Secret uses tempoSecretName(instance.Name), causing Tempo
to point to a non-existent Secret and risking a name collision with object
storage credentials; update the Secret creation code so the TLS Secret is
created with the same name used by Tempo (use
tempoStorageSecretName(instance.Name)) and ensure any CA Secret/ConfigMap uses
tempoStorageCAConfigMapName(instance.Name) so names align and avoid collision
with tempoSecretName.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@pkg/controllers/observability/tempo_components.go`:
- Around line 263-270: The error message in the GCSWIF branch is stale: when Get
fails for the key JSON secret (variable keyJSONSecret) you should update the
fmt.Errorf call in the objectStorageSpec.GCSWIF handling to reference GCSWIF
(not GCSSTS), e.g. change the message passed to fmt.Errorf in the block that
fetches objectStorageSpec.GCSWIF.KeyJSONSecret.Name so it accurately says
"failed to get GCSWIF keyJSON secret <name>: %w" while keeping the existing
error wrapping and returned values.

---

Outside diff comments:
In `@pkg/controllers/observability/observability_controller.go`:
- Around line 207-233: The code only clears instance.Status.Tempo and
instance.Status.OpenTelemetry when instance.Spec.Capabilities is nil, leaving
stale values when Capabilities exists but capabilities.Tracing is nil or
capabilities.Tracing.Enabled is false; update the logic in the reconciliation
block (around the otelcol/tempo retrieval) so that when capabilities.Tracing ==
nil or capabilities.Tracing.Enabled == false you explicitly set
instance.Status.Tempo = "" and instance.Status.OpenTelemetry = "" (i.e., add an
else branch for the capabilities.Tracing check that clears those status fields),
leaving the existing nil Capabilities branch as-is.

In `@pkg/controllers/observability/tempo_components.go`:
- Around line 63-78: Tempo's TLS cert Secret is being referenced as
tempoStorageSecretName(instance.Name) in tempo.Spec.Storage.TLS.Cert but the
code that creates the Secret uses tempoSecretName(instance.Name), causing Tempo
to point to a non-existent Secret and risking a name collision with object
storage credentials; update the Secret creation code so the TLS Secret is
created with the same name used by Tempo (use
tempoStorageSecretName(instance.Name)) and ensure any CA Secret/ConfigMap uses
tempoStorageCAConfigMapName(instance.Name) so names align and avoid collision
with tempoSecretName.
🪄 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: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 27c981da-b5db-4b69-87f6-9b160772cc57

📥 Commits

Reviewing files that changed from the base of the PR and between bf363be and 04129b9.

📒 Files selected for processing (14)
  • bundle/manifests/observability-operator.clusterserviceversion.yaml
  • bundle/manifests/observability.openshift.io_observabilityinstallers.yaml
  • deploy/crds/common/observability.openshift.io_observabilityinstallers.yaml
  • docs/api.md
  • pkg/apis/observability/v1alpha1/objectstorage.go
  • pkg/apis/observability/v1alpha1/tracing.go
  • pkg/apis/observability/v1alpha1/tracing_test.go
  • pkg/apis/observability/v1alpha1/types.go
  • pkg/apis/observability/v1alpha1/zz_generated.deepcopy.go
  • pkg/controllers/observability/observability_controller.go
  • pkg/controllers/observability/reconcilers.go
  • pkg/controllers/observability/reconcilers_test.go
  • pkg/controllers/observability/tempo_components.go
  • test/e2e/observability_installer_test.go

Comment thread pkg/controllers/observability/tempo_components.go Outdated
@alanconway
Copy link
Copy Markdown
Contributor Author

@pavolloffay need a new LGTM, rebased and added nil-safe GetFoo() accessors to get rid of long, error-prone != nil tests.

Use pointers for API struct fields marked "omitempty".

"omitempty" does not work on non-pointer struct fields.
A zero valued struct will serialize at least as "{}" and may contain zero valued fields
if any fields are not "omitempty".
This can cause problems with default values and round-trip (de)serialization
and break even if the kubebuilder "+optional" comment is applied.

Additional fixes:
- Add nil-safe GetFoo() methods to avoid long !=nil tests.
- Rename TracingObjectStorageSpec.GCSSTSSpec to GCSWIF to match its type and json tag
- Update CEL validation rule to handle nil storage/objectStorage with has() guards
- Add nil guards for Tracing, Storage, ObjectStorageSpec, and Operators in controller code
- Remove spurious omitempty from required S3Spec.AccessKeySecret field
- Fix ConfigMapKeySelector doc comments that incorrectly referenced "Secret"
@openshift-ci openshift-ci Bot added the lgtm label May 14, 2026
@alanconway
Copy link
Copy Markdown
Contributor Author

/label approved

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 14, 2026

@alanconway: The label(s) approved cannot be applied or removed, because you are not in one of the allowed teams and are not an allowed user. Must be a member of one of these teams: openshift-release-oversight, openshift-staff-engineers, openshift-sustaining-engineers

Details

In response to this:

/label approved

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.

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented May 14, 2026

[APPROVALNOTIFIER] This PR is APPROVED

Approval requirements bypassed by manually added approval.

This pull-request has been approved by: alanconway, pavolloffay

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

@alanconway alanconway enabled auto-merge (squash) May 14, 2026 14:18
@alanconway alanconway disabled auto-merge May 14, 2026 14:19
@openshift-merge-bot openshift-merge-bot Bot merged commit 587f9dc into rhobs:main May 14, 2026
12 checks passed
jan--f added a commit that referenced this pull request May 19, 2026
* fix: update tls log to omit length of ciphers array (#1074)

* fix: update tls log to omit length of ciphers array

Signed-off-by: Jenny Zhu <jenny.a.zhu@gmail.com>

* fix: tls cipher logging

Signed-off-by: Jenny Zhu <jenny.a.zhu@gmail.com>

---------

Signed-off-by: Jenny Zhu <jenny.a.zhu@gmail.com>

* build(deps): bump github.com/operator-framework/api (#1059)

Bumps [github.com/operator-framework/api](https://github.com/operator-framework/api) from 0.38.0 to 0.42.0.
- [Release notes](https://github.com/operator-framework/api/releases)
- [Changelog](https://github.com/operator-framework/api/blob/master/RELEASE.md)
- [Commits](operator-framework/api@v0.38.0...v0.42.0)

---
updated-dependencies:
- dependency-name: github.com/operator-framework/api
  dependency-version: 0.42.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* chore: update obo-prom-op to v0.90.1 (#1077)

Signed-off-by: Jan Fajerski <jfajersk@redhat.com>

* build(deps): bump github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring (#1060)

Bumps [github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring](https://github.com/prometheus-operator/prometheus-operator) from 0.89.0 to 0.90.1.
- [Release notes](https://github.com/prometheus-operator/prometheus-operator/releases)
- [Changelog](https://github.com/prometheus-operator/prometheus-operator/blob/main/CHANGELOG.md)
- [Commits](prometheus-operator/prometheus-operator@v0.89.0...v0.90.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring
  dependency-version: 0.90.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* feat: update perses operand image (#1085)

Signed-off-by: Gabriel Bernal <gbernal@redhat.com>

* feat: coo 1.5 image tag and compat. matrix update (#1075)

* fix: add 'create tokenreview' to korrel8r RBAC (#1073)

Korrel8r uses 'create tokenreview' to get user names for session tokens.
Need usernames for reliable session keys.
Same user can get different tokens per log-in.

* fix: remove ui plugin finalizers in favor of k8s garbage collection (#1084)

Signed-off-by: Gabriel Bernal <gbernal@redhat.com>

* NO-JIRA: remove SupportsTLSProfile (#1089)

* fix: enable tls support for troubleshooting plugin

* feat: remove supports tls profile  flag because all uiplugin support tls now

* fix: lint

* chore: unpin github.com/openshift/api (#1090)

This commit unpins the version of `github.com/openshift/api` to depend
on the latest version. To continue supporting older OpenShift versions
which require the Console v1alpha1 API (removed since 2024), we fork the
`github.com/openshift/api` under `github.com/rhobs/openshift-api` and
pinned to the same version that was used before this change.

Signed-off-by: Simon Pasquier <spasquie@redhat.com>

* fix: use pointer-to-struct for fields with json omitempty (#1063)

Use pointers for API struct fields marked "omitempty".

"omitempty" does not work on non-pointer struct fields.
A zero valued struct will serialize at least as "{}" and may contain zero valued fields
if any fields are not "omitempty".
This can cause problems with default values and round-trip (de)serialization
and break even if the kubebuilder "+optional" comment is applied.

Additional fixes:
- Add nil-safe GetFoo() methods to avoid long !=nil tests.
- Rename TracingObjectStorageSpec.GCSSTSSpec to GCSWIF to match its type and json tag
- Update CEL validation rule to handle nil storage/objectStorage with has() guards
- Add nil guards for Tracing, Storage, ObjectStorageSpec, and Operators in controller code
- Remove spurious omitempty from required S3Spec.AccessKeySecret field
- Fix ConfigMapKeySelector doc comments that incorrectly referenced "Secret"

* fix: escape reserved words from perses cel validation expressions (#1091)

Signed-off-by: Gabriel Bernal <gbernal@redhat.com>

---------

Signed-off-by: Jenny Zhu <jenny.a.zhu@gmail.com>
Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Jan Fajerski <jfajersk@redhat.com>
Signed-off-by: Gabriel Bernal <gbernal@redhat.com>
Signed-off-by: Simon Pasquier <spasquie@redhat.com>
Co-authored-by: Jenny Zhu <jenny.a.zhu@gmail.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Jan Fajerski <jan--f@users.noreply.github.com>
Co-authored-by: Alan Conway <aconway@redhat.com>
Co-authored-by: Simon Pasquier <spasquie@redhat.com>
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