Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[7.x] Prevent putting V2 index template when overlapping with existing template (#54933) #55042

Merged
merged 1 commit into from
Apr 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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