Skip to content

[ISSUE #7122]🚀feat(cli): refactor ACL command implementations to use new request structures and improve error handling#7123

Merged
rocketmq-rust-bot merged 1 commit intomainfrom
feat-7122
Apr 12, 2026
Merged

[ISSUE #7122]🚀feat(cli): refactor ACL command implementations to use new request structures and improve error handling#7123
rocketmq-rust-bot merged 1 commit intomainfrom
feat-7122

Conversation

@mxsm
Copy link
Copy Markdown
Owner

@mxsm mxsm commented Apr 12, 2026

Which Issue(s) This PR Fixes(Closes)

Brief Description

How Did You Test This Change?

Summary by CodeRabbit

  • New Features

    • Implemented functional ACL retrieval with proper error handling for missing ACL entries.
  • Refactor

    • Simplified ACL command workflows (create, update, delete, get, list, copy) by consolidating internal logic into centralized service operations.
    • Streamlined CLI ACL management by removing intermediate validation layers and delegating operations to core auth service.

…new request structures and improve error handling
@rocketmq-rust-robot rocketmq-rust-robot added the feature🚀 Suggest an idea for this project. label Apr 12, 2026
@rocketmq-rust-bot
Copy link
Copy Markdown
Collaborator

🔊@mxsm 🚀Thanks for your contribution🎉!

💡CodeRabbit(AI) will review your code first🔥!

Note

🚨The code review suggestions from CodeRabbit are to be used as a reference only, and the PR submitter can decide whether to make changes based on their own judgment. Ultimately, the project management personnel will conduct the final code review💥.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 12, 2026

Walkthrough

This PR refactors ACL command implementations across the RocketMQ admin CLI to delegate ACL operations to a new centralized AuthService layer, replacing direct admin extension manipulation with request-based abstractions. The get_acl client method is implemented with actual lookup logic, and the Target module is removed as its validation logic migrates into request structures.

Changes

Cohort / File(s) Summary
ACL Client Implementation
rocketmq-client/src/admin/default_mq_admin_ext_impl.rs, rocketmq-admin-core/src/admin/default_mq_admin_ext.rs
Implemented get_acl by converting from unimplemented!() to functional lookup via list_acl, returning first matching AclInfo or raising error if not found. Added test verifying correct error handling for unstarted admin instances.
Core Auth Service Layer
rocketmq-admin-core/src/core/auth.rs
Added comprehensive ACL request/response models (CreateAclRequest, UpdateAclRequest, DeleteAclRequest, GetAclRequest, ListAclRequest, CopyAclRequest) and corresponding result types. Implemented async service methods delegating to DefaultMQAdminExt with per-broker RPC calls, parallel fan-out for cluster targets, and aggregated error tracking.
CLI ACL Command Refactoring
rocketmq-admin-cli/src/commands/auth/create_acl_sub_command.rs, update_acl_sub_command.rs, delete_acl_sub_command.rs, get_acl_sub_command.rs, list_acl_sub_command.rs, copy_acl_sub_command.rs
Replaced manual admin extension lifecycle management and per-broker logic with request construction via *Request::try_new(...) and centralized AuthService calls. Consolidated output rendering and error aggregation into helper functions.
Module Cleanup
rocketmq-admin-cli/src/commands/target.rs, rocketmq-admin-cli/src/commands.rs
Removed Target enum and module (previously handled BrokerAddr/ClusterName branching); functionality consolidated into request structures.
Tests
rocketmq-admin-core/tests/auth_core_models.rs
Added test coverage for ACL request creation, field normalization, target resolution, and ACL info construction.

Sequence Diagram

sequenceDiagram
    actor User as CLI User
    participant CLI as ACL Subcommand
    participant Auth as AuthService
    participant Admin as DefaultMQAdminExt
    participant Broker as Broker RPC

    User->>CLI: Execute ACL command with args
    activate CLI
    CLI->>CLI: Create *Request via try_new()
    CLI->>Auth: call_acl_by_request_with_rpc_hook(request, hook)
    activate Auth
    Auth->>Admin: new + start()
    activate Admin
    
    alt Broker Target
        Auth->>Admin: get_acl(broker_addr, subject)
        Admin->>Broker: RPC call
        Broker-->>Admin: AclInfo result
    else Cluster Target
        Auth->>Admin: resolve_cluster_addresses()
        Admin-->>Auth: [broker_addrs]
        Auth->>Admin: parallel get_acl() for each broker
        Admin->>Broker: parallel RPC calls
        Broker-->>Admin: AclInfo results
    end
    
    Admin->>Auth: return aggregated result
    deactivate Admin
    Auth->>Admin: shutdown()
    Auth-->>CLI: *Result (success_data, failed_broker_addrs)
    deactivate Auth
    
    CLI->>CLI: render_*_result(result)
    CLI-->>User: formatted output + warnings
    deactivate CLI
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • #5694: Modifies ACL update functionality and UpdateAcl subcommand delegation patterns, with overlapping admin extension refactoring.
  • #7121: Extends the same authentication admin service layer with user-management request/result types and RPC-backed async operations, establishing parallel architecture patterns.

Suggested labels

feature🚀, ready to review, waiting-review, AI review first, Difficulty level/Moderate

Suggested reviewers

  • TeslaRustor
  • SpaceXCN

Poem

🐰 Hoppy hoppy, refactor day!
ACL requests now lead the way,
No more direct admin calls,
Service layer catches all!
Requests dance where Target dwelled,
Our bunny code's now finally spelled! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.98% 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 PR title accurately describes the main refactoring effort: migrating ACL command implementations from direct admin calls to new request structures with improved error handling.
Linked Issues check ✅ Passed The code changes fully implement the feature objective: CLI ACL commands (create, update, delete, get, list, copy) are refactored to use new request structures (CreateAclRequest, UpdateAclRequest, DeleteAclRequest, GetAclRequest, ListAclRequest, CopyAclRequest) and AuthService with enhanced error handling.
Out of Scope Changes check ✅ Passed All changes are directly in scope: implementation of get_acl in DefaultMQAdminExtImpl, removal of obsolete Target enum, refactoring of auth CLI commands to use new request structures, and addition of core auth service with proper error handling.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-7122

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
Contributor

@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: 6

Caution

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

⚠️ Outside diff range comments (1)
rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/auth.rs (1)

1-1: ⚠️ Potential issue | 🟡 Minor

Use the repository-standard copyright year.

This header regresses from the repo convention and should stay on 2023.

Based on learnings, In Rust source files (*.rs) across the rocketmq-rust repository, enforce using "Copyright 2023" as the year in the header instead of the current calendar year.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/auth.rs` at line
1, The file header in rocketmq-admin-core's auth.rs uses "Copyright 2026" which
violates the repository standard; update the top-of-file copyright line in
auth.rs to read "Copyright 2023" (preserving the rest of the header text and
formatting) so it matches the repo-wide convention used across Rust source files
in this crate.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/auth/get_acl_sub_command.rs`:
- Around line 56-60: In render_get_acl_result, don't treat single-broker
failures as "not found": change the early-return condition to require
result.failed_broker_addrs.is_empty() as well (i.e., only return Ok(()) and
print "No ACL..." when single_broker_target && result.acl_infos.is_empty() &&
result.failed_broker_addrs.is_empty()); if failed_broker_addrs is non-empty, do
not return early—report the broker failure(s) (include
result.failed_broker_addrs in the output or error path) so real
timeouts/rejections from the single broker are surfaced instead of being masked.

In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/auth.rs`:
- Around line 1231-1241: The current match on
admin.get_acl(request.to_broker().clone(), subject.clone()).await treats any Err
as “ACL absent” and always calls create_acl_with_acl_info; instead inspect the
returned error from admin.get_acl and only call admin.create_acl_with_acl_info
when the error indicates a definite NotFound/missing-ACL condition, while for
transport/auth/RPC or other errors return/propagate the error into failures (do
not attempt create). Adjust the match/if handling around
admin.get_acl(...).await, using the error variant or status check to distinguish
NotFound from other errors before invoking create_acl_with_acl_info; keep the
existing update_acl_with_acl_info branch for Ok responses and ensure
non-NotFound errors are preserved in failures rather than swallowed.
- Around line 1202-1210: The loop that calls admin.get_acl currently treats any
Err as a failure; change it to detect "not found" results and record those into
skipped_subjects instead of failures while preserving successful AclInfo values
verbatim. Specifically, inside the loop in auth.rs where
admin.get_acl(request.from_broker().clone(), subject.clone()).await is matched,
map the NotFound/ACL-missing error (or the error variant/message your admin
client uses for a missing ACL) to pushing the subject into skipped_subjects
rather than pushing an AuthOperationFailure into failures; for all Ok(acl_info)
keep pushing the acl_info as-is into acl_infos, and for other error kinds
continue to push AuthOperationFailure. Apply the same change to the analogous
block referenced at lines 1226-1228. Ensure you reference admin.get_acl,
skipped_subjects, failures, AuthOperationFailure, and AclInfo when making the
edits.
- Around line 635-646: The current try_new uses
subjects.map(split_csv_values).filter(|subjects| !subjects.is_empty()) which
turns an explicitly-provided but-empty --subjects into None (meaning "copy
all"); instead, after mapping with split_csv_values in try_new, detect if
Some(vec) and vec.is_empty() and return an error (RocketMQResult::Err)
indicating an invalid/empty subjects list so consumers cannot accidentally
trigger "copy all"; update the try_new function (reference: try_new, the
subjects local variable and split_csv_values) to perform this check and return a
descriptive error rather than converting empty input to None.

In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/tests/auth_core_models.rs`:
- Around line 1-8: The file lacks the repository's standard 2023
copyright/license header; prepend the canonical "Copyright 2023" header block to
the top of this test file (above the current imports such as AuthTarget,
CopyAclRequest, CreateAclRequest, CreateUserRequest, DeleteAclRequest,
ListAclRequest, ListUsersRequest, UpdateAclRequest) so the file matches the
project's required header convention.
- Around line 110-125: The test shows build_acl_info() produces a single ACL
entry with entry.resource containing comma-separated resources, but the admin
consumer in DefaultMQAdminExtImpl reads entry.resource as a single resource; fix
by either changing request.build_acl_info() to emit one ACL entry per individual
resource (split the input resource list into multiple entries) or update the
DefaultMQAdminExtImpl code that consumes entry.resource to split on commas and
iterate/create one outgoing ACL request per split resource before forwarding;
reference the request.build_acl_info() producer and the DefaultMQAdminExtImpl
consumer that currently uses entry.resource.

---

Outside diff comments:
In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/auth.rs`:
- Line 1: The file header in rocketmq-admin-core's auth.rs uses "Copyright 2026"
which violates the repository standard; update the top-of-file copyright line in
auth.rs to read "Copyright 2023" (preserving the rest of the header text and
formatting) so it matches the repo-wide convention used across Rust source files
in this crate.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: aa4e5c95-fd24-4ebf-8d4f-e4bea58b60d1

📥 Commits

Reviewing files that changed from the base of the PR and between 588a5c7 and a80358c.

📒 Files selected for processing (12)
  • rocketmq-client/src/admin/default_mq_admin_ext_impl.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/auth/copy_acl_sub_command.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/auth/create_acl_sub_command.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/auth/delete_acl_sub_command.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/auth/get_acl_sub_command.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/auth/list_acl_sub_command.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/auth/update_acl_sub_command.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/target.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/admin/default_mq_admin_ext.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/auth.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-core/tests/auth_core_models.rs
💤 Files with no reviewable changes (2)
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands.rs
  • rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/target.rs

Comment on lines +56 to 60
fn render_get_acl_result(result: GetAclResult, subject: &str, single_broker_target: bool) -> RocketMQResult<()> {
if single_broker_target && result.acl_infos.is_empty() {
eprintln!("No ACL with subject {} was found", subject);
return Ok(());
}
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.

⚠️ Potential issue | 🟠 Major

Don’t treat single-broker failures as “not found.”

This early return fires before failed_broker_addrs is checked. If the only broker times out or rejects the request, the command exits successfully and prints “No ACL…”, which masks a real failure. Only return the not-found case here when failed_broker_addrs is also empty.

Suggested fix
 fn render_get_acl_result(result: GetAclResult, subject: &str, single_broker_target: bool) -> RocketMQResult<()> {
-    if single_broker_target && result.acl_infos.is_empty() {
+    if single_broker_target
+        && result.acl_infos.is_empty()
+        && result.failed_broker_addrs.is_empty()
+    {
         eprintln!("No ACL with subject {} was found", subject);
         return Ok(());
     }
📝 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
fn render_get_acl_result(result: GetAclResult, subject: &str, single_broker_target: bool) -> RocketMQResult<()> {
if single_broker_target && result.acl_infos.is_empty() {
eprintln!("No ACL with subject {} was found", subject);
return Ok(());
}
fn render_get_acl_result(result: GetAclResult, subject: &str, single_broker_target: bool) -> RocketMQResult<()> {
if single_broker_target
&& result.acl_infos.is_empty()
&& result.failed_broker_addrs.is_empty()
{
eprintln!("No ACL with subject {} was found", subject);
return Ok(());
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@rocketmq-tools/rocketmq-admin/rocketmq-admin-cli/src/commands/auth/get_acl_sub_command.rs`
around lines 56 - 60, In render_get_acl_result, don't treat single-broker
failures as "not found": change the early-return condition to require
result.failed_broker_addrs.is_empty() as well (i.e., only return Ok(()) and
print "No ACL..." when single_broker_target && result.acl_infos.is_empty() &&
result.failed_broker_addrs.is_empty()); if failed_broker_addrs is non-empty, do
not return early—report the broker failure(s) (include
result.failed_broker_addrs in the output or error path) so real
timeouts/rejections from the single broker are surfaced instead of being masked.

Comment on lines +635 to +646
pub fn try_new(
from_broker: impl Into<String>,
to_broker: impl Into<String>,
subjects: Option<String>,
) -> RocketMQResult<Self> {
let subjects = subjects.map(split_csv_values).filter(|subjects| !subjects.is_empty());

Ok(Self {
from_broker: trim_required_cheetah("fromBroker", from_broker)?,
to_broker: trim_required_cheetah("toBroker", to_broker)?,
subjects,
namesrv_addr: None,
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.

⚠️ Potential issue | 🟠 Major

Reject an empty --subjects list instead of copying everything.

If the flag is present but parses to zero subjects (--subjects "", " , "), this currently becomes None, which flips the request into “copy all ACLs”. That is a dangerous behavior change for a typoed targeted copy.

Suggested fix
     pub fn try_new(
         from_broker: impl Into<String>,
         to_broker: impl Into<String>,
         subjects: Option<String>,
     ) -> RocketMQResult<Self> {
-        let subjects = subjects.map(split_csv_values).filter(|subjects| !subjects.is_empty());
+        let subjects = match subjects {
+            Some(subjects) => {
+                let parsed = split_csv_values(subjects);
+                if parsed.is_empty() {
+                    return Err(
+                        ToolsError::validation_error(
+                            "subjects",
+                            "subjects must contain at least one non-empty subject",
+                        )
+                        .into(),
+                    );
+                }
+                Some(parsed)
+            }
+            None => None,
+        };
 
         Ok(Self {
             from_broker: trim_required_cheetah("fromBroker", from_broker)?,
             to_broker: trim_required_cheetah("toBroker", to_broker)?,
             subjects,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/auth.rs` around
lines 635 - 646, The current try_new uses
subjects.map(split_csv_values).filter(|subjects| !subjects.is_empty()) which
turns an explicitly-provided but-empty --subjects into None (meaning "copy
all"); instead, after mapping with split_csv_values in try_new, detect if
Some(vec) and vec.is_empty() and return an error (RocketMQResult::Err)
indicating an invalid/empty subjects list so consumers cannot accidentally
trigger "copy all"; update the try_new function (reference: try_new, the
subjects local variable and split_csv_values) to perform this check and return a
descriptive error rather than converting empty input to None.

Comment on lines +1202 to +1210
let acl_infos = if let Some(subjects) = request.subjects() {
let mut acl_infos = Vec::new();
for subject in subjects {
match admin.get_acl(request.from_broker().clone(), subject.clone()).await {
Ok(acl_info) => acl_infos.push(acl_info),
Err(error) => failures.push(AuthOperationFailure {
broker_addr: request.from_broker().clone(),
error: format!("get ACL {subject}: {error}"),
}),
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.

⚠️ Potential issue | 🟠 Major

Missing source ACLs are being reported as failures, not skips.

skipped_subjects is only populated when the returned AclInfo has no subject, so a requested subject that does not exist on from_broker never reaches the skip path. That changes the command behavior and bypasses the "Could not find ACL ..." rendering that this result type already supports.

When you fix this, keep copying the fetched AclInfo as-is so source ACL fields are preserved verbatim. Based on learnings, In the copyAcls command implementation (rocketmq-client/src/admin/default_mq_admin_ext_impl.rs), when copying ACL entries, empty decision values from the source should be preserved as-is in the destination.

Also applies to: 1226-1228

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/auth.rs` around
lines 1202 - 1210, The loop that calls admin.get_acl currently treats any Err as
a failure; change it to detect "not found" results and record those into
skipped_subjects instead of failures while preserving successful AclInfo values
verbatim. Specifically, inside the loop in auth.rs where
admin.get_acl(request.from_broker().clone(), subject.clone()).await is matched,
map the NotFound/ACL-missing error (or the error variant/message your admin
client uses for a missing ACL) to pushing the subject into skipped_subjects
rather than pushing an AuthOperationFailure into failures; for all Ok(acl_info)
keep pushing the acl_info as-is into acl_infos, and for other error kinds
continue to push AuthOperationFailure. Apply the same change to the analogous
block referenced at lines 1226-1228. Ensure you reference admin.get_acl,
skipped_subjects, failures, AuthOperationFailure, and AclInfo when making the
edits.

Comment on lines +1231 to +1241
let copy_result = match admin.get_acl(request.to_broker().clone(), subject.clone()).await {
Ok(_) => {
admin
.update_acl_with_acl_info(request.to_broker().clone(), acl_info.clone())
.await
}
Err(_) => {
admin
.create_acl_with_acl_info(request.to_broker().clone(), acl_info.clone())
.await
}
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.

⚠️ Potential issue | 🟠 Major

Do not treat every destination get_acl error as “ACL absent”.

The Err(_) => create branch also swallows transport/auth/RPC failures from the existence check. In those cases we should surface a failure, not attempt a create against a broker we just failed to query.

Only fall back to create_acl_with_acl_info for a definite not-found error; keep other errors in failures.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/src/core/auth.rs` around
lines 1231 - 1241, The current match on
admin.get_acl(request.to_broker().clone(), subject.clone()).await treats any Err
as “ACL absent” and always calls create_acl_with_acl_info; instead inspect the
returned error from admin.get_acl and only call admin.create_acl_with_acl_info
when the error indicates a definite NotFound/missing-ACL condition, while for
transport/auth/RPC or other errors return/propagate the error into failures (do
not attempt create). Adjust the match/if handling around
admin.get_acl(...).await, using the error variant or status check to distinguish
NotFound from other errors before invoking create_acl_with_acl_info; keep the
existing update_acl_with_acl_info branch for Ok responses and ensure
non-NotFound errors are preserved in failures rather than swallowed.

Comment on lines 1 to +8
use rocketmq_admin_core::core::auth::AuthTarget;
use rocketmq_admin_core::core::auth::CopyAclRequest;
use rocketmq_admin_core::core::auth::CreateAclRequest;
use rocketmq_admin_core::core::auth::CreateUserRequest;
use rocketmq_admin_core::core::auth::DeleteAclRequest;
use rocketmq_admin_core::core::auth::ListAclRequest;
use rocketmq_admin_core::core::auth::ListUsersRequest;
use rocketmq_admin_core::core::auth::UpdateAclRequest;
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.

⚠️ Potential issue | 🟡 Minor

Add the standard 2023 file header.

This test file now starts without the repository’s standard copyright/license header.

Based on learnings, Rust source files in this repository are expected to include the standard Copyright 2023 header.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/tests/auth_core_models.rs`
around lines 1 - 8, The file lacks the repository's standard 2023
copyright/license header; prepend the canonical "Copyright 2023" header block to
the top of this test file (above the current imports such as AuthTarget,
CopyAclRequest, CreateAclRequest, CreateUserRequest, DeleteAclRequest,
ListAclRequest, ListUsersRequest, UpdateAclRequest) so the file matches the
project's required header convention.

Comment on lines +110 to +125
let acl_info = request.build_acl_info();
assert_eq!(
acl_info.subject.as_ref().map(|subject| subject.as_str()),
Some("user:alice")
);
let entries = acl_info
.policies
.as_ref()
.and_then(|policies| policies.first())
.and_then(|policy| policy.entries.as_ref())
.unwrap();
let entry = entries.first().unwrap();
assert_eq!(
entry.resource.as_ref().map(|resource| resource.as_str()),
Some("Topic:order-topic,Topic:user-topic")
);
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.

⚠️ Potential issue | 🟠 Major

This ACL shape collapses multiple resources into one broker request.

The new expectation here is entry.resource == "Topic:order-topic,Topic:user-topic", but the consumer in rocketmq-client/src/admin/default_mq_admin_ext_impl.rs treats entry.resource as a single resource at Line 218 and Line 262 and never splits commas. That means create/update will send one malformed resource instead of two whenever the CLI passes multiple resources.

Please either emit one ACL entry per resource from the request model or split entry.resource in the admin impl before forwarding it.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@rocketmq-tools/rocketmq-admin/rocketmq-admin-core/tests/auth_core_models.rs`
around lines 110 - 125, The test shows build_acl_info() produces a single ACL
entry with entry.resource containing comma-separated resources, but the admin
consumer in DefaultMQAdminExtImpl reads entry.resource as a single resource; fix
by either changing request.build_acl_info() to emit one ACL entry per individual
resource (split the input resource list into multiple entries) or update the
DefaultMQAdminExtImpl code that consumes entry.resource to split on commas and
iterate/create one outgoing ACL request per split resource before forwarding;
reference the request.build_acl_info() producer and the DefaultMQAdminExtImpl
consumer that currently uses entry.resource.

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 12, 2026

Codecov Report

❌ Patch coverage is 31.29032% with 426 lines in your changes missing coverage. Please review.
✅ Project coverage is 59.40%. Comparing base (588a5c7) to head (a80358c).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ocketmq-admin/rocketmq-admin-core/src/core/auth.rs 36.15% 309 Missing ⚠️
...dmin-cli/src/commands/auth/copy_acl_sub_command.rs 0.00% 31 Missing ⚠️
...admin-cli/src/commands/auth/get_acl_sub_command.rs 0.00% 29 Missing ⚠️
...dmin-cli/src/commands/auth/list_acl_sub_command.rs 0.00% 16 Missing ⚠️
...in-cli/src/commands/auth/create_acl_sub_command.rs 0.00% 13 Missing ⚠️
...in-cli/src/commands/auth/update_acl_sub_command.rs 0.00% 12 Missing ⚠️
...in-cli/src/commands/auth/delete_acl_sub_command.rs 0.00% 10 Missing ⚠️
...etmq-client/src/admin/default_mq_admin_ext_impl.rs 45.45% 6 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7123      +/-   ##
==========================================
+ Coverage   59.29%   59.40%   +0.11%     
==========================================
  Files        1074     1073       -1     
  Lines      186916   186876      -40     
==========================================
+ Hits       110829   111012     +183     
+ Misses      76087    75864     -223     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Collaborator

@rocketmq-rust-bot rocketmq-rust-bot left a comment

Choose a reason for hiding this comment

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

LGTM - All CI checks passed ✅

@rocketmq-rust-bot rocketmq-rust-bot merged commit 7423a6b into main Apr 12, 2026
19 of 20 checks passed
@rocketmq-rust-bot rocketmq-rust-bot added approved PR has approved and removed ready to review waiting-review waiting review this PR labels Apr 12, 2026
@mxsm mxsm deleted the feat-7122 branch April 20, 2026 02:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

AI review first Ai review pr first approved PR has approved auto merge feature🚀 Suggest an idea for this project.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature🚀] feat(cli): refactor ACL command implementations to use new request structures and improve error handling

3 participants