rustfs icon indicating copy to clipboard operation
rustfs copied to clipboard

fix: correct ARN parsing for notification targets

Open tennisleng opened this issue 3 weeks ago • 3 comments

Summary

This PR fixes an issue where bucket event notifications fail with a duplicated ARN prefix error.

Fixes #1007

Problem

When using minio mc to set bucket event notifications, the ARN validation fails with:

ARN not found:arn:rustfs:sqs:eu-central:arn:rustfs:sqs:eu-central:primary:webhook

Root Cause

In ecfs.rs and main.rs, TargetID::from_str was used to parse full ARN strings like arn:rustfs:sqs:eu-central:primary:webhook. However, TargetID::from_str expects the format ID:Name (e.g., primary:webhook).

This caused the TargetID to be incorrectly constructed with:

  • id = "arn"
  • name = "rustfs:sqs:eu-central:primary:webhook"

When the config was validated, calling target_id.to_arn() produced a duplicated ARN prefix.

Fix

Changed the parser to use ARN::parse() to properly parse the full ARN string and extract the correct TargetID with:

  • id = "primary"
  • name = "webhook"

Changes

  • rustfs/src/storage/ecfs.rs: Updated ARN parsing in put_bucket_notification_configuration
  • rustfs/src/main.rs: Updated ARN parsing in add_bucket_notification_configuration

tennisleng avatar Dec 05 '25 20:12 tennisleng

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Dec 05 '25 20:12 CLAassistant

Hey @tennisleng ,

Thank you for your contribution! CLA signing has been added to the merge, without it, automated CI testing cannot be initiated.

loverustfs avatar Dec 06 '25 01:12 loverustfs

Hey @tennisleng ,

Thank you for your contribution, but CI failed. https://github.com/rustfs/rustfs/actions/runs/19985181187/job/57319734273?pr=1010

Run cargo fmt --all --check
Diff in /home/runner/work/rustfs/rustfs/rustfs/src/main.rs:516:
                     "Bucket '{}' has existing notification configuration: {:?}", bucket, cfg);
 
                 let mut event_rules = Vec::new();
-                process_queue_configurations(&mut event_rules, cfg.queue_configurations.clone(), |arn_str| ARN::parse(arn_str).map(|arn| arn.target_id).map_err(|e| TargetIDError::InvalidFormat(e.to_string())));
-                process_topic_configurations(&mut event_rules, cfg.topic_configurations.clone(), |arn_str| ARN::parse(arn_str).map(|arn| arn.target_id).map_err(|e| TargetIDError::InvalidFormat(e.to_string())));
-                process_lambda_configurations(&mut event_rules, cfg.lambda_function_configurations.clone(), |arn_str| ARN::parse(arn_str).map(|arn| arn.target_id).map_err(|e| TargetIDError::InvalidFormat(e.to_string())));
+                process_queue_configurations(&mut event_rules, cfg.queue_configurations.clone(), |arn_str| {
+                    ARN::parse(arn_str)
+                        .map(|arn| arn.target_id)
+                        .map_err(|e| TargetIDError::InvalidFormat(e.to_string()))
+                });
+                process_topic_configurations(&mut event_rules, cfg.topic_configurations.clone(), |arn_str| {
+                    ARN::parse(arn_str)
+                        .map(|arn| arn.target_id)
+                        .map_err(|e| TargetIDError::InvalidFormat(e.to_string()))
+                });
+                process_lambda_configurations(&mut event_rules, cfg.lambda_function_configurations.clone(), |arn_str| {
+                    ARN::parse(arn_str)
+                        .map(|arn| arn.target_id)
+                        .map_err(|e| TargetIDError::InvalidFormat(e.to_string()))
+                });
 
                 if let Err(e) = notifier_global::add_event_specific_rules(bucket, region, &event_rules)
                     .await
Diff in /home/runner/work/rustfs/rustfs/rustfs/src/storage/ecfs.rs:4890:
         let parse_rules = async {
             let mut event_rules = Vec::new();
 
-            process_queue_configurations(
-                &mut event_rules,
-                notification_configuration.queue_configurations.clone(),
-                |arn_str| ARN::parse(arn_str).map(|arn| arn.target_id).map_err(|e| TargetIDError::InvalidFormat(e.to_string())),
-            );
-            process_topic_configurations(
-                &mut event_rules,
-                notification_configuration.topic_configurations.clone(),
-                |arn_str| ARN::parse(arn_str).map(|arn| arn.target_id).map_err(|e| TargetIDError::InvalidFormat(e.to_string())),
-            );
+            process_queue_configurations(&mut event_rules, notification_configuration.queue_configurations.clone(), |arn_str| {
+                ARN::parse(arn_str)
+                    .map(|arn| arn.target_id)
+                    .map_err(|e| TargetIDError::InvalidFormat(e.to_string()))
+            });
+            process_topic_configurations(&mut event_rules, notification_configuration.topic_configurations.clone(), |arn_str| {
+                ARN::parse(arn_str)
+                    .map(|arn| arn.target_id)
+                    .map_err(|e| TargetIDError::InvalidFormat(e.to_string()))
+            });
             process_lambda_configurations(
                 &mut event_rules,
                 notification_configuration.lambda_function_configurations.clone(),
Diff in /home/runner/work/rustfs/rustfs/rustfs/src/storage/ecfs.rs:4906:
-                |arn_str| ARN::parse(arn_str).map(|arn| arn.target_id).map_err(|e| TargetIDError::InvalidFormat(e.to_string())),
+                |arn_str| {
+                    ARN::parse(arn_str)
+                        .map(|arn| arn.target_id)
+                        .map_err(|e| TargetIDError::InvalidFormat(e.to_string()))
+                },
             );
 
             event_rules
Error: Process completed with exit code 1.

loverustfs avatar Dec 06 '25 08:12 loverustfs

Hey @tennisleng ,

Thank you so much for your contribution! We have merged the code.

Thank you!

loverustfs avatar Dec 07 '25 03:12 loverustfs