Skip to content

Commit

Permalink
Prevent putting V2 index template when overlapping with existing temp…
Browse files Browse the repository at this point in the history
…late (elastic#54933)

* Prevent putting V2 index template when overlapping with existing template

This change prevents putting V2 index template when it would overlap with existing V2 template
of the same priority

Relates to elastic#53101
  • Loading branch information
probakowski committed Apr 10, 2020
1 parent a7e4f79 commit 365df7f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,23 @@ ClusterState addIndexTemplateV2(final ClusterState currentState, final boolean c
throw new IllegalArgumentException("index template [" + name + "] already exists");
}

Map<String, List<String>> overlaps = findConflictingV1Templates(currentState, name, template.indexPatterns());
Map<String, List<String>> overlaps = findConflictingV2Templates(currentState, name, template.indexPatterns(), true,
template.priority());
if (overlaps.size() > 0) {
String error = String.format(Locale.ROOT, "index template [%s] has index patterns %s matching patterns from " +
"existing templates [%s] with patterns (%s) that have the same priority [%d], multiple index templates may not " +
"match during index creation, please use a different priority",
name,
template.indexPatterns(),
Strings.collectionToCommaDelimitedString(overlaps.keySet()),
overlaps.entrySet().stream()
.map(e -> e.getKey() + " => " + e.getValue())
.collect(Collectors.joining(",")),
template.priority());
throw new IllegalArgumentException(error);
}

overlaps = findConflictingV1Templates(currentState, name, template.indexPatterns());
if (overlaps.size() > 0) {
String warning = String.format(Locale.ROOT, "index template [%s] has index patterns %s matching patterns from " +
"existing older templates [%s] with patterns (%s); this template [%s] will take precedence during new index creation",
Expand Down Expand Up @@ -385,16 +401,27 @@ static Map<String, List<String>> findConflictingV1Templates(final ClusterState s
*/
static Map<String, List<String>> findConflictingV2Templates(final ClusterState state, final String candidateName,
final List<String> indexPatterns) {
return findConflictingV2Templates(state, candidateName, indexPatterns, false, null);
}

/**
* Return a map of v2 template names to their index patterns for v2 templates that would overlap
* with the given template's index patterns.
*/
static Map<String, List<String>> findConflictingV2Templates(final ClusterState state, final String candidateName,
final List<String> indexPatterns, boolean checkPriority, Long priority) {
Automaton v1automaton = Regex.simpleMatchToAutomaton(indexPatterns.toArray(Strings.EMPTY_ARRAY));
Map<String, List<String>> overlappingTemplates = new HashMap<>();
for (Map.Entry<String, IndexTemplateV2> entry : state.metadata().templatesV2().entrySet()) {
String name = entry.getKey();
IndexTemplateV2 template = entry.getValue();
Automaton v2automaton = Regex.simpleMatchToAutomaton(template.indexPatterns().toArray(Strings.EMPTY_ARRAY));
if (Operations.isEmpty(Operations.intersection(v1automaton, v2automaton)) == false) {
logger.debug("old template {} and index template {} would overlap: {} <=> {}",
candidateName, name, indexPatterns, template.indexPatterns());
overlappingTemplates.put(name, template.indexPatterns());
if (checkPriority == false || Objects.equals(priority, template.priority())) {
logger.debug("old template {} and index template {} would overlap: {} <=> {}",
candidateName, name, indexPatterns, template.indexPatterns());
overlappingTemplates.put(name, template.indexPatterns());
}
}
}
return overlappingTemplates;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,16 @@ public void testAddIndexTemplateV2() throws Exception {
assertNotNull(state.metadata().templatesV2().get("foo"));
assertTemplatesEqual(state.metadata().templatesV2().get("foo"), template);


IndexTemplateV2 newTemplate = randomValueOtherThanMany(t -> Objects.equals(template.priority(), t.priority()),
IndexTemplateV2Tests::randomInstance);

final ClusterState throwState = ClusterState.builder(state).build();
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> metadataIndexTemplateService.addIndexTemplateV2(throwState, true, "foo", template));
() -> metadataIndexTemplateService.addIndexTemplateV2(throwState, true, "foo", newTemplate));
assertThat(e.getMessage(), containsString("index template [foo] already exists"));

state = metadataIndexTemplateService.addIndexTemplateV2(state, randomBoolean(), "bar", template);
state = metadataIndexTemplateService.addIndexTemplateV2(state, randomBoolean(), "bar", newTemplate);
assertNotNull(state.metadata().templatesV2().get("bar"));
}

Expand Down Expand Up @@ -471,6 +475,18 @@ public void testUpdatingV1NonStarWithChangedPatternsTemplateGeneratesError() thr
"templates (/_index_template) instead"));
}

public void testPuttingOverlappingV2Template() throws Exception {
IndexTemplateV2 template = new IndexTemplateV2(Arrays.asList("egg*", "baz"), null, null, 1L, null, null);
MetadataIndexTemplateService metadataIndexTemplateService = getMetadataIndexTemplateService();
ClusterState state = metadataIndexTemplateService.addIndexTemplateV2(ClusterState.EMPTY_STATE, false, "foo", template);
IndexTemplateV2 newTemplate = new IndexTemplateV2(Arrays.asList("abc", "baz*"), null, null, 1L, null, null);
IllegalArgumentException e = expectThrows(IllegalArgumentException.class,
() -> metadataIndexTemplateService.addIndexTemplateV2(state, false, "foo2", newTemplate));
assertThat(e.getMessage(), equalTo("index template [foo2] has index patterns [abc, baz*] matching patterns from existing " +
"templates [foo] with patterns (foo => [egg*, baz]) that have the same priority [1], multiple index templates may not " +
"match during index creation, please use a different priority"));
}

public void testFindV2Templates() throws Exception {
final MetadataIndexTemplateService service = getMetadataIndexTemplateService();
ClusterState state = ClusterState.EMPTY_STATE;
Expand Down

0 comments on commit 365df7f

Please sign in to comment.