diff --git a/docs/en/settings/configuring-xes.asciidoc b/docs/en/settings/configuring-xes.asciidoc index b12969b772e..d13efc55190 100644 --- a/docs/en/settings/configuring-xes.asciidoc +++ b/docs/en/settings/configuring-xes.asciidoc @@ -11,3 +11,4 @@ include::ml-settings.asciidoc[] include::monitoring-settings.asciidoc[] include::security-settings.asciidoc[] include::notification-settings.asciidoc[] +include::sql-settings.asciidoc[] diff --git a/docs/en/settings/sql-settings.asciidoc b/docs/en/settings/sql-settings.asciidoc new file mode 100644 index 00000000000..52e11d30989 --- /dev/null +++ b/docs/en/settings/sql-settings.asciidoc @@ -0,0 +1,17 @@ +[role="xpack"] +[[sql-settings]] +=== SQL Access Settings in Elasticsearch +++++ +SQL Access Settings +++++ + +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. + + diff --git a/plugin/src/main/java/org/elasticsearch/xpack/XPackPlugin.java b/plugin/src/main/java/org/elasticsearch/xpack/XPackPlugin.java index f5d8a1274bd..9f21ae16e51 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/XPackPlugin.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/XPackPlugin.java @@ -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); diff --git a/plugin/src/main/java/org/elasticsearch/xpack/XPackSettings.java b/plugin/src/main/java/org/elasticsearch/xpack/XPackSettings.java index d29e1cf3f46..5dd6308d51e 100644 --- a/plugin/src/main/java/org/elasticsearch/xpack/XPackSettings.java +++ b/plugin/src/main/java/org/elasticsearch/xpack/XPackSettings.java @@ -76,6 +76,9 @@ public class XPackSettings { } }, Setting.Property.NodeScope); + /** Setting for enabling or disabling sql. Defaults to true. */ + public static final Setting 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); } } diff --git a/plugin/src/test/java/org/elasticsearch/xpack/sql/SqlDisabledIT.java b/plugin/src/test/java/org/elasticsearch/xpack/sql/SqlDisabledIT.java new file mode 100644 index 00000000000..6b9b1f346a9 --- /dev/null +++ b/plugin/src/test/java/org/elasticsearch/xpack/sql/SqlDisabledIT.java @@ -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 + } +} + diff --git a/sql/server/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java b/sql/server/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java index ff79acc2180..d0d9477f2d4 100644 --- a/sql/server/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java +++ b/sql/server/src/main/java/org/elasticsearch/xpack/sql/plugin/SqlPlugin.java @@ -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 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 createComponents(Client client, ClusterService clusterService, @Nullable FilteredCatalog.Filter catalogFilter) { + if (false == enabled) { + return emptyList(); + } Function 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 getRestHandlers(Settings settings, RestController restController, ClusterSettings clusterSettings, IndexScopedSettings indexScopedSettings, SettingsFilter settingsFilter, IndexNameExpressionResolver indexNameExpressionResolver, Supplier 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> 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)); diff --git a/sql/server/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlPluginTests.java b/sql/server/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlPluginTests.java new file mode 100644 index 00000000000..d2b480525a4 --- /dev/null +++ b/sql/server/src/test/java/org/elasticsearch/xpack/sql/plugin/SqlPluginTests.java @@ -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()); + } + +}