Skip to content

Commit

Permalink
[Backport 2.7] Manual Backport of Dynamic tenancy configurations (#2693
Browse files Browse the repository at this point in the history
…) (#2696)

* Manual Backport of Dynamic tenancy configurations
Signed-off-by: Stephen Crawford <[email protected]>
Signed-off-by: Abhi Kalra <[email protected]>

Co-authored-by: Stephen Crawford <[email protected]>
  • Loading branch information
RyanL1997 and stephen-crawford authored Apr 18, 2023
1 parent f0340b5 commit f79faec
Show file tree
Hide file tree
Showing 65 changed files with 1,007 additions and 74 deletions.
2 changes: 2 additions & 0 deletions config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ config:
#kibana:
# Kibana multitenancy
#multitenancy_enabled: true
#private_tenant_enabled: true
#default_tenant: ""
#server_username: kibanaserver
#index: '.kibana'
http:
Expand Down
1 change: 1 addition & 0 deletions legacy/securityconfig_v6/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ opendistro_security:
#filtered_alias_mode: warn
#kibana:
#multitenancy_enabled: true

#server_username: kibanaserver
#index: '.kibana'
#do_not_fail_on_forbidden: false
Expand Down
96 changes: 52 additions & 44 deletions src/main/java/org/opensearch/security/OpenSearchSecurityPlugin.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.action.tenancy;

import java.io.IOException;

import org.opensearch.action.ActionRequest;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.common.io.stream.StreamInput;

public class EmptyRequest extends ActionRequest {

public EmptyRequest(final StreamInput in) throws IOException {
super(in);
}

public EmptyRequest() throws IOException {
super();
}

@Override
public ActionRequestValidationException validate()
{
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.action.tenancy;

import java.io.IOException;
import java.util.List;

import com.google.common.collect.ImmutableList;

import org.opensearch.client.node.NodeClient;
import org.opensearch.rest.BaseRestHandler;
import org.opensearch.rest.RestRequest;
import org.opensearch.rest.action.RestToXContentListener;

import static org.opensearch.rest.RestRequest.Method.GET;
import static org.opensearch.rest.RestRequest.Method.PUT;

public class TenancyConfigRestHandler extends BaseRestHandler {

public TenancyConfigRestHandler() {
super();
}

@Override
public String getName() {
return "Multi Tenancy actions to Retrieve / Update configs.";
}

@Override
public List<Route> routes() {
return ImmutableList.of(
new Route(GET, "/_plugins/_security/api/tenancy/config"),
new Route(PUT, "/_plugins/_security/api/tenancy/config")
);
}

@Override
protected RestChannelConsumer prepareRequest(final RestRequest request, final NodeClient nodeClient) throws IOException {

switch (request.method()) {
case GET:
return channel -> nodeClient.execute(
TenancyConfigRetrieveActions.INSTANCE,
new EmptyRequest(),
new RestToXContentListener<>(channel));
case PUT:
return channel -> nodeClient.execute(
TenancyConfigUpdateAction.INSTANCE,
TenancyConfigUpdateRequest.fromXContent(request.contentParser()),
new RestToXContentListener<>(channel));
default:
throw new RuntimeException("Not implemented");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.action.tenancy;

import org.opensearch.action.ActionType;

public class TenancyConfigRetrieveActions extends ActionType<TenancyConfigRetrieveResponse> {

public static final TenancyConfigRetrieveActions INSTANCE = new TenancyConfigRetrieveActions();
public static final String NAME = "cluster:feature/tenancy/config/read";

protected TenancyConfigRetrieveActions() {
super(NAME, TenancyConfigRetrieveResponse::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.action.tenancy;

import java.io.IOException;

import org.opensearch.action.ActionResponse;
import org.opensearch.common.Strings;
import org.opensearch.common.io.stream.StreamInput;
import org.opensearch.common.io.stream.StreamOutput;
import org.opensearch.common.xcontent.XContentType;
import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;

public class TenancyConfigRetrieveResponse extends ActionResponse implements ToXContentObject {

public TenancyConfigs tenancyConfigs = new TenancyConfigs();

public TenancyConfigRetrieveResponse(final StreamInput in) throws IOException {
super(in);
this.tenancyConfigs.multitenancy_enabled = in.readOptionalBoolean();
this.tenancyConfigs.private_tenant_enabled = in.readOptionalBoolean();
this.tenancyConfigs.default_tenant = in.readOptionalString();
}

public TenancyConfigRetrieveResponse(final TenancyConfigs tenancyConfigs) {
this.tenancyConfigs = tenancyConfigs;
}

public TenancyConfigs getMultitenancyConfig() {
return tenancyConfigs;
}

public Boolean getMultitenancyEnabled() { return tenancyConfigs.multitenancy_enabled; }

public Boolean getPrivateTenantEnabled() { return tenancyConfigs.private_tenant_enabled; }

public String getDefaultTenant() { return tenancyConfigs.default_tenant; }

@Override
public void writeTo(final StreamOutput out) throws IOException {
out.writeBoolean(getMultitenancyEnabled());
out.writeBoolean(getPrivateTenantEnabled());
out.writeString(getDefaultTenant());
}

@Override
public String toString() {
return Strings.toString(XContentType.JSON, this, true, true);
}

@Override
public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
builder.startObject();
builder.field("multitenancy_enabled", getMultitenancyEnabled());
builder.field("private_tenant_enabled", getPrivateTenantEnabled());
builder.field("default_tenant", getDefaultTenant());
builder.endObject();
return builder;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.action.tenancy;

import java.util.Collections;

import org.opensearch.action.ActionListener;
import org.opensearch.action.support.ActionFilters;
import org.opensearch.action.support.HandledTransportAction;
import org.opensearch.common.inject.Inject;
import org.opensearch.common.settings.Settings;
import org.opensearch.security.configuration.ConfigurationRepository;
import org.opensearch.security.securityconf.impl.CType;
import org.opensearch.security.securityconf.impl.SecurityDynamicConfiguration;
import org.opensearch.security.securityconf.impl.v7.ConfigV7;
import org.opensearch.tasks.Task;
import org.opensearch.transport.TransportService;

public class TenancyConfigRetrieveTransportAction
extends HandledTransportAction<EmptyRequest, TenancyConfigRetrieveResponse> {

private final ConfigurationRepository config;

@Inject
public TenancyConfigRetrieveTransportAction(final Settings settings,
final TransportService transportService,
final ActionFilters actionFilters,
final ConfigurationRepository config) {
super(TenancyConfigRetrieveActions.NAME, transportService, actionFilters, EmptyRequest::new);

this.config = config;
}

/** Load the configuration from the security index and return a copy */
protected final SecurityDynamicConfiguration<?> load() {
return config.getConfigurationsFromIndex(Collections.singleton(CType.CONFIG), false).get(CType.CONFIG).deepClone();
}

@Override
protected void doExecute(final Task task, final EmptyRequest request, final ActionListener<TenancyConfigRetrieveResponse> listener) {

// Get the security configuration and lookup the config setting state
final SecurityDynamicConfiguration<?> dynamicConfig = load();
ConfigV7 config = (ConfigV7)dynamicConfig.getCEntry("config");

final TenancyConfigs tenancyConfigs= new TenancyConfigs();

tenancyConfigs.multitenancy_enabled = config.dynamic.kibana.multitenancy_enabled;
tenancyConfigs.private_tenant_enabled = config.dynamic.kibana.private_tenant_enabled;
tenancyConfigs.default_tenant = config.dynamic.kibana.default_tenant;

listener.onResponse(new TenancyConfigRetrieveResponse(tenancyConfigs));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.action.tenancy;

import org.opensearch.action.ActionType;

public class TenancyConfigUpdateAction extends ActionType<TenancyConfigRetrieveResponse> {

public static final TenancyConfigUpdateAction INSTANCE = new TenancyConfigUpdateAction();
public static final String NAME = "cluster:feature/tenancy/config/update";


protected TenancyConfigUpdateAction()
{
super(NAME, TenancyConfigRetrieveResponse::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*
* Modifications Copyright OpenSearch Contributors. See
* GitHub history for details.
*/

package org.opensearch.security.action.tenancy;
import java.io.IOException;

import org.opensearch.action.ActionRequest;
import org.opensearch.action.ActionRequestValidationException;
import org.opensearch.common.io.stream.StreamInput;
import org.opensearch.core.ParseField;
import org.opensearch.core.xcontent.ConstructingObjectParser;
import org.opensearch.core.xcontent.XContentParser;

public class TenancyConfigUpdateRequest extends ActionRequest {

private TenancyConfigs tenancyConfigs = new TenancyConfigs();

public TenancyConfigUpdateRequest(final StreamInput in) throws IOException {
super(in);
in.readOptionalBoolean();
in.readOptionalBoolean();
in.readOptionalString();
}

public TenancyConfigUpdateRequest(final Boolean multitenancy_enabled, final Boolean private_tenant_enabled, final String default_tenant) {
super();
this.tenancyConfigs.multitenancy_enabled = multitenancy_enabled;
this.tenancyConfigs.private_tenant_enabled = private_tenant_enabled;
this.tenancyConfigs.default_tenant = default_tenant;
}

public TenancyConfigs getTenancyConfigs() {
return tenancyConfigs;
}

@Override
public ActionRequestValidationException validate() {
if (getTenancyConfigs() == null) {
final ActionRequestValidationException validationException = new ActionRequestValidationException();
validationException.addValidationError("Missing tenancy configs");
return validationException;
}
return null;
}

private static final ConstructingObjectParser<TenancyConfigUpdateRequest, Void> PARSER = new ConstructingObjectParser<>(
TenancyConfigUpdateRequest.class.getName(),
args -> new TenancyConfigUpdateRequest((Boolean)args[0], (Boolean) args[1], (String) args[2])
);

static {
PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), new ParseField("multitenancy_enabled"));
PARSER.declareBoolean(ConstructingObjectParser.optionalConstructorArg(), new ParseField("private_tenant_enabled"));
PARSER.declareString(ConstructingObjectParser.optionalConstructorArg(), new ParseField("default_tenant"));

}

public static TenancyConfigUpdateRequest fromXContent(final XContentParser parser) {
return PARSER.apply(parser, null);
}
}
Loading

0 comments on commit f79faec

Please sign in to comment.