Skip to content

Commit 9bbc2a5

Browse files
committed
NC | Adding support of user bucket path
Signed-off-by: jackyalbo <jacky.albo@gmail.com>
1 parent 75036b9 commit 9bbc2a5

File tree

13 files changed

+159
-11
lines changed

13 files changed

+159
-11
lines changed

config.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,9 @@ config.NSFS_LIST_IGNORE_ENTRY_ON_EACCES = true;
10181018
// we will for now handle the same way also EINVAL error - for gpfs stat issues on list (.snapshots)
10191019
config.NSFS_LIST_IGNORE_ENTRY_ON_EINVAL = true;
10201020

1021+
config.NSFS_CUSTOM_BUCKET_PATH_HTTP_HEADER = 'x-noobaa-custom-bucket-path';
1022+
config.NSFS_CUSTOM_BUCKET_PATH_ALLOWED_LIST = ''; // colon separated list of paths prefixes
1023+
10211024
////////////////////////////
10221025
// NSFS NON CONTAINERIZED //
10231026
////////////////////////////

src/api/account_api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,7 @@ module.exports = {
308308
supplemental_groups: {
309309
$ref: 'common_api#/definitions/supplemental_groups'
310310
},
311+
custom_bucket_path_allowed_list: { type: 'string' },
311312
}
312313
},
313314
},

src/api/bucket_api.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ module.exports = {
3333
},
3434
bucket_claim: { $ref: '#/definitions/bucket_claim' },
3535
force_md5_etag: { type: 'boolean' },
36+
custom_bucket_path: { type: 'string' }
3637
}
3738
},
3839
reply: {

src/api/common_api.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1454,14 +1454,16 @@ module.exports = {
14541454
supplemental_groups: {
14551455
$ref: '#/definitions/supplemental_groups'
14561456
},
1457+
custom_bucket_path_allowed_list: { type: 'string' },
14571458
}
14581459
}, {
14591460
type: 'object',
14601461
required: ['distinguished_name', 'new_buckets_path', 'nsfs_only'],
14611462
properties: {
14621463
distinguished_name: { wrapper: SensitiveString },
14631464
new_buckets_path: { type: 'string' },
1464-
nsfs_only: { type: 'boolean' }
1465+
nsfs_only: { type: 'boolean' },
1466+
custom_bucket_path_allowed_list: { type: 'string' },
14651467
}
14661468
}]
14671469
},

src/cmd/manage_nsfs.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,8 @@ async function fetch_account_data(action, user_input) {
503503
uid: user_input.user ? undefined : user_input.uid,
504504
gid: user_input.user ? undefined : user_input.gid,
505505
new_buckets_path: user_input.new_buckets_path,
506-
fs_backend: user_input.fs_backend ? String(user_input.fs_backend) : config.NSFS_NC_STORAGE_BACKEND
506+
fs_backend: user_input.fs_backend ? String(user_input.fs_backend) : config.NSFS_NC_STORAGE_BACKEND,
507+
custom_bucket_path_allowed_list: user_input.custom_bucket_path_allowed_list,
507508
},
508509
default_connection: user_input.default_connection === undefined ? undefined : String(user_input.default_connection)
509510
};
@@ -542,6 +543,8 @@ async function fetch_account_data(action, user_input) {
542543
} else { // string of true or false
543544
data.allow_bucket_creation = user_input.allow_bucket_creation.toLowerCase() === 'true';
544545
}
546+
// custom_bucket_path_allowed_list deletion specified with empty string ''
547+
data.nsfs_account_config.custom_bucket_path_allowed_list = data.nsfs_account_config.custom_bucket_path_allowed_list || undefined;
545548

546549
return data;
547550
}

src/endpoint/s3/ops/s3_put_bucket.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ const config = require('../../../../config');
99
async function put_bucket(req, res) {
1010
const lock_enabled = config.WORM_ENABLED ? req.headers['x-amz-bucket-object-lock-enabled'] &&
1111
req.headers['x-amz-bucket-object-lock-enabled'].toUpperCase() === 'TRUE' : undefined;
12-
await req.object_sdk.create_bucket({ name: req.params.bucket, lock_enabled: lock_enabled });
12+
const custom_bucket_path = req.headers[config.NSFS_CUSTOM_BUCKET_PATH_HTTP_HEADER];
13+
await req.object_sdk.create_bucket({ name: req.params.bucket, lock_enabled, custom_bucket_path });
1314
if (config.allow_anonymous_access_in_test && req.headers['x-amz-acl'] === 'public-read') { // For now we will enable only for tests
1415
const policy = {
1516
Version: '2012-10-17',

src/manage_nsfs/manage_nsfs_constants.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ const FROM_FILE = 'from_file';
4646
const ANONYMOUS = 'anonymous';
4747

4848
const VALID_OPTIONS_ACCOUNT = {
49-
'add': new Set(['name', 'uid', 'gid', 'supplemental_groups', 'new_buckets_path', 'user', 'access_key', 'secret_key', 'fs_backend', 'allow_bucket_creation', 'force_md5_etag', 'iam_operate_on_root_account', 'default_connection', FROM_FILE, ...CLI_MUTUAL_OPTIONS]),
50-
'update': new Set(['name', 'uid', 'gid', 'supplemental_groups', 'new_buckets_path', 'user', 'access_key', 'secret_key', 'fs_backend', 'allow_bucket_creation', 'force_md5_etag', 'iam_operate_on_root_account', 'new_name', 'regenerate', 'default_connection', ...CLI_MUTUAL_OPTIONS]),
49+
'add': new Set(['name', 'uid', 'gid', 'supplemental_groups', 'new_buckets_path', 'custom_bucket_path_allowed_list', 'user', 'access_key', 'secret_key', 'fs_backend', 'allow_bucket_creation', 'force_md5_etag', 'iam_operate_on_root_account', 'default_connection', FROM_FILE, ...CLI_MUTUAL_OPTIONS]),
50+
'update': new Set(['name', 'uid', 'gid', 'supplemental_groups', 'new_buckets_path', 'custom_bucket_path_allowed_list', 'user', 'access_key', 'secret_key', 'fs_backend', 'allow_bucket_creation', 'force_md5_etag', 'iam_operate_on_root_account', 'new_name', 'regenerate', 'default_connection', ...CLI_MUTUAL_OPTIONS]),
5151
'delete': new Set(['name', ...CLI_MUTUAL_OPTIONS]),
5252
'list': new Set(['wide', 'show_secrets', 'gid', 'uid', 'user', 'name', 'access_key', ...CLI_MUTUAL_OPTIONS]),
5353
'status': new Set(['name', 'access_key', 'show_secrets', ...CLI_MUTUAL_OPTIONS]),
@@ -123,6 +123,7 @@ const OPTION_TYPE = {
123123
gid: 'number',
124124
supplemental_groups: 'string',
125125
new_buckets_path: 'string',
126+
custom_bucket_path_allowed_list: 'string',
126127
user: 'string',
127128
access_key: 'string',
128129
secret_key: 'string',
@@ -196,6 +197,7 @@ const UNSETTABLE_OPTIONS_OBJ = Object.freeze({
196197
'force_md5_etag': CLI_EMPTY_STRING,
197198
'supplemental_groups': CLI_EMPTY_STRING,
198199
'new_buckets_path': CLI_EMPTY_STRING,
200+
'custom_bucket_path_allowed_list': CLI_EMPTY_STRING,
199201
'ips': CLI_EMPTY_STRING_ARRAY,
200202
});
201203

src/manage_nsfs/manage_nsfs_help_utils.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ Flags:
143143
--force_md5_etag <true | false> (optional) Set the account to force md5 etag calculation. (unset with '') (will override default config.NSFS_NC_STORAGE_BACKEND)
144144
--iam_operate_on_root_account <true | false> (optional) Set the account to create root accounts instead of IAM users in IAM API requests.
145145
--from_file <string> (optional) Use details from the JSON file, there is no need to mention all the properties individually in the CLI
146+
--custom_bucket_path_allowed_list <string> (optional) Set the list of allowed custom bucket paths, separated by colons (:) example: '/gpfs/data/custom1/:/gpfs/data/custom2/'
146147
`;
147148

148149
const ACCOUNT_FLAGS_UPDATE = `
@@ -170,6 +171,7 @@ Flags:
170171
--allow_bucket_creation <true | false> (optional) Update the account to explicitly allow or block bucket creation
171172
--force_md5_etag <true | false> (optional) Update the account to force md5 etag calculation (unset with '') (will override default config.NSFS_NC_STORAGE_BACKEND)
172173
--iam_operate_on_root_account <true | false> (optional) Update the account to create root accounts instead of IAM users in IAM API requests.
174+
--custom_bucket_path_allowed_list <string> (optional) Update the list of allowed custom bucket paths, separated by colons (:) example: '/gpfs/data/custom1/:/gpfs/data/custom2/' (override;unset with '')
173175
`;
174176

175177
const ACCOUNT_FLAGS_DELETE = `

src/sdk/accountspace_fs.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,7 @@ class AccountSpaceFS {
608608
supplemental_groups: requesting_account.nsfs_account_config.supplemental_groups,
609609
new_buckets_path: requesting_account.nsfs_account_config.new_buckets_path,
610610
fs_backend: requesting_account.nsfs_account_config.fs_backend,
611+
custom_bucket_path_allowed_list: requesting_account.nsfs_account_config.custom_bucket_path_allowed_list,
611612
}
612613
};
613614
if (requesting_account.iam_operate_on_root_account) {

src/sdk/bucketspace_fs.js

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,9 +303,19 @@ class BucketSpaceFS extends BucketSpaceSimpleFS {
303303
const fs_context = this.prepare_fs_context(sdk);
304304
validate_bucket_creation(params);
305305

306-
const { name } = params;
306+
const { name, custom_bucket_path } = params;
307307
const bucket_config_path = this.config_fs.get_bucket_path_by_name(name);
308-
const bucket_storage_path = path.join(sdk.requesting_account.nsfs_account_config.new_buckets_path, name);
308+
if (custom_bucket_path) {
309+
const allowed_list = sdk.requesting_account.nsfs_account_config.custom_bucket_path_allowed_list ||
310+
config.NSFS_CUSTOM_BUCKET_PATH_ALLOWED_LIST;
311+
const allowed_path_prefixes = allowed_list ? allowed_list.split(':').map(p => p.trim()).filter(p => p) : [];
312+
if (!allowed_path_prefixes.length || !allowed_path_prefixes.some(prefix => custom_bucket_path.startsWith(prefix))) {
313+
const message = `Not allowed to create new buckets: ${custom_bucket_path} outside of the custom_bucket_path_allowed_list: ${allowed_list}`;
314+
dbg.error(`BucketSpaceFS.create_bucket: ${message}`);
315+
throw new RpcError('UNAUTHORIZED', message);
316+
}
317+
}
318+
const bucket_storage_path = custom_bucket_path || path.join(sdk.requesting_account.nsfs_account_config.new_buckets_path, name);
309319

310320
dbg.log0(`BucketSpaceFS.create_bucket
311321
requesting_account=${util.inspect(sdk.requesting_account)},

0 commit comments

Comments
 (0)