SQL: introduce setting to disable SQL (elastic/x-pack-elasticsearch#2966)

Adds xpack.sql.enabled setting to provide ability to disable SQL on elasticsearch nodes.

relates elastic/x-pack-elasticsearch#2872

Original commit: elastic/x-pack-elasticsearch@d13b72e9ea
This commit is contained in:
Igor Motov 2017-11-13 15:10:47 -05:00 committed by GitHub
parent 774f423d9e
commit ea0e58f971
7 changed files with 117 additions and 3 deletions

View File

@ -11,3 +11,4 @@ include::ml-settings.asciidoc[]
include::monitoring-settings.asciidoc[]
include::security-settings.asciidoc[]
include::notification-settings.asciidoc[]
include::sql-settings.asciidoc[]

View File

@ -0,0 +1,17 @@
[role="xpack"]
[[sql-settings]]
=== SQL Access Settings in Elasticsearch
++++
<titleabbrev>SQL Access Settings</titleabbrev>
++++
SQL Access is enabled by default when you install {xpack}. You can configure
these SQL Access settings in the `elasticsearch.yml` file.
[float]
[[general-sql-settings]]
==== General SQL Access Settings
`xpack.sql.enabled`::
Set to `false` to disable SQL Access on the node.

View File

@ -244,7 +244,7 @@ public class XPackPlugin extends Plugin implements ScriptPlugin, ActionPlugin, I
this.deprecation = new Deprecation();
this.upgrade = new Upgrade(settings);
// sql projects don't depend on x-pack and as a result we cannot pass XPackLicenseState object to SqlPlugin directly here
this.sql = new SqlPlugin(new SqlLicenseChecker(
this.sql = new SqlPlugin(XPackSettings.SQL_ENABLED.get(settings), new SqlLicenseChecker(
() -> {
if (!licenseState.isSqlAllowed()) {
throw LicenseUtils.newComplianceException(XPackPlugin.SQL);

View File

@ -76,6 +76,9 @@ public class XPackSettings {
}
}, Setting.Property.NodeScope);
/** Setting for enabling or disabling sql. Defaults to true. */
public static final Setting<Boolean> SQL_ENABLED = Setting.boolSetting("xpack.sql.enabled", true, Setting.Property.NodeScope);
/*
* SSL settings. These are the settings that are specifically registered for SSL. Many are private as we do not explicitly use them
* but instead parse based on a prefix (eg *.ssl.*)
@ -138,6 +141,7 @@ public class XPackSettings {
settings.add(HTTP_SSL_ENABLED);
settings.add(RESERVED_REALM_ENABLED_SETTING);
settings.add(TOKEN_SERVICE_ENABLED_SETTING);
settings.add(SQL_ENABLED);
return Collections.unmodifiableList(settings);
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.xpack.XPackSettings;
import org.elasticsearch.xpack.sql.plugin.sql.action.SqlAction;
import static org.hamcrest.CoreMatchers.either;
import static org.hamcrest.CoreMatchers.startsWith;
public class SqlDisabledIT extends AbstractSqlIntegTestCase {
@Override
protected Settings nodeSettings(int nodeOrdinal) {
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put(XPackSettings.SQL_ENABLED.getKey(), false)
.build();
}
@Override
protected Settings transportClientSettings() {
return Settings.builder()
.put(super.transportClientSettings())
.put(XPackSettings.SQL_ENABLED.getKey(), randomBoolean())
.build();
}
public void testSqlAction() throws Exception {
Throwable throwable = expectThrows(Throwable.class,
() -> client().prepareExecute(SqlAction.INSTANCE).query("SHOW tables").get());
assertThat(throwable.getMessage(),
either(startsWith("no proxy found for action")) // disabled on client
.or(startsWith("failed to find action")) // disabled on proxy client
.or(startsWith("No handler for action [indices:data/read/sql]"))); // disabled on server
}
}

View File

@ -37,6 +37,8 @@ import java.util.List;
import java.util.function.Function;
import java.util.function.Supplier;
import static java.util.Collections.emptyList;
public class SqlPlugin implements ActionPlugin {
public static List<NamedWriteableRegistry.Entry> getNamedWriteables() {
return Cursor.getNamedWriteables();
@ -44,8 +46,11 @@ public class SqlPlugin implements ActionPlugin {
private final SqlLicenseChecker sqlLicenseChecker;
public SqlPlugin(SqlLicenseChecker sqlLicenseChecker) {
private final boolean enabled;
public SqlPlugin(boolean enabled, SqlLicenseChecker sqlLicenseChecker) {
this.sqlLicenseChecker = sqlLicenseChecker;
this.enabled = enabled;
}
/**
@ -54,6 +59,9 @@ public class SqlPlugin implements ActionPlugin {
*/
public Collection<Object> createComponents(Client client, ClusterService clusterService,
@Nullable FilteredCatalog.Filter catalogFilter) {
if (false == enabled) {
return emptyList();
}
Function<ClusterState, Catalog> catalog = EsCatalog::new;
if (catalogFilter != null) {
catalog = catalog.andThen(c -> new FilteredCatalog(c, catalogFilter));
@ -68,7 +76,9 @@ public class SqlPlugin implements ActionPlugin {
public List<RestHandler> getRestHandlers(Settings settings, RestController restController,
ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter,
IndexNameExpressionResolver indexNameExpressionResolver, Supplier<DiscoveryNodes> nodesInCluster) {
if (false == enabled) {
return emptyList();
}
return Arrays.asList(new RestSqlAction(settings, restController),
new SqlTranslateAction.RestAction(settings, restController),
new RestSqlCliAction(settings, restController),
@ -77,6 +87,9 @@ public class SqlPlugin implements ActionPlugin {
@Override
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
if (false == enabled) {
return emptyList();
}
return Arrays.asList(new ActionHandler<>(SqlAction.INSTANCE, TransportSqlAction.class),
new ActionHandler<>(SqlGetIndicesAction.INSTANCE, SqlGetIndicesAction.TransportAction.class),
new ActionHandler<>(SqlTranslateAction.INSTANCE, SqlTranslateAction.TransportAction.class));

View File

@ -0,0 +1,37 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
package org.elasticsearch.xpack.sql.plugin;
import org.elasticsearch.client.Client;
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
import org.elasticsearch.cluster.node.DiscoveryNodes;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.IndexScopedSettings;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.settings.SettingsFilter;
import org.elasticsearch.rest.RestController;
import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.xpack.sql.analysis.catalog.FilteredCatalog;
import java.util.Collections;
import static org.hamcrest.Matchers.empty;
import static org.mockito.Mockito.mock;
public class SqlPluginTests extends ESTestCase {
public void testSqlDisabled() {
SqlPlugin plugin = new SqlPlugin(false, new SqlLicenseChecker(() -> {}, () -> {}));
assertThat(plugin.createComponents(mock(Client.class), mock(ClusterService.class), mock(FilteredCatalog.Filter.class)), empty());
assertThat(plugin.getActions(), empty());
assertThat(plugin.getRestHandlers(Settings.EMPTY, mock(RestController.class),
new ClusterSettings(Settings.EMPTY, ClusterSettings.BUILT_IN_CLUSTER_SETTINGS),
IndexScopedSettings.DEFAULT_SCOPED_SETTINGS, new SettingsFilter(Settings.EMPTY, Collections.emptyList()),
mock(IndexNameExpressionResolver.class), () -> mock(DiscoveryNodes.class)), empty());
}
}