@@ -110,20 +110,8 @@ func MakeCreateHandler(cfg *types.Config, back types.ServerlessBackend) gin.Hand
110
110
111
111
if len (service .AllowedUsers ) > 0 {
112
112
// If AllowedUsers is empty don't add uid
113
- service .Labels ["uid" ] = full_uid [0 :8 ]
114
-
115
- // If the uid of the owner is not on the allowed_users list append it
116
- ownerOnList := false
117
- for _ , user := range service .AllowedUsers {
118
- if user == service .Owner {
119
- ownerOnList = true
120
- break
121
- }
122
- }
123
- if ! ownerOnList {
124
- service .AllowedUsers = append (service .AllowedUsers , uid )
125
- }
126
- // Check if the uid's from allowed_users have and associated MinIO user
113
+ service .Labels ["uid" ] = full_uid [:10 ]
114
+ // Check if the uid's from allowed_users have and asociated MinIO user
127
115
// and create it if not
128
116
uids := mc .CheckUsersInCache (service .AllowedUsers )
129
117
if len (uids ) > 0 {
@@ -133,6 +121,39 @@ func MakeCreateHandler(cfg *types.Config, back types.ServerlessBackend) gin.Hand
133
121
mc .CreateSecretForOIDC (uid , sk )
134
122
}
135
123
}
124
+
125
+ path := strings .Trim (service .Input [0 ].Path , "/" )
126
+ splitPath := strings .SplitN (path , "/" , 2 )
127
+
128
+ ownerOnList := false
129
+ // Create service bucket list if isolation_level = user
130
+ if strings .ToUpper (service .IsolationLevel ) == "USER" {
131
+ var userBucket string
132
+ for _ , user := range service .AllowedUsers {
133
+
134
+ // Check the uid of the owner is on the allowed_users list
135
+ if user == service .Owner {
136
+ ownerOnList = true
137
+ }
138
+ // Fill the list of private buckets to create
139
+ userBucket = splitPath [0 ] + "-" + user [:10 ]
140
+ service .BucketList = append (service .BucketList , userBucket )
141
+ }
142
+ } else {
143
+ index := 0
144
+ for ! ownerOnList {
145
+ // Check the uid of the owner is on the allowed_users list
146
+ // If isolation level is not user the list may not need to be go through fully
147
+ if service .AllowedUsers [index ] == service .Owner {
148
+ ownerOnList = true
149
+ }
150
+ index ++
151
+ }
152
+ }
153
+ if ! ownerOnList {
154
+ service .AllowedUsers = append (service .AllowedUsers , uid )
155
+ }
156
+
136
157
}
137
158
}
138
159
@@ -155,7 +176,7 @@ func MakeCreateHandler(cfg *types.Config, back types.ServerlessBackend) gin.Hand
155
176
}
156
177
157
178
// Create buckets/folders based on the Input and Output and enable notifications
158
- if err := createBuckets (& service , cfg , minIOAdminClient , service . AllowedUsers , false ); err != nil {
179
+ if err := createBuckets (& service , cfg , minIOAdminClient , false ); err != nil {
159
180
if err == errInput {
160
181
c .String (http .StatusBadRequest , err .Error ())
161
182
} else {
@@ -232,12 +253,16 @@ func checkValues(service *types.Service, cfg *types.Config) {
232
253
service .Token = utils .GenerateToken ()
233
254
}
234
255
235
- func createBuckets (service * types.Service , cfg * types.Config , minIOAdminClient * utils.MinIOAdminClient , allowed_users [] string , isUpdate bool ) error {
256
+ func createBuckets (service * types.Service , cfg * types.Config , minIOAdminClient * utils.MinIOAdminClient , isUpdate bool ) error {
236
257
var s3Client * s3.S3
237
258
var cdmiClient * cdmi.Client
238
259
var provName , provID string
239
260
261
+ // Create private buckets
262
+
263
+ // Create shared buckets (if defined)
240
264
// Create input buckets
265
+ createLogger .Printf ("Creating input buckets .." )
241
266
for _ , in := range service .Input {
242
267
provID , provName = getProviderInfo (in .Provider )
243
268
@@ -269,10 +294,11 @@ func createBuckets(service *types.Service, cfg *types.Config, minIOAdminClient *
269
294
path := strings .Trim (in .Path , " /" )
270
295
// Split buckets and folders from path
271
296
splitPath := strings .SplitN (path , "/" , 2 )
272
- // Create bucket
297
+
273
298
_ , err := s3Client .CreateBucket (& s3.CreateBucketInput {
274
299
Bucket : aws .String (splitPath [0 ]),
275
300
})
301
+
276
302
if err != nil {
277
303
if aerr , ok := err .(awserr.Error ); ok {
278
304
// Check if the error is caused because the bucket already exists
@@ -286,13 +312,66 @@ func createBuckets(service *types.Service, cfg *types.Config, minIOAdminClient *
286
312
}
287
313
}
288
314
315
+ // Create generic folder(s)
316
+ var folderKey string
317
+ if len (splitPath ) == 2 {
318
+ // Add "/" to the end of the key in order to create a folder
319
+ folderKey = fmt .Sprintf ("%s/" , splitPath [1 ])
320
+ _ , err := s3Client .PutObject (& s3.PutObjectInput {
321
+ Bucket : aws .String (splitPath [0 ]),
322
+ Key : aws .String (folderKey ),
323
+ })
324
+ if err != nil {
325
+ return fmt .Errorf ("error creating folder \" %s\" in bucket \" %s\" : %v" , folderKey , splitPath [0 ], err )
326
+ }
327
+ // Enable MinIO notifications based on the Input []StorageIOConfig
328
+ if err := enableInputNotification (s3Client , service .GetMinIOWebhookARN (), splitPath [0 ], folderKey ); err != nil {
329
+ return err
330
+ }
331
+ }
332
+
333
+ if strings .ToUpper (service .IsolationLevel ) == "USER" && len (service .BucketList ) > 0 {
334
+ for i , b := range service .BucketList {
335
+ // Create a bucket for each allowed user if allowed_users is not empty
336
+ _ , err = s3Client .CreateBucket (& s3.CreateBucketInput {
337
+ Bucket : aws .String (b ),
338
+ })
339
+ if err != nil {
340
+ if aerr , ok := err .(awserr.Error ); ok {
341
+ // Check if the error is caused because the bucket already exists
342
+ if aerr .Code () == s3 .ErrCodeBucketAlreadyExists || aerr .Code () == s3 .ErrCodeBucketAlreadyOwnedByYou {
343
+ log .Printf ("The bucket \" %s\" already exists\n " , b )
344
+ } else {
345
+ return fmt .Errorf ("error creating bucket %s: %v" , b , err )
346
+ }
347
+ } else {
348
+ return fmt .Errorf ("error creating bucket %s: %v" , b , err )
349
+ }
350
+ }
351
+ _ , err := s3Client .PutObject (& s3.PutObjectInput {
352
+ Bucket : aws .String (b ),
353
+ Key : aws .String (folderKey ),
354
+ })
355
+ if err != nil {
356
+ return fmt .Errorf ("error creating folder \" %s\" in bucket \" %s\" : %v" , folderKey , b , err )
357
+ }
358
+ if err := enableInputNotification (s3Client , service .GetMinIOWebhookARN (), b , folderKey ); err != nil {
359
+ return err
360
+ }
361
+
362
+ if ! isAdminUser {
363
+ minIOAdminClient .CreateAddPolicy (b , service .AllowedUsers [i ], false )
364
+ }
365
+ }
366
+ }
367
+
289
368
// Create group for the service and add users
290
369
// Check if users in allowed_users have a MinIO associated user
291
- // If new allowed users list is empty the service becomes public
370
+ // If new allowed users list is empty the service becames public
292
371
if ! isUpdate {
293
372
if ! isAdminUser {
294
- if len (allowed_users ) == 0 {
295
- err = minIOAdminClient .AddServiceToAllUsersGroup (splitPath [0 ])
373
+ if len (service . AllowedUsers ) == 0 {
374
+ err = minIOAdminClient .CreateAddPolicy (splitPath [0 ], ALL_USERS_GROUP , true )
296
375
if err != nil {
297
376
return fmt .Errorf ("error adding service %s to all users group: %v" , splitPath [0 ], err )
298
377
}
@@ -302,38 +381,26 @@ func createBuckets(service *types.Service, cfg *types.Config, minIOAdminClient *
302
381
return fmt .Errorf ("error creating service group for bucket %s: %v" , splitPath [0 ], err )
303
382
}
304
383
305
- err = minIOAdminClient .UpdateUsersInGroup (allowed_users , splitPath [0 ], false )
384
+ err = minIOAdminClient .UpdateUsersInGroup (service .AllowedUsers , splitPath [0 ], false )
385
+ if err != nil {
386
+ return err
387
+ }
388
+ err = minIOAdminClient .CreateAddPolicy (splitPath [0 ], splitPath [0 ], true )
306
389
if err != nil {
307
390
return err
308
391
}
309
392
}
310
393
}
311
394
}
312
- // Create folder(s)
313
- if len (splitPath ) == 2 {
314
- // Add "/" to the end of the key in order to create a folder
315
- folderKey := fmt .Sprintf ("%s/" , splitPath [1 ])
316
- _ , err := s3Client .PutObject (& s3.PutObjectInput {
317
- Bucket : aws .String (splitPath [0 ]),
318
- Key : aws .String (folderKey ),
319
- })
320
- if err != nil {
321
- return fmt .Errorf ("error creating folder \" %s\" in bucket \" %s\" : %v" , folderKey , splitPath [0 ], err )
322
- }
323
- }
324
-
325
- // Enable MinIO notifications based on the Input []StorageIOConfig
326
- if err := enableInputNotification (s3Client , service .GetMinIOWebhookARN (), in ); err != nil {
327
- return err
328
- }
329
395
}
330
-
396
+ createLogger . Printf ( "Creating output buckets .." )
331
397
// Create output buckets
332
398
for _ , out := range service .Output {
333
399
provID , provName = getProviderInfo (out .Provider )
334
400
// Check if the provider identifier is defined in StorageProviders
335
401
if ! isStorageProviderDefined (provName , provID , service .StorageProviders ) {
336
- disableInputNotifications (service .GetMinIOWebhookARN (), service .Input , cfg .MinIOProvider )
402
+ // TODO fix
403
+ disableInputNotifications (s3Client , service .GetMinIOWebhookARN (), "" )
337
404
return fmt .Errorf ("the StorageProvider \" %s.%s\" is not defined" , provName , provID )
338
405
}
339
406
@@ -350,44 +417,63 @@ func createBuckets(service *types.Service, cfg *types.Config, minIOAdminClient *
350
417
s3Client = service .StorageProviders .S3 [provID ].GetS3Client ()
351
418
}
352
419
// Create bucket
353
- _ , err := s3Client .CreateBucket (& s3.CreateBucketInput {
354
- Bucket : aws .String (splitPath [0 ]),
355
- })
356
- if err != nil {
357
- if aerr , ok := err .(awserr.Error ); ok {
358
- // Check if the error is caused because the bucket already exists
359
- if aerr .Code () == s3 .ErrCodeBucketAlreadyExists || aerr .Code () == s3 .ErrCodeBucketAlreadyOwnedByYou {
360
- log .Printf ("The bucket \" %s\" already exists\n " , splitPath [0 ])
361
- } else {
362
- disableInputNotifications (service .GetMinIOWebhookARN (), service .Input , cfg .MinIOProvider )
363
- return fmt .Errorf ("error creating bucket %s: %v" , splitPath [0 ], err )
364
- }
365
- } else {
366
- disableInputNotifications (service .GetMinIOWebhookARN (), service .Input , cfg .MinIOProvider )
367
- return fmt .Errorf ("error creating bucket %s: %v" , splitPath [0 ], err )
368
- }
369
- }
420
+ // ==== TODO check if is necessary repeat the create bucket code ====
421
+ // _, err := s3Client.CreateBucket(&s3.CreateBucketInput{
422
+ // Bucket: aws.String(splitPath[0]),
423
+ // })
424
+
425
+ // // TODO Add disable notifications in case of an error for every bucket on service.BucketList
426
+ // if err != nil {
427
+ // if aerr, ok := err.(awserr.Error); ok {
428
+ // // Check if the error is caused because the bucket already exists
429
+ // if aerr.Code() == s3.ErrCodeBucketAlreadyExists || aerr.Code() == s3.ErrCodeBucketAlreadyOwnedByYou {
430
+ // log.Printf("The bucket \"%s\" already exists\n", splitPath[0])
431
+ // } else {
432
+ // disableInputNotifications(service.GetMinIOWebhookARN(), service.Input, cfg.MinIOProvider)
433
+ // return fmt.Errorf("error creating bucket %s: %v", splitPath[0], err)
434
+ // }
435
+ // } else {
436
+ // disableInputNotifications(service.GetMinIOWebhookARN(), service.Input, cfg.MinIOProvider)
437
+ // return fmt.Errorf("error creating bucket %s: %v", splitPath[0], err)
438
+ // }
439
+ // }
370
440
// Create folder(s)
441
+ var folderKey string
371
442
if len (splitPath ) == 2 {
372
443
// Add "/" to the end of the key in order to create a folder
373
- folderKey : = fmt .Sprintf ("%s/" , splitPath [1 ])
444
+ folderKey = fmt .Sprintf ("%s/" , splitPath [1 ])
374
445
_ , err := s3Client .PutObject (& s3.PutObjectInput {
375
446
Bucket : aws .String (splitPath [0 ]),
376
447
Key : aws .String (folderKey ),
377
448
})
378
449
if err != nil {
379
- disableInputNotifications (service .GetMinIOWebhookARN (), service . Input , cfg . MinIOProvider )
450
+ disableInputNotifications (s3Client , service .GetMinIOWebhookARN (), splitPath [ 0 ] )
380
451
return fmt .Errorf ("error creating folder \" %s\" in bucket \" %s\" : %v" , folderKey , splitPath [0 ], err )
381
452
}
382
453
}
454
+
455
+ if service .IsolationLevel == "USER" && len (service .BucketList ) > 0 {
456
+ for _ , b := range service .BucketList {
457
+ _ , err := s3Client .PutObject (& s3.PutObjectInput {
458
+ Bucket : aws .String (b ),
459
+ Key : aws .String (folderKey ),
460
+ })
461
+ if err != nil {
462
+ return fmt .Errorf ("error creating folder \" %s\" in bucket \" %s\" : %v" , folderKey , b , err )
463
+ }
464
+
465
+ }
466
+ }
467
+
383
468
case types .OnedataName :
384
469
cdmiClient = service .StorageProviders .Onedata [provID ].GetCDMIClient ()
385
470
err := cdmiClient .CreateContainer (fmt .Sprintf ("%s/%s" , service .StorageProviders .Onedata [provID ].Space , path ), true )
386
471
if err != nil {
387
472
if err == cdmi .ErrBadRequest {
388
473
log .Printf ("Error creating \" %s\" folder in Onedata. Error: %v\n " , path , err )
389
474
} else {
390
- disableInputNotifications (service .GetMinIOWebhookARN (), service .Input , cfg .MinIOProvider )
475
+ // TODO fix
476
+ disableInputNotifications (s3Client , service .GetMinIOWebhookARN (), "" )
391
477
return fmt .Errorf ("error connecting to Onedata's Oneprovider \" %s\" . Error: %v" , service .StorageProviders .Onedata [provID ].OneproviderHost , err )
392
478
}
393
479
}
@@ -431,7 +517,7 @@ func createBuckets(service *types.Service, cfg *types.Config, minIOAdminClient *
431
517
}
432
518
if ! isUpdate {
433
519
if ! isAdminUser {
434
- if len (allowed_users ) == 0 {
520
+ if len (service . AllowedUsers ) == 0 {
435
521
err = minIOAdminClient .AddServiceToAllUsersGroup (splitPath [0 ])
436
522
if err != nil {
437
523
return fmt .Errorf ("error adding service %s to all users group: %v" , splitPath [0 ], err )
@@ -442,7 +528,7 @@ func createBuckets(service *types.Service, cfg *types.Config, minIOAdminClient *
442
528
return fmt .Errorf ("error creating service group for bucket %s: %v" , splitPath [0 ], err )
443
529
}
444
530
445
- err = minIOAdminClient .UpdateUsersInGroup (allowed_users , splitPath [0 ], false )
531
+ err = minIOAdminClient .UpdateUsersInGroup (service . AllowedUsers , splitPath [0 ], false )
446
532
if err != nil {
447
533
return err
448
534
}
@@ -530,32 +616,32 @@ func registerMinIOWebhook(name string, token string, minIO *types.MinIOProvider,
530
616
return minIOAdminClient .RestartServer ()
531
617
}
532
618
533
- func enableInputNotification ( minIOClient * s3. S3 , arnStr string , input types. StorageIOConfig ) error {
534
- path := strings . Trim ( input . Path , " /" )
535
- // Split buckets and folders from path
536
- splitPath := strings . SplitN ( path , "/" , 2 )
537
-
619
+ // TODO pass the user UID string
620
+ func enableInputNotification ( minIOClient * s3. S3 , arnStr string , bucket string , path string ) error {
621
+ // path := strings.Trim(input.Path, " /")
622
+ // // Split buckets and folders from path
623
+ // splitPath := strings.SplitN(path, "/", 2)
538
624
// Get current BucketNotificationConfiguration
539
625
gbncRequest := & s3.GetBucketNotificationConfigurationRequest {
540
- Bucket : aws .String (splitPath [ 0 ] ),
626
+ Bucket : aws .String (bucket ),
541
627
}
542
628
nCfg , err := minIOClient .GetBucketNotificationConfiguration (gbncRequest )
543
629
if err != nil {
544
- return fmt .Errorf ("error getting bucket \" %s\" notifications: %v" , splitPath [ 0 ] , err )
630
+ return fmt .Errorf ("error getting bucket \" %s\" notifications: %v" , bucket , err )
545
631
}
546
632
queueConfiguration := s3.QueueConfiguration {
547
633
QueueArn : aws .String (arnStr ),
548
634
Events : []* string {aws .String (s3 .EventS3ObjectCreated )},
549
635
}
550
636
551
637
// Add folder filter if required
552
- if len ( splitPath ) == 2 {
638
+ if path != "" {
553
639
queueConfiguration .Filter = & s3.NotificationConfigurationFilter {
554
640
Key : & s3.KeyFilter {
555
641
FilterRules : []* s3.FilterRule {
556
642
{
557
643
Name : aws .String (s3 .FilterRuleNamePrefix ),
558
- Value : aws .String (fmt . Sprintf ( "%s/" , splitPath [ 1 ]) ),
644
+ Value : aws .String (path ),
559
645
},
560
646
},
561
647
},
@@ -565,13 +651,14 @@ func enableInputNotification(minIOClient *s3.S3, arnStr string, input types.Stor
565
651
// Append the new queueConfiguration
566
652
nCfg .QueueConfigurations = append (nCfg .QueueConfigurations , & queueConfiguration )
567
653
pbncInput := & s3.PutBucketNotificationConfigurationInput {
568
- Bucket : aws .String (splitPath [ 0 ] ),
654
+ Bucket : aws .String (bucket ),
569
655
NotificationConfiguration : nCfg ,
570
656
}
571
657
572
658
// Enable the notification
573
659
_ , err = minIOClient .PutBucketNotificationConfiguration (pbncInput )
574
- if err != nil {
660
+
661
+ if err != nil && ! strings .Contains (err .Error (), "An object key name filtering rule defined with overlapping prefixes" ) {
575
662
return fmt .Errorf ("error enabling bucket notification: %v" , err )
576
663
}
577
664
0 commit comments