Skip to content

ROSAENG-63260 | refactor: Create reusable request/response conventions - #3452

Draft
markirish wants to merge 1 commit into
openshift:masterfrom
markirish:ROSAENG-63260-define-reusable-workflow-conventions
Draft

ROSAENG-63260 | refactor: Create reusable request/response conventions#3452
markirish wants to merge 1 commit into
openshift:masterfrom
markirish:ROSAENG-63260-define-reusable-workflow-conventions

Conversation

@markirish

@markirish markirish commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

PR Summary

Detailed Description of the Issue

  • Create a document outlining how requests from CLI to core layers should be structured
  • Outline how responses from core layer to CLI should be structured
  • Implement a minimal request/response workflow when creating an IAMServiceAccount

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

Behavior After This Change

How to Test (Step-by-Step)

Preconditions

Test Steps

Expected Results

Proof of the Fix

  • Screenshots:
  • Videos:
  • Logs/CLI output:
  • Other artifacts:

Breaking Changes

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

Breaking Change Details / Migration Plan

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 IAM service-account creation workflows with role generation, trust policies, managed and inline policies, permissions boundaries, paths, and GovCloud support.
    • Added validation and structured results for IAM service-account operations.
  • Documentation

    • Added workflow conventions covering request/result naming, validation, lifecycle boundaries, optional values, and domain types.
    • Updated architecture guidance and documentation indexes.
  • Tests

    • Added comprehensive coverage for successful creation, configuration options, GovCloud handling, validation, and error scenarios.

@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 Aug 6, 2026
@openshift-ci

openshift-ci Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

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

openshift-ci Bot commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: markirish
Once this PR has been reviewed and has the lgtm label, please assign jerichokeyne 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 Aug 6, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Pro Plus

Run ID: 6b8002b6-9c8e-4e0a-8c14-09c67ec26942

📥 Commits

Reviewing files that changed from the base of the PR and between e82fa7d and 79b1c0a.

📒 Files selected for processing (6)
  • AGENTS.md
  • guidelines/ARCHITECTURE.md
  • guidelines/workflow-conventions.md
  • pkg/iamserviceaccount/client.go
  • pkg/iamserviceaccount/create.go
  • pkg/iamserviceaccount/create_test.go
🚧 Files skipped from review as they are similar to previous changes (6)
  • pkg/iamserviceaccount/client.go
  • AGENTS.md
  • guidelines/ARCHITECTURE.md
  • pkg/iamserviceaccount/create_test.go
  • guidelines/workflow-conventions.md
  • pkg/iamserviceaccount/create.go

📝 Walkthrough

Walkthrough

The change documents workflow Request and Result conventions and updates architecture references. It adds IAM service-account client and service interfaces, request validation, role creation, trust-policy generation, tag handling, policy attachment, GovCloud ARN handling, structured results, and contextual errors. Ginkgo tests cover successful creation, validation failures, client errors, policy options, and stopping after the first attachment failure.

🚥 Pre-merge checks | ✅ 13 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description states the intended changes but leaves the issue context, testing steps, proof, breaking-change status, and verification checklist incomplete. Complete the required sections, including the problem and rationale, related issue links, test instructions and results, breaking-change selection, proof, and verification checklist.
Test Structure And Quality ⚠️ Warning pkg/iamserviceaccount/create_test.go uses 85 Expect assertions, with 82 lacking meaningful failure messages; mock-only tests otherwise need no cluster waits or cleanup. Add diagnostic messages to the assertions, especially error checks and recorded-call checks, such as the operation and relevant role or policy.
✅ Passed checks (13 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the refactor and its main focus on reusable request and response conventions.
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 The added Ginkgo titles are 28 static string literals. They contain no generated identifiers, timestamps, UUIDs, node or namespace values, IPs, or interpolated expressions.
Microshift Test Compatibility ✅ Passed The only new Ginkgo test is pkg/iamserviceaccount/create_test.go, a unit test with a mock IAM client; no tests were added under tests/e2e or OpenShift/MicroShift APIs.
Single Node Openshift (Sno) Test Compatibility ✅ Passed The added Ginkgo tests are unit tests in pkg/iamserviceaccount, using a local IAM mock; they do not access clusters or assume nodes, topology, scheduling, or HA.
Topology-Aware Scheduling Compatibility ✅ Passed The diff adds documentation and IAM service-account workflow code only; it changes no manifests, operators, controllers, replicas, affinities, tolerations, selectors, or disruption budgets.
Ote Binary Stdout Contract ✅ Passed Changed Go files add no main/init/TestMain or suite-setup stdout writes; fmt usage only constructs errors/ARNs, and the new tests use Describe/BeforeEach without output calls.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed The only added Ginkgo test is a package-level unit test using a local IAM mock; no e2e test, IP assumption, or external network operation was added.
No-Weak-Crypto ✅ Passed The added IAM workflow imports only context and fmt; scans of added lines and changed Go code found no MD5, SHA-1, DES, RC4, Blowfish, ECB, custom crypto, or secret comparisons.
Container-Privileges ✅ Passed The PR changes only documentation and Go IAM workflow files. No changed container or Kubernetes manifest contains privileged:true, host namespaces, SYS_ADMIN, root settings, or allowPrivilegeEscala...
No-Sensitive-Data-In-Logs ✅ Passed The PR adds no logging or print calls in the new workflow; it only returns wrapped errors and passes IAM policy data to the client.
✨ 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: 3

🧹 Nitpick comments (1)
pkg/iamserviceaccount/client.go (1)

40-46: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the unused producer-side interface abstraction.

IAMServiceAccountService has only one implementation and no production caller uses it. Move this to a concrete Service in pkg/iamserviceaccount; if an external consumer needs an interface, define a minimal interface at that consumer boundary instead.

🤖 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/iamserviceaccount/client.go` around lines 40 - 46, Remove the unused
IAMServiceAccountService interface and define the workflow on a concrete Service
type in pkg/iamserviceaccount, updating CreateIAMServiceAccount references and
construction accordingly. Preserve the existing CreateIAMServiceAccount
signature and behavior; any interface needed by external consumers should be
declared at their boundary.

Source: Coding guidelines

🤖 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/iamserviceaccount/create.go`:
- Around line 114-117: Update the request validation flow in the create
operation to check whether req is nil before calling req.Validate(), and return
an appropriate validation error instead of dereferencing it. Add a focused spec
covering a nil request passed through this call path, while preserving the
existing validation behavior for non-nil requests.
- Around line 141-150: Update the concrete IAM client methods EnsureRole,
AttachRolePolicy, and PutRolePolicy to accept ctx context.Context, then
propagate that context to every AWS SDK IAM request and paginator page call
instead of using context.Background() or context.TODO(). Update all callers,
including the service-account creation flow, to pass the existing caller context
through.
- Around line 51-83: Update CreateIAMServiceAccountRequest.Validate to reject
blank entries in PolicyARNs and validate that a non-empty InlinePolicy contains
valid JSON before returning success. Ensure these checks occur before role
creation through the existing validation path, and add specs verifying invalid
policy inputs fail without making IAM client calls.

---

Nitpick comments:
In `@pkg/iamserviceaccount/client.go`:
- Around line 40-46: Remove the unused IAMServiceAccountService interface and
define the workflow on a concrete Service type in pkg/iamserviceaccount,
updating CreateIAMServiceAccount references and construction accordingly.
Preserve the existing CreateIAMServiceAccount signature and behavior; any
interface needed by external consumers should be declared at their boundary.
🪄 Autofix

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: Pro Plus

Run ID: 09987a68-a0a5-4b33-87b5-779254be2e3f

📥 Commits

Reviewing files that changed from the base of the PR and between e82fa7d and b13666e.

📒 Files selected for processing (6)
  • AGENTS.md
  • guidelines/ARCHITECTURE.md
  • guidelines/workflow-conventions.md
  • pkg/iamserviceaccount/client.go
  • pkg/iamserviceaccount/create.go
  • pkg/iamserviceaccount/create_test.go

Comment on lines +51 to +83
func (r *CreateIAMServiceAccountRequest) Validate() error {
if r.ClusterName == "" {
return fmt.Errorf("cluster name is required")
}
if r.OIDCProviderARN == "" {
return fmt.Errorf("OIDC provider ARN is required")
}
if len(r.ServiceAccounts) == 0 {
return fmt.Errorf("at least one service account is required")
}
for _, sa := range r.ServiceAccounts {
if err := ValidateServiceAccountName(sa.Name); err != nil {
return fmt.Errorf("invalid service account name %q: %w", sa.Name, err)
}
if err := ValidateNamespaceName(sa.Namespace); err != nil {
return fmt.Errorf("invalid namespace %q for service account %q: %w", sa.Namespace, sa.Name, err)
}
}
if len(r.PolicyARNs) == 0 && r.InlinePolicy == "" {
return fmt.Errorf("at least one policy ARN or inline policy is required")
}
if r.RoleName == "" && len(r.ServiceAccounts) > 1 {
return fmt.Errorf("role name is required when specifying multiple service accounts")
}
if r.IsGovcloud {
if r.AccountID == "" {
return fmt.Errorf("account ID is required for GovCloud environments")
}
if r.Partition == "" {
return fmt.Errorf("partition is required for GovCloud environments")
}
}
return nil

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Validate each policy input before role creation.

PolicyARNs: []string{""} passes validation. A malformed non-empty InlinePolicy also passes validation. The workflow then calls EnsureRole before IAM rejects the policy input. This can leave a created or modified role after the command returns an error.

Reject blank policy ARN entries. Reject invalid inline-policy JSON before calling EnsureRole. Add specs that confirm these inputs make no IAM client calls.

Proposed validation change
 import (
 	"context"
+	"encoding/json"
 	"fmt"
+	"strings"
 )
 
-	if len(r.PolicyARNs) == 0 && r.InlinePolicy == "" {
+	if len(r.PolicyARNs) == 0 && strings.TrimSpace(r.InlinePolicy) == "" {
 		return fmt.Errorf("at least one policy ARN or inline policy is required")
 	}
+	for _, policyARN := range r.PolicyARNs {
+		if strings.TrimSpace(policyARN) == "" {
+			return fmt.Errorf("policy ARN cannot be empty")
+		}
+	}
+	if r.InlinePolicy != "" && !json.Valid([]byte(r.InlinePolicy)) {
+		return fmt.Errorf("inline policy must be valid JSON")
+	}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func (r *CreateIAMServiceAccountRequest) Validate() error {
if r.ClusterName == "" {
return fmt.Errorf("cluster name is required")
}
if r.OIDCProviderARN == "" {
return fmt.Errorf("OIDC provider ARN is required")
}
if len(r.ServiceAccounts) == 0 {
return fmt.Errorf("at least one service account is required")
}
for _, sa := range r.ServiceAccounts {
if err := ValidateServiceAccountName(sa.Name); err != nil {
return fmt.Errorf("invalid service account name %q: %w", sa.Name, err)
}
if err := ValidateNamespaceName(sa.Namespace); err != nil {
return fmt.Errorf("invalid namespace %q for service account %q: %w", sa.Namespace, sa.Name, err)
}
}
if len(r.PolicyARNs) == 0 && r.InlinePolicy == "" {
return fmt.Errorf("at least one policy ARN or inline policy is required")
}
if r.RoleName == "" && len(r.ServiceAccounts) > 1 {
return fmt.Errorf("role name is required when specifying multiple service accounts")
}
if r.IsGovcloud {
if r.AccountID == "" {
return fmt.Errorf("account ID is required for GovCloud environments")
}
if r.Partition == "" {
return fmt.Errorf("partition is required for GovCloud environments")
}
}
return nil
func (r *CreateIAMServiceAccountRequest) Validate() error {
if r.ClusterName == "" {
return fmt.Errorf("cluster name is required")
}
if r.OIDCProviderARN == "" {
return fmt.Errorf("OIDC provider ARN is required")
}
if len(r.ServiceAccounts) == 0 {
return fmt.Errorf("at least one service account is required")
}
for _, sa := range r.ServiceAccounts {
if err := ValidateServiceAccountName(sa.Name); err != nil {
return fmt.Errorf("invalid service account name %q: %w", sa.Name, err)
}
if err := ValidateNamespaceName(sa.Namespace); err != nil {
return fmt.Errorf("invalid namespace %q for service account %q: %w", sa.Namespace, sa.Name, err)
}
}
if len(r.PolicyARNs) == 0 && strings.TrimSpace(r.InlinePolicy) == "" {
return fmt.Errorf("at least one policy ARN or inline policy is required")
}
for _, policyARN := range r.PolicyARNs {
if strings.TrimSpace(policyARN) == "" {
return fmt.Errorf("policy ARN cannot be empty")
}
}
if r.InlinePolicy != "" && !json.Valid([]byte(r.InlinePolicy)) {
return fmt.Errorf("inline policy must be valid JSON")
}
if r.RoleName == "" && len(r.ServiceAccounts) > 1 {
return fmt.Errorf("role name is required when specifying multiple service accounts")
}
if r.IsGovcloud {
if r.AccountID == "" {
return fmt.Errorf("account ID is required for GovCloud environments")
}
if r.Partition == "" {
return fmt.Errorf("partition is required for GovCloud environments")
}
}
return nil
}
🤖 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/iamserviceaccount/create.go` around lines 51 - 83, Update
CreateIAMServiceAccountRequest.Validate to reject blank entries in PolicyARNs
and validate that a non-empty InlinePolicy contains valid JSON before returning
success. Ensure these checks occur before role creation through the existing
validation path, and add specs verifying invalid policy inputs fail without
making IAM client calls.

Comment thread pkg/iamserviceaccount/create.go
Comment thread pkg/iamserviceaccount/create.go
- Create a document outlining how requests from CLI to core layers should be structured
- Outline how responses from core layer to CLI should be structured
- Implement a minimal request/response workflow when creating an IAMServiceAccount
@markirish
markirish force-pushed the ROSAENG-63260-define-reusable-workflow-conventions branch from b13666e to 79b1c0a Compare August 6, 2026 16:15
@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

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

Labels

dco-signoff: yes do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant