-
Notifications
You must be signed in to change notification settings - Fork 292
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dynamic tenancy configurations #2607
Dynamic tenancy configurations #2607
Conversation
|
||
final HttpResponse getSettingResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/api/tenancy/default_tenant", asAdminUser); | ||
assertThat(getSettingResponse.getStatusCode(), equalTo(HttpStatus.SC_OK)); | ||
assertThat(getSettingResponse.findValueInJson("value"), equalTo("")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Can we read ""
from a constant for Global tenant instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for iterating on this @abhivka7 huge improvement. Many comments on here, but most of these should be fairly straight forward. Let me know if you need help.
Another area I'd like us to shine some visibility on is the permission names and the REST API paths. Can you enumerate those in a comment and walk through them?
From the draft pull request there was a lot of back and forth and those permissions / paths never really gelled, lets make sure we nail these down since we will have to live with them for a long time.
src/main/java/org/opensearch/security/rest/SecurityInfoAction.java
Outdated
Show resolved
Hide resolved
@@ -525,6 +525,15 @@ public boolean multitenancyEnabled() { | |||
&& dcm.isDashboardsMultitenancyEnabled(); | |||
} | |||
|
|||
public boolean privateTenantEnabled() { | |||
return privilegesInterceptor.getClass() != PrivilegesInterceptor.class |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have context on what this check? IMO I don't see any reason we need to restrict these results based on PrivilegesInterceptor used to construct this class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@peternied I don't have much context on why we are using this check. But the function above (multitenancyEnabled) is using the same check that's why I thought of using it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as this is exercised in end to end tests, ok.
src/main/java/org/opensearch/security/action/tenancy/DefaultTenantRestHandler.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/action/tenancy/DefaultTenantRestHandler.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/action/tenancy/DefaultTenantRestHandler.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/action/tenancy/PrivateTenantEnabledRestHandler.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/action/tenancy/StringSettingUpdateRequest.java
Outdated
Show resolved
Hide resolved
src/test/java/org/opensearch/security/multitenancy/test/TenancyDefaultTenantTests.java
Outdated
Show resolved
Hide resolved
assertThat(getSettingResponseAfterUpdate.getStatusCode(), equalTo(HttpStatus.SC_OK)); | ||
assertThat(getSettingResponseAfterUpdate.findValueInJson("value"), equalTo("Private")); | ||
|
||
getAuthinfoResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/authinfo", asAdminUser); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
End to end test should replicate the workflow that is used by dashboards. If we just call the config APIs / confirm we are reading out the same value we put in it only indicates that the config was updated not that the users are seeing the correct behavior.
Same issue for the TenancyPrivateTenantEnabledTests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Those tests will be covered in Security Dashboards plugin PR. Anyways the Dashboards also will be calling this API (DashboardsInfo) as replicated in test to get final config so that should be fine.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need the end to end coverage of this scenarios in the security plugin. Otherwise breaking changes could be make in this repo.
The example from TenancyMultitenancyEnabledTests.java shows how when the feature is activated behavior changes, please use this as a starting point. Let me know if you need help to test these scenarios.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have added that for TenancyPrivateTenantEnabledTests. Not sure what else to add for Default tenant tests. What test scenario are you thinking @peternied ?
src/test/java/org/opensearch/security/multitenancy/test/TenancyPrivateTenantEnabledTests.java
Outdated
Show resolved
Hide resolved
@abhivka7 We are using separate Rest Actions for every configuration being added as part of this PR like Since these are individual properties, the approach will require adding multiple classes for every property added in the future as well. This will in-turn end up increasing the metaspace of OS JVM. Can we try an approach where separate endpoints/routes are not required for every property ? |
@anijain-Amazon Thanks for the comments, data consistency was a considerable trade-offs with the previous iteration that used a single API, see the discussion in #2444. We've got an issue centered around granular access of security config, we would welcome your feedback in this space.
This is a good consideration. Is this an immediate issue, can you quantify the severity? I expect all OpenSearch components + plugins + extensions to be impacting the memory usage of OpenSearch as we incorporate more features. I don't see an issue in the OpenSearch repo, could you create one? |
I could see the comments in previous iteration are w.r.t. using a new document vs reusing the existing security config document. Didn't find anything mentioning the flaws of using a single API. Having separate APIs for every property requires the users/clients to take the overhead of ensuring transaction while updating multiple properties OR consider the drawbacks of having partial failures. For instance, if a user wants to update
Ack will take a look into it. This should help bring more flexibility for OpenSearch users to control admin privileges.
My concern is how will this approach scale with more properties in future. From a quick glance at this PR, it looks like we are adding at least 3 classes per property which can be simplified. Although, this will immediately not affect OpenSearch but will sure eat up the JVM Metaspace in future with say like 30-50 properties requiring 60-150 classes for updating their settings. |
Since the classes are statically referenced, I expect OpenSearch will detect any increase in its JVM Metaspace while running performance tests and adjust it's xmS and xmX accordingly. |
This PR should have v2.7.0 label on this PR? @peternied can you help please? |
Thanks a lot @anijain-Amazon for bringing this up. After a lot of considerations and POC, I have decided to move to a single API model for cleaner user experience and better metaspace utilisation. I will raise a new revision with that approach. Please take a look and give your feedbacks. |
b54d66f
to
b6f70da
Compare
0d0c7e4
to
9009e30
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring looks good, notable callouts:
- API / permissions naming needs iteration, I've made suggestions, but product team might need to be engaged.
- Need end to end verification in the test cases. Cannot depend on test cases in other repositories.
- Looks like many test cases are broken. Check the CI results.
|
||
package org.opensearch.security.action.tenancy; | ||
|
||
public class MultiTenancyConfigurations { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like it can be removed as the object isn't serialized/deserialized directly, replace it with using Request/Response classes with fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going forward we want to contribute more to tenancy in OpenSearch and therefore add new properties. It makes more sense to have an object for same for better accessibility and keeping everything together in a structured form.
src/main/java/org/opensearch/security/action/tenancy/MultiTenancyConfigurationsRestHandler.java
Outdated
Show resolved
Hide resolved
...n/java/org/opensearch/security/action/tenancy/MultiTenancyConfigurationsRetrieveActions.java
Outdated
Show resolved
Hide resolved
src/main/java/org/opensearch/security/action/tenancy/MultiTenancyConfigurationsRestHandler.java
Outdated
Show resolved
Hide resolved
...main/java/org/opensearch/security/action/tenancy/MultiTenancyConfigurationsUpdateAction.java
Outdated
Show resolved
Hide resolved
.../org/opensearch/security/action/tenancy/MultiTenancyConfigurationsUpdateTransportAction.java
Outdated
Show resolved
Hide resolved
@@ -525,6 +525,15 @@ public boolean multitenancyEnabled() { | |||
&& dcm.isDashboardsMultitenancyEnabled(); | |||
} | |||
|
|||
public boolean privateTenantEnabled() { | |||
return privilegesInterceptor.getClass() != PrivilegesInterceptor.class |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as this is exercised in end to end tests, ok.
src/main/java/org/opensearch/security/action/tenancy/EmptyRequest.java
Outdated
Show resolved
Hide resolved
assertThat(getSettingResponseAfterUpdate.getStatusCode(), equalTo(HttpStatus.SC_OK)); | ||
assertThat(getSettingResponseAfterUpdate.findValueInJson("value"), equalTo("Private")); | ||
|
||
getAuthinfoResponse = nonSslRestHelper().executeGetRequest("/_plugins/_security/authinfo", asAdminUser); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need the end to end coverage of this scenarios in the security plugin. Otherwise breaking changes could be make in this repo.
The example from TenancyMultitenancyEnabledTests.java shows how when the feature is activated behavior changes, please use this as a starting point. Let me know if you need help to test these scenarios.
src/test/java/org/opensearch/security/multitenancy/test/TenancyDefaultTenantTests.java
Show resolved
Hide resolved
c843cd6
to
51e1148
Compare
Signed-off-by: Abhi Kalra <[email protected]>
6e7daa7
to
bfbe371
Compare
Set<String> availableTenants = getAllConfiguredTenantNames(); | ||
|
||
if(!availableTenants.contains(updatedConfig.dynamic.kibana.default_tenant)){ | ||
throw new IllegalArgumentException(updatedConfig.dynamic.kibana.default_tenant + " can not be set to default tenant. Default tenant should be selected from one of the available tenants."); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Intentionally not adding the availableTenants
in the logs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @abhivka7, I see that a few of my questions got answered. Reviewing the remaining ones and the state of the PR, I am fine to merge this without any further conversation. Thank you for the contribution and being so quick to respond throughout. Great job!
Thanks @peternied and @scrawfor99 for reviewing and merging this PR. Also thanks @prabhat-chaturvedi @anijain-Amazon @devardee @shikharj05 @cliu123 for helping with this feature. |
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]>
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]>
The backport to
To backport manually, run these commands in your terminal: # Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add .worktrees/backport-2.x 2.x
# Navigate to the new working tree
cd .worktrees/backport-2.x
# Create a new branch
git switch --create backport/backport-2607-to-2.x
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x --mainline 1 9fca0dae5c1e3fe4746381d9f87c4d4abb0f0fda
# Push it to GitHub
git push --set-upstream origin backport/backport-2607-to-2.x
# Go back to the original working tree
cd ../..
# Delete the working tree
git worktree remove .worktrees/backport-2.x Then, create a pull request where the |
The backport to
To backport manually, run these commands in your terminal: # Fetch latest updates from GitHub
git fetch
# Create a new working tree
git worktree add .worktrees/backport-2.7 2.7
# Navigate to the new working tree
cd .worktrees/backport-2.7
# Create a new branch
git switch --create backport/backport-2607-to-2.7
# Cherry-pick the merged commit of this pull request and resolve the conflicts
git cherry-pick -x --mainline 1 9fca0dae5c1e3fe4746381d9f87c4d4abb0f0fda
# Push it to GitHub
git push --set-upstream origin backport/backport-2607-to-2.7
# Go back to the original working tree
cd ../..
# Delete the working tree
git worktree remove .worktrees/backport-2.7 Then, create a pull request where the |
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]>
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]>
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]> Signed-off-by: Maciej Mierzwa <[email protected]>
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]> Signed-off-by: Maciej Mierzwa <[email protected]>
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]> Signed-off-by: Maciej Mierzwa <[email protected]>
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]> Signed-off-by: Maciej Mierzwa <[email protected]>
Signed-off-by: Abhi Kalra <[email protected]> Co-authored-by: Abhi Kalra <[email protected]> Signed-off-by: Sam <[email protected]>
Description
These changes are required to dynamically enable/disable multi-tenancy, private tenant and set a default tenant.
Earlier users had to change YAML files in each node and restart node to enable/disable multi-tenancy and private tenant. With our changes, users will be able to change these settings dynamically. We will also give admins the option to set a default tenant for all users for first time log in.
More details can be found here:
[RFC] Dynamically Configurable Tenancy Feature OpenSearch#5853
[FEATURE] Enable/Disable Multi-Tenancy, Private Tenant and set Default Tenant in OS Dashboards. security-dashboards-plugin#1302
Previous PR for the same issue: #2444
Issues Resolved
opensearch-project/security-dashboards-plugin#1302
Is this a backport? If so, please add backport PR # and/or commits #
Nope
Testing
We have done manual testing for all changes on our local server. We have also unit tests for our api changes.
Check List
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
For more information on following Developer Certificate of Origin and signing off your commits, please check here.