Skip to content

🐛 normalize Helm values before schema validation - #389

Merged
openshift-merge-bot[bot] merged 1 commit into
open-cluster-management-io:mainfrom
kahirokunn:agent/normalize-helm-values
Jul 23, 2026
Merged

🐛 normalize Helm values before schema validation#389
openshift-merge-bot[bot] merged 1 commit into
open-cluster-management-io:mainfrom
kahirokunn:agent/normalize-helm-values

Conversation

@kahirokunn

@kahirokunn kahirokunn commented Jul 21, 2026

Copy link
Copy Markdown
Contributor

Summary

Helm schema validation rejects concrete Go collections returned by GetValuesFuncs with invalid jsonType, forcing each add-on to merge and normalize values itself; normalize the merged values in addon-framework instead.

Related issue(s)

N/A

Summary by CodeRabbit

  • Bug Fixes
    • Improved Helm value handling by normalizing user-provided values into JSON-compatible forms before merging, fixing rendering for settings such as pod tolerations.
    • Better failure behavior and clearer error messages when Helm values contain unsupported data types.
  • Documentation
    • Clarified that returned Helm values may be typed and are normalized to JSON-compatible types prior to validation/rendering.
  • Tests
    • Expanded coverage for collection-based values, tolerations, and normalization error scenarios (including expected failures).
  • Chores
    • Added a JSON Schema used to exercise Helm values validation in tests.

@openshift-ci
openshift-ci Bot requested review from deads2k and elgnay July 21, 2026 08:19
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9f0135d7-1d00-43e1-96ef-4e1bfca06df5

📥 Commits

Reviewing files that changed from the base of the PR and between 893c955 and a09bf57.

📒 Files selected for processing (4)
  • docs/helmAgentAddon.md
  • pkg/addonfactory/helm_agentaddon.go
  • pkg/addonfactory/helm_agentaddon_test.go
  • pkg/addonfactory/testmanifests/chart/values.schema.json
🚧 Files skipped from review as they are similar to previous changes (3)
  • pkg/addonfactory/testmanifests/chart/values.schema.json
  • docs/helmAgentAddon.md
  • pkg/addonfactory/helm_agentaddon_test.go

Walkthrough

GetValuesFuncs outputs are normalized to JSON-compatible Helm values before merging. Tests cover typed collections, rendered tolerations, and unsupported value errors, while documentation describes the normalization and failure behavior.

Changes

Helm values normalization

Layer / File(s) Summary
Values contract and rendering
pkg/addonfactory/helm_agentaddon.go, pkg/addonfactory/testmanifests/chart/values.schema.json
getValues normalizes user-provided values through JsonStructToValues before merging; the chart adds a tolerations schema.
Rendering validation and documentation
pkg/addonfactory/helm_agentaddon_test.go, docs/helmAgentAddon.md
Tests cover typed Go collections, rendered tolerations, and unsupported normalization types; documentation describes conversion and failure behavior.

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

Suggested reviewers: zhiweiyin318, deads2k, zhujian7, elgnay

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change and uses the required 🐛 prefix.
Description check ✅ Passed The description matches the template's sections and summarizes the fix well, but it lacks a concrete Fixes # reference.
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.
✨ 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.

@kahirokunn
kahirokunn force-pushed the agent/normalize-helm-values branch from 629fddc to b3f875e Compare July 21, 2026 08:24

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

Caution

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

⚠️ Outside diff range comments (1)
pkg/addonfactory/helm_agentaddon.go (1)

184-214: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Normalize user values before merging to prevent deep-merge data loss.

Normalizing overrideValues at the end means MergeValues is executed with un-normalized userValues (which may contain concrete Go maps like map[string]string). Standard deep-merge implementations often fail type assertions (e.g., v.(map[string]interface{})) on concrete maps, resulting in silent overwrites of entire blocks instead of expected deep merges.

Since defaultValues and builtinValues are already normalized internally before merging, applying JsonStructToValues to userValues before the merge ensures that MergeValues always operates on compatible map[string]interface{} types. This protects the integrity of the merged values and allows the redundant final normalization to be safely removed.

🐛 Proposed fix
 		if a.getValuesFuncs[i] != nil {
 			userValues, err := a.getValuesFuncs[i](cluster, addon)
 			if err != nil {
 				return overrideValues, err
 			}
 
+			normalizedUserValues, err := JsonStructToValues(userValues)
+			if err != nil {
+				return overrideValues, fmt.Errorf("failed to normalize Helm values: %w", err)
+			}
+
 			klog.V(4).Infof("index=%d, user values: %v", i, userValues)
-			overrideValues = MergeValues(overrideValues, userValues)
+			overrideValues = MergeValues(overrideValues, normalizedUserValues)
 			klog.V(4).Infof("index=%d, override values: %v", i, overrideValues)
 		}
 	}
 
 	builtinValues, err := a.getBuiltinValues(cluster, addon)
 	if err != nil {
 		klog.Errorf("failed to get builtinValue. err:%v", err)
 		return nil, err
 	}
 
 	overrideValues = MergeValues(overrideValues, builtinValues)
 
 	releaseOptions, err := a.releaseOptions(addon)
 	if err != nil {
 		return nil, err
 	}
 	cap := a.capabilities(cluster, addon)
-	normalizedValues, err := JsonStructToValues(overrideValues)
-	if err != nil {
-		return overrideValues, fmt.Errorf("failed to normalize Helm values: %w", err)
-	}
-	values, err := chartutil.ToRenderValues(a.chart, normalizedValues,
+	values, err := chartutil.ToRenderValues(a.chart, overrideValues,
 		releaseOptions, cap)
 	if err != nil {
 		klog.Errorf("failed to render helm chart with values %v. err:%v", overrideValues, err)
 		return values, err
 	}
🤖 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 `@pkg/addonfactory/helm_agentaddon.go` around lines 184 - 214, Normalize each
user value returned by getValuesFuncs before passing it to MergeValues, ensuring
concrete map types are converted to compatible map[string]interface{}
structures. Handle normalization errors at that point and return them, then
remove the redundant final JsonStructToValues call and use the
already-normalized overrideValues for chartutil.ToRenderValues.
🤖 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.

Outside diff comments:
In `@pkg/addonfactory/helm_agentaddon.go`:
- Around line 184-214: Normalize each user value returned by getValuesFuncs
before passing it to MergeValues, ensuring concrete map types are converted to
compatible map[string]interface{} structures. Handle normalization errors at
that point and return them, then remove the redundant final JsonStructToValues
call and use the already-normalized overrideValues for chartutil.ToRenderValues.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: eae15ce5-a6c5-4c41-9adc-b0364f378d43

📥 Commits

Reviewing files that changed from the base of the PR and between 11a5182 and 629fddc.

📒 Files selected for processing (4)
  • docs/helmAgentAddon.md
  • pkg/addonfactory/helm_agentaddon.go
  • pkg/addonfactory/helm_agentaddon_test.go
  • pkg/addonfactory/testmanifests/chart/values.schema.json

@kahirokunn
kahirokunn marked this pull request as draft July 21, 2026 08:54
@kahirokunn
kahirokunn force-pushed the agent/normalize-helm-values branch from b3f875e to 893c955 Compare July 21, 2026 14:46
@kahirokunn
kahirokunn marked this pull request as ready for review July 21, 2026 14:50
@openshift-ci
openshift-ci Bot requested review from zhiweiyin318 and zhujian7 July 21, 2026 14:50
@kahirokunn

Copy link
Copy Markdown
Contributor Author

@mikeshng Hi ✋ value.schema.json is an extremely powerful Helm feature, and I'd like to make it more user-friendly. If you're available, I'd be grateful for your feedback. Thank you 🙏

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

🧹 Nitpick comments (1)
pkg/addonfactory/helm_agentaddon_test.go (1)

307-309: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Prefer assert.Equal over reflect.DeepEqual for clearer test failure diffs.

Since github.com/stretchr/testify/assert is now imported, you can use assert.Equal here. When slices or structs don't match, assert.Equal provides a much clearer line-by-line diff than reflect.DeepEqual combined with the %v formatter, making test failures easier to debug.

♻️ Proposed refactor
-					if c.expectedTolerations != nil && !reflect.DeepEqual(object.Spec.Template.Spec.Tolerations, c.expectedTolerations) {
-						t.Errorf("expected tolerations are %v, but got %v", c.expectedTolerations, object.Spec.Template.Spec.Tolerations)
-					}
+					if c.expectedTolerations != nil {
+						assert.Equal(t, c.expectedTolerations, object.Spec.Template.Spec.Tolerations, "expected tolerations to match")
+					}
🤖 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 `@pkg/addonfactory/helm_agentaddon_test.go` around lines 307 - 309, Update the
toleration comparison in the test case around expectedTolerations to use
testify's assert.Equal instead of reflect.DeepEqual and the manual t.Errorf,
preserving the existing conditional check and failure context.
🤖 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.

Nitpick comments:
In `@pkg/addonfactory/helm_agentaddon_test.go`:
- Around line 307-309: Update the toleration comparison in the test case around
expectedTolerations to use testify's assert.Equal instead of reflect.DeepEqual
and the manual t.Errorf, preserving the existing conditional check and failure
context.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 648679ef-41a4-45ea-8c9f-0743a9bf87e6

📥 Commits

Reviewing files that changed from the base of the PR and between 629fddc and 893c955.

📒 Files selected for processing (4)
  • docs/helmAgentAddon.md
  • pkg/addonfactory/helm_agentaddon.go
  • pkg/addonfactory/helm_agentaddon_test.go
  • pkg/addonfactory/testmanifests/chart/values.schema.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • docs/helmAgentAddon.md
  • pkg/addonfactory/helm_agentaddon.go

Signed-off-by: kahirokunn <okinakahiro@gmail.com>
@kahirokunn
kahirokunn force-pushed the agent/normalize-helm-values branch from 893c955 to a09bf57 Compare July 21, 2026 15:20
@kahirokunn

Copy link
Copy Markdown
Contributor Author

Thank you @coderabbitai . Fixed it.

@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@kahirokunn Thanks for fixing it! 🐇


If you found this review helpful, would you consider giving us a shout-out on X?

Thank you for using CodeRabbit!

@@ -0,0 +1,10 @@
{
"$schema": "https://json-schema.org/draft-07/schema#",
"$comment": "exercises helm schema validation; typed Go values that are not normalized to JSON-compatible types fail this validation",

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I welcome this enhancement.

My biggest concern will be any backward compatibility issues for existing addons? Any migration step require? I am worry that if we upgrade to this addon-framework version with this change and it might break existing addons unless they do something.

If it's possible to break existing addons, could we enhance the PR so that we get this feature and also not break existing users. That will be ideal.

/assign @qiujian16

@kahirokunn kahirokunn Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks for raising this.

Existing add-ons that return JSON-compatible values will keep working without any migration. This includes annotation values and values already converted with JsonStructToValues. values.schema.json also remains optional; this change does not enable schema validation for existing charts.

I also checked addon-contrib. There is currently no tracked use of BuildHelmAgentAddon; its addonfactory consumers all use BuildTemplateAgentAddon, so they are not affected.

For schema-enabled Helm add-ons, this removes the need for local normalization. For example, cluster-proxy currently has its own merge-and-normalize workaround, although that change is still part of cluster-proxy PR #329.

Normalization is applied to Helm charts without a schema as well. In theory, values that cannot be marshaled to JSON will now fail, but those are outside the documented and recommended usage of Helm values. Concrete nested maps will also be deep-merged as intended by MergeValues.

Therefore, I do not expect this change to affect existing add-ons, and no migration should be required.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/lgtm

Thank you for taking a look at my feedback.

I am not a maintainer for this repo so @qiujian16 will have to approve. Thanks.

@kahirokunn

Copy link
Copy Markdown
Contributor Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 22, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@qiujian16 qiujian16 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

/approve
/lgtm

@openshift-ci

openshift-ci Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: kahirokunn, qiujian16

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 8c9c7b7 into open-cluster-management-io:main Jul 23, 2026
15 checks passed
@kahirokunn

Copy link
Copy Markdown
Contributor Author

Thanks for your review 🙏

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.

3 participants