fix: correct ARN parsing for notification targets
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 input_bucket_notification_configurationrustfs/src/main.rs: Updated ARN parsing inadd_bucket_notification_configuration
Hey @tennisleng ,
Thank you for your contribution! CLA signing has been added to the merge, without it, automated CI testing cannot be initiated.
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.
Hey @tennisleng ,
Thank you so much for your contribution! We have merged the code.
Thank you!