Skip to content

Commit 844830d

Browse files
committed
Merge branch 'master' into generalize-remote-license-check
* master: NETWORKING: Make RemoteClusterConn. Lazy Resolve DNS (elastic#32764) [DOCS] Splits the users API documentation into multiple pages (elastic#32825) [DOCS] Splits the token APIs into separate pages (elastic#32865) [DOCS] Creates redirects for role management APIs page Bypassing failing test PainlessDomainSplitIT#testHRDSplit (elastic#32966) TEST: Mute testRetentionPolicyChangeDuringRecovery [DOCS] Fixes more broken links to role management APIs [Docs] Tweaks and fixes to rollup docs [DOCS] Fixes links to role management APIs [ML][TEST] Fix BasicRenormalizationIT after adding multibucket feature [DOCS] Splits the roles API documentation into multiple pages (elastic#32794) [TEST] Run pre 6.4 nodes in non-FIPS JVMs (elastic#32901) Make Geo Context Mapping Parsing More Strict (elastic#32821)
2 parents 3744702 + f82bb64 commit 844830d

File tree

57 files changed

+1155
-657
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+1155
-657
lines changed

buildSrc/src/main/groovy/org/elasticsearch/gradle/test/NodeInfo.groovy

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,12 @@ class NodeInfo {
177177
javaVersion = 8
178178
} else if (nodeVersion.onOrAfter("6.2.0") && nodeVersion.before("6.3.0")) {
179179
javaVersion = 9
180+
} else if (project.inFipsJvm && nodeVersion.onOrAfter("6.3.0") && nodeVersion.before("6.4.0")) {
181+
/*
182+
* Elasticsearch versions before 6.4.0 cannot be run in a FIPS-140 JVM. If we're running
183+
* bwc tests in a FIPS-140 JVM, ensure that the pre v6.4.0 nodes use a Java 10 JVM instead.
184+
*/
185+
javaVersion = 10
180186
}
181187

182188
args.addAll("-E", "node.portsfile=true")

docs/reference/migration/migrate_7_0/search.asciidoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ deprecated in 6.x, has been removed. Context enabled suggestion queries
9292
without contexts have to visit every suggestion, which degrades the search performance
9393
considerably.
9494

95+
For geo context the value of the `path` parameter is now validated against the mapping,
96+
and the context is only accepted if `path` points to a field with `geo_point` type.
97+
9598
==== Semantics changed for `max_concurrent_shard_requests`
9699

97100
`max_concurrent_shard_requests` used to limit the total number of concurrent shard

docs/reference/redirects.asciidoc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,3 +503,31 @@ guide to the {painless}/index.html[Painless Scripting Language].
503503

504504
See the {painless}/painless-api-reference.html[Painless API Reference] in
505505
the guide to the {painless}/index.html[Painless Scripting Language].
506+
507+
[role="exclude", id="security-api-roles"]
508+
=== Role management APIs
509+
510+
You can use the following APIs to add, remove, and retrieve roles in the native realm:
511+
512+
* <<security-api-put-role,Create role>>, <<security-api-delete-role,Delete role>>
513+
* <<security-api-clear-role-cache,Clear roles cache>>
514+
* <<security-api-get-role,Get roles>>
515+
516+
[role="exclude",id="security-api-tokens"]
517+
=== Token management APIs
518+
519+
You can use the following APIs to create and invalidate bearer tokens for access
520+
without requiring basic authentication:
521+
522+
* <<security-api-get-token,Get token>>, <<security-api-invalidate-token,Invalidate token>>
523+
524+
[role="exclude",id="security-api-users"]
525+
=== User Management APIs
526+
527+
You can use the following APIs to create, read, update, and delete users from the
528+
native realm:
529+
530+
* <<security-api-put-user,Create users>>, <<security-api-delete-user,Delete users>>
531+
* <<security-api-enable-user,Enable users>>, <<security-api-disable-user,Disable users>>
532+
* <<security-api-change-password,Change passwords>>
533+
* <<security-api-get-user,Get users>>

server/src/main/java/org/elasticsearch/index/mapper/MapperService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@
5252
import org.elasticsearch.index.similarity.SimilarityService;
5353
import org.elasticsearch.indices.InvalidTypeNameException;
5454
import org.elasticsearch.indices.mapper.MapperRegistry;
55+
import org.elasticsearch.search.suggest.completion.context.ContextMapping;
5556

5657
import java.io.Closeable;
5758
import java.io.IOException;
@@ -421,6 +422,8 @@ private synchronized Map<String, DocumentMapper> internalMerge(@Nullable Documen
421422
MapperMergeValidator.validateFieldReferences(fieldMappers, fieldAliasMappers,
422423
fullPathObjectMappers, fieldTypes);
423424

425+
ContextMapping.validateContextPaths(indexSettings.getIndexVersionCreated(), fieldMappers, fieldTypes::get);
426+
424427
if (reason == MergeReason.MAPPING_UPDATE) {
425428
// this check will only be performed on the master node when there is
426429
// a call to the update mapping API. For all other cases like

server/src/main/java/org/elasticsearch/search/suggest/completion/context/ContextMapping.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
package org.elasticsearch.search.suggest.completion.context;
2121

2222
import org.elasticsearch.ElasticsearchParseException;
23+
import org.elasticsearch.Version;
2324
import org.elasticsearch.common.Strings;
2425
import org.elasticsearch.common.xcontent.ToXContent;
2526
import org.elasticsearch.common.xcontent.ToXContentFragment;
@@ -28,13 +29,16 @@
2829
import org.elasticsearch.common.xcontent.XContentParser.Token;
2930
import org.elasticsearch.common.xcontent.json.JsonXContent;
3031
import org.elasticsearch.index.mapper.CompletionFieldMapper;
32+
import org.elasticsearch.index.mapper.FieldMapper;
33+
import org.elasticsearch.index.mapper.MappedFieldType;
3134
import org.elasticsearch.index.mapper.ParseContext;
3235

3336
import java.io.IOException;
3437
import java.util.ArrayList;
3538
import java.util.List;
3639
import java.util.Objects;
3740
import java.util.Set;
41+
import java.util.function.Function;
3842

3943
/**
4044
* A {@link ContextMapping} defines criteria that can be used to
@@ -131,6 +135,31 @@ public final List<InternalQueryContext> parseQueryContext(XContentParser parser)
131135
*/
132136
protected abstract XContentBuilder toInnerXContent(XContentBuilder builder, Params params) throws IOException;
133137

138+
/**
139+
* Checks if the current context is consistent with the rest of the fields. For example, the GeoContext
140+
* should check that the field that it points to has the correct type.
141+
*/
142+
protected void validateReferences(Version indexVersionCreated, Function<String, MappedFieldType> fieldResolver) {
143+
// No validation is required by default
144+
}
145+
146+
/**
147+
* Verifies that all field paths specified in contexts point to the fields with correct mappings
148+
*/
149+
public static void validateContextPaths(Version indexVersionCreated, List<FieldMapper> fieldMappers,
150+
Function<String, MappedFieldType> fieldResolver) {
151+
for (FieldMapper fieldMapper : fieldMappers) {
152+
if (CompletionFieldMapper.CONTENT_TYPE.equals(fieldMapper.typeName())) {
153+
CompletionFieldMapper.CompletionFieldType fieldType = ((CompletionFieldMapper) fieldMapper).fieldType();
154+
if (fieldType.hasContextMappings()) {
155+
for (ContextMapping context : fieldType.getContextMappings()) {
156+
context.validateReferences(indexVersionCreated, fieldResolver);
157+
}
158+
}
159+
}
160+
}
161+
}
162+
134163
@Override
135164
public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
136165
builder.field(FIELD_NAME, name);

server/src/main/java/org/elasticsearch/search/suggest/completion/context/ContextMappings.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
import java.util.Collections;
3838
import java.util.HashMap;
3939
import java.util.HashSet;
40+
import java.util.Iterator;
4041
import java.util.List;
4142
import java.util.Map;
4243
import java.util.Objects;
@@ -50,7 +51,7 @@
5051
* and creates context queries for defined {@link ContextMapping}s
5152
* for a {@link CompletionFieldMapper}
5253
*/
53-
public class ContextMappings implements ToXContent {
54+
public class ContextMappings implements ToXContent, Iterable<ContextMapping<?>> {
5455

5556
private final List<ContextMapping<?>> contextMappings;
5657
private final Map<String, ContextMapping<?>> contextNameMap;
@@ -97,6 +98,11 @@ public void addField(ParseContext.Document document, String name, String input,
9798
document.add(new TypedContextField(name, input, weight, contexts, document));
9899
}
99100

101+
@Override
102+
public Iterator<ContextMapping<?>> iterator() {
103+
return contextMappings.iterator();
104+
}
105+
100106
/**
101107
* Field prepends context values with a suggestion
102108
* Context values are associated with a type, denoted by

server/src/main/java/org/elasticsearch/search/suggest/completion/context/GeoContextMapping.java

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,17 @@
1919

2020
package org.elasticsearch.search.suggest.completion.context;
2121

22+
import org.apache.logging.log4j.LogManager;
23+
import org.apache.lucene.document.LatLonDocValuesField;
24+
import org.apache.lucene.document.LatLonPoint;
2225
import org.apache.lucene.document.StringField;
2326
import org.apache.lucene.index.DocValuesType;
2427
import org.apache.lucene.index.IndexableField;
2528
import org.elasticsearch.ElasticsearchParseException;
29+
import org.elasticsearch.Version;
2630
import org.elasticsearch.common.geo.GeoPoint;
2731
import org.elasticsearch.common.geo.GeoUtils;
32+
import org.elasticsearch.common.logging.DeprecationLogger;
2833
import org.elasticsearch.common.unit.DistanceUnit;
2934
import org.elasticsearch.common.xcontent.XContentBuilder;
3035
import org.elasticsearch.common.xcontent.XContentParser;
@@ -42,6 +47,7 @@
4247
import java.util.Map;
4348
import java.util.Objects;
4449
import java.util.Set;
50+
import java.util.function.Function;
4551
import java.util.stream.Collectors;
4652

4753
import static org.elasticsearch.common.geo.GeoHashUtils.addNeighbors;
@@ -69,6 +75,8 @@ public class GeoContextMapping extends ContextMapping<GeoQueryContext> {
6975
static final String CONTEXT_PRECISION = "precision";
7076
static final String CONTEXT_NEIGHBOURS = "neighbours";
7177

78+
private static final DeprecationLogger DEPRECATION_LOGGER = new DeprecationLogger(LogManager.getLogger(GeoContextMapping.class));
79+
7280
private final int precision;
7381
private final String fieldName;
7482

@@ -205,11 +213,11 @@ public Set<CharSequence> parseContext(Document document) {
205213
for (IndexableField field : fields) {
206214
if (field instanceof StringField) {
207215
spare.resetFromString(field.stringValue());
208-
} else {
209-
// todo return this to .stringValue() once LatLonPoint implements it
216+
geohashes.add(spare.geohash());
217+
} else if (field instanceof LatLonPoint || field instanceof LatLonDocValuesField) {
210218
spare.resetFromIndexableField(field);
219+
geohashes.add(spare.geohash());
211220
}
212-
geohashes.add(spare.geohash());
213221
}
214222
}
215223
}
@@ -279,6 +287,32 @@ public List<InternalQueryContext> toInternalQueryContexts(List<GeoQueryContext>
279287
return internalQueryContextList;
280288
}
281289

290+
@Override
291+
protected void validateReferences(Version indexVersionCreated, Function<String, MappedFieldType> fieldResolver) {
292+
if (fieldName != null) {
293+
MappedFieldType mappedFieldType = fieldResolver.apply(fieldName);
294+
if (mappedFieldType == null) {
295+
if (indexVersionCreated.before(Version.V_7_0_0_alpha1)) {
296+
DEPRECATION_LOGGER.deprecatedAndMaybeLog("geo_context_mapping",
297+
"field [{}] referenced in context [{}] is not defined in the mapping", fieldName, name);
298+
} else {
299+
throw new ElasticsearchParseException(
300+
"field [{}] referenced in context [{}] is not defined in the mapping", fieldName, name);
301+
}
302+
} else if (GeoPointFieldMapper.CONTENT_TYPE.equals(mappedFieldType.typeName()) == false) {
303+
if (indexVersionCreated.before(Version.V_7_0_0_alpha1)) {
304+
DEPRECATION_LOGGER.deprecatedAndMaybeLog("geo_context_mapping",
305+
"field [{}] referenced in context [{}] must be mapped to geo_point, found [{}]",
306+
fieldName, name, mappedFieldType.typeName());
307+
} else {
308+
throw new ElasticsearchParseException(
309+
"field [{}] referenced in context [{}] must be mapped to geo_point, found [{}]",
310+
fieldName, name, mappedFieldType.typeName());
311+
}
312+
}
313+
}
314+
}
315+
282316
@Override
283317
public boolean equals(Object o) {
284318
if (this == o) return true;

server/src/main/java/org/elasticsearch/transport/RemoteClusterAware.java

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
*/
1919
package org.elasticsearch.transport;
2020

21+
import java.util.function.Supplier;
2122
import org.elasticsearch.Version;
2223
import org.elasticsearch.cluster.metadata.ClusterNameExpressionResolver;
2324
import org.elasticsearch.cluster.node.DiscoveryNode;
@@ -48,9 +49,20 @@ public abstract class RemoteClusterAware extends AbstractComponent {
4849
/**
4950
* A list of initial seed nodes to discover eligible nodes from the remote cluster
5051
*/
51-
public static final Setting.AffixSetting<List<InetSocketAddress>> REMOTE_CLUSTERS_SEEDS = Setting.affixKeySetting("search.remote.",
52-
"seeds", (key) -> Setting.listSetting(key, Collections.emptyList(), RemoteClusterAware::parseSeedAddress,
53-
Setting.Property.NodeScope, Setting.Property.Dynamic));
52+
public static final Setting.AffixSetting<List<String>> REMOTE_CLUSTERS_SEEDS = Setting.affixKeySetting(
53+
"search.remote.",
54+
"seeds",
55+
key -> Setting.listSetting(
56+
key, Collections.emptyList(),
57+
s -> {
58+
// validate seed address
59+
parsePort(s);
60+
return s;
61+
},
62+
Setting.Property.NodeScope,
63+
Setting.Property.Dynamic
64+
)
65+
);
5466
public static final char REMOTE_CLUSTER_INDEX_SEPARATOR = ':';
5567
public static final String LOCAL_CLUSTER_GROUP_KEY = "";
5668

@@ -65,18 +77,20 @@ protected RemoteClusterAware(Settings settings) {
6577
this.clusterNameResolver = new ClusterNameExpressionResolver(settings);
6678
}
6779

68-
protected static Map<String, List<DiscoveryNode>> buildRemoteClustersSeeds(Settings settings) {
69-
Stream<Setting<List<InetSocketAddress>>> allConcreteSettings = REMOTE_CLUSTERS_SEEDS.getAllConcreteSettings(settings);
80+
protected static Map<String, List<Supplier<DiscoveryNode>>> buildRemoteClustersSeeds(Settings settings) {
81+
Stream<Setting<List<String>>> allConcreteSettings = REMOTE_CLUSTERS_SEEDS.getAllConcreteSettings(settings);
7082
return allConcreteSettings.collect(
7183
Collectors.toMap(REMOTE_CLUSTERS_SEEDS::getNamespace, concreteSetting -> {
7284
String clusterName = REMOTE_CLUSTERS_SEEDS.getNamespace(concreteSetting);
73-
List<DiscoveryNode> nodes = new ArrayList<>();
74-
for (InetSocketAddress address : concreteSetting.get(settings)) {
75-
TransportAddress transportAddress = new TransportAddress(address);
76-
DiscoveryNode node = new DiscoveryNode(clusterName + "#" + transportAddress.toString(),
77-
transportAddress,
78-
Version.CURRENT.minimumCompatibilityVersion());
79-
nodes.add(node);
85+
List<String> addresses = concreteSetting.get(settings);
86+
List<Supplier<DiscoveryNode>> nodes = new ArrayList<>(addresses.size());
87+
for (String address : addresses) {
88+
nodes.add(() -> {
89+
TransportAddress transportAddress = new TransportAddress(RemoteClusterAware.parseSeedAddress(address));
90+
return new DiscoveryNode(clusterName + "#" + transportAddress.toString(),
91+
transportAddress,
92+
Version.CURRENT.minimumCompatibilityVersion());
93+
});
8094
}
8195
return nodes;
8296
}));
@@ -128,7 +142,7 @@ public Map<String, List<String>> groupClusterIndices(String[] requestIndices, Pr
128142
* Subclasses must implement this to receive information about updated cluster aliases. If the given address list is
129143
* empty the cluster alias is unregistered and should be removed.
130144
*/
131-
protected abstract void updateRemoteCluster(String clusterAlias, List<InetSocketAddress> addresses);
145+
protected abstract void updateRemoteCluster(String clusterAlias, List<String> addresses);
132146

133147
/**
134148
* Registers this instance to listen to updates on the cluster settings.
@@ -138,27 +152,35 @@ public void listenForUpdates(ClusterSettings clusterSettings) {
138152
(namespace, value) -> {});
139153
}
140154

141-
private static InetSocketAddress parseSeedAddress(String remoteHost) {
142-
int portSeparator = remoteHost.lastIndexOf(':'); // in case we have a IPv6 address ie. [::1]:9300
143-
if (portSeparator == -1 || portSeparator == remoteHost.length()) {
144-
throw new IllegalArgumentException("remote hosts need to be configured as [host:port], found [" + remoteHost + "] instead");
145-
}
146-
String host = remoteHost.substring(0, portSeparator);
155+
protected static InetSocketAddress parseSeedAddress(String remoteHost) {
156+
String host = remoteHost.substring(0, indexOfPortSeparator(remoteHost));
147157
InetAddress hostAddress;
148158
try {
149159
hostAddress = InetAddress.getByName(host);
150160
} catch (UnknownHostException e) {
151161
throw new IllegalArgumentException("unknown host [" + host + "]", e);
152162
}
163+
return new InetSocketAddress(hostAddress, parsePort(remoteHost));
164+
}
165+
166+
private static int parsePort(String remoteHost) {
153167
try {
154-
int port = Integer.valueOf(remoteHost.substring(portSeparator + 1));
168+
int port = Integer.valueOf(remoteHost.substring(indexOfPortSeparator(remoteHost) + 1));
155169
if (port <= 0) {
156170
throw new IllegalArgumentException("port number must be > 0 but was: [" + port + "]");
157171
}
158-
return new InetSocketAddress(hostAddress, port);
172+
return port;
159173
} catch (NumberFormatException e) {
160-
throw new IllegalArgumentException("port must be a number", e);
174+
throw new IllegalArgumentException("failed to parse port", e);
175+
}
176+
}
177+
178+
private static int indexOfPortSeparator(String remoteHost) {
179+
int portSeparator = remoteHost.lastIndexOf(':'); // in case we have a IPv6 address ie. [::1]:9300
180+
if (portSeparator == -1 || portSeparator == remoteHost.length()) {
181+
throw new IllegalArgumentException("remote hosts need to be configured as [host:port], found [" + remoteHost + "] instead");
161182
}
183+
return portSeparator;
162184
}
163185

164186
public static String buildRemoteIndexName(String clusterAlias, String indexName) {

0 commit comments

Comments
 (0)