Skip to content

Conversation

@jackyalbo
Copy link
Contributor

@jackyalbo jackyalbo commented Nov 6, 2025

Describe the Problem

Adding support for an out-of-S3 header to let the user control where the bucket is supposed to be created.
x-noobaa-custom-bucket-path - will point to where the user wants their new bucket to be saved in the file system.

Explain the Changes

  1. Adapting APIs to support x-noobaa-custom-bucket-path http header - once provided, instead of using the account new_bucket_path directory added to the bucket name, the name in the header will be used.
  2. Accounts can define an allow-list for permitted custom bucket paths; CLI options added to set or unset this allow-list.
  3. Adding a test to check this scenario.

config.NSFS_CUSTOM_BUCKET_PATH_ALLOWED_LIST = '/ibm1/:/ibm3/'
or as part of the account, nsfs_account_config, for example:

nsfs_account_config: {
uid: 100,
gid: 100,
new_buckets_path: '/gpfs/new_buckets',
nsfs_only: false,
custom_bucket_path_allowed_list: /gpfs1/:/gpfs2/,
}
If it exists, the account's custom_bucket_path_allowed_list will override the system's one.
If neither does, we will drop the request with 'access denied'.

Issues: Fixed #xxx / Gap #xxx

Testing Instructions:

  1. Apply custom_bucket_path_allowed_list in config.js and/or in your account
  2. Send x-noobaa-custom-bucket-path header as part of S3 put_bucket request (using account creds)
  3. Verify that the bucket was created in the provided path and not under the account's new_buckets_path/bucket_name
  • Doc added/updated
  • Tests added

Summary by CodeRabbit

  • New Features

    • Bucket creation can accept a custom storage path via an HTTP header.
    • Accounts can define an allow-list for permitted custom bucket paths; CLI options added to set or unset this allow-list.
    • Public configuration entries added to recognize the custom-path header and its allow-list.
  • Tests

    • Integration tests covering creation, conflicts, and access-denied cases for custom bucket paths.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 6, 2025

Walkthrough

Adds optional custom NSFS bucket path support: new config keys, request/header handling, API/schema additions, bucketspace FS validation against an allow-list, CLI/account plumbing, and integration tests covering success, collision and authorization cases.

Changes

Cohort / File(s) Summary
Configuration
config.js
Adds NSFS_CUSTOM_BUCKET_PATH_HTTP_HEADER = 'x-noobaa-custom-bucket-path' and NSFS_CUSTOM_BUCKET_PATH_ALLOWED_LIST = ''.
S3 endpoint
src/endpoint/s3/ops/s3_put_bucket.js
Reads header defined by config.NSFS_CUSTOM_BUCKET_PATH_HTTP_HEADER and passes custom_bucket_path to req.object_sdk.create_bucket.
Bucket API / Schema
src/api/bucket_api.js
Adds optional custom_bucket_path: { type: 'string' } to create_bucket request schema.
Bucketspace FS logic
src/sdk/bucketspace_fs.js
create_bucket accepts params.custom_bucket_path; validates it against allowed prefixes (from account config or default) and sets bucket_storage_path to the custom path when authorized; otherwise falls back or throws UNAUTHORIZED.
Account / Common API schemas
src/api/account_api.js, src/api/common_api.js, src/server/system_services/schemas/nsfs_account_schema.js
Add custom_bucket_path_allowed_list (string) to nsfs_account_config schema variants.
CLI / manage_nsfs
src/cmd/manage_nsfs.js, src/manage_nsfs/manage_nsfs_constants.js, src/manage_nsfs/manage_nsfs_help_utils.js
Add custom_bucket_path_allowed_list option/flag, include in VALID_OPTIONS_ACCOUNT, OPTION_TYPE and UNSETTABLE_OPTIONS_OBJ; normalize empty value to undefined.
Account defaults / SDK
src/sdk/accountspace_fs.js
Propagate custom_bucket_path_allowed_list into new user defaults.
Core test utilities
src/test/utils/coretest/nc_coretest.js
Support passing custom_bucket_path_allowed_list in account create/update test helpers.
Integration tests
src/test/integration_tests/nsfs/test_nsfs_integration.js
Add tests for header-provided custom path: unauthorized when not allowed, successful creation when allowed, collision (BucketAlreadyExists), and account-scoped allow-list enforcement; bump ESLint max-lines.

Sequence Diagram(s)

sequenceDiagram
    participant Client
    participant S3Endpoint as S3 Put Bucket Endpoint
    participant ObjectSDK
    participant BucketspaceFS
    participant AccountCfg as Account Config

    Client->>S3Endpoint: PUT Bucket (Header: x-noobaa-custom-bucket-path: /custom/path)
    S3Endpoint->>S3Endpoint: read header -> params.custom_bucket_path
    S3Endpoint->>ObjectSDK: create_bucket(name, lock_enabled, custom_bucket_path)
    ObjectSDK->>AccountCfg: fetch nsfs_account_config.custom_bucket_path_allowed_list
    ObjectSDK->>BucketspaceFS: create_bucket(params)
    alt custom path provided
        BucketspaceFS->>AccountCfg: determine allowed list (account or default)
        alt path matches allowed prefix
            BucketspaceFS->>BucketspaceFS: bucket_storage_path = params.custom_bucket_path
            BucketspaceFS->>BucketspaceFS: create/init bucket at custom path
            BucketspaceFS-->>ObjectSDK: success
        else path not allowed
            BucketspaceFS-->>ObjectSDK: throw UNAUTHORIZED / AccessDenied
        end
    else no custom path
        BucketspaceFS->>BucketspaceFS: bucket_storage_path = default (new_buckets_path + name)
        BucketspaceFS->>BucketspaceFS: create/init bucket at default path
        BucketspaceFS-->>ObjectSDK: success
    end
    ObjectSDK-->>S3Endpoint: success / error
    S3Endpoint-->>Client: 200 OK / error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Areas to inspect closely:
    • src/sdk/bucketspace_fs.js — path validation logic, prefix matching, path normalization, and correct error codes.
    • src/endpoint/s3/ops/s3_put_bucket.js — header extraction and parameter propagation.
    • Schema changes (src/api/*, src/server/system_services/schemas/*) — ensure backward-compatible validation and required fields.
    • CLI/manage_nsfs plumbing — normalization/unset semantics for empty string.
    • Integration tests — filesystem isolation, cleanup, and correct assertions for AccessDenied/BucketAlreadyExists.

Suggested reviewers

  • tangledbytes
  • liranmauda

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'NC | Adding support of user bucket path' is partially related to the changeset. It mentions 'user bucket path' but the actual implementation uses an HTTP header (x-noobaa-custom-bucket-path) to specify a custom bucket path, not strictly a 'user bucket path'. The title is somewhat vague and could better reflect the specific feature being added (custom bucket path via HTTP header). Consider clarifying the title to reflect the actual implementation, such as 'NC | Add support for custom bucket path via HTTP header' or 'NC | Add x-noobaa-custom-bucket-path header support for custom bucket locations'.
✅ Passed checks (2 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/sdk/bucketspace_fs.js (1)

306-314: Critical: Validate and confine filesystem path from header to prevent unauthorized bucket creation

The user_bucket_path parameter (from HTTP headers) is accepted without validation, enabling a client to direct bucket creation to arbitrary filesystem paths. The existing validation function only validates the bucket name, not this path.

Apply the suggested guard to ensure user_bucket_path is absolutely rejected if it's an absolute path (e.g., /etc/passwd) and confined to remain strictly within the intended base directory:

-            const { name } = params;
-            const bucket_config_path = this.config_fs.get_bucket_path_by_name(name);
-            const bucket_storage_path = params.user_bucket_path ||
-                path.join(sdk.requesting_account.nsfs_account_config.new_buckets_path, name);
+            const { name } = params;
+            const bucket_config_path = this.config_fs.get_bucket_path_by_name(name);
+            let bucket_storage_path;
+            if (params.user_bucket_path) {
+                if (typeof params.user_bucket_path !== 'string' || params.user_bucket_path.trim() === '') {
+                    throw new RpcError('INVALID_REQUEST', 'user_bucket_path must be a non-empty string');
+                }
+                const resolved = path.resolve(params.user_bucket_path);
+                if (!path.isAbsolute(resolved)) {
+                    throw new RpcError('INVALID_REQUEST', 'user_bucket_path must be an absolute path');
+                }
+                const base = path.resolve(sdk.requesting_account.nsfs_account_config.new_buckets_path);
+                // Constrain to the account's bucket root
+                if (!(resolved === base || resolved.startsWith(base + path.sep))) {
+                    throw new RpcError('FORBIDDEN', 'user_bucket_path must reside under the account new_buckets_path');
+                }
+                bucket_storage_path = resolved;
+            } else {
+                bucket_storage_path = path.join(
+                    sdk.requesting_account.nsfs_account_config.new_buckets_path,
+                    name
+                );
+            }
🧹 Nitpick comments (6)
config.js (1)

1019-1020: Header constant looks good; consider default CORS allow-listing it

If browsers will send this header, add it to S3_CORS_ALLOW_HEADERS to pass preflight.

Apply after the new constant:

 config.NSFS_USER_BUCKET_PATH_HTTP_HEADER = 'x-nsfs-bucket-path';
+
+// Allow the custom header for browser clients (preflight)
+if (Array.isArray(config.S3_CORS_ALLOW_HEADERS) &&
+    !config.S3_CORS_ALLOW_HEADERS.includes(config.NSFS_USER_BUCKET_PATH_HTTP_HEADER)) {
+  config.S3_CORS_ALLOW_HEADERS.push(config.NSFS_USER_BUCKET_PATH_HTTP_HEADER);
+}
src/api/bucket_api.js (1)

36-36: Tighten schema for user_bucket_path

Enforce non-empty, absolute path (NSFS-only) to fail early on bad input.

-                    user_bucket_path: { type: 'string' }
+                    user_bucket_path: {
+                        type: 'string',
+                        minLength: 1,
+                        description: 'Absolute filesystem path for underlying bucket directory (NSFS only).',
+                        pattern: '^/'   // require absolute POSIX path
+                    }
src/endpoint/s3/ops/s3_put_bucket.js (1)

12-13: Normalize header key to lowercase before lookup

Node lowercases incoming header keys. If the header name is overridden via ENV, normalize toLowerCase to avoid mismatches. Based on learnings

-    const user_bucket_path = req.headers[config.NSFS_USER_BUCKET_PATH_HTTP_HEADER];
-    await req.object_sdk.create_bucket({ name: req.params.bucket, lock_enabled: lock_enabled, user_bucket_path: user_bucket_path });
+    const header_name = String(config.NSFS_USER_BUCKET_PATH_HTTP_HEADER || '').toLowerCase();
+    const user_bucket_path = typeof req.headers[header_name] === 'string'
+        ? req.headers[header_name].trim()
+        : undefined;
+    await req.object_sdk.create_bucket({
+        name: req.params.bucket,
+        lock_enabled,
+        user_bucket_path
+    });
src/test/integration_tests/nsfs/test_nsfs_integration.js (3)

383-401: Use the config constant for header name and reflect it in the test title

Avoid string drift and keep title accurate.

-    mocha.it('create s3 bucket with x-nsfs-bucket-path', async function() {
+    mocha.it(`create s3 bucket with ${config.NSFS_USER_BUCKET_PATH_HTTP_HEADER}`, async function() {
@@
-        s3_correct_uid_default_nsr.middlewareStack.add(
+        s3_correct_uid_default_nsr.middlewareStack.add(
             (next, context) => args => {
-                args.request.headers["x-nsfs-bucket-path"] = x_nsfs_bucket_path;
+                args.request.headers[config.NSFS_USER_BUCKET_PATH_HTTP_HEADER] = x_nsfs_bucket_path;
                 return next(args);
             },
             {
                 step: "finalizeRequest",
                 name: "addCustomHeader",
             }
         );

402-425: Fix typo in test name and reuse the config header constant

Title mentions x-mcg-bucket-path; should be the configured header. Reuse the constant to prevent drift.

-    mocha.it('create s3 bucket with x-mcg-bucket-path fail as directory exist', async function() {
+    mocha.it(`create s3 bucket with ${config.NSFS_USER_BUCKET_PATH_HTTP_HEADER} - fail if directory exists`, async function() {
@@
-                args.request.headers["x-nsfs-bucket-path"] = x_nsfs_bucket_path;
+                args.request.headers[config.NSFS_USER_BUCKET_PATH_HTTP_HEADER] = x_nsfs_bucket_path;
                 return next(args);

383-401: Add negative tests for path validation (relative/out-of-root)

Once validation is added, add cases that assert INVALID_REQUEST for relative paths and FORBIDDEN for paths outside new_buckets_path.

I can draft the additional test cases after you pick the exact errors to assert.

Also applies to: 402-425

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d75c6a and 1bf7a19.

📒 Files selected for processing (5)
  • config.js (1 hunks)
  • src/api/bucket_api.js (1 hunks)
  • src/endpoint/s3/ops/s3_put_bucket.js (1 hunks)
  • src/sdk/bucketspace_fs.js (1 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/integration_tests/nsfs/test_nsfs_integration.js
🧠 Learnings (2)
📚 Learning: 2025-08-08T13:08:38.361Z
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9182
File: src/server/system_services/bucket_server.js:1324-1327
Timestamp: 2025-08-08T13:08:38.361Z
Learning: In src/server/system_services/bucket_server.js, the update_all_buckets_default_pool(req) handler expects req.rpc_params.pool_name to be a plain string (not a SensitiveString wrapper), so calling .unwrap() is not needed there.

Applied to files:

  • src/endpoint/s3/ops/s3_put_bucket.js
📚 Learning: 2025-07-30T10:20:09.402Z
Learnt from: liranmauda
Repo: noobaa/noobaa-core PR: 9174
File: config.js:1044-1046
Timestamp: 2025-07-30T10:20:09.402Z
Learning: The NooBaa config.js file has a built-in environment variable override system via `load_config_env_overrides()` function. Any config property can be overridden using environment variables prefixed with `CONFIG_JS_`. For example, `CONFIG_JS_NC_HEALTH_BUCKETS_COUNT_LIMIT=10000` would override `config.NC_HEALTH_BUCKETS_COUNT_LIMIT`. The system handles type conversion automatically and provides consistent override patterns across all config values.

Applied to files:

  • config.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Build Noobaa Image
  • GitHub Check: run-jest-unit-tests
  • GitHub Check: run-package-lock-validation

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/endpoint/s3/ops/s3_put_bucket.js (1)

12-13: Consider adding defensive validation at the entry point.

Even if downstream validation exists, applying defense-in-depth principles by adding basic checks here would reduce the attack surface and provide clearer error messages:

 const user_bucket_path = req.headers[config.NSFS_USER_BUCKET_PATH_HTTP_HEADER];
+if (user_bucket_path !== undefined) {
+    if (typeof user_bucket_path !== 'string' || user_bucket_path.trim() === '') {
+        throw new S3Error(S3Error.InvalidArgument);
+    }
+    if (user_bucket_path.includes('\0') || user_bucket_path.includes('..')) {
+        throw new S3Error(S3Error.InvalidArgument);
+    }
+}
 await req.object_sdk.create_bucket({ name: req.params.bucket, lock_enabled: lock_enabled, user_bucket_path: user_bucket_path });

This provides basic sanitization while allowing comprehensive validation downstream.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1bf7a19 and bc8b718.

📒 Files selected for processing (5)
  • config.js (1 hunks)
  • src/api/bucket_api.js (1 hunks)
  • src/endpoint/s3/ops/s3_put_bucket.js (1 hunks)
  • src/sdk/bucketspace_fs.js (1 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • config.js
  • src/api/bucket_api.js
  • src/sdk/bucketspace_fs.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-08T13:08:38.361Z
Learnt from: naveenpaul1
Repo: noobaa/noobaa-core PR: 9182
File: src/server/system_services/bucket_server.js:1324-1327
Timestamp: 2025-08-08T13:08:38.361Z
Learning: In src/server/system_services/bucket_server.js, the update_all_buckets_default_pool(req) handler expects req.rpc_params.pool_name to be a plain string (not a SensitiveString wrapper), so calling .unwrap() is not needed there.

Applied to files:

  • src/endpoint/s3/ops/s3_put_bucket.js
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: run-jest-unit-tests
  • GitHub Check: run-package-lock-validation
  • GitHub Check: Build Noobaa Image

Comment on lines 308 to 309
const bucket_storage_path = params.user_bucket_path ||
path.join(sdk.requesting_account.nsfs_account_config.new_buckets_path, name);
Copy link
Member

@guymguym guymguym Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First - the term "user_bucket_path" is confusing - the user has a new_buckets_path where buckets gets created by default. So in this new feature we are actually allowing to override that path, which I would name as "custom_bucket_path".

Second - I think we need some minimal protection for the custom path - Otherwise the request might specify very sensitive paths in the host such as /etc or /root. We need to have some whitelist of paths that the custom_bucket_path is required to be a subpath of, this can be a config such as:

config.NSFS_CUSTOM_BUCKET_PATHS_WHITELIST = ['/ibm', '/gpfs']

I am even contemplating if we can restrict the custom paths to always be a subpath of the account's new_buckets_path to allow more flexibility in restricting every account to a specific subtree of the filesystem.

FYI @madhuthorat @jackyalbo @nimrod-becker

Copy link
Contributor Author

@jackyalbo jackyalbo Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We decided to go with two levels of allowed_bucket_paths. per system, using config.js:
config.NSFS_CUSTOM_BUCKET_PATH_ALLOWED_LIST = '/ibm1/:/ibm3/'
or as part of the account, nsfs_account_config, for example:

nsfs_account_config: {
        uid: 100,
        gid: 100,
        new_buckets_path: '/gpfs/new_buckets',
        nsfs_only: false,
        custom_bucket_path_allowed_list: `/gpfs1/:/gpfs2/`,
}

If it exists, the account's custom_bucket_path_allowed_list will override the system's one.
If neither does, we will drop the request with 'access denied'.
@guymguym @madhuthorat for any last feedback

@jackyalbo jackyalbo marked this pull request as draft November 11, 2025 09:33
@pull-request-size pull-request-size bot added size/L and removed size/M labels Nov 24, 2025
@jackyalbo jackyalbo force-pushed the jacky-nc-fixes branch 3 times, most recently from b982863 to 5f51d95 Compare November 24, 2025 14:28
@jackyalbo jackyalbo marked this pull request as ready for review November 24, 2025 15:06
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/cmd/manage_nsfs.js (1)

486-510: fs_backend empty-string deletion semantics are broken; fix confirmed

The issue is verified and accurate. Line 506 uses a truthiness check:

fs_backend: user_input.fs_backend ? String(user_input.fs_backend) : config.NSFS_NC_STORAGE_BACKEND,

This prevents empty strings from reaching the normalization at line 534 (data.nsfs_account_config.fs_backend = data.nsfs_account_config.fs_backend || undefined;), breaking the intended "deletion via empty string" behavior.

The bucket version (line 133) correctly uses an explicit undefined check, allowing empty strings through:

fs_backend: user_input.fs_backend === undefined ? config.NSFS_NC_STORAGE_BACKEND : String(user_input.fs_backend),

The custom_bucket_path_allowed_list at line 507 is handled correctly—it assigns directly and lets line 547's normalization handle falsy values.

Apply the suggested fix at line 506:

-            fs_backend: user_input.fs_backend ? String(user_input.fs_backend) : config.NSFS_NC_STORAGE_BACKEND,
+            fs_backend: user_input.fs_backend === undefined
+                ? config.NSFS_NC_STORAGE_BACKEND
+                : String(user_input.fs_backend),
🧹 Nitpick comments (3)
src/test/integration_tests/nsfs/test_nsfs_integration.js (3)

418-457: Happy-path test for custom bucket path + allowed-list is solid

Creating a dedicated account with custom_bucket_path_allowed_list including tmp_fs_root and then asserting that:

  • the bucket create succeeds when the header points under new_buckets_path, and
  • the filesystem path at x_nsfs_bucket_path exists

gives good end-to-end coverage that the allow-list is honored and the header path is actually used. As an optional cleanup, you could extract the repeated middleware wiring into a small helper to reduce duplication across these tests.

As per coding guidelines, the new behavior is covered by tests under src/test/**.


459-485: Directory-exists collision test for custom path behaves as expected

This test reuses the account with an allow-list to ensure:

  • creating a bucket with a custom path that already exists returns BucketAlreadyExists, and
  • no directory is created at the default new_buckets_path (when the header is present).

That correctly validates collision handling and that the header overrides the default location rather than falling back to it. For robustness and readability, consider using a single consistent pattern for building x_nsfs_bucket_path and no_x_nsfs_bucket_path (e.g., via path.join or a shared helper) to avoid relying on implicit trailing slashes in new_buckets_path.


486-508: Disallowed-prefix test is correct; comment could be clarified

The test correctly checks that:

  • using a custom path like /root/${bucket_name}-custom-path that is outside the account’s custom_bucket_path_allowed_list returns AccessDenied, and
  • the target path is not created on disk.

The inline comment on Line 489 ("already created in previous test") is misleading, since /root/... is intentionally not created earlier; cleaning that up would avoid future confusion. You might also align the path construction style here with the earlier tests for consistency.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bc8b718 and 9bbc2a5.

📒 Files selected for processing (13)
  • config.js (1 hunks)
  • src/api/account_api.js (1 hunks)
  • src/api/bucket_api.js (1 hunks)
  • src/api/common_api.js (1 hunks)
  • src/cmd/manage_nsfs.js (2 hunks)
  • src/endpoint/s3/ops/s3_put_bucket.js (1 hunks)
  • src/manage_nsfs/manage_nsfs_constants.js (3 hunks)
  • src/manage_nsfs/manage_nsfs_help_utils.js (2 hunks)
  • src/sdk/accountspace_fs.js (1 hunks)
  • src/sdk/bucketspace_fs.js (1 hunks)
  • src/server/system_services/schemas/nsfs_account_schema.js (2 hunks)
  • src/test/integration_tests/nsfs/test_nsfs_integration.js (3 hunks)
  • src/test/utils/coretest/nc_coretest.js (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/endpoint/s3/ops/s3_put_bucket.js
  • src/api/bucket_api.js
  • config.js
  • src/sdk/bucketspace_fs.js
🧰 Additional context used
📓 Path-based instructions (1)
src/test/**/*.*

⚙️ CodeRabbit configuration file

src/test/**/*.*: Ensure that the PR includes tests for the changes.

Files:

  • src/test/utils/coretest/nc_coretest.js
  • src/test/integration_tests/nsfs/test_nsfs_integration.js
🧠 Learnings (1)
📚 Learning: 2025-11-13T07:56:23.620Z
Learnt from: shirady
Repo: noobaa/noobaa-core PR: 9281
File: src/server/system_services/account_server.js:1053-1058
Timestamp: 2025-11-13T07:56:23.620Z
Learning: In noobaa-core, account_server.js is only used in containerized deployments, not in NSFS/NC deployments. NSFS/NC deployments have separate account management code in src/manage_nsfs/ directory. Therefore, account_server.js only processes accounts from account_schema.js where owner is an objectid reference, never from nsfs_account_schema.js where owner is a string.

Applied to files:

  • src/server/system_services/schemas/nsfs_account_schema.js
  • src/sdk/accountspace_fs.js
  • src/cmd/manage_nsfs.js
  • src/test/utils/coretest/nc_coretest.js
  • src/api/common_api.js
🧬 Code graph analysis (1)
src/api/common_api.js (16)
src/api/account_api.js (1)
  • SensitiveString (4-4)
src/cmd/manage_nsfs.js (1)
  • SensitiveString (25-25)
src/sdk/accountspace_fs.js (1)
  • SensitiveString (16-16)
src/sdk/bucketspace_fs.js (1)
  • SensitiveString (28-28)
src/test/integration_tests/nsfs/test_nsfs_integration.js (1)
  • SensitiveString (21-21)
src/test/utils/coretest/nc_coretest.js (1)
  • SensitiveString (10-10)
src/server/common_services/auth_server.js (1)
  • SensitiveString (12-12)
src/util/account_util.js (1)
  • SensitiveString (9-9)
src/server/system_services/bucket_server.js (1)
  • SensitiveString (14-14)
src/server/system_services/account_server.js (1)
  • SensitiveString (15-15)
src/server/system_services/schemas/account_schema.js (1)
  • SensitiveString (4-4)
src/server/system_services/schemas/bucket_schema.js (1)
  • SensitiveString (4-4)
src/sdk/config_fs.js (1)
  • SensitiveString (13-13)
src/cmd/nsfs.js (1)
  • SensitiveString (38-38)
src/endpoint/s3/ops/s3_get_bucket_logging.js (1)
  • SensitiveString (4-4)
src/server/system_services/tier_server.js (1)
  • SensitiveString (19-19)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: ceph-s3-tests / Ceph S3 Tests
  • GitHub Check: mint-nc-tests / Mint NC Tests
  • GitHub Check: mint-tests / Mint Tests
  • GitHub Check: run-nc-unit-tests / Non Containerized Unit Tests
  • GitHub Check: warp-nc-tests / Warp NC Tests
  • GitHub Check: warp-tests / Warp Tests
  • GitHub Check: ceph-nsfs-s3-tests / NSFS Ceph S3 Tests
  • GitHub Check: run-sanity-tests / Sanity Tests
  • GitHub Check: run-sanity-ssl-tests / Sanity SSL Tests
  • GitHub Check: run-unit-tests / Unit Tests
  • GitHub Check: run-unit-tests-postgres / Unit Tests with Postgres
  • GitHub Check: run-jest-unit-tests
🔇 Additional comments (11)
src/sdk/accountspace_fs.js (1)

590-613: Propagating custom_bucket_path_allowed_list to new users is consistent and safe

Copying custom_bucket_path_allowed_list from requesting_account.nsfs_account_config into new user defaults aligns with how other NSFS fields are propagated and ensures IAM users respect the same bucket-path policy as their owner.

src/api/account_api.js (1)

280-313: Schema extension for custom_bucket_path_allowed_list in update_account_s3_access looks correct

Adding custom_bucket_path_allowed_list to nsfs_account_config here matches the common_api and nsfs_account_schema definitions and keeps the update path in sync with account creation / manage_nsfs flows.

src/test/utils/coretest/nc_coretest.js (1)

327-343: Test helpers wiring custom_bucket_path_allowed_list into manage_nsfs CLI is aligned with runtime changes

Propagating nsfs_account_config.custom_bucket_path_allowed_list into the add/update account CLI options keeps the NC core tests compatible with the new field and allows exercising the allow-list behavior end‑to‑end.

Also applies to: 431-439

src/api/common_api.js (1)

1445-1469: nsfs_account_config schema now includes custom_bucket_path_allowed_list in both variants

Adding custom_bucket_path_allowed_list: { type: 'string' } to both nsfs_account_config oneOf branches is consistent with the rest of the PR (account_api, nsfs_account_schema, manage_nsfs) and maintains backward compatibility since it’s not required.

src/server/system_services/schemas/nsfs_account_schema.js (1)

77-105: NSFS account schema aligned with new custom_bucket_path_allowed_list property

Including custom_bucket_path_allowed_list in both nsfs_account_config shapes keeps the on‑disk schema compatible with the updated common/account APIs and manage_nsfs tooling; the field is optional, so existing accounts remain valid.

src/test/integration_tests/nsfs/test_nsfs_integration.js (3)

2-2: Eslint max-lines override is reasonable

Raising max-lines to 3000 is consistent with the current file size (~2500 lines) and avoids spurious lint failures without behavioral impact.


84-91: New S3 client variable for custom bucket-path tests is scoped correctly

let s3_correct_uid_bucket_path; is in the same scope as the other S3 clients and used only in the new custom-bucket-path tests, so there’s no leakage or shadowing risk.


393-416: Negative test for header without allowed-list looks correct

This test validates that using config.NSFS_CUSTOM_BUCKET_PATH_HTTP_HEADER without configuring custom_bucket_path_allowed_list on the account yields AccessDenied and does not create the target directory, which matches the intended security behavior.

src/manage_nsfs/manage_nsfs_help_utils.js (2)

133-147: Add-account help for --custom_bucket_path_allowed_list is aligned with semantics

The new flag description clearly conveys that the value is a colon-separated list of allowed custom bucket paths and uses the same option name as the internal wiring (custom_bucket_path_allowed_list), so users will discover the feature via account add --help.


160-175: Update-account help correctly documents override/unset behavior

The update flag text explains that --custom_bucket_path_allowed_list overrides the existing list and can be unset with '', which matches how UNSETTABLE options are handled in the constants. This keeps CLI behavior and help in sync.

src/manage_nsfs/manage_nsfs_constants.js (1)

48-54: CLI wiring for custom_bucket_path_allowed_list is consistent and complete

Including custom_bucket_path_allowed_list in:

  • VALID_OPTIONS_ACCOUNT.add / .update,
  • OPTION_TYPE as a 'string', and
  • UNSETTABLE_OPTIONS_OBJ with CLI_EMPTY_STRING

ensures the new flag is accepted for account add/update, typed correctly, and can be unset via '' as documented in the help. This lines up cleanly with the account schema and CLI help text for the feature.

Also applies to: 119-127, 193-201

@nimrod-becker
Copy link
Contributor

@nadavMiz if you could take a look please

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants