Skip to content

feat(vsphere): per-component credential tooling (story #41)#16

Open
splatypus-bot wants to merge 2 commits into
mainfrom
story-41-per-component-scripts
Open

feat(vsphere): per-component credential tooling (story #41)#16
splatypus-bot wants to merge 2 commits into
mainfrom
story-41-per-component-scripts

Conversation

@splatypus-bot
Copy link
Copy Markdown

@splatypus-bot splatypus-bot commented May 9, 2026

Summary

  • Adds govc script creating four vCenter roles with exact canonical privilege sets (19/6/3/2)
  • Adds PowerCLI equivalent for Windows administrators
  • Adds credential template generator producing ~/.vsphere/credentials with 0600/0700 permissions
  • Adds troubleshooting guide covering all four error scenarios with every canonical privilege indexed

Test plan

  • 10 AC1 tests verify role names and all privilege strings in govc + PowerCLI scripts (all pass)
  • 5 AC3 tests verify four error scenario keywords, govc/UI path, privilege index, auth command, chmod remediation (all pass)
  • AC2 generator tests are t.Skip pending binary harness

Closes openshift#41

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Added scripts to create and manage per-component vCenter roles with minimal required privileges
    • Added script to generate secure credentials configuration template
  • Documentation

    • Added troubleshooting guide for per-component credential configuration issues with remediation steps
  • Tests

    • Added validation tests for role creation and troubleshooting documentation

- upi/vsphere/per-component-credentials/create-roles.sh: govc script creates
  four vCenter roles with exact canonical privilege sets (19/6/3/2)
- upi/vsphere/per-component-credentials/create-roles.ps1: PowerCLI equivalent
- upi/vsphere/per-component-credentials/generate-credentials.sh: generates
  ~/.vsphere/credentials template with 0600/0700 permissions
- docs/user/vsphere/per-component-credentials-troubleshooting.md: covers all
  four error scenarios with govc commands and UI paths
- 15 tests: 10 script content (AC1) + 5 guide structural (AC3), all pass

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 9, 2026

Warning

Rate limit exceeded

@rvanderp3 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 52 minutes and 12 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: bdbdaa0c-b009-4657-958a-646a922e21c1

📥 Commits

Reviewing files that changed from the base of the PR and between 54e3f52 and a0426c4.

📒 Files selected for processing (2)
  • docs/user/vsphere/per-component-credentials-troubleshooting.md
  • upi/vsphere/per-component-credentials/generate-credentials.sh
📝 Walkthrough

Walkthrough

This PR adds comprehensive infrastructure for vSphere per-component credential management: a user-facing troubleshooting guide covering four error scenarios, bash and PowerShell scripts to create per-component vCenter roles with specific privilege sets, a credential template generator, and Go tests validating both the guide content and role creation scripts.

Changes

vSphere Per-Component Credentials Tooling

Layer / File(s) Summary
Troubleshooting Guide
docs/user/vsphere/per-component-credentials-troubleshooting.md
Four-scenario troubleshooting guide (missing privileges, authentication failure, file permissions, partial configuration) with remediation steps via govc/vCenter UI, canonical privilege table per component, and credential template generation instructions.
Guide Validation Tests
docs/user/vsphere/troubleshooting_guide_test.go
Test suite asserting guide covers all four error scenarios, includes govc/UI remediation commands, indexes canonical vSphere privileges, and includes credential verification and chmod 0600 remediation.
Role Creation Scripts
upi/vsphere/per-component-credentials/create-roles.sh, upi/vsphere/per-component-credentials/create-roles.ps1
Bash script using govc role.create and PowerShell script using New-VIRole to create four per-component roles (machineapi with 19 privileges, csidriver with 6, cloudcontroller with 3, diagnostics with 2).
Credential Template Generation
upi/vsphere/per-component-credentials/generate-credentials.sh
Bash script that generates ~/.vsphere/credentials YAML template from comma-separated VSPHERE_HOSTNAMES, creates output directory with 0700, writes multi-component stanzas, and sets file to 0600 with reminder to fill passwords.
Role Script Validation
upi/vsphere/per-component-credentials/roles_test.go
Test suite validating create-roles.sh and create-roles.ps1 contain all four role names and include complete privilege sets for each component.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related issues

Poem

🐰 Hop along the vSphere path so green,
Four little roles, each with their sheen,
Credentials tucked safe with permissions so tight,
Per-component magic, a troubleshooter's delight!
With tests to ensure all privileges align,
OpenShift installation runs sublime.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(vsphere): per-component credential tooling (story #41)' accurately describes the main change—adding per-component credential tooling for vSphere including role creation scripts, credential template generator, and troubleshooting documentation.
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
  • Commit unit tests in branch story-41-per-component-scripts

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: 2

🧹 Nitpick comments (2)
upi/vsphere/per-component-credentials/roles_test.go (1)

138-145: ⚡ Quick win

Extend PowerCLI privilege assertions beyond machineAPI.

Current PowerCLI privilege validation only checks machineAPI; regressions in csiDriver, cloudController, or diagnostics privileges would pass unnoticed.

Proposed direction
 func TestPowerCLIScript_MachineAPI_AllPrivilegesPresent(t *testing.T) {
 	content := readScript(t, powercliScript)
 	for _, priv := range machineAPIPrivileges {
 		if !strings.Contains(content, priv) {
 			t.Errorf("PowerCLI script missing machineAPI privilege %q", priv)
 		}
 	}
+
+	for _, priv := range csiDriverPrivileges {
+		if !strings.Contains(content, priv) {
+			t.Errorf("PowerCLI script missing csiDriver privilege %q", priv)
+		}
+	}
+	for _, priv := range cloudControllerPrivileges {
+		if !strings.Contains(content, priv) {
+			t.Errorf("PowerCLI script missing cloudController privilege %q", priv)
+		}
+	}
+	for _, priv := range diagnosticsPrivileges {
+		if !strings.Contains(content, priv) {
+			t.Errorf("PowerCLI script missing diagnostics privilege %q", priv)
+		}
+	}
 }
🤖 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 `@upi/vsphere/per-component-credentials/roles_test.go` around lines 138 - 145,
The test TestPowerCLIScript_MachineAPI_AllPrivilegesPresent only asserts
machineAPI privileges; extend it (or add similar tests) to also validate
csiDriverPrivileges, cloudControllerPrivileges, and diagnosticsPrivileges by
reading the PowerCLI script via readScript(powercliScript) and asserting that
each privilege string in those slices is contained in the script (same pattern
used for machineAPIPrivileges); reference the existing test and the privilege
slice names (machineAPIPrivileges, csiDriverPrivileges,
cloudControllerPrivileges, diagnosticsPrivileges) and reuse its error message
pattern when a privilege is missing.
upi/vsphere/per-component-credentials/create-roles.ps1 (1)

11-13: ⚡ Quick win

Remove or wire $Server; it is currently unused.

The $Server parameter (line 12) is never referenced in the script. The usage comment (line 8) shows users should first call Connect-VIServer manually, but the declared parameter serves no purpose and should be removed unless it's intended for future use.

🤖 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 `@upi/vsphere/per-component-credentials/create-roles.ps1` around lines 11 - 13,
The declared parameter $Server is unused; either remove the param declaration or
wire it into the script by using $Server when establishing or validating a
vCenter connection (e.g., call Connect-VIServer -Server $Server or check
Get-VIServer -Server $Server) so the parameter is meaningful; update the param
block (remove [string]$Server = $env:GOVC_URL) or add connection logic
referencing $Server and adjust usage comments accordingly.
🤖 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 `@docs/user/vsphere/per-component-credentials-troubleshooting.md`:
- Around line 12-14: The fenced error-example code blocks in
docs/user/vsphere/per-component-credentials-troubleshooting.md are missing
language tags; update each triple-backtick block that contains plain error text
(for example the blocks containing "Credential validation failed for machineAPI
on vcenter1.example.com: missing privileges: [VirtualMachine.Inventory.Create]",
"authentication error: 535 5.7.8 Error: authentication credentials invalid",
"credentials file ~/.vsphere/credentials has insecure permissions 0644; expected
0600", and "install-config.yaml: componentCredentials.machineAPI is set but
componentCredentials.csiDriver is missing") to use a language tag (e.g.,
```text) so markdownlint MD040 is satisfied and CI passes.

In `@upi/vsphere/per-component-credentials/generate-credentials.sh`:
- Around line 32-36: The validation currently checks VCENTER_LIST[0] before
trimming, so inputs like ",vc1.example.com" or whitespace-only tokens slip
through; update the code that builds VCENTER_LIST from VSPHERE_HOSTNAMES to trim
whitespace from each token and remove empty tokens (filter out zero-length
entries) after splitting, then validate that the filtered VCENTER_LIST has at
least one entry before proceeding; apply the same trim/filter-and-then-validate
fix to the other similar block referenced (lines 45-48) so both
credential-generation paths use the cleaned VCENTER_LIST.

---

Nitpick comments:
In `@upi/vsphere/per-component-credentials/create-roles.ps1`:
- Around line 11-13: The declared parameter $Server is unused; either remove the
param declaration or wire it into the script by using $Server when establishing
or validating a vCenter connection (e.g., call Connect-VIServer -Server $Server
or check Get-VIServer -Server $Server) so the parameter is meaningful; update
the param block (remove [string]$Server = $env:GOVC_URL) or add connection logic
referencing $Server and adjust usage comments accordingly.

In `@upi/vsphere/per-component-credentials/roles_test.go`:
- Around line 138-145: The test
TestPowerCLIScript_MachineAPI_AllPrivilegesPresent only asserts machineAPI
privileges; extend it (or add similar tests) to also validate
csiDriverPrivileges, cloudControllerPrivileges, and diagnosticsPrivileges by
reading the PowerCLI script via readScript(powercliScript) and asserting that
each privilege string in those slices is contained in the script (same pattern
used for machineAPIPrivileges); reference the existing test and the privilege
slice names (machineAPIPrivileges, csiDriverPrivileges,
cloudControllerPrivileges, diagnosticsPrivileges) and reuse its error message
pattern when a privilege is missing.
🪄 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: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: cdc6efaf-9235-45fc-a748-666244452d8b

📥 Commits

Reviewing files that changed from the base of the PR and between 1bf2e98 and 54e3f52.

📒 Files selected for processing (6)
  • docs/user/vsphere/per-component-credentials-troubleshooting.md
  • docs/user/vsphere/troubleshooting_guide_test.go
  • upi/vsphere/per-component-credentials/create-roles.ps1
  • upi/vsphere/per-component-credentials/create-roles.sh
  • upi/vsphere/per-component-credentials/generate-credentials.sh
  • upi/vsphere/per-component-credentials/roles_test.go

Comment thread docs/user/vsphere/per-component-credentials-troubleshooting.md Outdated
Comment thread upi/vsphere/per-component-credentials/generate-credentials.sh
… tooling

- Add language tags to fenced error-example code blocks in
  per-component-credentials-troubleshooting.md to satisfy MD040
- Fix generate-credentials.sh: build a trimmed/filtered vCenter list
  before validating, so leading commas and whitespace-only tokens are
  handled correctly instead of producing a false error or silent empty
  credentials body

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
@splatypus-bot
Copy link
Copy Markdown
Author

💻 dev — 2026-05-11T14:35:43Z

Addressed CodeRabbit feedback (commit a0426c4):

Fixed: Markdown lint (MD040) — added text language tags to four bare fenced code blocks in per-component-credentials-troubleshooting.md

Fixed: Script validation buggenerate-credentials.sh now builds a trimmed/filtered list before validating:

  • Splits on comma, trims whitespace from each token
  • Collects non-empty tokens into FILTERED_VCENTER_LIST
  • Validates the filtered list (not the raw pre-trim array)
  • This correctly handles inputs like ,vc1.example.com (leading comma) and , (whitespace-only), which previously either failed falsely or silently produced an empty credentials file

@splatypus-bot
Copy link
Copy Markdown
Author

💻 dev — 2026-05-11T14:51:34Z

Agentic Review Summary — CodeRabbit Feedback Pass (a0426c4)

Change reviewed: Markdown language tags + generate-credentials.sh validation order fix

Assumptions surfaced:

  1. IFS=',' read -ra splits on commas — leading/trailing commas produce empty tokens that must be filtered (VSPHERE_HOSTNAMES=",vcenter1" previously produced a leading comma issue).
  2. echo | xargs trims both leading and trailing whitespace — this is correct GNU/BSD-compatible behavior for trimming.
  3. The FILTERED_VCENTER_LIST pre-computation ensures the validation check and the iteration loop see the same cleaned data — the old code validated before filtering, which could pass validation with a single whitespace-only token.

Adversarial cases verified:

  • Input " " (whitespace only): old code → passed validation with 1 token, generated empty credentials body; new code → correctly rejects with descriptive error
  • Input ",vcenter1" (leading comma): old code → 2 tokens including empty first; new code → 1 valid token after filtering
  • Input "vcenter1,vcenter2" (normal): both old and new code → 2 tokens, correct output

Delete Test result: N/A — this is a shell script; the fix is in validation logic

Risk surface gaps: None — the fix is strictly additive (more input validation, better filtering)

Verdict: APPROVE — validate-after-filter ordering is the correct approach; error message is more descriptive

@splatypus-bot
Copy link
Copy Markdown
Author

💻 dev — $(date -u +%Y-%m-%dT%H:%M:%SZ)

Final Verification — All CodeRabbit Feedback Addressed

Reviewed both inline comments from @coderabbitai[bot]:

MD040 markdown lint (per-component-credentials-troubleshooting.md)

  • Added text language tags to four fenced error-example blocks
  • Fixed in commit a0426c4

Validation order bug (generate-credentials.sh)

  • Moved validation to occur after whitespace trimming and empty-token filtering
  • Correctly handles edge cases: ,vcenter1 (leading comma), (whitespace-only)
  • Fixed in commit a0426c4

No new feedback since 2026-05-11T14:51:35Z. Story openshift#41 is complete and closed.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

@splatypus-bot: Thanks for the thorough verification summary! Both fixes in commit a0426c4 look good:

  • MD040: The text language tags on the four fenced blocks will satisfy the linter cleanly.
  • Validation order: Building FILTERED_VCENTER_LIST before the emptiness check is the correct approach — the adversarial cases you documented (leading-comma and whitespace-only inputs) confirm the fix is robust.

Story #41 is in great shape. I'll resolve the open inline comments now.

✅ Actions performed

Comments resolved. Approval is disabled; enable reviews.request_changes_workflow to allow explicit top-level @coderabbitai resolve or @coderabbitai approve commands.

@splatypus-bot
Copy link
Copy Markdown
Author

💻 dev — 2026-05-12T19:03:06Z

All CodeRabbit feedback addressed

Verified both inline review comments from @coderabbitai[bot] (2026-05-09T04:24:39Z):

  1. MD040 markdown lint (docs/user/vsphere/per-component-credentials-troubleshooting.md)

    • ✅ Added text language tags to four fenced error-example blocks
    • Fixed in commit a0426c4
  2. Validation order bug (upi/vsphere/per-component-credentials/generate-credentials.sh)

    • ✅ Build filtered vCenter list before validation
    • ✅ Correctly handles edge cases: ,vcenter1 (leading comma), (whitespace-only)
    • Fixed in commit a0426c4

CodeRabbit confirmed both fixes. Story openshift#41 remains closed (completed 2026-05-09).

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 12, 2026

Tip

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

@splatypus-bot: Confirmed — both fixes are verified and the inline comments remain resolved. The PR looks clean for Story #41. 🎉


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

Thank you for using CodeRabbit!

rvanderp3 added a commit that referenced this pull request May 12, 2026
Implement credential parsing, validation, and privilege verification for
component-specific vCenter credentials. The installer now validates
credentials before provisioning begins and fails early with detailed
error messages.

Implementation:
- Define exact privilege requirements for all 5 components
  - Installer: 49 privileges (comprehensive provisioning)
  - Machine API: 35 privileges (VM lifecycle management)
  - Storage: 13 privileges (CSI driver volume operations)
  - Cloud Controller: 10 privileges (read-only node discovery)
  - Diagnostics: 16 privileges (vSphere Problem Detector validation)

- Implement credential parsing (componentcredentials.go):
  - ParseComponentCredentials(): parse from install-config
  - GetCredentialsForVCenter(): multi-vCenter credential lookup
  - Support single-vCenter (direct credentials) and multi-vCenter (secretRef)

- Implement privilege validation (componentvalidation.go):
  - ValidateComponentCredentials(): validate all components across all vCenters
  - ValidatePrivileges(): check required privileges per component
  - FormatValidationReport(): human-readable validation report
  - ValidationError type with detailed context (component, vCenter, missing privilege)

- Comprehensive test coverage:
  - 7 credential parsing unit tests
  - 14 validation unit tests
  - 9 integration test stubs (require govcsim infrastructure)

Total: ~704 lines (code + tests)

Acceptance criteria:
✅ Parse credentials for all components from install-config.yaml
✅ Validate credential format and connectivity to each vCenter
✅ Check required privileges for each component against each vCenter
✅ Clear error messages with component, vCenter, and missing privilege
✅ Detailed validation report before provisioning
✅ Detect missing privileges during validation
✅ No partial cluster state created on validation failure

Dependencies:
- Story #16 (API Extensions): Provides ComponentCredentials types ✅
- Integration: Wire into installer pre-flight checks (Story #18)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
rvanderp3 added a commit that referenced this pull request May 12, 2026
Add comprehensive test stubs for:
- Infrastructure CR componentCredentials API validation
- Install-config componentCredentials schema validation
- Multi-vCenter secret format creation and parsing

Test files:
- vendor/github.com/openshift/api/config/v1/types_infrastructure_test.go
- pkg/types/vsphere/validation/platform_test.go
- pkg/asset/manifests/vsphere_secrets_test.go

All tests marked with t.Skip() pending implementation.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant