Merge branch 'master' into close-index-api-refactoring
This commit is contained in:
commit
1f6f236d44
|
@ -315,9 +315,11 @@ public final class Role {
|
|||
public static final String MANAGE_PIPELINE = "manage_pipeline";
|
||||
public static final String MANAGE_CCR = "manage_ccr";
|
||||
public static final String READ_CCR = "read_ccr";
|
||||
public static final String MANAGE_ILM = "manage_ilm";
|
||||
public static final String READ_ILM = "read_ilm";
|
||||
public static final String[] ALL_ARRAY = new String[] { NONE, ALL, MONITOR, MONITOR_ML, MONITOR_WATCHER, MONITOR_ROLLUP, MANAGE,
|
||||
MANAGE_ML, MANAGE_WATCHER, MANAGE_ROLLUP, MANAGE_INDEX_TEMPLATES, MANAGE_INGEST_PIPELINES, TRANSPORT_CLIENT,
|
||||
MANAGE_SECURITY, MANAGE_SAML, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_CCR, READ_CCR };
|
||||
MANAGE_SECURITY, MANAGE_SAML, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_CCR, READ_CCR, MANAGE_ILM, READ_ILM };
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -338,8 +340,9 @@ public final class Role {
|
|||
public static final String CREATE_INDEX = "create_index";
|
||||
public static final String VIEW_INDEX_METADATA = "view_index_metadata";
|
||||
public static final String MANAGE_FOLLOW_INDEX = "manage_follow_index";
|
||||
public static final String MANAGE_ILM = "manage_ilm";
|
||||
public static final String[] ALL_ARRAY = new String[] { NONE, ALL, READ, READ_CROSS, CREATE, INDEX, DELETE, WRITE, MONITOR, MANAGE,
|
||||
DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX };
|
||||
DELETE_INDEX, CREATE_INDEX, VIEW_INDEX_METADATA, MANAGE_FOLLOW_INDEX, MANAGE_ILM };
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -45,6 +45,15 @@
|
|||
# 10-:-XX:+UseG1GC
|
||||
# 10-:-XX:InitiatingHeapOccupancyPercent=75
|
||||
|
||||
## DNS cache policy
|
||||
# cache ttl in seconds for positive DNS lookups noting that this overrides the
|
||||
# JDK security property networkaddress.cache.ttl; set to -1 to cache forever
|
||||
-Des.networkaddress.cache.ttl=60
|
||||
# cache ttl in seconds for negative DNS lookups noting that this overrides the
|
||||
# JDK security property networkaddress.cache.negative ttl; set to -1 to cache
|
||||
# forever
|
||||
-Des.networkaddress.cache.negative.ttl=10
|
||||
|
||||
## optimizations
|
||||
|
||||
# pre-touch memory pages used by the JVM during initialization
|
||||
|
|
|
@ -2,17 +2,18 @@
|
|||
=== DNS cache settings
|
||||
|
||||
Elasticsearch runs with a security manager in place. With a security manager in
|
||||
place, the JVM defaults to caching positive hostname resolutions
|
||||
indefinitely. If your Elasticsearch nodes rely on DNS in an environment where
|
||||
DNS resolutions vary with time (e.g., for node-to-node discovery) then you might
|
||||
want to modify the default JVM behavior. This can be modified by adding
|
||||
place, the JVM defaults to caching positive hostname resolutions indefinitely
|
||||
and defaults to caching negative hostname resolutions for ten
|
||||
seconds. Elasticsearch overrides this behavior with default values to cache
|
||||
positive lookups for sixty seconds, and to cache negative lookups for ten
|
||||
seconds. These values should be suitable for most environments, including
|
||||
environments where DNS resolutions vary with time. If not, you can edit the
|
||||
values `es.networkaddress.cache.ttl` and `es.networkaddress.cache.negative.ttl`
|
||||
in the <<jvm-options,JVM options>>. Note that the values
|
||||
http://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html[`networkaddress.cache.ttl=<timeout>`]
|
||||
to your
|
||||
http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html[Java
|
||||
security policy]. Any hosts that fail to resolve will be logged. Note also that
|
||||
with the Java security manager in place, the JVM defaults to caching negative
|
||||
hostname resolutions for ten seconds. This can be modified by adding
|
||||
and
|
||||
http://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html[`networkaddress.cache.negative.ttl=<timeout>`]
|
||||
to your
|
||||
in the
|
||||
http://docs.oracle.com/javase/8/docs/technotes/guides/security/PolicyFiles.html[Java
|
||||
security policy].
|
||||
security policy] are ignored by Elasticsearch unless you remove the settings for
|
||||
`es.networkaddress.cache.ttl` and `es.networkaddress.cache.negative.ttl`.
|
||||
|
|
|
@ -36,6 +36,7 @@ import org.elasticsearch.node.NodeValidationException;
|
|||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.security.Permission;
|
||||
import java.security.Security;
|
||||
import java.util.Arrays;
|
||||
import java.util.Locale;
|
||||
|
||||
|
@ -72,13 +73,19 @@ class Elasticsearch extends EnvironmentAwareCommand {
|
|||
* Main entry point for starting elasticsearch
|
||||
*/
|
||||
public static void main(final String[] args) throws Exception {
|
||||
// we want the JVM to think there is a security manager installed so that if internal policy decisions that would be based on the
|
||||
// presence of a security manager or lack thereof act as if there is a security manager present (e.g., DNS cache policy)
|
||||
overrideDnsCachePolicyProperties();
|
||||
/*
|
||||
* We want the JVM to think there is a security manager installed so that if internal policy decisions that would be based on the
|
||||
* presence of a security manager or lack thereof act as if there is a security manager present (e.g., DNS cache policy). This
|
||||
* forces such policies to take effect immediately.
|
||||
*/
|
||||
System.setSecurityManager(new SecurityManager() {
|
||||
|
||||
@Override
|
||||
public void checkPermission(Permission perm) {
|
||||
// grant all permissions so that we can later set the security manager to the one that we want
|
||||
}
|
||||
|
||||
});
|
||||
LogConfigurator.registerErrorListener();
|
||||
final Elasticsearch elasticsearch = new Elasticsearch();
|
||||
|
@ -88,6 +95,22 @@ class Elasticsearch extends EnvironmentAwareCommand {
|
|||
}
|
||||
}
|
||||
|
||||
private static void overrideDnsCachePolicyProperties() {
|
||||
for (final String property : new String[] {"networkaddress.cache.ttl", "networkaddress.cache.negative.ttl" }) {
|
||||
final String overrideProperty = "es." + property;
|
||||
final String overrideValue = System.getProperty(overrideProperty);
|
||||
if (overrideValue != null) {
|
||||
try {
|
||||
// round-trip the property to an integer and back to a string to ensure that it parses properly
|
||||
Security.setProperty(property, Integer.toString(Integer.valueOf(overrideValue)));
|
||||
} catch (final NumberFormatException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"failed to parse [" + overrideProperty + "] with value [" + overrideValue + "]", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int main(final String[] args, final Elasticsearch elasticsearch, final Terminal terminal) throws Exception {
|
||||
return elasticsearch.main(args, terminal);
|
||||
}
|
||||
|
|
|
@ -207,7 +207,9 @@ public abstract class MultiValuesSourceAggregationBuilder<VS extends ValuesSourc
|
|||
public final XContentBuilder internalXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
if (fields != null) {
|
||||
builder.field(CommonFields.FIELDS.getPreferredName(), fields);
|
||||
for (Map.Entry<String, MultiValuesSourceFieldConfig> fieldEntry : fields.entrySet()) {
|
||||
builder.field(fieldEntry.getKey(), fieldEntry.getValue());
|
||||
}
|
||||
}
|
||||
if (format != null) {
|
||||
builder.field(CommonFields.FORMAT.getPreferredName(), format);
|
||||
|
|
|
@ -25,16 +25,17 @@ import org.elasticsearch.common.io.stream.StreamInput;
|
|||
import org.elasticsearch.common.io.stream.StreamOutput;
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.common.xcontent.ObjectParser;
|
||||
import org.elasticsearch.common.xcontent.ToXContentFragment;
|
||||
import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Objects;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
public class MultiValuesSourceFieldConfig implements Writeable, ToXContentFragment {
|
||||
public class MultiValuesSourceFieldConfig implements Writeable, ToXContentObject {
|
||||
private String fieldName;
|
||||
private Object missing;
|
||||
private Script script;
|
||||
|
@ -110,6 +111,7 @@ public class MultiValuesSourceFieldConfig implements Writeable, ToXContentFragme
|
|||
|
||||
@Override
|
||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||
builder.startObject();
|
||||
if (missing != null) {
|
||||
builder.field(ParseField.CommonFields.MISSING.getPreferredName(), missing);
|
||||
}
|
||||
|
@ -120,11 +122,33 @@ public class MultiValuesSourceFieldConfig implements Writeable, ToXContentFragme
|
|||
builder.field(ParseField.CommonFields.FIELD.getPreferredName(), fieldName);
|
||||
}
|
||||
if (timeZone != null) {
|
||||
builder.field(ParseField.CommonFields.TIME_ZONE.getPreferredName(), timeZone);
|
||||
builder.field(ParseField.CommonFields.TIME_ZONE.getPreferredName(), timeZone.getID());
|
||||
}
|
||||
builder.endObject();
|
||||
return builder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
MultiValuesSourceFieldConfig that = (MultiValuesSourceFieldConfig) o;
|
||||
return Objects.equals(fieldName, that.fieldName)
|
||||
&& Objects.equals(missing, that.missing)
|
||||
&& Objects.equals(script, that.script)
|
||||
&& Objects.equals(timeZone, that.timeZone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(fieldName, missing, script, timeZone);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Strings.toString(this);
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private String fieldName;
|
||||
private Object missing = null;
|
||||
|
|
|
@ -32,7 +32,7 @@ import org.elasticsearch.common.network.NetworkService;
|
|||
import org.elasticsearch.common.settings.ClusterSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.unit.ByteSizeValue;
|
||||
import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.common.util.PageCacheRecycler;
|
||||
import org.elasticsearch.discovery.zen.FaultDetection;
|
||||
import org.elasticsearch.discovery.zen.MasterFaultDetection;
|
||||
import org.elasticsearch.discovery.zen.NodesFaultDetection;
|
||||
|
@ -43,10 +43,10 @@ import org.elasticsearch.test.ESTestCase;
|
|||
import org.elasticsearch.test.transport.MockTransportService;
|
||||
import org.elasticsearch.threadpool.TestThreadPool;
|
||||
import org.elasticsearch.threadpool.ThreadPool;
|
||||
import org.elasticsearch.transport.MockTcpTransport;
|
||||
import org.elasticsearch.transport.TransportConnectionListener;
|
||||
import org.elasticsearch.transport.TransportRequestOptions;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
import org.elasticsearch.transport.nio.MockNioTransport;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.After;
|
||||
|
@ -138,8 +138,8 @@ public class ZenFaultDetectionTests extends ESTestCase {
|
|||
// trace zenfd actions but keep the default otherwise
|
||||
.putList(TransportService.TRACE_LOG_EXCLUDE_SETTING.getKey(), TransportLivenessAction.NAME)
|
||||
.build(),
|
||||
new MockTcpTransport(settings, threadPool, BigArrays.NON_RECYCLING_INSTANCE, circuitBreakerService,
|
||||
namedWriteableRegistry, new NetworkService(Collections.emptyList()), version),
|
||||
new MockNioTransport(settings, version, threadPool, new NetworkService(Collections.emptyList()),
|
||||
PageCacheRecycler.NON_RECYCLING_INSTANCE, namedWriteableRegistry, circuitBreakerService),
|
||||
threadPool,
|
||||
TransportService.NOOP_TRANSPORT_INTERCEPTOR,
|
||||
(boundAddress) ->
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.elasticsearch.common.transport.BoundTransportAddress;
|
|||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.common.unit.TimeValue;
|
||||
import org.elasticsearch.common.util.BigArrays;
|
||||
import org.elasticsearch.common.util.PageCacheRecycler;
|
||||
import org.elasticsearch.common.util.concurrent.AbstractRunnable;
|
||||
import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
|
||||
import org.elasticsearch.common.util.concurrent.EsExecutors;
|
||||
|
@ -56,6 +57,7 @@ import org.elasticsearch.transport.TransportException;
|
|||
import org.elasticsearch.transport.TransportRequestOptions;
|
||||
import org.elasticsearch.transport.TransportResponseHandler;
|
||||
import org.elasticsearch.transport.TransportService;
|
||||
import org.elasticsearch.transport.nio.MockNioTransport;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.mockito.Matchers;
|
||||
|
@ -143,14 +145,14 @@ public class UnicastZenPingTests extends ESTestCase {
|
|||
|
||||
NetworkService networkService = new NetworkService(Collections.emptyList());
|
||||
|
||||
final BiFunction<Settings, Version, Transport> supplier = (s, v) -> new MockTcpTransport(
|
||||
final BiFunction<Settings, Version, Transport> supplier = (s, v) -> new MockNioTransport(
|
||||
s,
|
||||
v,
|
||||
threadPool,
|
||||
BigArrays.NON_RECYCLING_INSTANCE,
|
||||
new NoneCircuitBreakerService(),
|
||||
new NamedWriteableRegistry(Collections.emptyList()),
|
||||
networkService,
|
||||
v);
|
||||
PageCacheRecycler.NON_RECYCLING_INSTANCE,
|
||||
new NamedWriteableRegistry(Collections.emptyList()),
|
||||
new NoneCircuitBreakerService());
|
||||
|
||||
NetworkHandle handleA = startServices(settings, threadPool, "UZP_A", Version.CURRENT, supplier);
|
||||
closeables.push(handleA.transportService);
|
||||
|
@ -268,14 +270,14 @@ public class UnicastZenPingTests extends ESTestCase {
|
|||
final NetworkService networkService = new NetworkService(Collections.emptyList());
|
||||
|
||||
final Map<String, TransportAddress[]> addresses = new HashMap<>();
|
||||
final BiFunction<Settings, Version, Transport> supplier = (s, v) -> new MockTcpTransport(
|
||||
final BiFunction<Settings, Version, Transport> supplier = (s, v) -> new MockNioTransport(
|
||||
s,
|
||||
v,
|
||||
threadPool,
|
||||
BigArrays.NON_RECYCLING_INSTANCE,
|
||||
new NoneCircuitBreakerService(),
|
||||
new NamedWriteableRegistry(Collections.emptyList()),
|
||||
networkService,
|
||||
v) {
|
||||
PageCacheRecycler.NON_RECYCLING_INSTANCE,
|
||||
new NamedWriteableRegistry(Collections.emptyList()),
|
||||
new NoneCircuitBreakerService()) {
|
||||
@Override
|
||||
public TransportAddress[] addressesFromString(String address, int perAddressLimit) throws UnknownHostException {
|
||||
final TransportAddress[] transportAddresses = addresses.get(address);
|
||||
|
@ -634,14 +636,14 @@ public class UnicastZenPingTests extends ESTestCase {
|
|||
|
||||
NetworkService networkService = new NetworkService(Collections.emptyList());
|
||||
|
||||
final BiFunction<Settings, Version, Transport> supplier = (s, v) -> new MockTcpTransport(
|
||||
final BiFunction<Settings, Version, Transport> supplier = (s, v) -> new MockNioTransport(
|
||||
s,
|
||||
v,
|
||||
threadPool,
|
||||
BigArrays.NON_RECYCLING_INSTANCE,
|
||||
new NoneCircuitBreakerService(),
|
||||
new NamedWriteableRegistry(Collections.emptyList()),
|
||||
networkService,
|
||||
v);
|
||||
PageCacheRecycler.NON_RECYCLING_INSTANCE,
|
||||
new NamedWriteableRegistry(Collections.emptyList()),
|
||||
new NoneCircuitBreakerService());
|
||||
|
||||
NetworkHandle handleA = startServices(settings, threadPool, "UZP_A", Version.CURRENT, supplier, EnumSet.allOf(Role.class));
|
||||
closeables.push(handleA.transportService);
|
||||
|
@ -689,15 +691,14 @@ public class UnicastZenPingTests extends ESTestCase {
|
|||
|
||||
public void testInvalidHosts() throws InterruptedException {
|
||||
final Logger logger = mock(Logger.class);
|
||||
final NetworkService networkService = new NetworkService(Collections.emptyList());
|
||||
final Transport transport = new MockTcpTransport(
|
||||
final Transport transport = new MockNioTransport(
|
||||
Settings.EMPTY,
|
||||
Version.CURRENT,
|
||||
threadPool,
|
||||
BigArrays.NON_RECYCLING_INSTANCE,
|
||||
new NoneCircuitBreakerService(),
|
||||
new NetworkService(Collections.emptyList()),
|
||||
PageCacheRecycler.NON_RECYCLING_INSTANCE,
|
||||
new NamedWriteableRegistry(Collections.emptyList()),
|
||||
networkService,
|
||||
Version.CURRENT) {
|
||||
new NoneCircuitBreakerService()) {
|
||||
@Override
|
||||
public BoundTransportAddress boundAddress() {
|
||||
return new BoundTransportAddress(
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.search.aggregations.metrics.weighted_avg;
|
||||
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.NamedXContentRegistry;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.search.SearchModule;
|
||||
import org.elasticsearch.search.aggregations.AggregatorFactories;
|
||||
import org.elasticsearch.search.aggregations.metrics.WeightedAvgAggregationBuilder;
|
||||
import org.elasticsearch.search.aggregations.support.MultiValuesSourceFieldConfig;
|
||||
import org.elasticsearch.test.AbstractSerializingTestCase;
|
||||
import org.junit.Before;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
|
||||
public class WeightedAvgAggregationBuilderTests extends AbstractSerializingTestCase<WeightedAvgAggregationBuilder> {
|
||||
String aggregationName;
|
||||
|
||||
@Before
|
||||
public void setupName() {
|
||||
aggregationName = randomAlphaOfLength(10);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected NamedXContentRegistry xContentRegistry() {
|
||||
SearchModule searchModule = new SearchModule(Settings.EMPTY, false, Collections.emptyList());
|
||||
return new NamedXContentRegistry(searchModule.getNamedXContents());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WeightedAvgAggregationBuilder doParseInstance(XContentParser parser) throws IOException {
|
||||
assertSame(XContentParser.Token.START_OBJECT, parser.nextToken());
|
||||
AggregatorFactories.Builder parsed = AggregatorFactories.parseAggregators(parser);
|
||||
assertThat(parsed.getAggregatorFactories(), hasSize(1));
|
||||
assertThat(parsed.getPipelineAggregatorFactories(), hasSize(0));
|
||||
WeightedAvgAggregationBuilder agg = (WeightedAvgAggregationBuilder) parsed.getAggregatorFactories().iterator().next();
|
||||
assertNull(parser.nextToken());
|
||||
assertNotNull(agg);
|
||||
return agg;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WeightedAvgAggregationBuilder createTestInstance() {
|
||||
MultiValuesSourceFieldConfig valueConfig = new MultiValuesSourceFieldConfig.Builder().setFieldName("value_field").build();
|
||||
MultiValuesSourceFieldConfig weightConfig = new MultiValuesSourceFieldConfig.Builder().setFieldName("weight_field").build();
|
||||
WeightedAvgAggregationBuilder aggregationBuilder = new WeightedAvgAggregationBuilder(aggregationName)
|
||||
.value(valueConfig)
|
||||
.weight(weightConfig);
|
||||
return aggregationBuilder;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Writeable.Reader<WeightedAvgAggregationBuilder> instanceReader() {
|
||||
return WeightedAvgAggregationBuilder::new;
|
||||
}
|
||||
}
|
|
@ -19,12 +19,37 @@
|
|||
|
||||
package org.elasticsearch.search.aggregations.support;
|
||||
|
||||
import org.elasticsearch.common.io.stream.Writeable;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.script.Script;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.test.AbstractSerializingTestCase;
|
||||
import org.joda.time.DateTimeZone;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
|
||||
public class MultiValuesSourceFieldConfigTests extends ESTestCase {
|
||||
public class MultiValuesSourceFieldConfigTests extends AbstractSerializingTestCase<MultiValuesSourceFieldConfig> {
|
||||
|
||||
@Override
|
||||
protected MultiValuesSourceFieldConfig doParseInstance(XContentParser parser) throws IOException {
|
||||
return MultiValuesSourceFieldConfig.PARSER.apply(true, true).apply(parser, null).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected MultiValuesSourceFieldConfig createTestInstance() {
|
||||
String field = randomAlphaOfLength(10);
|
||||
Object missing = randomBoolean() ? randomAlphaOfLength(10) : null;
|
||||
DateTimeZone timeZone = randomBoolean() ? randomDateTimeZone() : null;
|
||||
return new MultiValuesSourceFieldConfig.Builder()
|
||||
.setFieldName(field).setMissing(missing).setScript(null).setTimeZone(timeZone).build();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Writeable.Reader<MultiValuesSourceFieldConfig> instanceReader() {
|
||||
return MultiValuesSourceFieldConfig::new;
|
||||
}
|
||||
|
||||
public void testMissingFieldScript() {
|
||||
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new MultiValuesSourceFieldConfig.Builder().build());
|
||||
assertThat(e.getMessage(), equalTo("[field] and [script] cannot both be null. Please specify one or the other."));
|
||||
|
|
|
@ -9,6 +9,8 @@ import org.apache.lucene.util.automaton.Automaton;
|
|||
import org.elasticsearch.action.admin.cluster.state.ClusterStateAction;
|
||||
import org.elasticsearch.common.Strings;
|
||||
import org.elasticsearch.common.collect.MapBuilder;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.action.GetLifecycleAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.action.GetStatusAction;
|
||||
import org.elasticsearch.xpack.core.security.action.token.InvalidateTokenAction;
|
||||
import org.elasticsearch.xpack.core.security.action.token.RefreshTokenAction;
|
||||
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesAction;
|
||||
|
@ -47,6 +49,8 @@ public final class ClusterPrivilege extends Privilege {
|
|||
private static final Automaton MANAGE_CCR_AUTOMATON =
|
||||
patterns("cluster:admin/xpack/ccr/*", ClusterStateAction.NAME, HasPrivilegesAction.NAME);
|
||||
private static final Automaton READ_CCR_AUTOMATON = patterns(ClusterStateAction.NAME, HasPrivilegesAction.NAME);
|
||||
private static final Automaton MANAGE_ILM_AUTOMATON = patterns("cluster:admin/ilm/*");
|
||||
private static final Automaton READ_ILM_AUTOMATON = patterns(GetLifecycleAction.NAME, GetStatusAction.NAME);
|
||||
|
||||
public static final ClusterPrivilege NONE = new ClusterPrivilege("none", Automatons.EMPTY);
|
||||
public static final ClusterPrivilege ALL = new ClusterPrivilege("all", ALL_CLUSTER_AUTOMATON);
|
||||
|
@ -69,6 +73,8 @@ public final class ClusterPrivilege extends Privilege {
|
|||
public static final ClusterPrivilege MANAGE_PIPELINE = new ClusterPrivilege("manage_pipeline", "cluster:admin/ingest/pipeline/*");
|
||||
public static final ClusterPrivilege MANAGE_CCR = new ClusterPrivilege("manage_ccr", MANAGE_CCR_AUTOMATON);
|
||||
public static final ClusterPrivilege READ_CCR = new ClusterPrivilege("read_ccr", READ_CCR_AUTOMATON);
|
||||
public static final ClusterPrivilege MANAGE_ILM = new ClusterPrivilege("manage_ilm", MANAGE_ILM_AUTOMATON);
|
||||
public static final ClusterPrivilege READ_ILM = new ClusterPrivilege("read_ilm", READ_ILM_AUTOMATON);
|
||||
|
||||
public static final Predicate<String> ACTION_MATCHER = ClusterPrivilege.ALL.predicate();
|
||||
|
||||
|
@ -92,6 +98,8 @@ public final class ClusterPrivilege extends Privilege {
|
|||
.put("manage_rollup", MANAGE_ROLLUP)
|
||||
.put("manage_ccr", MANAGE_CCR)
|
||||
.put("read_ccr", READ_CCR)
|
||||
.put("manage_ilm", MANAGE_ILM)
|
||||
.put("read_ilm", READ_ILM)
|
||||
.immutableMap();
|
||||
|
||||
private static final ConcurrentHashMap<Set<String>, ClusterPrivilege> CACHE = new ConcurrentHashMap<>();
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.elasticsearch.common.Strings;
|
|||
import org.elasticsearch.common.collect.MapBuilder;
|
||||
import org.elasticsearch.xpack.core.ccr.action.PutFollowAction;
|
||||
import org.elasticsearch.xpack.core.ccr.action.UnfollowAction;
|
||||
import org.elasticsearch.xpack.core.indexlifecycle.action.ExplainLifecycleAction;
|
||||
import org.elasticsearch.xpack.core.security.support.Automatons;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
@ -57,9 +58,11 @@ public final class IndexPrivilege extends Privilege {
|
|||
private static final Automaton DELETE_INDEX_AUTOMATON = patterns(DeleteIndexAction.NAME);
|
||||
private static final Automaton VIEW_METADATA_AUTOMATON = patterns(GetAliasesAction.NAME, AliasesExistAction.NAME,
|
||||
GetIndexAction.NAME, IndicesExistsAction.NAME, GetFieldMappingsAction.NAME + "*", GetMappingsAction.NAME,
|
||||
ClusterSearchShardsAction.NAME, TypesExistsAction.NAME, ValidateQueryAction.NAME + "*", GetSettingsAction.NAME);
|
||||
ClusterSearchShardsAction.NAME, TypesExistsAction.NAME, ValidateQueryAction.NAME + "*", GetSettingsAction.NAME,
|
||||
ExplainLifecycleAction.NAME);
|
||||
private static final Automaton MANAGE_FOLLOW_INDEX_AUTOMATON = patterns(PutFollowAction.NAME, UnfollowAction.NAME,
|
||||
CloseIndexAction.NAME + "*");
|
||||
private static final Automaton MANAGE_ILM_AUTOMATON = patterns("indices:admin/ilm/*");
|
||||
|
||||
public static final IndexPrivilege NONE = new IndexPrivilege("none", Automatons.EMPTY);
|
||||
public static final IndexPrivilege ALL = new IndexPrivilege("all", ALL_AUTOMATON);
|
||||
|
@ -75,6 +78,7 @@ public final class IndexPrivilege extends Privilege {
|
|||
public static final IndexPrivilege CREATE_INDEX = new IndexPrivilege("create_index", CREATE_INDEX_AUTOMATON);
|
||||
public static final IndexPrivilege VIEW_METADATA = new IndexPrivilege("view_index_metadata", VIEW_METADATA_AUTOMATON);
|
||||
public static final IndexPrivilege MANAGE_FOLLOW_INDEX = new IndexPrivilege("manage_follow_index", MANAGE_FOLLOW_INDEX_AUTOMATON);
|
||||
public static final IndexPrivilege MANAGE_ILM = new IndexPrivilege("manage_ilm", MANAGE_ILM_AUTOMATON);
|
||||
|
||||
private static final Map<String, IndexPrivilege> VALUES = MapBuilder.<String, IndexPrivilege>newMapBuilder()
|
||||
.put("none", NONE)
|
||||
|
@ -91,6 +95,7 @@ public final class IndexPrivilege extends Privilege {
|
|||
.put("view_index_metadata", VIEW_METADATA)
|
||||
.put("read_cross_cluster", READ_CROSS_CLUSTER)
|
||||
.put("manage_follow_index", MANAGE_FOLLOW_INDEX)
|
||||
.put("manage_ilm", MANAGE_ILM)
|
||||
.immutableMap();
|
||||
|
||||
public static final Predicate<String> ACTION_MATCHER = ALL.predicate();
|
||||
|
|
|
@ -138,4 +138,57 @@ public class PrivilegeTests extends ESTestCase {
|
|||
assertThat(predicate.test("cluster:admin/xpack/whatever"), is(false));
|
||||
}
|
||||
|
||||
public void testIlmPrivileges() {
|
||||
{
|
||||
Predicate<String> predicate = ClusterPrivilege.MANAGE_ILM.predicate();
|
||||
// check cluster actions
|
||||
assertThat(predicate.test("cluster:admin/ilm/delete"), is(true));
|
||||
assertThat(predicate.test("cluster:admin/ilm/_move/post"), is(true));
|
||||
assertThat(predicate.test("cluster:admin/ilm/put"), is(true));
|
||||
assertThat(predicate.test("cluster:admin/ilm/start"), is(true));
|
||||
assertThat(predicate.test("cluster:admin/ilm/stop"), is(true));
|
||||
assertThat(predicate.test("cluster:admin/ilm/brand_new_api"), is(true));
|
||||
assertThat(predicate.test("cluster:admin/ilm/get"), is(true));
|
||||
assertThat(predicate.test("cluster:admin/ilm/operation_mode/get"), is(true));
|
||||
// check non-ilm action
|
||||
assertThat(predicate.test("cluster:admin/whatever"), is(false));
|
||||
}
|
||||
|
||||
{
|
||||
Predicate<String> predicate = ClusterPrivilege.READ_ILM.predicate();
|
||||
// check cluster actions
|
||||
assertThat(predicate.test("cluster:admin/ilm/delete"), is(false));
|
||||
assertThat(predicate.test("cluster:admin/ilm/_move/post"), is(false));
|
||||
assertThat(predicate.test("cluster:admin/ilm/put"), is(false));
|
||||
assertThat(predicate.test("cluster:admin/ilm/start"), is(false));
|
||||
assertThat(predicate.test("cluster:admin/ilm/stop"), is(false));
|
||||
assertThat(predicate.test("cluster:admin/ilm/brand_new_api"), is(false));
|
||||
assertThat(predicate.test("cluster:admin/ilm/get"), is(true));
|
||||
assertThat(predicate.test("cluster:admin/ilm/operation_mode/get"), is(true));
|
||||
// check non-ilm action
|
||||
assertThat(predicate.test("cluster:admin/whatever"), is(false));
|
||||
}
|
||||
|
||||
{
|
||||
Predicate<String> predicate = IndexPrivilege.MANAGE_ILM.predicate();
|
||||
// check indices actions
|
||||
assertThat(predicate.test("indices:admin/ilm/retry"), is(true));
|
||||
assertThat(predicate.test("indices:admin/ilm/remove_policy"), is(true));
|
||||
assertThat(predicate.test("indices:admin/ilm/brand_new_api"), is(true));
|
||||
assertThat(predicate.test("indices:admin/ilm/explain"), is(true));
|
||||
// check non-ilm action
|
||||
assertThat(predicate.test("indices:admin/whatever"), is(false));
|
||||
}
|
||||
|
||||
{
|
||||
Predicate<String> predicate = IndexPrivilege.VIEW_METADATA.predicate();
|
||||
// check indices actions
|
||||
assertThat(predicate.test("indices:admin/ilm/retry"), is(false));
|
||||
assertThat(predicate.test("indices:admin/ilm/remove_policy"), is(false));
|
||||
assertThat(predicate.test("indices:admin/ilm/brand_new_api"), is(false));
|
||||
assertThat(predicate.test("indices:admin/ilm/explain"), is(true));
|
||||
// check non-ilm action
|
||||
assertThat(predicate.test("indices:admin/whatever"), is(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
ilm:
|
||||
cluster:
|
||||
- monitor
|
||||
- manage
|
||||
- manage_ilm
|
||||
indices:
|
||||
- names: [ 'view-only-*' ]
|
||||
privileges:
|
||||
- view_index_metadata
|
||||
- names: [ 'ilm-*' ]
|
||||
privileges:
|
||||
- monitor
|
||||
|
|
|
@ -119,6 +119,13 @@ public class PermissionsIT extends ESRestTestCase {
|
|||
});
|
||||
}
|
||||
|
||||
public void testCanViewExplainOnUnmanagedIndex() throws Exception {
|
||||
createIndexAsAdmin("view-only-ilm", indexSettingsWithPolicy, "");
|
||||
Request request = new Request("GET", "/view-only-ilm/_ilm/explain");
|
||||
// test_ilm user has permissions to view
|
||||
assertOK(client().performRequest(request));
|
||||
}
|
||||
|
||||
private void createNewSingletonPolicy(String policy, String phaseName, LifecycleAction action) throws IOException {
|
||||
Phase phase = new Phase(phaseName, TimeValue.ZERO, singletonMap(action.getWriteableName(), action));
|
||||
LifecyclePolicy lifecyclePolicy = new LifecyclePolicy(policy, singletonMap(phase.getName(), phase));
|
||||
|
|
Loading…
Reference in New Issue