@@ -88,6 +88,7 @@ def __init__(
8888 ] = []
8989 self .topic_configurations : list [tuple [dict [str , str ], Topic | None , str ]] = []
9090 self .queue_configurations : list [tuple [dict [str , str ], Queue | None , str ]] = []
91+ self .notification_resources : list [AWSObject ] = []
9192 self .depends_on : list [str ] = []
9293 self .bucket_kwargs = bucket_kwargs
9394
@@ -134,12 +135,38 @@ def add_notification_configuration(
134135 if isinstance (target , Topic ):
135136 params ["Topic" ] = target .arn
136137 self .topic_configurations .append ((params , target , permission_suffix ))
138+
139+ # Add policy allowing to publish to topic
140+ topic_policy_name = target .add_allow_service_to_publish_statement (
141+ applicant = f"{ name_to_id (self .name )} " ,
142+ service = "s3" ,
143+ condition = {"ArnLike" : {"aws:SourceArn" : self .arn }},
144+ )
145+ self .depends_on .append (topic_policy_name )
137146 elif isinstance (target , Function ):
138147 params ["Function" ] = target .arn
139148 self .lambda_configurations .append ((params , target , permission_suffix ))
149+
150+ # Add Permission invoke for lambda
151+ self .notification_resources .append (
152+ target .invoke_permission (
153+ name_suffix = permission_suffix ,
154+ service = "s3" ,
155+ source_arn = self .arn ,
156+ source_account = AccountId ,
157+ )
158+ )
140159 elif isinstance (target , Queue ):
141160 params ["Queue" ] = target .arn
142161 self .queue_configurations .append ((params , target , permission_suffix ))
162+
163+ # Add policy allowing to publish to queue
164+ queue_policy_name = target .add_allow_service_to_write_statement (
165+ applicant = f"{ name_to_id (self .name )} " ,
166+ service = "s3" ,
167+ condition = {"ArnLike" : {"aws:SourceArn" : self .arn }},
168+ )
169+ self .depends_on .append (queue_policy_name )
143170 elif ":sns:" in target :
144171 params ["Topic" ] = target
145172 self .topic_configurations .append ((params , None , permission_suffix ))
@@ -150,81 +177,9 @@ def add_notification_configuration(
150177 params ["Queue" ] = target
151178 self .queue_configurations .append ((params , None , permission_suffix ))
152179
153- @property
154- def notification_setup (
155- self ,
156- ) -> tuple [s3 .NotificationConfiguration , list [AWSObject ]]:
157- """Return notification configuration and associated resources."""
158- notification_resources = []
159- notification_config = None
160- params = {}
161- if self .lambda_configurations :
162- params .update (
163- {
164- "LambdaConfigurations" : [
165- s3 .LambdaConfigurations (** lambda_params )
166- for lambda_params , _ , _ in self .lambda_configurations
167- ]
168- }
169- )
170- # Add Permission invoke for lambdas
171- for _ , function , suffix in self .lambda_configurations :
172- if function :
173- notification_resources .append (
174- function .invoke_permission (
175- name_suffix = suffix ,
176- service = "s3" ,
177- source_arn = self .arn ,
178- source_account = AccountId ,
179- )
180- )
181- if self .topic_configurations :
182- params .update (
183- {
184- "TopicConfigurations" : [
185- s3 .TopicConfigurations (** topic_params )
186- for topic_params , _ , _ in self .topic_configurations
187- ]
188- }
189- )
190- # Add policy allowing to publish to topics
191- for _ , topic , _ in self .topic_configurations :
192- if topic :
193- topic_policy_name = topic .add_allow_service_to_publish_statement (
194- applicant = f"{ name_to_id (self .name )} " ,
195- service = "s3" ,
196- condition = {"ArnLike" : {"aws:SourceArn" : self .arn }},
197- )
198- self .depends_on .append (topic_policy_name )
199- if self .queue_configurations :
200- params .update (
201- {
202- "QueueConfigurations" : [
203- s3 .QueueConfigurations (** queue_params )
204- for queue_params , _ , _ in self .queue_configurations
205- ]
206- }
207- )
208- for _ , queue , _ in self .queue_configurations :
209- if queue :
210- queue_policy_name = queue .add_allow_service_to_write_statement (
211- applicant = f"{ name_to_id (self .name )} " ,
212- service = "s3" ,
213- condition = {"ArnLike" : {"aws:SourceArn" : self .arn }},
214- )
215- self .depends_on .append (queue_policy_name )
216-
217- if params :
218- notification_config = s3 .NotificationConfiguration (
219- name_to_id (self .name + "NotifConfig" ), ** params
220- )
221-
222- return notification_config , notification_resources
223-
224180 def resources (self , stack : Stack ) -> list [AWSObject ]:
225181 """Construct and return a s3.Bucket and its associated s3.BucketPolicy."""
226182 # Handle versioning configuration
227- optional_resources = []
228183 versioning_status = "Suspended"
229184 if self .enable_versioning :
230185 versioning_status = "Enabled"
@@ -256,8 +211,35 @@ def resources(self, stack: Stack) -> list[AWSObject]:
256211 name_to_id (self .name ) + "LifeCycleConfig" , Rules = self .lifecycle_rules
257212 )
258213
259- notification_config , notification_resources = self .notification_setup
260- optional_resources .extend (notification_resources )
214+ # Build the parameters of NotificationConfiguration, keeping only the
215+ # parameters with non empty lists
216+ notification_params : dict [str , Any ] = {
217+ k : v
218+ for k , v in [
219+ (
220+ "LambdaConfigurations" ,
221+ [
222+ s3 .LambdaConfigurations (** params )
223+ for params , _ , _ in self .lambda_configurations
224+ ],
225+ ),
226+ (
227+ "TopicConfigurations" ,
228+ [
229+ s3 .TopicConfigurations (** params )
230+ for params , _ , _ in self .topic_configurations
231+ ],
232+ ),
233+ (
234+ "QueueConfigurations" ,
235+ [
236+ s3 .QueueConfigurations (** params )
237+ for params , _ , _ in self .queue_configurations
238+ ],
239+ ),
240+ ]
241+ if v
242+ }
261243
262244 attr = {"DeletionPolicy" : "Retain" }
263245 for key , val in {
@@ -268,7 +250,13 @@ def resources(self, stack: Stack) -> list[AWSObject]:
268250 Status = versioning_status
269251 ),
270252 "LifecycleConfiguration" : lifecycle_config ,
271- "NotificationConfiguration" : notification_config ,
253+ "NotificationConfiguration" : (
254+ s3 .NotificationConfiguration (
255+ name_to_id (self .name + "NotifConfig" ), ** notification_params
256+ )
257+ if notification_params
258+ else None
259+ ),
272260 "DependsOn" : self .depends_on ,
273261 }.items ():
274262 if val :
@@ -282,7 +270,7 @@ def resources(self, stack: Stack) -> list[AWSObject]:
282270 Bucket = self .ref ,
283271 PolicyDocument = self .policy_document .as_dict ,
284272 ),
285- * optional_resources ,
273+ * self . notification_resources ,
286274 ]
287275
288276 @property
0 commit comments