Skip to content

Commit c1a4b5d

Browse files
authored
Merge pull request #8224 from shirady/nsfs-nc-delete-bucket-no-path
NC | NSFS | S3 Flow `delete_bucket` When ULS Was Deleted + Refactor Function `translate_error_codes`
2 parents c5026ab + 1f2cfcf commit c1a4b5d

File tree

5 files changed

+145
-94
lines changed

5 files changed

+145
-94
lines changed

src/sdk/accountspace_fs.js

Lines changed: 14 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,6 @@ const { get_symlink_config_file_path, get_config_file_path, get_config_data,
2121
const nc_mkm = require('../manage_nsfs/nc_master_key_manager').get_instance();
2222
const { account_cache } = require('./object_sdk');
2323

24-
const entity_enum = Object.freeze({
25-
USER: 'USER',
26-
ACCESS_KEY: 'ACCESS_KEY',
27-
});
28-
2924
// TODO - rename (the typo), move and reuse in manage_nsfs
3025
const acounts_dir_relative_path = '../accounts/';
3126

@@ -87,7 +82,7 @@ class AccountSpaceFS {
8782
};
8883
} catch (err) {
8984
dbg.error(`AccountSpaceFS.${action} error`, err);
90-
throw this._translate_error_codes(err, entity_enum.USER);
85+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.USER);
9186
}
9287
}
9388

@@ -125,7 +120,7 @@ class AccountSpaceFS {
125120
};
126121
} catch (err) {
127122
dbg.error(`AccountSpaceFS.${action} error`, err);
128-
throw this._translate_error_codes(err, entity_enum.USER);
123+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.USER);
129124
}
130125
}
131126

@@ -179,7 +174,7 @@ class AccountSpaceFS {
179174
};
180175
} catch (err) {
181176
dbg.error(`AccountSpaceFS.${action} error`, err);
182-
throw this._translate_error_codes(err, entity_enum.USER);
177+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.USER);
183178
}
184179
}
185180

@@ -213,7 +208,7 @@ class AccountSpaceFS {
213208
await native_fs_utils.delete_config_file(this.fs_context, this.accounts_dir, account_config_path);
214209
} catch (err) {
215210
dbg.error(`AccountSpaceFS.${action} error`, err);
216-
throw this._translate_error_codes(err, entity_enum.USER);
211+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.USER);
217212
}
218213
}
219214

@@ -237,7 +232,7 @@ class AccountSpaceFS {
237232
return { members, is_truncated };
238233
} catch (err) {
239234
dbg.error(`AccountSpaceFS.${action} error`, err);
240-
throw this._translate_error_codes(err, entity_enum.USER);
235+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.USER);
241236
}
242237
}
243238

@@ -297,7 +292,7 @@ class AccountSpaceFS {
297292
};
298293
} catch (err) {
299294
dbg.error(`AccountSpaceFS.${action} error`, err);
300-
throw this._translate_error_codes(err, entity_enum.ACCESS_KEY);
295+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.ACCESS_KEY);
301296
}
302297
}
303298

@@ -329,7 +324,7 @@ class AccountSpaceFS {
329324
};
330325
} catch (err) {
331326
dbg.error('AccountSpaceFS.get_access_key_last_used error', err);
332-
throw this._translate_error_codes(err, entity_enum.ACCESS_KEY);
327+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.ACCESS_KEY);
333328
}
334329
}
335330

@@ -380,7 +375,7 @@ class AccountSpaceFS {
380375
this._clean_account_cache(requested_account);
381376
} catch (err) {
382377
dbg.error(`AccountSpaceFS.${action} error`, err);
383-
throw this._translate_error_codes(err, entity_enum.ACCESS_KEY);
378+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.ACCESS_KEY);
384379
}
385380
}
386381

@@ -426,7 +421,7 @@ class AccountSpaceFS {
426421
this._clean_account_cache(requested_account);
427422
} catch (err) {
428423
dbg.error(`AccountSpaceFS.${action} error`, err);
429-
throw this._translate_error_codes(err, entity_enum.ACCESS_KEY);
424+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.ACCESS_KEY);
430425
}
431426
}
432427

@@ -460,26 +455,14 @@ class AccountSpaceFS {
460455
return { members, is_truncated, username: name_for_access_key };
461456
} catch (err) {
462457
dbg.error(`AccountSpaceFS.${action} error`, err);
463-
throw this._translate_error_codes(err, entity_enum.ACCESS_KEY);
458+
throw native_fs_utils.translate_error_codes(err, native_fs_utils.entity_enum.ACCESS_KEY);
464459
}
465460
}
466461

467462
////////////////////////
468463
// INTERNAL FUNCTIONS //
469464
////////////////////////
470465

471-
// this function was copied from namespace_fs and bucketspace_fs
472-
// It is a fallback that we use, but might be not accurate
473-
_translate_error_codes(err, entity) {
474-
if (err.rpc_code) return err;
475-
if (err.code === 'ENOENT') err.rpc_code = `NO_SUCH_${entity}`;
476-
if (err.code === 'EEXIST') err.rpc_code = `${entity}_ALREADY_EXISTS`;
477-
if (err.code === 'EPERM' || err.code === 'EACCES') err.rpc_code = 'UNAUTHORIZED';
478-
if (err.code === 'IO_STREAM_ITEM_TIMEOUT') err.rpc_code = 'IO_STREAM_ITEM_TIMEOUT';
479-
if (err.code === 'INTERNAL_ERROR') err.rpc_code = 'INTERNAL_ERROR';
480-
return err;
481-
}
482-
483466
_get_account_config_path(name) {
484467
return get_config_file_path(this.accounts_dir, name);
485468
}
@@ -572,7 +555,7 @@ class AccountSpaceFS {
572555
const basic_message = `User: ${arn_for_requesting_account} is not authorized to perform:` +
573556
`${full_action_name} on resource: `;
574557
let message_with_details;
575-
if (entity === entity_enum.USER) {
558+
if (entity === native_fs_utils.entity_enum.USER) {
576559
let user_message;
577560
if (action === 'list_access_keys') {
578561
user_message = `user ${requesting_account.name.unwrap()}`;
@@ -581,7 +564,7 @@ class AccountSpaceFS {
581564
}
582565
message_with_details = basic_message +
583566
`${user_message} because no identity-based policy allows the ${full_action_name} action`;
584-
} else { // entity_enum.ACCESS_KEY
567+
} else { // native_fs_utils.entity_enum.ACCESS_KEY
585568
message_with_details = basic_message + `access key ${details.access_key}`;
586569
}
587570
const { code, http_code, type } = IamError.AccessDeniedException;
@@ -658,7 +641,7 @@ class AccountSpaceFS {
658641
if (!is_root_account) {
659642
dbg.error(`AccountSpaceFS.${action} requesting account is not a root account`,
660643
requesting_account);
661-
this._throw_access_denied_error(action, requesting_account, user_details, entity_enum.USER);
644+
this._throw_access_denied_error(action, requesting_account, user_details, native_fs_utils.entity_enum.USER);
662645
}
663646
}
664647

@@ -895,7 +878,7 @@ class AccountSpaceFS {
895878
dbg.error(`AccountSpaceFS.${action} requesting account is neither a root account ` +
896879
`nor user requester on himself`,
897880
requesting_account);
898-
this._throw_access_denied_error(action, requesting_account, { username }, entity_enum.USER);
881+
this._throw_access_denied_error(action, requesting_account, { username }, native_fs_utils.entity_enum.USER);
899882
}
900883
return requester;
901884
}

src/sdk/bucketspace_fs.js

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ const { CONFIG_SUBDIRS } = require('../manage_nsfs/manage_nsfs_constants');
2121

2222
const KeysSemaphore = require('../util/keys_semaphore');
2323
const { get_umasked_mode, isDirectory, validate_bucket_creation,
24-
create_config_file, delete_config_file, get_bucket_tmpdir_full_path, folder_delete } = require('../util/native_fs_utils');
24+
create_config_file, delete_config_file, get_bucket_tmpdir_full_path, folder_delete,
25+
entity_enum, translate_error_codes } = require('../util/native_fs_utils');
2526
const NoobaaEvent = require('../manage_nsfs/manage_nsfs_events_utils').NoobaaEvent;
2627
const { anonymous_access_key } = require('./object_sdk');
2728

@@ -86,16 +87,6 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
8687
}
8788
}
8889

89-
_translate_bucket_error_codes(err) {
90-
if (err.rpc_code) return err;
91-
if (err.code === 'ENOENT') err.rpc_code = 'NO_SUCH_BUCKET';
92-
if (err.code === 'EEXIST') err.rpc_code = 'BUCKET_ALREADY_EXISTS';
93-
if (err.code === 'EPERM' || err.code === 'EACCES') err.rpc_code = 'UNAUTHORIZED';
94-
if (err.code === 'IO_STREAM_ITEM_TIMEOUT') err.rpc_code = 'IO_STREAM_ITEM_TIMEOUT';
95-
if (err.code === 'INTERNAL_ERROR') err.rpc_code = 'INTERNAL_ERROR';
96-
return err;
97-
}
98-
9990
async read_account_by_access_key({ access_key }) {
10091
try {
10192
if (!access_key) throw new Error('no access key');
@@ -178,7 +169,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
178169
}
179170
return bucket;
180171
} catch (err) {
181-
const rpc_error = this._translate_bucket_error_codes(err);
172+
const rpc_error = translate_error_codes(err, entity_enum.BUCKET);
182173
if (err.rpc_code === 'INVALID_SCHEMA') err.rpc_code = 'INVALID_BUCKET_STATE';
183174
new NoobaaEvent(NoobaaEvent[rpc_error.rpc_code]).create_event(name, {bucket_name: name}, err);
184175
throw rpc_error;
@@ -222,7 +213,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
222213
dbg.error('BucketSpaceFS: root dir not found', err, this.bucket_schema_dir);
223214
throw new S3Error(S3Error.NoSuchBucket);
224215
}
225-
throw this._translate_bucket_error_codes(err);
216+
throw translate_error_codes(err, entity_enum.BUCKET);
226217
}
227218

228219
const account = object_sdk.requesting_account;
@@ -302,7 +293,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
302293
await create_config_file(this.fs_context, this.bucket_schema_dir, bucket_config_path, bucket_config);
303294
} catch (err) {
304295
new NoobaaEvent(NoobaaEvent.BUCKET_CREATION_FAILED).create_event(name, {bucket_name: name}, err);
305-
throw this._translate_bucket_error_codes(err);
296+
throw translate_error_codes(err, entity_enum.BUCKET);
306297
}
307298

308299
// create bucket's underlying storage directory
@@ -313,7 +304,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
313304
dbg.error('BucketSpaceFS: create_bucket could not create underlying directory - nsfs, deleting bucket', err);
314305
new NoobaaEvent(NoobaaEvent.BUCKET_DIR_CREATION_FAILED).create_event(name, {bucket: name, path: bucket_storage_path}, err);
315306
await nb_native().fs.unlink(this.fs_context, bucket_config_path);
316-
throw this._translate_bucket_error_codes(err);
307+
throw translate_error_codes(err, entity_enum.BUCKET);
317308
}
318309
});
319310
}
@@ -359,13 +350,27 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
359350
if (!namespace_bucket_config) throw new RpcError('INTERNAL_ERROR', 'Invalid Bucket configuration');
360351

361352
if (namespace_bucket_config.should_create_underlying_storage) {
362-
// 1. delete underlying storage
353+
// 1. delete underlying storage (ULS = Underline Storage)
363354
dbg.log1('BucketSpaceFS.delete_bucket: deleting uls', this.fs_root, namespace_bucket_config.write_resource.path);
364355
const bucket_storage_path = path.join(this.fs_root, namespace_bucket_config.write_resource.path); // includes write_resource.path + bucket name (s3 flow)
365-
await ns.delete_uls({ name, full_path: bucket_storage_path }, object_sdk);
356+
try {
357+
await ns.delete_uls({ name, full_path: bucket_storage_path }, object_sdk);
358+
} catch (err) {
359+
dbg.warn('delete_bucket: bucket name', name, 'with bucket_storage_path', bucket_storage_path,
360+
'got an error while trying to delete_uls', err);
361+
// in case the ULS was deleted - we will continue
362+
if (err.rpc_code !== 'NO_SUCH_BUCKET') throw err;
363+
}
366364
} else {
367365
// 2. delete only bucket tmpdir
368-
const list = await ns.list_objects({ ...params, bucket: name, limit: 1 }, object_sdk);
366+
let list;
367+
try {
368+
list = await ns.list_objects({ ...params, bucket: name, limit: 1 }, object_sdk);
369+
} catch (err) {
370+
dbg.warn('delete_bucket: bucket name', name, 'got an error while trying to list_objects', err);
371+
// in case the ULS was deleted - we will continue
372+
if (err.rpc_code !== 'NO_SUCH_BUCKET') throw err;
373+
}
369374
if (list && list.objects && list.objects.length > 0) throw new RpcError('NOT_EMPTY', 'underlying directory has files in it');
370375
const bucket_tmpdir_path = get_bucket_tmpdir_full_path(namespace_bucket_config.write_resource.path, bucket._id);
371376
await folder_delete(bucket_tmpdir_path, this.fs_context, true);
@@ -375,10 +380,10 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
375380
await delete_config_file(this.fs_context, this.bucket_schema_dir, bucket_config_path);
376381
new NoobaaEvent(NoobaaEvent.BUCKET_DELETE).create_event(name, { bucket_name: name });
377382
} catch (err) {
378-
dbg.error('BucketSpaceFS: delete_bucket: error', err);
383+
dbg.error('BucketSpaceFS: delete_bucket: bucket name', name, 'error', err);
379384
new NoobaaEvent(NoobaaEvent.BUCKET_DELETE_FAILED).create_event(name,
380385
{ bucket_name: name, bucket_path: bucket_config_path }, err);
381-
throw this._translate_bucket_error_codes(err);
386+
throw translate_error_codes(err, entity_enum.BUCKET);
382387
}
383388
});
384389
}
@@ -426,7 +431,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
426431
}
427432
);
428433
} catch (err) {
429-
throw this._translate_bucket_error_codes(err);
434+
throw translate_error_codes(err, entity_enum.BUCKET);
430435
}
431436
}
432437

@@ -484,7 +489,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
484489
}
485490
);
486491
} catch (err) {
487-
throw this._translate_bucket_error_codes(err);
492+
throw translate_error_codes(err, entity_enum.BUCKET);
488493
}
489494
}
490495

@@ -508,7 +513,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
508513
}
509514
);
510515
} catch (err) {
511-
throw this._translate_bucket_error_codes(err);
516+
throw translate_error_codes(err, entity_enum.BUCKET);
512517
}
513518
}
514519

@@ -521,7 +526,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
521526
const bucket = JSON.parse(data.toString());
522527
return bucket.logging;
523528
} catch (err) {
524-
throw this._translate_bucket_error_codes(err);
529+
throw translate_error_codes(err, entity_enum.BUCKET);
525530
}
526531
}
527532

@@ -550,7 +555,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
550555
{ mode: get_umasked_mode(config.BASE_MODE_CONFIG_FILE) }
551556
);
552557
} catch (err) {
553-
throw this._translate_bucket_error_codes(err);
558+
throw translate_error_codes(err, entity_enum.BUCKET);
554559
}
555560
}
556561

@@ -563,7 +568,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
563568
const bucket = JSON.parse(data.toString());
564569
return bucket.encryption;
565570
} catch (err) {
566-
throw this._translate_bucket_error_codes(err);
571+
throw translate_error_codes(err, entity_enum.BUCKET);
567572
}
568573
}
569574

@@ -586,7 +591,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
586591
{ mode: get_umasked_mode(config.BASE_MODE_CONFIG_FILE) }
587592
);
588593
} catch (err) {
589-
throw this._translate_bucket_error_codes(err);
594+
throw translate_error_codes(err, entity_enum.BUCKET);
590595
}
591596
}
592597

@@ -614,7 +619,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
614619
{ mode: get_umasked_mode(config.BASE_MODE_CONFIG_FILE) }
615620
);
616621
} catch (err) {
617-
throw this._translate_bucket_error_codes(err);
622+
throw translate_error_codes(err, entity_enum.BUCKET);
618623
}
619624
}
620625

@@ -637,7 +642,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
637642
{ mode: get_umasked_mode(config.BASE_MODE_CONFIG_FILE) }
638643
);
639644
} catch (err) {
640-
throw this._translate_bucket_error_codes(err);
645+
throw translate_error_codes(err, entity_enum.BUCKET);
641646
}
642647
}
643648

@@ -654,7 +659,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
654659
const bucket = JSON.parse(data.toString());
655660
return { website: bucket.website };
656661
} catch (err) {
657-
throw this._translate_bucket_error_codes(err);
662+
throw translate_error_codes(err, entity_enum.BUCKET);
658663
}
659664
}
660665

@@ -685,7 +690,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
685690
{ mode: get_umasked_mode(config.BASE_MODE_CONFIG_FILE) }
686691
);
687692
} catch (err) {
688-
throw this._translate_bucket_error_codes(err);
693+
throw translate_error_codes(err, entity_enum.BUCKET);
689694
}
690695
}
691696

@@ -708,7 +713,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
708713
{ mode: get_umasked_mode(config.BASE_MODE_CONFIG_FILE) }
709714
);
710715
} catch (err) {
711-
throw this._translate_bucket_error_codes(err);
716+
throw translate_error_codes(err, entity_enum.BUCKET);
712717
}
713718
}
714719

@@ -722,7 +727,7 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
722727
policy: bucket_policy_info.s3_policy
723728
};
724729
} catch (err) {
725-
throw this._translate_bucket_error_codes(err);
730+
throw translate_error_codes(err, entity_enum.BUCKET);
726731
}
727732
}
728733

0 commit comments

Comments
 (0)