Skip to content

OCM-23343 | feat: Added support for --no-console to rosa create ocm-role#3252

Open
andclt wants to merge 1 commit into
openshift:masterfrom
andclt:master
Open

OCM-23343 | feat: Added support for --no-console to rosa create ocm-role#3252
andclt wants to merge 1 commit into
openshift:masterfrom
andclt:master

Conversation

@andclt
Copy link
Copy Markdown
Contributor

@andclt andclt commented May 27, 2026

PR Summary

Adds --no-console flag to rosa create ocm-role for creating OCM roles with minimal permissions for customers not using console.redhat.com.

Detailed Description of the Issue

This PR adds support for creating OCM roles with minimal permissions (no-console).

Related Issues and PRs

Type of Change

  • feat - adds a new user-facing capability.
  • fix - resolves an incorrect behavior or bug.
  • docs - updates documentation only.
  • style - formatting or naming changes with no logic impact.
  • refactor - code restructuring with no behavior change.
  • test - adds or updates tests only.
  • chore - maintenance work (tooling, housekeeping, non-product code).
  • build - changes build system, packaging, or dependencies for build output.
  • ci - changes CI pipelines, jobs, or automation workflows.
  • perf - improves performance without changing intended behavior.

Previous Behavior

Users could only create standard or admin OCM roles. All OCM roles had permissions suitable for console.redhat.com usage.

Behavior After This Change

Users can create three OCM role profiles:

  • Standard (default): Full OCM permissions for console and CLI usage
  • Admin (--admin): Enhanced permissions for administrative operations
  • No-console (--no-console): Minimal permissions

The --admin and --no-console flags are mutually exclusive. No-console roles are tagged with rosa_no_console_role:true and attach the sts_ocm_no_console_permission_policy instead of the standard policy.

User-Facing Changes

New --no-console flag for OCM role creation:

  • Customers can now create OCM roles with minimal permissions using rosa create ocm-role --no-console
  • The --no-console and --admin flags are mutually exclusive
  • When creating a no-console role, a warning is displayed: "This OCM role cannot be used to provision clusters via console.redhat.com"

Interactive mode behavior:

  • In interactive mode, users are first asked if they want an admin role
  • If they decline admin, they're then asked if they want a no-console role
  • This ensures users understand they have three options: standard, admin, or no-console

Role conflict detection:

  • If a role already exists, the CLI provides clear guidance on what to do based on the requested vs. existing role type
  • Users cannot convert between role types - they must delete and recreate

Manual mode (--mode manual):

  • Generates the correct policy files and AWS CLI commands for no-console roles
  • Policy file: sts_ocm_no_console_permission_policy.json instead of the standard policy file

Graceful degradation:

  • If the no-console policy is not yet available from the OCM API, users get a clear error: "no-console OCM role is not yet enabled"

How to Test (Step-by-Step)

Preconditions

  • AWS credentials configured with appropriate IAM permissions
  • ROSA CLI built from this branch: make rosa
  • OCM login configured: rosa login

Test Results

Test 1: Mutual Exclusivity

Command:

./rosa create ocm-role --prefix test --admin --no-console

Expected: Error about mutually exclusive flags

Result: PASS

Error: if any flags in the group [admin no-console] are set none of the others can be; 
[admin no-console] were all set

Test 2: Standard Role Creation

Command:

./rosa create ocm-role --prefix test-standard --mode auto

Expected: Role created with no special tags (no admin, no no-console)

Result: PASS

I: Created role 'test-standard-OCM-Role-13829321'
I: Attached policy 'test-standard-OCM-Role-13829321-Policy'

Tags: rosa_role_type:OCM, red-hat-managed:true, rosa_environment:production
NO rosa_admin_role or rosa_no_console_role tags 

Test 3: Admin Role Creation

Command:

./rosa create ocm-role --prefix test-admin --admin --mode auto

Expected: Admin tag present, two policies attached

Result: PASS

I: Created role 'test-admin-OCM-Role-13829321'
I: Attached policy 'test-admin-OCM-Role-13829321-Policy'
I: Attached policy 'test-admin-OCM-Role-13829321-Admin-Policy'

Tags: rosa_admin_role:true 
Policies: Standard + Admin (2 total) 

Test 4: No-Console - Graceful Degradation (Production OCM)

Command:

./rosa create ocm-role --prefix test-noconsole --no-console --mode auto

Expected: Warning + error when policy not available, no AWS resources created

Result: PASS

W: This OCM role cannot be used to provision clusters via console.redhat.com 
I: Created role 'test-noconsole-OCM-Role-13829321'
E: There was an error creating the ocm role: no-console OCM role is not yet enabled 

Graceful error handling works correctly 
No partial resources created 

Test 5: No-Console - Full End-to-End (Local OCM with Policy)

Command:

./rosa create ocm-role --prefix test-noconsole-local --no-console --mode auto

Expected: Warning + full role creation with no-console policy

Result: PASS

W: This OCM role cannot be used to provision clusters via console.redhat.com 
I: Created role 'test-noconsole-local-OCM-Role-12541229'
I: Attached policy 'test-noconsole-local-OCM-Role-12541229-NoConsole-Policy' 

Tags: rosa_no_console_role:true 
Policy: Only NoConsole-Policy (NOT standard) 
Policy Content: {"Action":"iam:GetRole", "Condition":{...tags...}} 

Test 6: Manual Mode - Graceful Degradation (Production OCM)

Command:

mkdir /tmp/rosa-test && cd /tmp/rosa-test
./rosa create ocm-role --prefix test-manual --no-console --mode manual

Expected: Warning + error, no empty files

Result: PASS

W: This OCM role cannot be used to provision clusters via console.redhat.com 
E: There was an error creating the ocm role: no-console OCM role is not yet enabled 

No empty policy files generated 
Consistent with auto mode 

Test 7: Manual Mode - Full Success (Local OCM with Policy)

Command:

mkdir /tmp/rosa-manual && cd /tmp/rosa-manual
./rosa create ocm-role --prefix test-manual-noconsole --no-console --mode manual

Expected: Policy files with content, correct commands

Result: PASS

W: This OCM role cannot be used to provision clusters via console.redhat.com 
I: All policy files saved to the current directory

Files Generated:
 sts_ocm_trust_policy.json (has content)
 sts_ocm_no_console_permission_policy.json (has content, NOT empty!)

Commands Include:
 Key=rosa_no_console_role,Value=true
 --policy-name test-manual-noconsole-OCM-Role-12541229-NoConsole-Policy
 file://sts_ocm_no_console_permission_policy.json

Test 8: Interactive Mode - No Console

Command:

./rosa create ocm-role --prefix test-interactive -i
# Prompts: admin=No, no-console=Yes, mode=auto

Expected: No-console prompt shown after admin=No

Result: PASS

? Enable admin capabilities for the OCM role: No 
? Create OCM role with minimal permissions (no console access): Yes 
W: This OCM role cannot be used to provision clusters via console.redhat.com 
I: Created role 'test-no-console-interactive-OCM-Role-12541229'

Interactive flow correct: asked admin first, then no-console 
Tags: rosa_no_console_role:true 

Test 9: Interactive Mode - Admin

Command:

./rosa create ocm-role --prefix test-admin-interactive -i
# Prompts: admin=Yes, mode=auto

Expected: No-console prompt skipped (mutual exclusivity)

Result: PASS

? Enable admin capabilities for the OCM role: Yes 
[NO no-console prompt - correctly skipped] 
I: Created role 'test-admin-interactive-OCM-Role-12541229'
I: Attached policy 'test-admin-interactive-OCM-Role-12541229-Policy'
I: Attached policy 'test-admin-interactive-OCM-Role-12541229-Admin-Policy'

Tags: rosa_admin_role:true (NO rosa_no_console_role) 
Policies: Standard + Admin (2 total) 

Test 10: Conflict Detection - Standard → No Console

Command:

./rosa create ocm-role --prefix test-conflict --mode auto
./rosa create ocm-role --prefix test-conflict --no-console --mode auto

Expected: Error preventing conversion

Result: PASS

W: Role 'test-conflict-OCM-Role-13829321' already exists
E: There was an error creating the ocm role: the existing role is a standard role. 
   To use no-console permissions please delete the role and recreate it 

Clear, actionable error message 
No AWS resources modified 

Test 11: Conflict Detection - Admin → No Console

Command:

./rosa create ocm-role --prefix test-conflict2 --admin --mode auto
./rosa create ocm-role --prefix test-conflict2 --no-console --mode auto

Expected: Error preventing conversion

Result: PASS

W: Role 'test-conflict2-OCM-Role-13829321' already exists
E: There was an error creating the ocm role: the existing role is an admin role. 
   To use no-console permissions please delete the role and recreate it 

Clear, actionable error message 
No AWS resources modified 

Test 12: Upgrade Path - Standard → Admin

Command:

./rosa create ocm-role --prefix test-conflict3 --mode auto
./rosa create ocm-role --prefix test-conflict3 --admin --mode auto

Expected: Idempotent upgrade allowed

Result: PASS

W: Role 'test-conflict3-OCM-Role-13829321' already exists
? Add admin policies to 'test-conflict3-OCM-Role-13829321' role? Yes
I: Attached policy 'test-conflict3-OCM-Role-13829321-Admin-Policy' 

Tags: rosa_admin_role:true (added) 
Policies: Standard + Admin (both present) 
Idempotent upgrade works correctly 

Test 13: Custom Path

Command:

./rosa create ocm-role --prefix test-path --no-console --path /rosa/ --mode auto

Expected: Custom path in both role and policy ARNs

Result: PASS

I: Created role 'test-path-OCM-Role-12541229' with ARN 
   'arn:aws:iam::471112697682:role/rosa/test-path-OCM-Role-12541229' 
I: Attached policy 
   'arn:aws:iam::471112697682:policy/rosa/test-path-OCM-Role-12541229-NoConsole-Policy' 

Custom path /rosa/ correctly applied to both role and policy 

Summary

Automated Tests: 11/11 passing

cd cmd/create/ocmrole && ginkgo
SUCCESS! -- 11 Passed | 0 Failed

Manual Tests: 13/13 passed

  • All core functionality working correctly
  • Graceful degradation verified (production OCM without policy)
  • Full end-to-end flow verified (local OCM with policy)
  • Interactive mode, conflict detection, and edge cases validated

Key Validations:

  • --no-console flag works and is mutually exclusive with --admin
  • Warning message displays correctly
  • Correct tags: rosa_no_console_role:true
  • Correct policy: Only NoConsole-Policy (not standard)
  • Policy content: Minimal permissions (iam:GetRole with tag conditions)
  • Graceful error when policy unavailable
  • No empty files in manual mode
  • Conflict detection prevents invalid conversions
  • Custom paths work correctly

Breaking Changes

  • No breaking changes
  • Yes, this PR introduces a breaking change (describe impact and migration plan below)

Breaking Change Details / Migration Plan

N/A

Developer Verification Checklist

  • Commit subject/title follows [JIRA-TICKET] | [TYPE]: <MESSAGE>.
  • PR description clearly explains both what changed and why.
  • Relevant Jira/GitHub issues and related PRs are linked.
  • make install-hooks has been run in this clone.
  • Tests were added/updated where appropriate.
  • I manually tested the change.
  • make test passes.
  • make lint passes.
  • make rosa passes.
  • Documentation or repo-local agent guidance was added/updated where appropriate.
  • Any risk, limitation, or follow-up work is documented.

Summary by CodeRabbit

  • New Features

    • Added a --no-console option to create OCM roles without console access (mutually exclusive with --admin)
    • OCM role profiles now include standard, admin, and no-console with guided interactive selection
  • Improvements

    • Enhanced validation to prevent reusing roles with incompatible variants and ensure correct policy selection
  • Tests

    • Added tests for profile constants, no-console behavior, and policy-file generation/validation

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 27, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a no-console OCM role profile end-to-end: new OCMRoleProfile constants and CreateOCMRole, a --no-console CLI flag with interactive prompts and mutual exclusion with --admin, propagate isNoConsole to buildCommands and createRoles, enforce variant compatibility in checkRoleExists, add AWS helpers (IsNoConsoleRole, GetNoConsolePolicyName/GetNoConsolePolicyARN), add rosa_no_console_role tag constant, update mocks and CLI metadata, and include unit tests for command generation, policy file output, and IsNoConsoleRole.


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error Error log at line 284-286 exposes AWS Account ID and Organization ID together, which are sensitive identifiers that create a linkable connection between customer organizations and AWS accounts. Review logging at line 284-286 and consider masking or removing the organization ID from the error message, or log it only at debug level instead of error level.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.82% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Test Structure And Quality ⚠️ Warning buildCommands tests lack assertion failure messages; Expect(err).ToNot(HaveOccurred()) without messages violate assertion message requirement. Add failure messages to all error assertions in buildCommands tests like: Expect(err).ToNot(HaveOccurred(), "failed to build commands").
✅ Passed checks (12 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the primary change: adding --no-console support to rosa create ocm-role, which aligns with the substantial implementation across multiple files.
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 Ginkgo test names in added test files are static and descriptive, containing no dynamic values, timestamps, UUIDs, or generated identifiers that would change between runs.
Microshift Test Compatibility ✅ Passed Tests added are unit tests (not e2e) in cmd/create/ocmrole/. They test CLI command/policy generation with no cluster interaction or MicroShift-incompatible APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed PR adds Ginkgo unit tests (not e2e tests) for the --no-console flag feature. Tests are colocated with package code and use mocks with no cluster interaction.
Topology-Aware Scheduling Compatibility ✅ Passed This PR contains no deployment manifests, operator code, or controllers with scheduling constraints. Changes are limited to AWS IAM role/policy management and CLI command logic.
Ote Binary Stdout Contract ✅ Passed The only fmt.Println() is in a Cobra command handler, not process-level code, so it safely executes during command execution rather than at startup.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed Tests added are unit tests in cmd/create/ocmrole/ and pkg/aws/, not e2e tests in tests/e2e/. They use mocking, no IPv4 assumptions, and no external connectivity.
No-Weak-Crypto ✅ Passed No weak cryptography detected. The PR adds OCM role management features with no MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB mode, custom crypto, or non-constant-time secret comparisons.
Container-Privileges ✅ Passed This PR modifies only Go source files and YAML test configuration files; no container or Kubernetes manifests are modified, making the container-privileges check not applicable.
Description check ✅ Passed The PR description is comprehensive and well-structured, following the repository template with all major sections completed including summary, detailed description, related issues, type of change, behavioral changes, testing evidence, and developer checklist.
✨ 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 and usage tips.

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 27, 2026
@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 27, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 27, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: andclt
Once this PR has been reviewed and has the lgtm label, please assign gdbranco 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

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 (1)
cmd/create/ocmrole/cmd.go (1)

619-656: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Manual mode doesn’t generate the no-console permission policy file.

generateOcmRolePolicyFiles accepts isNoConsole but always writes sts_ocm_permission_policy.json. For --no-console, buildCommands expects sts_ocm_no_console_permission_policy.json, so generated commands can reference a missing file.

🔧 Suggested fix
-	filename = fmt.Sprintf("sts_%s_permission_policy", aws.OCMRolePolicyFile)
+	policyFile := aws.OCMRolePolicyFile
+	if isNoConsole {
+		policyFile = aws.OCMNoConsoleRolePolicyFile
+	}
+	filename = fmt.Sprintf("sts_%s_permission_policy", policyFile)
 	policyDetail = aws.GetPolicyDetails(policies, filename)
🤖 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 `@cmd/create/ocmrole/cmd.go` around lines 619 - 656, The function
generateOcmRolePolicyFiles currently ignores the isNoConsole flag and always
writes the standard permission file name; update the filename selection so when
isNoConsole is true you use the "sts_%s_no_console_permission_policy" pattern
(format with aws.OCMRolePolicyFile) and call aws.GetPolicyDetails/SaveDocument
with that detail, otherwise keep the existing "sts_%s_permission_policy"
behavior; ensure the r.Reporter.Debugf and filename formatting
(aws.GetFormattedFileName) use the chosen name so buildCommands can find
"sts_ocm_no_console_permission_policy.json" when --no-console is used.
🧹 Nitpick comments (1)
cmd/create/ocmrole/ocmrole.go (1)

25-33: ⚡ Quick win

Add doc comments for new exported API symbols.

Please add Go doc comments for OCMRoleProfile, exported profile constants, and CreateOCMRole.

✍️ Suggested update
+// OCMRoleProfile defines the OCM role permission profile.
 type OCMRoleProfile string
 
 const (
+	// ProfileStandard creates a standard OCM role.
 	ProfileStandard  OCMRoleProfile = "standard"
+	// ProfileAdmin creates an OCM role with admin permissions.
 	ProfileAdmin     OCMRoleProfile = "admin"
+	// ProfileNoConsole creates an OCM role with minimal permissions and no console compatibility.
 	ProfileNoConsole OCMRoleProfile = "no-console"
 )
 
+// CreateOCMRole creates the OCM role according to the selected profile.
 func CreateOCMRole(r *rosa.Runtime, prefix string, orgID string, profile OCMRoleProfile, permissionsBoundary string, rolePath string, policies map[string]*cmv1.AWSSTSPolicy, env string, managedPolicies bool) (string, error) {
As per coding guidelines `**/*.go`: "Use exported symbol doc comments when new public types or functions are introduced".
🤖 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 `@cmd/create/ocmrole/ocmrole.go` around lines 25 - 33, Add Go doc comments for
the exported symbols: the type OCMRoleProfile, the exported constants
ProfileStandard, ProfileAdmin, ProfileNoConsole, and the function CreateOCMRole;
for each, add a short sentence starting with the symbol name that describes its
purpose and behavior (e.g., "OCMRoleProfile represents ...", "ProfileStandard is
...", etc.), and for CreateOCMRole document its parameters and return values
succinctly (what the function does, key params like r *rosa.Runtime, prefix,
orgID, profile, permissionsBoundary, rolePath, policies, env, managedPolicies,
and the returned string and error). Ensure comments are placed immediately above
each declaration and follow Go doc comment style (start with the symbol name).
🤖 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 `@cmd/create/ocmrole/cmd.go`:
- Around line 600-607: When unmanaged (managedPolicies == false) and the
"no-console" flow is active, the code currently uses
aws.GetPolicyArnWithSuffix(...) which diverges from manual mode; change the else
branch so that when no-console is requested it calls
aws.GetNoConsolePolicyARN(...) (keeping the same inputs used in manual mode)
instead of aws.GetPolicyArnWithSuffix(r.Creator.Partition, r.Creator.AccountID,
roleName, rolePath); keep aws.GetManagedPolicyARN(policies, filename) for the
managedPolicies==true path and fall back to GetPolicyArnWithSuffix only when
no-console is not active.

---

Outside diff comments:
In `@cmd/create/ocmrole/cmd.go`:
- Around line 619-656: The function generateOcmRolePolicyFiles currently ignores
the isNoConsole flag and always writes the standard permission file name; update
the filename selection so when isNoConsole is true you use the
"sts_%s_no_console_permission_policy" pattern (format with
aws.OCMRolePolicyFile) and call aws.GetPolicyDetails/SaveDocument with that
detail, otherwise keep the existing "sts_%s_permission_policy" behavior; ensure
the r.Reporter.Debugf and filename formatting (aws.GetFormattedFileName) use the
chosen name so buildCommands can find
"sts_ocm_no_console_permission_policy.json" when --no-console is used.

---

Nitpick comments:
In `@cmd/create/ocmrole/ocmrole.go`:
- Around line 25-33: Add Go doc comments for the exported symbols: the type
OCMRoleProfile, the exported constants ProfileStandard, ProfileAdmin,
ProfileNoConsole, and the function CreateOCMRole; for each, add a short sentence
starting with the symbol name that describes its purpose and behavior (e.g.,
"OCMRoleProfile represents ...", "ProfileStandard is ...", etc.), and for
CreateOCMRole document its parameters and return values succinctly (what the
function does, key params like r *rosa.Runtime, prefix, orgID, profile,
permissionsBoundary, rolePath, policies, env, managedPolicies, and the returned
string and error). Ensure comments are placed immediately above each declaration
and follow Go doc comment style (start with the symbol name).
🪄 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: 647c19b7-f66e-4662-be1c-cffb03f79c86

📥 Commits

Reviewing files that changed from the base of the PR and between b71fe92 and 22e2699.

📒 Files selected for processing (6)
  • cmd/create/ocmrole/cmd.go
  • cmd/create/ocmrole/ocmrole.go
  • pkg/aws/client.go
  • pkg/aws/helpers.go
  • pkg/aws/policies.go
  • pkg/aws/tags/tags.go

Comment thread cmd/create/ocmrole/cmd.go
@amandahla
Copy link
Copy Markdown

@andclt Seems that is already being addressed by #3251
Can you confirm please?

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

🤖 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 `@cmd/create/ocmrole/cmd_test.go`:
- Around line 40-51: The test currently ignores errors from
cmv1.AWSSTSPolicyBuilder.Build() for standardPolicy, adminPolicy, and
noConsolePolicy; update the test to capture the error return for each Build()
call (e.g., standardPolicy, err :=
(&cmv1.AWSSTSPolicyBuilder{}).ARN(...).Details(...).Build()) and fail the test
on error (use t.Fatalf or a test helper like require.NoError) so broken fixtures
surface immediately; apply this change for all three builder invocations
(standardPolicy, adminPolicy, noConsolePolicy) in cmd_test.go.
🪄 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: eca4c984-a8b5-46ab-8975-96a8c151e85f

📥 Commits

Reviewing files that changed from the base of the PR and between 22e2699 and 7be18be.

⛔ Files ignored due to path filters (1)
  • assets/bindata.go is excluded by !assets/bindata.go
📒 Files selected for processing (11)
  • cmd/create/ocmrole/cmd.go
  • cmd/create/ocmrole/cmd_test.go
  • cmd/create/ocmrole/ocmrole.go
  • cmd/create/ocmrole/ocmrole_test.go
  • cmd/rosa/structure_test/command_args/rosa/create/ocm-role/command_args.yml
  • pkg/aws/client.go
  • pkg/aws/client_mock.go
  • pkg/aws/helpers.go
  • pkg/aws/policies.go
  • pkg/aws/policies_test.go
  • pkg/aws/tags/tags.go
✅ Files skipped from review due to trivial changes (2)
  • cmd/rosa/structure_test/command_args/rosa/create/ocm-role/command_args.yml
  • pkg/aws/client_mock.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • pkg/aws/tags/tags.go
  • cmd/create/ocmrole/ocmrole.go
  • pkg/aws/client.go
  • pkg/aws/helpers.go
  • pkg/aws/policies.go
  • cmd/create/ocmrole/cmd.go

Comment thread cmd/create/ocmrole/cmd_test.go Outdated
@andclt
Copy link
Copy Markdown
Contributor Author

andclt commented May 27, 2026

@andclt Seems that is already being addressed by #3251 Can you confirm please?

Yes! So far this is just a draft PR to test the no-console role changes!

@openshift-ci openshift-ci Bot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 27, 2026
@openshift-ci openshift-ci Bot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label May 27, 2026
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

🧹 Nitpick comments (2)
cmd/create/ocmrole/cmd_test.go (1)

66-190: ⚡ Quick win

Add a mutual-exclusion regression test for isAdmin && isNoConsole.

This suite validates each profile independently, but it does not assert behavior for the invalid combined profile. Add a negative case that verifies buildCommands rejects isAdmin=true with isNoConsole=true (or asserts the expected contract) to prevent silent mixed-profile regressions.

As per coding guidelines, **/*_test.go: "Flag weak tests that only restate implementation or changes that weaken existing assertions".

🤖 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 `@cmd/create/ocmrole/cmd_test.go` around lines 66 - 190, Add a negative test
inside the existing "Manual mode command generation" Context that calls
buildCommands with isAdmin=true and isNoConsole=true and asserts the expected
rejection (either Expect(err).To(HaveOccurred()) or the specific contract your
code enforces), e.g. an It block named "should reject combined isAdmin and
isNoConsole" that invokes buildCommands("test","test-OCM-Role",... , true, true,
...) and validates the function returns an error or fails the contract rather
than silently producing mixed-profile commands; place the test alongside the
other It cases so it covers the regression where both flags are set.
cmd/create/ocmrole/cmd.go (1)

419-437: 💤 Low value

Consider simplifying the policy ARN resolution logic.

Since policyKey is already computed correctly based on isNoConsole (line 418), the managed-policy branch is identical in both cases. This could be flattened to reduce duplication:

♻️ Suggested simplification
-	if isNoConsole {
-		if managedPolicies {
-			policyARN, err = aws.GetManagedPolicyARN(policies, policyKey)
-			if err != nil {
-				return "", err
-			}
-		} else {
-			policyARN = aws.GetNoConsolePolicyARN(creator.Partition, creator.AccountID, roleName, rolePath)
-		}
+	if managedPolicies {
+		policyARN, err = aws.GetManagedPolicyARN(policies, policyKey)
+		if err != nil {
+			return "", err
+		}
+	} else if isNoConsole {
+		policyARN = aws.GetNoConsolePolicyARN(creator.Partition, creator.AccountID, roleName, rolePath)
 	} else {
-		if managedPolicies {
-			policyARN, err = aws.GetManagedPolicyARN(policies, policyKey)
-			if err != nil {
-				return "", err
-			}
-		} else {
-			policyARN = aws.GetPolicyArnWithSuffix(creator.Partition, creator.AccountID, roleName, rolePath)
-		}
+		policyARN = aws.GetPolicyArnWithSuffix(creator.Partition, creator.AccountID, roleName, rolePath)
 	}
🤖 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 `@cmd/create/ocmrole/cmd.go` around lines 419 - 437, The current nested if/else
duplicates the managedPolicies branch; refactor the policy ARN resolution so you
first check managedPolicies once (call aws.GetManagedPolicyARN(policies,
policyKey) and handle error), and otherwise choose between
aws.GetNoConsolePolicyARN(creator.Partition, creator.AccountID, roleName,
rolePath) and aws.GetPolicyArnWithSuffix(creator.Partition, creator.AccountID,
roleName, rolePath) based on isNoConsole, assigning to policyARN accordingly;
this removes the duplicated managedPolicies logic while preserving use of
policyKey, creator.Partition, creator.AccountID, roleName, and rolePath.
🤖 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 `@cmd/create/ocmrole/cmd.go`:
- Around line 724-752: Fix the punctuation in the three error fmt.Errorf
messages that mention "role" so they end with a period to match the existing
style: update the error returned when isExistingRoleNoConsole is true ("the
existing role is a no-console role..."), the error returned when
isExistingRoleAdmin is true while isNoConsole is requested ("the existing role
is an admin role..."), and the error for existing standard role when isNoConsole
is requested ("the existing role is a standard role...") — locate these in
cmd/create/ocmrole/cmd.go around the checks using isExistingRoleNoConsole,
isExistingRoleAdmin and isNoConsole and add a period after "role" in each
fmt.Errorf string while preserving the rest of the text and spacing.

---

Nitpick comments:
In `@cmd/create/ocmrole/cmd_test.go`:
- Around line 66-190: Add a negative test inside the existing "Manual mode
command generation" Context that calls buildCommands with isAdmin=true and
isNoConsole=true and asserts the expected rejection (either
Expect(err).To(HaveOccurred()) or the specific contract your code enforces),
e.g. an It block named "should reject combined isAdmin and isNoConsole" that
invokes buildCommands("test","test-OCM-Role",... , true, true, ...) and
validates the function returns an error or fails the contract rather than
silently producing mixed-profile commands; place the test alongside the other It
cases so it covers the regression where both flags are set.

In `@cmd/create/ocmrole/cmd.go`:
- Around line 419-437: The current nested if/else duplicates the managedPolicies
branch; refactor the policy ARN resolution so you first check managedPolicies
once (call aws.GetManagedPolicyARN(policies, policyKey) and handle error), and
otherwise choose between aws.GetNoConsolePolicyARN(creator.Partition,
creator.AccountID, roleName, rolePath) and
aws.GetPolicyArnWithSuffix(creator.Partition, creator.AccountID, roleName,
rolePath) based on isNoConsole, assigning to policyARN accordingly; this removes
the duplicated managedPolicies logic while preserving use of policyKey,
creator.Partition, creator.AccountID, roleName, and rolePath.
🪄 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: 2a48e7e9-6a64-4f8d-963c-237321ec069a

📥 Commits

Reviewing files that changed from the base of the PR and between 7be18be and ad8f563.

⛔ Files ignored due to path filters (1)
  • assets/bindata.go is excluded by !assets/bindata.go
📒 Files selected for processing (11)
  • cmd/create/ocmrole/cmd.go
  • cmd/create/ocmrole/cmd_test.go
  • cmd/create/ocmrole/ocmrole.go
  • cmd/create/ocmrole/ocmrole_test.go
  • cmd/rosa/structure_test/command_args/rosa/create/ocm-role/command_args.yml
  • pkg/aws/client.go
  • pkg/aws/client_mock.go
  • pkg/aws/helpers.go
  • pkg/aws/policies.go
  • pkg/aws/policies_test.go
  • pkg/aws/tags/tags.go
✅ Files skipped from review due to trivial changes (2)
  • cmd/rosa/structure_test/command_args/rosa/create/ocm-role/command_args.yml
  • pkg/aws/client_mock.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • cmd/create/ocmrole/ocmrole_test.go
  • pkg/aws/tags/tags.go
  • cmd/create/ocmrole/ocmrole.go
  • pkg/aws/client.go
  • pkg/aws/policies_test.go
  • pkg/aws/policies.go
  • pkg/aws/helpers.go

Comment thread cmd/create/ocmrole/cmd.go
@andclt andclt force-pushed the master branch 3 times, most recently from 1c3e97f to 7ca2a51 Compare May 28, 2026 13:54
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: 0

🧹 Nitpick comments (1)
cmd/create/ocmrole/cmd_test.go (1)

203-213: ⚡ Quick win

Protect these specs from parallel execution side effects.

Lines 203–213 and 248–254 mutate process-global working directory via os.Chdir, which can make specs flaky when running in parallel. Consider marking this Describe as Serial (or refactor file generation to avoid cwd mutation).

Also applies to: 248-254

🤖 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 `@cmd/create/ocmrole/cmd_test.go` around lines 203 - 213, The tests call
os.Chdir in the BeforeEach (using tempDir, originalWd variables) which mutates
process-wide CWD and can cause flakiness in parallel runs; fix it by making the
enclosing Describe run serially (add the Ginkgo Serial option to the Describe
that contains these BeforeEach/AfterEach blocks, e.g. change Describe("…",
func() { to Describe("…", Serial, func() {) so the os.Chdir/restore (originalWd)
pair is not executed concurrently, or alternatively refactor the BeforeEach to
avoid calling os.Chdir at all by using absolute tempDir paths in file operations
instead of changing the process working directory.
🤖 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 `@cmd/create/ocmrole/cmd_test.go`:
- Around line 203-213: The tests call os.Chdir in the BeforeEach (using tempDir,
originalWd variables) which mutates process-wide CWD and can cause flakiness in
parallel runs; fix it by making the enclosing Describe run serially (add the
Ginkgo Serial option to the Describe that contains these BeforeEach/AfterEach
blocks, e.g. change Describe("…", func() { to Describe("…", Serial, func() {) so
the os.Chdir/restore (originalWd) pair is not executed concurrently, or
alternatively refactor the BeforeEach to avoid calling os.Chdir at all by using
absolute tempDir paths in file operations instead of changing the process
working directory.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 83b80cb6-f17f-43c7-b421-90cc96a83b91

📥 Commits

Reviewing files that changed from the base of the PR and between 3edc2c5 and 1c3e97f.

⛔ Files ignored due to path filters (1)
  • assets/bindata.go is excluded by !assets/bindata.go
📒 Files selected for processing (12)
  • cmd/create/ocmrole/cmd.go
  • cmd/create/ocmrole/cmd_test.go
  • cmd/create/ocmrole/ocmrole.go
  • cmd/create/ocmrole/ocmrole.test
  • cmd/create/ocmrole/ocmrole_test.go
  • cmd/rosa/structure_test/command_args/rosa/create/ocm-role/command_args.yml
  • pkg/aws/client.go
  • pkg/aws/client_mock.go
  • pkg/aws/helpers.go
  • pkg/aws/policies.go
  • pkg/aws/policies_test.go
  • pkg/aws/tags/tags.go
✅ Files skipped from review due to trivial changes (1)
  • pkg/aws/client_mock.go
🚧 Files skipped from review as they are similar to previous changes (7)
  • cmd/rosa/structure_test/command_args/rosa/create/ocm-role/command_args.yml
  • cmd/create/ocmrole/ocmrole.go
  • pkg/aws/tags/tags.go
  • cmd/create/ocmrole/ocmrole_test.go
  • pkg/aws/policies_test.go
  • pkg/aws/client.go
  • pkg/aws/helpers.go

@andclt andclt marked this pull request as ready for review May 28, 2026 17:13
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label May 28, 2026
Comment thread cmd/create/ocmrole/ocmrole.go Outdated
Comment thread cmd/create/ocmrole/cmd.go Outdated
Comment thread cmd/create/ocmrole/ocmrole.go Outdated
@amandahla
Copy link
Copy Markdown

@andclt I left some comments but I didnt review everything since one of them might change things here, please feel free to ping me if you want to discuss about it.

Comment thread cmd/create/ocmrole/cmd.go Outdated
// Check if no-console policy is available
if isNoConsole {
if _, ok := policies[filename]; !ok {
return fmt.Errorf("no-console OCM role is not yet enabled")
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.

@andclt This check is happening after the IAM role has been created in AWS, which leaves an orphaned IAM role with no policies attached. This makes it look like the OCM Role exists, but just hasn't been linked as it shows up when you run rosa list ocm-role.

We shouldn't attempt the role creation at all if the required permission policy is not available.

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.

@andclt Also wondering if we adjust the message a little to be more user friendly e.g.

The no-console OCM role profile is not yet enabled for your Organization

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.

Good point! Thanks, fixed!

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.

This is closer, but the preflight still only checks map membership. If the no-console STSPolicy comes back without ARN/details, auto mode can still create and tag the role before failing, so it would be safer to validate the exact data needed for the selected mode up front.

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.

As discussed offline, this applies to every profile and policies in the file, but for this PR we are tackling no-console only.

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.

Scoping the upfront validation to no-console makes sense for this PR because that’s the new rollout-gated path and the Jira acceptance criteria call it out explicitly. I’d still capture the broader standard/admin validation as follow-up, since the same late-failure pattern exists outside no-console too.

@andclt andclt force-pushed the master branch 2 times, most recently from ba578aa to 48f12e5 Compare May 29, 2026 12:52
Comment thread cmd/create/ocmrole/ocmrole.go Outdated
@amandahla
Copy link
Copy Markdown

Last comment: could you add some tests covering the checkRoleExists? Like when requesting No-Console profile, should succeed if existing role is No-Console and it should error if existing role is Admin or Standard.

@openshift-ci
Copy link
Copy Markdown
Contributor

openshift-ci Bot commented May 29, 2026

@andclt: all tests passed!

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.

Comment thread cmd/create/ocmrole/cmd.go
filename = fmt.Sprintf("sts_%s_permission_policy", aws.OCMNoConsoleRolePolicyFile)

// tag role with no-console tag
err = r.AWSClient.AddRoleTag(roleName, tags.NoConsoleRole, tags.True)
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.

This tags the role as no-console before the policy is attached. If the create or attach fails after tagging, a retry will treat the role as complete, so can we tag only after the policy attach succeeds or verify the attached policy in checkRoleExists?

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.

4 participants