From 8007ca2acc0fd65e4f7ce170d66d3c33d5358664 Mon Sep 17 00:00:00 2001 From: liranmauda Date: Sun, 24 Dec 2023 17:53:02 +0200 Subject: [PATCH] NSFS | NC | CLI | add filter to list NSFS | NC | CLI | add filter to list Signed-off-by: liranmauda --- src/cmd/manage_nsfs.js | 33 ++++- .../test_nc_nsfs_account_cli.test.js | 124 ++++++++++++++++-- src/test/unit_tests/test_nc_nsfs_cli.js | 6 +- 3 files changed, 145 insertions(+), 18 deletions(-) diff --git a/src/cmd/manage_nsfs.js b/src/cmd/manage_nsfs.js index 841a2acbbd..3b91968415 100644 --- a/src/cmd/manage_nsfs.js +++ b/src/cmd/manage_nsfs.js @@ -95,6 +95,8 @@ Account Options: # Used for list --wide (default none) Will print the list with details (same as status but for all accounts) --show_secrets (default false) Will print the access_keys of the account + --uid (default none) filter the list by uid. + --gid (default none) filter the list by gid. `; const BUCKET_OPTIONS = ` @@ -349,7 +351,7 @@ async function account_management(argv, config_root, from_file) { const show_secrets = Boolean(argv.show_secrets) || false; const config_root_backend = String(argv.config_root_backend); const data = await fetch_account_data(argv, config_root, from_file); - await manage_account_operations(action, data, config_root, config_root_backend, show_secrets); + await manage_account_operations(action, data, config_root, config_root_backend, show_secrets, argv); } /** @@ -382,7 +384,7 @@ async function fetch_account_data(argv, config_root, from_file) { const raw_data = (await nb_native().fs.readFile(fs_context, from_file)).data; data = JSON.parse(raw_data.toString()); } - _validate_access_keys(argv); + if (action !== ACTIONS.LIST && action !== ACTIONS.STATUS) _validate_access_keys(argv); let new_access_key = argv.new_access_key; if (action === 'update') { generate_access_keys = false; @@ -555,7 +557,7 @@ async function get_account_status(data, accounts_path, access_keys_path, show_se } } -async function manage_account_operations(action, data, config_root, config_root_backend, show_secrets) { +async function manage_account_operations(action, data, config_root, config_root_backend, show_secrets, argv) { const accounts_path = path.join(config_root, accounts_dir_name); const access_keys_path = path.join(config_root, access_keys_dir_name); if (action === ACTIONS.ADD) { @@ -568,6 +570,7 @@ async function manage_account_operations(action, data, config_root, config_root_ await delete_account(data, accounts_path, access_keys_path, config_root_backend); } else if (action === ACTIONS.LIST) { let accounts = await list_config_files(accounts_path, show_secrets); + accounts = filter_account_results(accounts, argv) if (!data.wide) accounts = accounts.map(item => ({ name: item.name })); write_stdout_response(ManageCLIResponse.AccountList, accounts); } else { @@ -575,6 +578,27 @@ async function manage_account_operations(action, data, config_root, config_root_ } } +/** + * filter_account_results will filter the results based on supported given flags + * @param {any[]} accounts + * @param {{}} argv + */ +function filter_account_results(accounts, argv) { + //supported filters for list + const filters = _.pick(argv, ['uid', 'gid']); //if we add filters we should remove this comment and the comment 4 lines below (else) + return accounts.filter(item => { + for (const [key, val] of Object.entries(filters)) { + if (key === 'uid' || key === 'gid') { + if (item.nsfs_account_config && item.nsfs_account_config[key] !== val) { + return false; + } + } else if (item[key] !== val) { // We will never reach here if we will not add an appropriate field to the filter + return false; + } + } + return true; + }); +} /** * list_config_files will list all the config files (json) in a given config directory @@ -725,8 +749,7 @@ function validate_whitelist_arg(ips) { function _validate_access_keys(argv) { // using the access_key flag requires also using the secret_key flag - // TODO: currently disabling it to avoid failing tests of update, we should talk if we want to remove this or readd it. - // if (!is_undefined(argv.access_key) && is_undefined(argv.secret_key)) throw_cli_error(ManageCLIError.MissingAccountSecretKeyFlag); + if (!is_undefined(argv.access_key) && is_undefined(argv.secret_key)) throw_cli_error(ManageCLIError.MissingAccountSecretKeyFlag); if (!is_undefined(argv.secret_key) && is_undefined(argv.access_key)) throw_cli_error(ManageCLIError.MissingAccountAccessKeyFlag); // checking the complexity of access_key if (!is_undefined(argv.access_key) && !string_utils.validate_complexity(argv.access_key, { diff --git a/src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js b/src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js index a5421c21f8..90e9fbcafc 100644 --- a/src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js +++ b/src/test/unit_tests/jest_tests/test_nc_nsfs_account_cli.test.js @@ -29,6 +29,7 @@ const DEFAULT_FS_CONFIG = { const nc_nsfs_manage_actions = { ADD: 'add', UPDATE: 'update', + LIST: 'list', DELETE: 'delete' }; @@ -47,7 +48,7 @@ describe('manage nsfs cli account flow', () => { uid: 999, gid: 999, access_key: 'GIGiFAnjaaE7OKD5N7hA', - secret_key: 'U2AYaMpU3zRDcRFWmvzgQr9MoHIAsDy3o+4h0oFR', + secret_key: 'U2AYaMpU3zRDcRFWmvzgQr9MoHIAsD+3oEXAMPLE', }; beforeEach(async () => { @@ -78,15 +79,15 @@ describe('manage nsfs cli account flow', () => { assert_account(account_symlink, account_options); }); - // it('cli create account with access_key and without secret_key', async () => { - // const action = nc_nsfs_manage_actions.ADD; - // const { type, access_key, name, email, new_buckets_path, uid, gid } = defaults; - // const account_options = { config_root, access_key, name, email, new_buckets_path, uid, gid }; - // await fs_utils.create_fresh_path(new_buckets_path); - // await fs_utils.file_must_exist(new_buckets_path); - // const res = await exec_manage_cli(type, action, account_options); - // expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.MissingAccountSecretKeyFlag.message); - // }); + it('cli create account with access_key and without secret_key', async () => { + const action = nc_nsfs_manage_actions.ADD; + const { type, access_key, name, email, new_buckets_path, uid, gid } = defaults; + const account_options = { config_root, access_key, name, email, new_buckets_path, uid, gid }; + await fs_utils.create_fresh_path(new_buckets_path); + await fs_utils.file_must_exist(new_buckets_path); + const res = await exec_manage_cli(type, action, account_options); + expect(JSON.parse(res.stdout).error.message).toBe(ManageCLIError.MissingAccountSecretKeyFlag.message); + }); it('cli create account without access_key and with secret_key', async () => { const action = nc_nsfs_manage_actions.ADD; @@ -153,7 +154,7 @@ describe('manage nsfs cli account flow', () => { uid: 999, gid: 999, access_key: 'GIGiFAnjaaE7OKD5N7hA', - secret_key: 'U2AYaMpU3zRDcRFWmvzgQr9MoHIAsDy3o+4h0oFR', + secret_key: 'U2AYaMpU3zRDcRFWmvzgQr9MoHIAsD+3oEXAMPLE', }; beforeEach(async () => { @@ -215,6 +216,107 @@ describe('manage nsfs cli account flow', () => { }); }); + + describe('cli list account', () => { + const config_root = path.join(tmp_fs_path, 'config_root_manage_nsfs1'); + const root_path = path.join(tmp_fs_path, 'root_path_manage_nsfs1/'); + const defaults = [{ + type: 'account', + name: 'account1', + email: 'account1@noobaa.io', + new_buckets_path: `${root_path}new_buckets_path_user1/`, + uid: 999, + gid: 999, + access_key: 'GIGiFAnjaaE7OKD5N7hA', + secret_key: 'U2AYaMpU3zRDcRFWmvzgQr9MoHIAsD+3oEXAMPLE', + }, { + type: 'account', + name: 'account2', + email: 'account2@noobaa.io', + new_buckets_path: `${root_path}new_buckets_path_user2/`, + uid: 888, + gid: 888, + access_key: 'BIBiFAnjaaE7OKD5N7hA', + secret_key: 'BIBYaMpU3zRDcRFWmvzgQr9MoHIAsD+3oEXAMPLE', + }, { + type: 'account', + name: 'account3', + email: 'account3@noobaa.io', + new_buckets_path: `${root_path}new_buckets_path_user2/`, + uid: 999, + gid: 888, + access_key: 'TIBiFAnjaaE7OKD5N7hA', + secret_key: 'BITYaMpU3zRDcRFWmvzgQr9MoHIAsD+3oEXAMPLE', + }]; + + beforeAll(async () => { + await P.all(_.map([accounts_schema_dir, access_keys_schema_dir], async dir => + fs_utils.create_fresh_path(`${config_root}/${dir}`))); + await fs_utils.create_fresh_path(root_path); + // Creating the account + const action = nc_nsfs_manage_actions.ADD; + for (const account_defaults of Object.values(defaults)) { + const { type, new_buckets_path } = account_defaults; + const account_options = { config_root, ...account_defaults }; + await fs_utils.create_fresh_path(new_buckets_path); + await fs_utils.file_must_exist(new_buckets_path); + await exec_manage_cli(type, action, account_options); + } + }); + + afterAll(async () => { + await fs_utils.folder_delete(`${config_root}`); + await fs_utils.folder_delete(`${root_path}`); + }); + + it('cli list', async () => { + const account_options = { config_root }; + const action = nc_nsfs_manage_actions.LIST; + const res = await exec_manage_cli('account', action, account_options); + expect(JSON.parse(res).response.reply.map(item => item.name)) + .toEqual(expect.arrayContaining(['account3', 'account2', 'account1'])); + }); + + it('cli list wide', async () => { + const account_options = { config_root, wide: true }; + const action = nc_nsfs_manage_actions.LIST; + const res = await exec_manage_cli('account', action, account_options); + expect(JSON.parse(res).response.reply.map(item => item.name)) + .toEqual(expect.arrayContaining(['account3', 'account2', 'account1'])); + }); + + it('cli list filter by UID', async () => { + const account_options = { config_root, uid: 999 }; + const action = nc_nsfs_manage_actions.LIST; + const res = await exec_manage_cli('account', action, account_options); + expect(JSON.parse(res).response.reply.map(item => item.name)) + .toEqual(expect.arrayContaining(['account3', 'account1'])); + }); + + it('cli list filter by GID', async () => { + const account_options = { config_root, gid: 999 }; + const action = nc_nsfs_manage_actions.LIST; + const res = await exec_manage_cli('account', action, account_options); + expect(JSON.parse(res).response.reply.map(item => item.name)) + .toEqual(expect.arrayContaining(['account1'])); + }); + + it('cli list filter by UID and GID (account 1)', async () => { + const account_options = { config_root, uid: 999, gid: 999 }; + const action = nc_nsfs_manage_actions.LIST; + const res = await exec_manage_cli('account', action, account_options); + expect(JSON.parse(res).response.reply.map(item => item.name)) + .toEqual(expect.arrayContaining(['account1'])); + }); + + it('cli list filter by UID and GID (account 3)', async () => { + const account_options = { config_root, uid: 999, gid: 888 }; + const action = nc_nsfs_manage_actions.LIST; + const res = await exec_manage_cli('account', action, account_options); + expect(JSON.parse(res).response.reply.map(item => item.name)) + .toEqual(expect.arrayContaining(['account3'])); + }); + }); }); /** diff --git a/src/test/unit_tests/test_nc_nsfs_cli.js b/src/test/unit_tests/test_nc_nsfs_cli.js index 1b7e740471..368d4f9abe 100644 --- a/src/test/unit_tests/test_nc_nsfs_cli.js +++ b/src/test/unit_tests/test_nc_nsfs_cli.js @@ -337,6 +337,7 @@ mocha.describe('manage_nsfs cli', function() { const update_options = { config_root, access_key: account_options.access_key, + secret_key: account_options.secret_key, email: 'account2@noobaa.io', uid: 222, gid: 222 @@ -379,7 +380,8 @@ mocha.describe('manage_nsfs cli', function() { const update_options = { config_root, new_name: 'account1_new_name', - access_key: account_options.access_key + access_key: account_options.access_key, + secret_key: account_options.secret_key, }; account_options.new_name = 'account1_new_name'; const update_response = await exec_manage_cli(type, action, update_options); @@ -544,7 +546,7 @@ mocha.describe('manage_nsfs cli', function() { mocha.it('cli account delete by access key', async function() { const action = nc_nsfs_manage_actions.DELETE; - const res = await exec_manage_cli(type, action, { config_root, access_key }); + const res = await exec_manage_cli(type, action, { config_root, access_key, secret_key }); assert_response(action, type, res); try { await read_config_file(config_root, access_keys_schema_dir, access_key, true);