Skip to content

ROSAENG-62105: PercentageValidator must require value greater than 0 and less than 1 - #3398

Open
nephomaniac wants to merge 1 commit into
openshift:masterfrom
nephomaniac:ROSAENG-62105/fix-utilization-threshold-validation
Open

ROSAENG-62105: PercentageValidator must require value greater than 0 and less than 1#3398
nephomaniac wants to merge 1 commit into
openshift:masterfrom
nephomaniac:ROSAENG-62105/fix-utilization-threshold-validation

Conversation

@nephomaniac

@nephomaniac nephomaniac commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Align PercentageValidator bounds to match the cluster-autoscaler-operator webhook and OCP documentation
  • Change number < 0 to number <= 0 and number > 1 to number >= 1 — value must be strictly between 0 and 1
  • Add test cases for 0 and 1 being rejected

Context

The ROSA CLI accepted --scale-down-utilization-threshold 0, storing "0.000000" in OCM. The cluster-autoscaler-operator's validating admission webhook rejects this value, causing Hive to enter a permanent patch rejection loop and blocking cluster upgrades.

The OCP 4.18 documentation states the value "must be a value greater than 0 but less than 1." Additionally, setting the threshold to 0 silently disables scale-down in the upstream Kubernetes autoscaler (kubernetes/autoscaler#2221).

Jira: https://redhat.atlassian.net/browse/ROSAENG-62105

Summary by CodeRabbit

  • Bug Fixes
    • Percentage validation now requires values strictly greater than 0 and strictly less than 1.
    • Boundary inputs (0, 1) and non-numeric inputs like NaN are rejected with improved validation messages.
  • Documentation / Help Text
    • Autoscaler flag help text and validation errors were updated for consistent wording (including lowercased “error validating …”).
  • Tests
    • Updated unit and end-to-end tests to reflect the new validation behavior and message text.

@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 18, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 18, 2026

Copy link
Copy Markdown

@nephomaniac: This pull request references ROSAENG-62105 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 bug to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Summary

  • Align PercentageValidator bounds to match the cluster-autoscaler-operator webhook and OCP documentation
  • Change number < 0 to number <= 0 and number > 1 to number >= 1 — value must be strictly between 0 and 1
  • Add test cases for 0 and 1 being rejected

Context

The ROSA CLI accepted --scale-down-utilization-threshold 0, storing "0.000000" in OCM. The cluster-autoscaler-operator's validating admission webhook rejects this value, causing Hive to enter a permanent patch rejection loop and blocking cluster upgrades.

The OCP 4.18 documentation states the value "must be a value greater than 0 but less than 1." Additionally, setting the threshold to 0 silently disables scale-down in the upstream Kubernetes autoscaler (kubernetes/autoscaler#2221).

Jira: https://redhat.atlassian.net/browse/ROSAENG-62105

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.

@openshift-ci

openshift-ci Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: nephomaniac
Once this PR has been reviewed and has the lgtm label, please assign robpblake 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 Jul 18, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

Percentage validation now rejects NaN, 0, 1, and values outside the strict (0, 1) range. Autoscaler help text and validation errors were updated, and unit, command, and end-to-end tests now use valid threshold values and revised error messages.

Possibly related PRs

  • openshift/rosa#3428: Updates overlapping autoscaler validation error expectations in test_rosacli_cluster.go.

Suggested reviewers: amandahla, braetroutman

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning Only Summary and Context are provided; required sections like Type of Change, Testing, and Related Issues are missing. Add the missing template sections, especially Type of Change, Related Issues, Previous/After Behavior, How to Test, Proof, and checklist items.
✅ Passed checks (14 passed)
Check name Status Explanation
Title check ✅ Passed The title is specific and accurately summarizes the main PercentageValidator bounds change.
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.
Stable And Deterministic Test Names ✅ Passed All changed Ginkgo titles are static strings; none embed generated IDs, timestamps, or other run-to-run values.
Test Structure And Quality ✅ Passed The PR only adds focused validator cases and adjusts expected strings; no new resources, waits, or multi-behavior It blocks were introduced, and existing setup/cleanup patterns remain intact.
Microshift Test Compatibility ✅ Passed No new Ginkgo tests were added; diffs only tweak assertions/expected strings in existing e2e suites, with no MicroShift-unsupported APIs introduced.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No new Ginkgo e2e tests were added; the touched e2e files only change autoscaler validation inputs/assertions, with no multi-node assumptions.
Topology-Aware Scheduling Compatibility ✅ Passed Only autoscaler validation/messages and tests changed; no manifests, controllers, replicas, affinity, or node selectors were added.
Ote Binary Stdout Contract ✅ Passed Touched files only change validators/flags/tests; no init/main/TestMain/BeforeSuite stdout writes were added, and found fmt.Println calls are inside It blocks.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The modified Ginkgo e2e tests only change autoscaler validation strings/thresholds; no hardcoded IPv4, host IP formatting, or public internet connectivity was added.
No-Weak-Crypto ✅ Passed No MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret/token comparisons appear in the changed files.
Container-Privileges ✅ Passed The PR only changes Go validators/tests and CLI error text; the patch contains no privileged=true, hostPID/Network/IPC, SYS_ADMIN, or allowPrivilegeEscalation settings.
No-Sensitive-Data-In-Logs ✅ Passed PASS: The patch only adjusts validator/help text and test expectations; no new log/debug statements or sensitive data fields were added.
✨ 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

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/ocm/validators.go`:
- Around line 71-72: Update the numeric validation guard in the visible
validator to explicitly reject NaN by incorporating math.IsNaN(number) alongside
the existing bounds checks, while preserving rejection of values outside the
open (0,1) interval. Add a validator test covering the "NaN" input in the
existing test suite.
🪄 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), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 35276561-b701-431e-8a50-90f9ef8c276f

📥 Commits

Reviewing files that changed from the base of the PR and between 3bb1e1a and 2c6664b.

📒 Files selected for processing (2)
  • pkg/ocm/validators.go
  • pkg/ocm/validators_test.go

Comment thread pkg/ocm/validators.go Outdated
})

It("raises an error if got exactly 1", func() {
Expect(PercentageValidator("1")).ToNot(BeNil())

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 unit test update is good, but the higher-level autoscaler tests still encode the old contract: they expect the old error string and still use 1 as a successful threshold. Since this PR changes user-visible validation behavior, please update the e2e cases so the broader suite reflects the new open interval.

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.

Addressed — updated all e2e tests in tests/e2e/rosa_autoscaler_test.go and tests/e2e/test_rosacli_cluster.go: changed threshold values from "1" to "0.5" in success paths, updated assertion from "1.000000" to "0.500000", and updated all error string expectations to match the new lowercase format.

Comment thread pkg/ocm/validators.go Outdated
if number > 1 || number < 0 {
return fmt.Errorf("Expecting a floating-point number between 0 and 1.")
if number >= 1 || number <= 0 {
return fmt.Errorf("Expecting a floating-point number greater than 0 and less than 1.")

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.

Now that 0 and 1 are rejected, the flag help should say 'greater than 0 and less than 1' instead of 'between 0 and 1'. That keeps CLI help aligned with the validator and the OCP docs.

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.

Addressed — updated flag help text in pkg/clusterautoscaler/flags.go line 247 from "between 0 and 1" to "greater than 0 and less than 1".

… and 1

Align PercentageValidator bounds with the cluster-autoscaler-operator
webhook and OCP documentation. Reject 0, 1, and NaN as invalid values.
Fix error strings to comply with Go staticcheck ST1005 conventions.
Update flag help text and all affected test expectations.
@nephomaniac
nephomaniac force-pushed the ROSAENG-62105/fix-utilization-threshold-validation branch from 2c6664b to f0e98e7 Compare July 28, 2026 23:31

@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 (3)
tests/e2e/test_rosacli_cluster.go (3)

197-197: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Complete the Hosted Control Plane assertion.

This branch silently passes without validating the HCP node representation. Add the expected assertion or track and skip the unsupported behavior explicitly. As per coding guidelines, Ginkgo tests must prove one specific behavior and TODOs require follow-up.

🤖 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 `@tests/e2e/test_rosacli_cluster.go` at line 197, Replace the TODO in the
Hosted Control Plane test branch with an assertion that validates the expected
HCP node representation, keeping the test focused on that behavior; if the
behavior is intentionally unsupported, explicitly mark or track the branch as
skipped instead of allowing it to pass silently.

Sources: Coding guidelines, Path instructions


4115-4133: 🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Restore the overwritten IAM trust policies after the test.

This test mutates installerRoleName and supportRoleName, but the surrounding cleanup path only calls CleanResources, which does not handle this in-memory accountRoleNames slice. Save the original policyDocument["Statement"] per role and restore it via UpdateAssumeRolePolicy on failure/skip, or delete/replace the roles after the test.

🤖 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 `@tests/e2e/test_rosacli_cluster.go` around lines 4115 - 4133, Preserve and
restore each role’s original IAM trust policy in the test that updates
installerRoleName and supportRoleName. Save policyDocument["Statement"]
separately per role before replacing it, then register failure/skip cleanup that
calls UpdateAssumeRolePolicy for both roles to restore the saved statements; do
not rely solely on CleanResources or the in-memory accountRoleNames slice.

Source: Coding guidelines


4141-4153: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Propagate the polling context to IAM.

Inside PollUntilContextTimeout(..., 300*time.Second, ...), context.TODO() bypasses the poll deadline, so a stuck GetRole call can keep the test running beyond the intended timeout.

Proposed fix
-						func(context.Context) (bool, error) {
-							result, err := awsClient.IamClient.GetRole(context.TODO(), &iam.GetRoleInput{
+						func(ctx context.Context) (bool, error) {
+							result, err := awsClient.IamClient.GetRole(ctx, &iam.GetRoleInput{
🤖 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 `@tests/e2e/test_rosacli_cluster.go` around lines 4141 - 4153, Update the
polling callback around awsClient.IamClient.GetRole to use its context.Context
parameter instead of context.TODO(). Preserve the existing timeout and
result-handling behavior while ensuring GetRole observes the
PollUntilContextTimeout deadline.

Sources: Coding guidelines, Path instructions

🤖 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 `@tests/e2e/test_rosacli_cluster.go`:
- Line 197: Replace the TODO in the Hosted Control Plane test branch with an
assertion that validates the expected HCP node representation, keeping the test
focused on that behavior; if the behavior is intentionally unsupported,
explicitly mark or track the branch as skipped instead of allowing it to pass
silently.
- Around line 4115-4133: Preserve and restore each role’s original IAM trust
policy in the test that updates installerRoleName and supportRoleName. Save
policyDocument["Statement"] separately per role before replacing it, then
register failure/skip cleanup that calls UpdateAssumeRolePolicy for both roles
to restore the saved statements; do not rely solely on CleanResources or the
in-memory accountRoleNames slice.
- Around line 4141-4153: Update the polling callback around
awsClient.IamClient.GetRole to use its context.Context parameter instead of
context.TODO(). Preserve the existing timeout and result-handling behavior while
ensuring GetRole observes the PollUntilContextTimeout deadline.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 514ff940-e700-43ae-823a-9e86ab3a684f

📥 Commits

Reviewing files that changed from the base of the PR and between 2c6664b and f0e98e7.

📒 Files selected for processing (7)
  • cmd/create/autoscaler/cmd_test.go
  • cmd/edit/autoscaler/cmd_test.go
  • pkg/clusterautoscaler/flags.go
  • pkg/ocm/validators.go
  • pkg/ocm/validators_test.go
  • tests/e2e/rosa_autoscaler_test.go
  • tests/e2e/test_rosacli_cluster.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • pkg/ocm/validators_test.go

@openshift-ci

openshift-ci Bot commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

@nephomaniac: The following tests 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/security f0e98e7 link false /test security
ci/prow/govulncheck f0e98e7 link false /test govulncheck

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.

@nephomaniac

Copy link
Copy Markdown
Contributor Author

Noting that the govulncheck, and security checks are, I believe, not related to and outside the scope of the PR. These appear to be failing in other recent MRs as well.

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

Labels

dco-signoff: yes jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants