Skip to content

fix(api-server): stop oidc/route jsonb normalization bumping gateway generation - #384

Merged
rh-amarin merged 2 commits into
openshift-online:mainfrom
rh-amarin:cp-reprovisioning
Sep 30, 2026
Merged

rh-amarin merged 2 commits into
openshift-online:mainfrom
rh-amarin:cp-reprovisioning

Conversation

@rh-amarin

@rh-amarin rh-amarin commented Sep 30, 2026 •

Copy link
Copy Markdown
Collaborator

Problem

Existing gateways toggled between Running and Provisioning. The control plane wrote back oidc on every reconcile as compact JSON; the oidc/route jsonb columns return normalized text, so desiredStateChanged (raw string compare) saw a spec change every time. That bumped generation past observed_generation, defeating the convergence gate, so each gateway was fully re-provisioned about every 7s (phase set to Provisioning, then promoted by the health reconciler).

This was introduced by #151

Fix

Compare oidc and route semantically (jsonEq), falling back to a string compare for non-JSON values.

Testing

  • New unit test TestDesiredStateChangedIgnoresJSONNormalization
  • make lint and api-server make test pass locally
  • Diagnosed on a live VM: generation climbed 110 -> 114 in minutes, always ahead of observed_generation

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 3d8c3fee-9741-4412-ab20-7f8b17aa6f7b

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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

@rh-amarin
rh-amarin enabled auto-merge September 30, 2026 08:16
@hypershell-delivery

hypershell-delivery Bot commented Sep 30, 2026 •

Copy link
Copy Markdown

Amber review: approve

Amber review

Status: Complete

View the submitted review.

hypershell-delivery[bot]

This comment was marked as outdated.

@hypershell-delivery hypershell-delivery Bot added the amber/approved The Amber review agent has approved this PR. label Sep 30, 2026
hypershell-delivery[bot]

This comment was marked as outdated.

rh-amarin and others added 2 commits September 30, 2026 12:51
…ate changes

oidc and route are jsonb columns, so PostgreSQL returns normalized text
(key order, spacing) that never byte-equals the compact JSON the control
plane writes back. desiredStateChanged reported a spec change on every
UpdateGateway, bumping generation and clearing provisioning conditions,
which re-opened the control plane's convergence gate. Gateways flapped
between Running and Provisioning as they were re-provisioned every ~7s.

Compare the two fields semantically.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

@hypershell-delivery hypershell-delivery 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.

Verdict

This remains a tight, correct fix. oidc/route are jsonb columns, so the PostgreSQL-normalized text (key order, spacing) never byte-equals the compact JSON the control plane writes back; the old strEq compare therefore bumped generation on every UpdateGateway, re-opening the convergence gate and flapping gateways between Running and Provisioning. Comparing those two fields semantically with jsonEq (nil-safe, byte fast-path, reflect.DeepEqual on the unmarshaled documents) resolves the spurious churn while leaving every other desired-state field on the strict strEq compare.

Findings

No new findings. The rebased head is diff-identical to the previously reviewed change: jsonEq is nil-safe (service.go:250-262), preserves the desired-state/observed-state split documented in data-model.spec.md (service.go:225-242), adds no secrets to logs, and weakens no pre-existing test assertion. The net-new desired_state_test.go is additive and covers the normalization no-op, a real audience change, and the cleared-field transition.

Cross-PR coordination

No material cross-PR coordination issue requires maintainer action.

Previous concerns

The committer addressed the previous concerns.

Findings Summary (ordered by severity, highest first):

No outstanding findings.

Convention Checklist

Convention Result
No panic() in production code Pass
Errors wrapped with fmt.Errorf context Pass
No secrets in logs or responses Pass
Input validated Pass
Test assertions not silently weakened Pass
Conventional commit message Pass

@rh-amarin
rh-amarin added this pull request to the merge queue Sep 30, 2026
Merged via the queue into openshift-online:main with commit 7e449fd Sep 30, 2026
37 of 39 checks passed
@rh-amarin
rh-amarin deleted the cp-reprovisioning branch September 30, 2026 11:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

amber/approved The Amber review agent has approved this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant