Add autoscaling API skelton (#51564)
The main purpose of this commit is to add a single autoscaling REST endpoint skeleton, for the purpose of starting to build out the build and testing infrastructure that will surround it. For example, rather than commiting a fully-functioning autoscaling API, we introduce here the skeleton so that we can start wiring up the build and testing infrastructure, establish security roles/permissions, an so on. This way, in a forthcoming PR that introduces actual functionality, that PR will be smaller and have less distractions around that sort of infrastructure.
This commit is contained in:
parent
488944f4a1
commit
25daf5f1e1
|
@ -318,6 +318,7 @@ public final class Role {
|
|||
public static final String MANAGE_OIDC = "manage_oidc";
|
||||
public static final String MANAGE_TOKEN = "manage_token";
|
||||
public static final String MANAGE_PIPELINE = "manage_pipeline";
|
||||
public static final String MANAGE_AUTOSCALING = "manage_autoscaling";
|
||||
public static final String MANAGE_CCR = "manage_ccr";
|
||||
public static final String READ_CCR = "read_ccr";
|
||||
public static final String MANAGE_ILM = "manage_ilm";
|
||||
|
@ -326,8 +327,8 @@ public final class Role {
|
|||
public static final String[] ALL_ARRAY = new String[] { NONE, ALL, MONITOR, MONITOR_TRANSFORM_DEPRECATED, MONITOR_TRANSFORM,
|
||||
MONITOR_ML, MONITOR_WATCHER, MONITOR_ROLLUP, MANAGE, MANAGE_TRANSFORM_DEPRECATED, MANAGE_TRANSFORM,
|
||||
MANAGE_ML, MANAGE_WATCHER, MANAGE_ROLLUP, MANAGE_INDEX_TEMPLATES, MANAGE_INGEST_PIPELINES, TRANSPORT_CLIENT,
|
||||
MANAGE_SECURITY, MANAGE_SAML, MANAGE_OIDC, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_CCR, READ_CCR, MANAGE_ILM, READ_ILM,
|
||||
MANAGE_ENRICH };
|
||||
MANAGE_SECURITY, MANAGE_SAML, MANAGE_OIDC, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_AUTOSCALING, MANAGE_CCR, READ_CCR,
|
||||
MANAGE_ILM, READ_ILM, MANAGE_ENRICH };
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
[role="xpack"]
|
||||
[testenv="platinum"]
|
||||
[[autoscaling-apis]]
|
||||
== Autoscaling APIs
|
||||
|
||||
You can use the following APIs to perform autoscaling operations.
|
||||
|
||||
[float]
|
||||
[[autoscaling-api-top-level]]
|
||||
=== Top-Level
|
||||
|
||||
* <<autoscaling-get-autoscaling-decision,Get autoscaling decision>>
|
||||
|
||||
// top-level
|
||||
include::get-autoscaling-decision.asciidoc[]
|
|
@ -0,0 +1,52 @@
|
|||
[role="xpack"]
|
||||
[testenv="platinum"]
|
||||
[[autoscaling-get-autoscaling-decision]]
|
||||
=== Get autoscaling decision API
|
||||
++++
|
||||
<titleabbrev>Get autoscaling decision</titleabbrev>
|
||||
++++
|
||||
|
||||
Get autoscaling decision.
|
||||
|
||||
[[autoscaling-get-autoscaling-decision-request]]
|
||||
==== {api-request-title}
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
GET /_autoscaling/decision/
|
||||
--------------------------------------------------
|
||||
// TEST
|
||||
|
||||
[[autoscaling-get-autoscaling-decision-prereqs]]
|
||||
==== {api-prereq-title}
|
||||
|
||||
* If the {es} {security-features} are enabled, you must have
|
||||
`manage_autoscaling` cluster privileges. For more information, see
|
||||
<<security-privileges>>.
|
||||
|
||||
[[autoscaling-get-autoscaling-decision-desc]]
|
||||
==== {api-description-title}
|
||||
|
||||
This API gets the current autoscaling decision based on the configured
|
||||
autoscaling policy. This API will return whether or not autoscaling is
|
||||
needed.
|
||||
|
||||
[[autoscaling-get-autoscaling-decision-examples]]
|
||||
==== {api-examples-title}
|
||||
|
||||
This example retrieves the current autoscaling decision.
|
||||
|
||||
[source,console]
|
||||
--------------------------------------------------
|
||||
GET /_autoscaling/decision
|
||||
--------------------------------------------------
|
||||
// TEST
|
||||
|
||||
The API returns the following result:
|
||||
|
||||
[source,console-result]
|
||||
--------------------------------------------------
|
||||
{
|
||||
|
||||
}
|
||||
--------------------------------------------------
|
|
@ -35,6 +35,7 @@ not be included yet.
|
|||
--
|
||||
|
||||
include::{es-repo-dir}/api-conventions.asciidoc[]
|
||||
include::{es-repo-dir}/autoscaling/apis/autoscaling-apis.asciidoc[]
|
||||
include::{es-repo-dir}/cat.asciidoc[]
|
||||
include::{es-repo-dir}/cluster.asciidoc[]
|
||||
include::{es-repo-dir}/ccr/apis/ccr-apis.asciidoc[]
|
||||
|
|
|
@ -66,6 +66,7 @@ A successful call returns an object with "cluster" and "index" fields.
|
|||
"delegate_pki",
|
||||
"manage",
|
||||
"manage_api_key",
|
||||
"manage_autoscaling",
|
||||
"manage_ccr",
|
||||
"manage_data_frame_transforms",
|
||||
"manage_enrich",
|
||||
|
|
|
@ -18,3 +18,12 @@ dependencies {
|
|||
compileOnly project(path: xpackModule('core'), configuration: 'default')
|
||||
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
|
||||
}
|
||||
|
||||
// add all sub-projects of the qa sub-project
|
||||
gradle.projectsEvaluated {
|
||||
project.subprojects
|
||||
.find { it.path == project.path + ":qa" }
|
||||
.subprojects
|
||||
.findAll { it.path.startsWith(project.path + ":qa") }
|
||||
.each { check.dependsOn it.check }
|
||||
}
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
import org.elasticsearch.gradle.test.RestIntegTestTask
|
||||
|
||||
apply plugin: 'elasticsearch.build'
|
||||
test.enabled = false
|
||||
|
||||
dependencies {
|
||||
compile project(':test:framework')
|
||||
}
|
||||
|
||||
subprojects {
|
||||
project.tasks.withType(RestIntegTestTask) {
|
||||
final File xPackResources = new File(xpackProject('plugin').projectDir, 'src/test/resources')
|
||||
project.copyRestSpec.from(xPackResources) {
|
||||
include 'rest-api-spec/api/**'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
autoscaling:
|
||||
cluster:
|
||||
- manage_autoscaling
|
|
@ -0,0 +1,25 @@
|
|||
import org.elasticsearch.gradle.test.RestIntegTestTask
|
||||
|
||||
apply plugin: 'elasticsearch.testclusters'
|
||||
apply plugin: 'elasticsearch.standalone-test'
|
||||
|
||||
dependencies {
|
||||
testCompile project(path: xpackModule('core'), configuration: 'testArtifacts')
|
||||
testCompile project(path: xpackModule('autoscaling'), configuration: 'runtime')
|
||||
}
|
||||
|
||||
task restTest(type: RestIntegTestTask) {
|
||||
mustRunAfter(precommit)
|
||||
}
|
||||
|
||||
testClusters.restTest {
|
||||
testDistribution = 'DEFAULT'
|
||||
setting 'xpack.autoscaling.enabled', 'true'
|
||||
setting 'xpack.security.enabled', 'true'
|
||||
extraConfigFile 'roles.yml', file('autoscaling-roles.yml')
|
||||
user username: 'autoscaling-admin', password: 'autoscaling-admin-password', role: 'superuser'
|
||||
user username: 'autoscaling-user', password: 'autoscaling-user-password', role: 'autoscaling'
|
||||
}
|
||||
|
||||
check.dependsOn restTest
|
||||
test.enabled = false
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.autoscaling;
|
||||
|
||||
import com.carrotsearch.randomizedtesting.annotations.ParametersFactory;
|
||||
import org.elasticsearch.common.settings.SecureString;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.util.concurrent.ThreadContext;
|
||||
import org.elasticsearch.test.rest.yaml.ClientYamlTestCandidate;
|
||||
import org.elasticsearch.test.rest.yaml.ESClientYamlSuiteTestCase;
|
||||
|
||||
import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue;
|
||||
|
||||
public class AutoscalingRestIT extends ESClientYamlSuiteTestCase {
|
||||
|
||||
public AutoscalingRestIT(final ClientYamlTestCandidate testCandidate) {
|
||||
super(testCandidate);
|
||||
}
|
||||
|
||||
@ParametersFactory
|
||||
public static Iterable<Object[]> parameters() throws Exception {
|
||||
return ESClientYamlSuiteTestCase.createParameters();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings restAdminSettings() {
|
||||
final String value = basicAuthHeaderValue("autoscaling-admin", new SecureString("autoscaling-admin-password".toCharArray()));
|
||||
return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", value).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Settings restClientSettings() {
|
||||
final String value = basicAuthHeaderValue("autoscaling-user", new SecureString("autoscaling-user-password".toCharArray()));
|
||||
return Settings.builder().put(ThreadContext.PREFIX + ".Authorization", value).build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
"Test get autoscaling decision":
|
||||
- do:
|
||||
autoscaling.get_autoscaling_decision: {}
|
|
@ -7,16 +7,31 @@
|
|||
package org.elasticsearch.xpack.autoscaling;
|
||||
|
||||
import org.elasticsearch.Build;
|
||||
import org.elasticsearch.action.ActionRequest;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.IndexScopedSettings;
|
||||
import org.elasticsearch.common.settings.Setting;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.settings.SettingsFilter;
|
||||
import org.elasticsearch.plugins.ActionPlugin;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestHandler;
|
||||
import org.elasticsearch.xpack.autoscaling.action.GetAutoscalingDecisionAction;
|
||||
import org.elasticsearch.xpack.autoscaling.action.TransportGetAutoscalingDecisionAction;
|
||||
import org.elasticsearch.xpack.autoscaling.rest.RestGetAutoscalingDecisionHandler;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Container class for autoscaling functionality.
|
||||
*/
|
||||
public class Autoscaling extends Plugin {
|
||||
public class Autoscaling extends Plugin implements ActionPlugin {
|
||||
|
||||
public static final Setting<Boolean> AUTOSCALING_ENABLED_SETTING = Setting.boolSetting(
|
||||
"xpack.autoscaling.enabled",
|
||||
|
@ -24,6 +39,12 @@ public class Autoscaling extends Plugin {
|
|||
Setting.Property.NodeScope
|
||||
);
|
||||
|
||||
private final boolean enabled;
|
||||
|
||||
public Autoscaling(final Settings settings) {
|
||||
this.enabled = AUTOSCALING_ENABLED_SETTING.get(settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* The settings defined by autoscaling.
|
||||
*
|
||||
|
@ -38,6 +59,34 @@ public class Autoscaling extends Plugin {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ActionHandler<? extends ActionRequest, ? extends ActionResponse>> getActions() {
|
||||
if (enabled) {
|
||||
return Collections.singletonList(
|
||||
new ActionHandler<>(GetAutoscalingDecisionAction.INSTANCE, TransportGetAutoscalingDecisionAction.class)
|
||||
);
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RestHandler> getRestHandlers(
|
||||
final Settings settings,
|
||||
final RestController controller,
|
||||
final ClusterSettings clusterSettings,
|
||||
final IndexScopedSettings indexScopedSettings,
|
||||
final SettingsFilter settingsFilter,
|
||||
final IndexNameExpressionResolver indexNameExpressionResolver,
|
||||
final Supplier<DiscoveryNodes> nodesInCluster
|
||||
) {
|
||||
if (enabled) {
|
||||
return Collections.singletonList(new RestGetAutoscalingDecisionHandler(controller));
|
||||
} else {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
boolean isSnapshot() {
|
||||
return Build.CURRENT.isSnapshot();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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.autoscaling.action;
|
||||
|
||||
import org.elasticsearch.action.ActionRequestValidationException;
|
||||
import org.elasticsearch.action.ActionResponse;
|
||||
import org.elasticsearch.action.ActionType;
|
||||
import org.elasticsearch.action.support.master.AcknowledgedRequest;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class GetAutoscalingDecisionAction extends ActionType<GetAutoscalingDecisionAction.Response> {
|
||||
|
||||
public static final GetAutoscalingDecisionAction INSTANCE = new GetAutoscalingDecisionAction();
|
||||
public static final String NAME = "cluster:admin/autoscaling/get_autoscaling_decision";
|
||||
|
||||
private GetAutoscalingDecisionAction() {
|
||||
super(NAME, Response::new);
|
||||
}
|
||||
|
||||
public static class Request extends AcknowledgedRequest<GetAutoscalingDecisionAction.Request> implements ToXContentObject {
|
||||
|
||||
public Request() {
|
||||
|
||||
}
|
||||
|
||||
public Request(final StreamInput in) throws IOException {
|
||||
super(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(final StreamOutput out) throws IOException {
|
||||
super.writeTo(out);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ActionRequestValidationException validate() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
|
||||
builder.startObject();
|
||||
{
|
||||
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class Response extends ActionResponse implements ToXContentObject {
|
||||
|
||||
public Response() {
|
||||
|
||||
}
|
||||
|
||||
public Response(final StreamInput in) throws IOException {
|
||||
super(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeTo(final StreamOutput out) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public XContentBuilder toXContent(final XContentBuilder builder, final Params params) throws IOException {
|
||||
builder.startObject();
|
||||
{
|
||||
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
* 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.autoscaling.action;
|
||||
|
||||
import org.elasticsearch.action.ActionListener;
|
||||
import org.elasticsearch.action.support.ActionFilters;
|
||||
import org.elasticsearch.action.support.master.TransportMasterNodeAction;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.block.ClusterBlockException;
|
||||
import org.elasticsearch.cluster.metadata.IndexNameExpressionResolver;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.inject.Inject;
|
||||
import org.elasticsearch.common.io.stream.StreamInput;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class TransportGetAutoscalingDecisionAction extends TransportMasterNodeAction<
|
||||
GetAutoscalingDecisionAction.Request,
|
||||
GetAutoscalingDecisionAction.Response> {
|
||||
|
||||
@Inject
|
||||
public TransportGetAutoscalingDecisionAction(
|
||||
final TransportService transportService,
|
||||
final ClusterService clusterService,
|
||||
final ThreadPool threadPool,
|
||||
final ActionFilters actionFilters,
|
||||
final IndexNameExpressionResolver indexNameExpressionResolver
|
||||
) {
|
||||
super(
|
||||
GetAutoscalingDecisionAction.NAME,
|
||||
transportService,
|
||||
clusterService,
|
||||
threadPool,
|
||||
actionFilters,
|
||||
GetAutoscalingDecisionAction.Request::new,
|
||||
indexNameExpressionResolver
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String executor() {
|
||||
return ThreadPool.Names.SAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GetAutoscalingDecisionAction.Response read(final StreamInput in) throws IOException {
|
||||
return new GetAutoscalingDecisionAction.Response(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void masterOperation(
|
||||
final GetAutoscalingDecisionAction.Request request,
|
||||
final ClusterState state,
|
||||
final ActionListener<GetAutoscalingDecisionAction.Response> listener
|
||||
) {
|
||||
listener.onResponse(new GetAutoscalingDecisionAction.Response());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClusterBlockException checkBlock(final GetAutoscalingDecisionAction.Request request, final ClusterState state) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* 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.autoscaling.rest;
|
||||
|
||||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.rest.BaseRestHandler;
|
||||
import org.elasticsearch.rest.RestController;
|
||||
import org.elasticsearch.rest.RestRequest;
|
||||
import org.elasticsearch.rest.action.RestToXContentListener;
|
||||
import org.elasticsearch.xpack.autoscaling.action.GetAutoscalingDecisionAction;
|
||||
|
||||
public class RestGetAutoscalingDecisionHandler extends BaseRestHandler {
|
||||
|
||||
public RestGetAutoscalingDecisionHandler(final RestController controller) {
|
||||
controller.registerHandler(RestRequest.Method.GET, "/_autoscaling/decision", this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "get_autoscaling_decision";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected RestChannelConsumer prepareRequest(final RestRequest restRequest, final NodeClient client) {
|
||||
final GetAutoscalingDecisionAction.Request request = new GetAutoscalingDecisionAction.Request();
|
||||
return channel -> client.execute(GetAutoscalingDecisionAction.INSTANCE, request, new RestToXContentListener<>(channel));
|
||||
}
|
||||
|
||||
}
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
package org.elasticsearch.xpack.autoscaling;
|
||||
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
|
@ -14,7 +15,7 @@ import static org.hamcrest.Matchers.not;
|
|||
public class AutoscalingTests extends ESTestCase {
|
||||
|
||||
public void testEnabledSettingRegisteredInSnapshotBuilds() {
|
||||
final Autoscaling plugin = new Autoscaling() {
|
||||
final Autoscaling plugin = new Autoscaling(Settings.EMPTY) {
|
||||
|
||||
@Override
|
||||
protected boolean isSnapshot() {
|
||||
|
@ -26,7 +27,7 @@ public class AutoscalingTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testEnabledSettingNotRegisteredInNonSnapshotBuilds() {
|
||||
final Autoscaling plugin = new Autoscaling() {
|
||||
final Autoscaling plugin = new Autoscaling(Settings.EMPTY) {
|
||||
|
||||
@Override
|
||||
protected boolean isSnapshot() {
|
||||
|
|
|
@ -120,6 +120,9 @@ public class ClusterPrivilegeResolver {
|
|||
public static final NamedClusterPrivilege MANAGE_API_KEY = new ActionClusterPrivilege("manage_api_key", MANAGE_API_KEY_PATTERN);
|
||||
public static final NamedClusterPrivilege MANAGE_PIPELINE = new ActionClusterPrivilege("manage_pipeline",
|
||||
Collections.singleton("cluster:admin/ingest/pipeline/*"));
|
||||
public static final NamedClusterPrivilege MANAGE_AUTOSCALING = new ActionClusterPrivilege(
|
||||
"manage_autoscaling",
|
||||
Collections.singleton("cluster:admin/autoscaling/*"));
|
||||
public static final NamedClusterPrivilege MANAGE_CCR = new ActionClusterPrivilege("manage_ccr", MANAGE_CCR_PATTERN);
|
||||
public static final NamedClusterPrivilege READ_CCR = new ActionClusterPrivilege("read_ccr", READ_CCR_PATTERN);
|
||||
public static final NamedClusterPrivilege CREATE_SNAPSHOT = new ActionClusterPrivilege("create_snapshot", CREATE_SNAPSHOT_PATTERN);
|
||||
|
@ -159,6 +162,7 @@ public class ClusterPrivilegeResolver {
|
|||
MANAGE_API_KEY,
|
||||
MANAGE_PIPELINE,
|
||||
MANAGE_ROLLUP,
|
||||
MANAGE_AUTOSCALING,
|
||||
MANAGE_CCR,
|
||||
READ_CCR,
|
||||
CREATE_SNAPSHOT,
|
||||
|
|
|
@ -174,6 +174,10 @@ public class PrivilegeTests extends ESTestCase {
|
|||
assertThat(predicate.test("indices:admin/settings/foo"), is(false));
|
||||
}
|
||||
|
||||
public void testManageAutoscalingPrivilege() {
|
||||
verifyClusterActionAllowed(ClusterPrivilegeResolver.MANAGE_AUTOSCALING, "cluster:admin/autoscaling/get_decision");
|
||||
}
|
||||
|
||||
public void testManageCcrPrivilege() {
|
||||
verifyClusterActionAllowed(ClusterPrivilegeResolver.MANAGE_CCR, "cluster:admin/xpack/ccr/follow_index",
|
||||
"cluster:admin/xpack/ccr/unfollow_index", "cluster:admin/xpack/ccr/brand_new_api");
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"autoscaling.get_autoscaling_decision":{
|
||||
"documentation":{
|
||||
"url":"https://www.elastic.co/guide/en/elasticsearch/reference/current/autoscaling-get-autoscaling-decision.html"
|
||||
},
|
||||
"stability":"experimental",
|
||||
"url":{
|
||||
"paths":[
|
||||
{
|
||||
"path":"/_autoscaling/decision",
|
||||
"methods":[
|
||||
"GET"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,5 +15,5 @@ setup:
|
|||
# This is fragile - it needs to be updated every time we add a new cluster/index privilege
|
||||
# I would much prefer we could just check that specific entries are in the array, but we don't have
|
||||
# an assertion for that
|
||||
- length: { "cluster" : 34 }
|
||||
- length: { "cluster" : 35 }
|
||||
- length: { "index" : 18 }
|
||||
|
|
Loading…
Reference in New Issue