Merge branch 'master' into close-index-api-refactoring

This commit is contained in:
Tanguy Leroux 2018-12-13 17:40:06 +01:00
commit 1f6f236d44
15 changed files with 290 additions and 48 deletions

View File

@ -315,9 +315,11 @@ public final class Role {
public static final String MANAGE_PIPELINE = "manage_pipeline"; public static final String MANAGE_PIPELINE = "manage_pipeline";
public static final String MANAGE_CCR = "manage_ccr"; public static final String MANAGE_CCR = "manage_ccr";
public static final String READ_CCR = "read_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, 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_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 CREATE_INDEX = "create_index";
public static final String VIEW_INDEX_METADATA = "view_index_metadata"; 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_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, 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 };
} }
} }

View File

@ -45,6 +45,15 @@
# 10-:-XX:+UseG1GC # 10-:-XX:+UseG1GC
# 10-:-XX:InitiatingHeapOccupancyPercent=75 # 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 ## optimizations
# pre-touch memory pages used by the JVM during initialization # pre-touch memory pages used by the JVM during initialization

View File

@ -2,17 +2,18 @@
=== DNS cache settings === DNS cache settings
Elasticsearch runs with a security manager in place. With a security manager in Elasticsearch runs with a security manager in place. With a security manager in
place, the JVM defaults to caching positive hostname resolutions place, the JVM defaults to caching positive hostname resolutions indefinitely
indefinitely. If your Elasticsearch nodes rely on DNS in an environment where and defaults to caching negative hostname resolutions for ten
DNS resolutions vary with time (e.g., for node-to-node discovery) then you might seconds. Elasticsearch overrides this behavior with default values to cache
want to modify the default JVM behavior. This can be modified by adding 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>`] http://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html[`networkaddress.cache.ttl=<timeout>`]
to your and
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
http://docs.oracle.com/javase/8/docs/technotes/guides/net/properties.html[`networkaddress.cache.negative.ttl=<timeout>`] 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 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`.

View File

@ -36,6 +36,7 @@ import org.elasticsearch.node.NodeValidationException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.security.Permission; import java.security.Permission;
import java.security.Security;
import java.util.Arrays; import java.util.Arrays;
import java.util.Locale; import java.util.Locale;
@ -72,13 +73,19 @@ class Elasticsearch extends EnvironmentAwareCommand {
* Main entry point for starting elasticsearch * Main entry point for starting elasticsearch
*/ */
public static void main(final String[] args) throws Exception { 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 overrideDnsCachePolicyProperties();
// presence of a security manager or lack thereof act as if there is a security manager present (e.g., DNS cache policy) /*
* 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() { System.setSecurityManager(new SecurityManager() {
@Override @Override
public void checkPermission(Permission perm) { public void checkPermission(Permission perm) {
// grant all permissions so that we can later set the security manager to the one that we want // grant all permissions so that we can later set the security manager to the one that we want
} }
}); });
LogConfigurator.registerErrorListener(); LogConfigurator.registerErrorListener();
final Elasticsearch elasticsearch = new Elasticsearch(); 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 { static int main(final String[] args, final Elasticsearch elasticsearch, final Terminal terminal) throws Exception {
return elasticsearch.main(args, terminal); return elasticsearch.main(args, terminal);
} }

View File

@ -207,7 +207,9 @@ public abstract class MultiValuesSourceAggregationBuilder<VS extends ValuesSourc
public final XContentBuilder internalXContent(XContentBuilder builder, Params params) throws IOException { public final XContentBuilder internalXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(); builder.startObject();
if (fields != null) { 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) { if (format != null) {
builder.field(CommonFields.FORMAT.getPreferredName(), format); builder.field(CommonFields.FORMAT.getPreferredName(), format);

View File

@ -25,16 +25,17 @@ import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput; import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.io.stream.Writeable; import org.elasticsearch.common.io.stream.Writeable;
import org.elasticsearch.common.xcontent.ObjectParser; 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.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentParser; import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.joda.time.DateTimeZone; import org.joda.time.DateTimeZone;
import java.io.IOException; import java.io.IOException;
import java.util.Objects;
import java.util.function.BiFunction; import java.util.function.BiFunction;
public class MultiValuesSourceFieldConfig implements Writeable, ToXContentFragment { public class MultiValuesSourceFieldConfig implements Writeable, ToXContentObject {
private String fieldName; private String fieldName;
private Object missing; private Object missing;
private Script script; private Script script;
@ -110,6 +111,7 @@ public class MultiValuesSourceFieldConfig implements Writeable, ToXContentFragme
@Override @Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException { public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject();
if (missing != null) { if (missing != null) {
builder.field(ParseField.CommonFields.MISSING.getPreferredName(), missing); builder.field(ParseField.CommonFields.MISSING.getPreferredName(), missing);
} }
@ -120,11 +122,33 @@ public class MultiValuesSourceFieldConfig implements Writeable, ToXContentFragme
builder.field(ParseField.CommonFields.FIELD.getPreferredName(), fieldName); builder.field(ParseField.CommonFields.FIELD.getPreferredName(), fieldName);
} }
if (timeZone != null) { if (timeZone != null) {
builder.field(ParseField.CommonFields.TIME_ZONE.getPreferredName(), timeZone); builder.field(ParseField.CommonFields.TIME_ZONE.getPreferredName(), timeZone.getID());
} }
builder.endObject();
return builder; 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 { public static class Builder {
private String fieldName; private String fieldName;
private Object missing = null; private Object missing = null;

View File

@ -32,7 +32,7 @@ import org.elasticsearch.common.network.NetworkService;
import org.elasticsearch.common.settings.ClusterSettings; import org.elasticsearch.common.settings.ClusterSettings;
import org.elasticsearch.common.settings.Settings; import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.ByteSizeValue; 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.FaultDetection;
import org.elasticsearch.discovery.zen.MasterFaultDetection; import org.elasticsearch.discovery.zen.MasterFaultDetection;
import org.elasticsearch.discovery.zen.NodesFaultDetection; import org.elasticsearch.discovery.zen.NodesFaultDetection;
@ -43,10 +43,10 @@ import org.elasticsearch.test.ESTestCase;
import org.elasticsearch.test.transport.MockTransportService; import org.elasticsearch.test.transport.MockTransportService;
import org.elasticsearch.threadpool.TestThreadPool; import org.elasticsearch.threadpool.TestThreadPool;
import org.elasticsearch.threadpool.ThreadPool; import org.elasticsearch.threadpool.ThreadPool;
import org.elasticsearch.transport.MockTcpTransport;
import org.elasticsearch.transport.TransportConnectionListener; import org.elasticsearch.transport.TransportConnectionListener;
import org.elasticsearch.transport.TransportRequestOptions; import org.elasticsearch.transport.TransportRequestOptions;
import org.elasticsearch.transport.TransportService; import org.elasticsearch.transport.TransportService;
import org.elasticsearch.transport.nio.MockNioTransport;
import org.hamcrest.Matcher; import org.hamcrest.Matcher;
import org.hamcrest.Matchers; import org.hamcrest.Matchers;
import org.junit.After; import org.junit.After;
@ -138,8 +138,8 @@ public class ZenFaultDetectionTests extends ESTestCase {
// trace zenfd actions but keep the default otherwise // trace zenfd actions but keep the default otherwise
.putList(TransportService.TRACE_LOG_EXCLUDE_SETTING.getKey(), TransportLivenessAction.NAME) .putList(TransportService.TRACE_LOG_EXCLUDE_SETTING.getKey(), TransportLivenessAction.NAME)
.build(), .build(),
new MockTcpTransport(settings, threadPool, BigArrays.NON_RECYCLING_INSTANCE, circuitBreakerService, new MockNioTransport(settings, version, threadPool, new NetworkService(Collections.emptyList()),
namedWriteableRegistry, new NetworkService(Collections.emptyList()), version), PageCacheRecycler.NON_RECYCLING_INSTANCE, namedWriteableRegistry, circuitBreakerService),
threadPool, threadPool,
TransportService.NOOP_TRANSPORT_INTERCEPTOR, TransportService.NOOP_TRANSPORT_INTERCEPTOR,
(boundAddress) -> (boundAddress) ->

View File

@ -38,6 +38,7 @@ import org.elasticsearch.common.transport.BoundTransportAddress;
import org.elasticsearch.common.transport.TransportAddress; import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.common.unit.TimeValue; import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.BigArrays; 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.AbstractRunnable;
import org.elasticsearch.common.util.concurrent.ConcurrentCollections; import org.elasticsearch.common.util.concurrent.ConcurrentCollections;
import org.elasticsearch.common.util.concurrent.EsExecutors; 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.TransportRequestOptions;
import org.elasticsearch.transport.TransportResponseHandler; import org.elasticsearch.transport.TransportResponseHandler;
import org.elasticsearch.transport.TransportService; import org.elasticsearch.transport.TransportService;
import org.elasticsearch.transport.nio.MockNioTransport;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.mockito.Matchers; import org.mockito.Matchers;
@ -143,14 +145,14 @@ public class UnicastZenPingTests extends ESTestCase {
NetworkService networkService = new NetworkService(Collections.emptyList()); 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, s,
v,
threadPool, threadPool,
BigArrays.NON_RECYCLING_INSTANCE,
new NoneCircuitBreakerService(),
new NamedWriteableRegistry(Collections.emptyList()),
networkService, networkService,
v); PageCacheRecycler.NON_RECYCLING_INSTANCE,
new NamedWriteableRegistry(Collections.emptyList()),
new NoneCircuitBreakerService());
NetworkHandle handleA = startServices(settings, threadPool, "UZP_A", Version.CURRENT, supplier); NetworkHandle handleA = startServices(settings, threadPool, "UZP_A", Version.CURRENT, supplier);
closeables.push(handleA.transportService); closeables.push(handleA.transportService);
@ -268,14 +270,14 @@ public class UnicastZenPingTests extends ESTestCase {
final NetworkService networkService = new NetworkService(Collections.emptyList()); final NetworkService networkService = new NetworkService(Collections.emptyList());
final Map<String, TransportAddress[]> addresses = new HashMap<>(); 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, s,
v,
threadPool, threadPool,
BigArrays.NON_RECYCLING_INSTANCE,
new NoneCircuitBreakerService(),
new NamedWriteableRegistry(Collections.emptyList()),
networkService, networkService,
v) { PageCacheRecycler.NON_RECYCLING_INSTANCE,
new NamedWriteableRegistry(Collections.emptyList()),
new NoneCircuitBreakerService()) {
@Override @Override
public TransportAddress[] addressesFromString(String address, int perAddressLimit) throws UnknownHostException { public TransportAddress[] addressesFromString(String address, int perAddressLimit) throws UnknownHostException {
final TransportAddress[] transportAddresses = addresses.get(address); final TransportAddress[] transportAddresses = addresses.get(address);
@ -634,14 +636,14 @@ public class UnicastZenPingTests extends ESTestCase {
NetworkService networkService = new NetworkService(Collections.emptyList()); 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, s,
v,
threadPool, threadPool,
BigArrays.NON_RECYCLING_INSTANCE,
new NoneCircuitBreakerService(),
new NamedWriteableRegistry(Collections.emptyList()),
networkService, 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)); NetworkHandle handleA = startServices(settings, threadPool, "UZP_A", Version.CURRENT, supplier, EnumSet.allOf(Role.class));
closeables.push(handleA.transportService); closeables.push(handleA.transportService);
@ -689,15 +691,14 @@ public class UnicastZenPingTests extends ESTestCase {
public void testInvalidHosts() throws InterruptedException { public void testInvalidHosts() throws InterruptedException {
final Logger logger = mock(Logger.class); final Logger logger = mock(Logger.class);
final NetworkService networkService = new NetworkService(Collections.emptyList()); final Transport transport = new MockNioTransport(
final Transport transport = new MockTcpTransport(
Settings.EMPTY, Settings.EMPTY,
Version.CURRENT,
threadPool, threadPool,
BigArrays.NON_RECYCLING_INSTANCE, new NetworkService(Collections.emptyList()),
new NoneCircuitBreakerService(), PageCacheRecycler.NON_RECYCLING_INSTANCE,
new NamedWriteableRegistry(Collections.emptyList()), new NamedWriteableRegistry(Collections.emptyList()),
networkService, new NoneCircuitBreakerService()) {
Version.CURRENT) {
@Override @Override
public BoundTransportAddress boundAddress() { public BoundTransportAddress boundAddress() {
return new BoundTransportAddress( return new BoundTransportAddress(

View File

@ -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;
}
}

View File

@ -19,12 +19,37 @@
package org.elasticsearch.search.aggregations.support; 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.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; 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() { public void testMissingFieldScript() {
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> new MultiValuesSourceFieldConfig.Builder().build()); 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.")); assertThat(e.getMessage(), equalTo("[field] and [script] cannot both be null. Please specify one or the other."));

View File

@ -9,6 +9,8 @@ import org.apache.lucene.util.automaton.Automaton;
import org.elasticsearch.action.admin.cluster.state.ClusterStateAction; import org.elasticsearch.action.admin.cluster.state.ClusterStateAction;
import org.elasticsearch.common.Strings; import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.MapBuilder; 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.InvalidateTokenAction;
import org.elasticsearch.xpack.core.security.action.token.RefreshTokenAction; import org.elasticsearch.xpack.core.security.action.token.RefreshTokenAction;
import org.elasticsearch.xpack.core.security.action.user.HasPrivilegesAction; 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 = private static final Automaton MANAGE_CCR_AUTOMATON =
patterns("cluster:admin/xpack/ccr/*", ClusterStateAction.NAME, HasPrivilegesAction.NAME); 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 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 NONE = new ClusterPrivilege("none", Automatons.EMPTY);
public static final ClusterPrivilege ALL = new ClusterPrivilege("all", ALL_CLUSTER_AUTOMATON); 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_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 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 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(); 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_rollup", MANAGE_ROLLUP)
.put("manage_ccr", MANAGE_CCR) .put("manage_ccr", MANAGE_CCR)
.put("read_ccr", READ_CCR) .put("read_ccr", READ_CCR)
.put("manage_ilm", MANAGE_ILM)
.put("read_ilm", READ_ILM)
.immutableMap(); .immutableMap();
private static final ConcurrentHashMap<Set<String>, ClusterPrivilege> CACHE = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<Set<String>, ClusterPrivilege> CACHE = new ConcurrentHashMap<>();

View File

@ -24,6 +24,7 @@ import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.MapBuilder; import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.xpack.core.ccr.action.PutFollowAction; import org.elasticsearch.xpack.core.ccr.action.PutFollowAction;
import org.elasticsearch.xpack.core.ccr.action.UnfollowAction; 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 org.elasticsearch.xpack.core.security.support.Automatons;
import java.util.Arrays; 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 DELETE_INDEX_AUTOMATON = patterns(DeleteIndexAction.NAME);
private static final Automaton VIEW_METADATA_AUTOMATON = patterns(GetAliasesAction.NAME, AliasesExistAction.NAME, private static final Automaton VIEW_METADATA_AUTOMATON = patterns(GetAliasesAction.NAME, AliasesExistAction.NAME,
GetIndexAction.NAME, IndicesExistsAction.NAME, GetFieldMappingsAction.NAME + "*", GetMappingsAction.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, private static final Automaton MANAGE_FOLLOW_INDEX_AUTOMATON = patterns(PutFollowAction.NAME, UnfollowAction.NAME,
CloseIndexAction.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 NONE = new IndexPrivilege("none", Automatons.EMPTY);
public static final IndexPrivilege ALL = new IndexPrivilege("all", ALL_AUTOMATON); 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 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 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_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() private static final Map<String, IndexPrivilege> VALUES = MapBuilder.<String, IndexPrivilege>newMapBuilder()
.put("none", NONE) .put("none", NONE)
@ -91,6 +95,7 @@ public final class IndexPrivilege extends Privilege {
.put("view_index_metadata", VIEW_METADATA) .put("view_index_metadata", VIEW_METADATA)
.put("read_cross_cluster", READ_CROSS_CLUSTER) .put("read_cross_cluster", READ_CROSS_CLUSTER)
.put("manage_follow_index", MANAGE_FOLLOW_INDEX) .put("manage_follow_index", MANAGE_FOLLOW_INDEX)
.put("manage_ilm", MANAGE_ILM)
.immutableMap(); .immutableMap();
public static final Predicate<String> ACTION_MATCHER = ALL.predicate(); public static final Predicate<String> ACTION_MATCHER = ALL.predicate();

View File

@ -138,4 +138,57 @@ public class PrivilegeTests extends ESTestCase {
assertThat(predicate.test("cluster:admin/xpack/whatever"), is(false)); 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));
}
}
} }

View File

@ -1,8 +1,11 @@
ilm: ilm:
cluster: cluster:
- monitor - monitor
- manage - manage_ilm
indices: indices:
- names: [ 'view-only-*' ]
privileges:
- view_index_metadata
- names: [ 'ilm-*' ] - names: [ 'ilm-*' ]
privileges: privileges:
- monitor - monitor

View File

@ -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 { private void createNewSingletonPolicy(String policy, String phaseName, LifecycleAction action) throws IOException {
Phase phase = new Phase(phaseName, TimeValue.ZERO, singletonMap(action.getWriteableName(), action)); Phase phase = new Phase(phaseName, TimeValue.ZERO, singletonMap(action.getWriteableName(), action));
LifecyclePolicy lifecyclePolicy = new LifecyclePolicy(policy, singletonMap(phase.getName(), phase)); LifecyclePolicy lifecyclePolicy = new LifecyclePolicy(policy, singletonMap(phase.getName(), phase));