Commit 05827413 authored by Nils Bandener's avatar Nils Bandener
Browse files

Support for IndicesAliasesRequest in PrivilegesInterceptor

parent 840b7ef4
......@@ -28,6 +28,8 @@ import org.elasticsearch.ElasticsearchSecurityException;
import org.elasticsearch.action.ActionRequest;
import org.elasticsearch.action.DocWriteRequest;
import org.elasticsearch.action.IndicesRequest.Replaceable;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsIndexRequest;
import org.elasticsearch.action.admin.indices.mapping.get.GetFieldMappingsRequest;
......@@ -72,8 +74,9 @@ public class PrivilegesInterceptorImpl extends PrivilegesInterceptor {
this.kibanaServerUsername = dynamicConfigModel.getKibanaServerUsername();//config.dynamic.kibana.server_username;
this.kibanaIndexName = dynamicConfigModel.getKibanaIndexname();//config.dynamic.kibana.index;
this.kibanaIndexNamePrefix = this.kibanaIndexName + "_";
this.versionedKibanaIndexPattern = Pattern.compile(Pattern.quote(this.kibanaIndexName) + "(_-?[0-9]+_[a-z0-9]+)?(_\\d+\\.\\d+\\.\\d+)");
this.kibanaIndexPatternWithTenant = Pattern.compile(Pattern.quote(this.kibanaIndexName) + "(_-?[0-9]+_[a-z0-9]+)");
this.versionedKibanaIndexPattern = Pattern
.compile(Pattern.quote(this.kibanaIndexName) + "(_-?[0-9]+_[a-z0-9]+)?(_[0-9]+\\.[0-9]+\\.[0-9]+(_[0-9]{3})?)");
this.kibanaIndexPatternWithTenant = Pattern.compile(Pattern.quote(this.kibanaIndexName) + "(_-?[0-9]+_[a-z0-9]+(_[0-9]{3})?)");
this.configModel = configModel;
}
......@@ -150,7 +153,7 @@ public class PrivilegesInterceptorImpl extends PrivilegesInterceptor {
} else {
if (isTenantAllowed(request, action, user, sgRoles, requestedTenant)) {
if (kibanaIndexInfo.isReplacementNeeded()) {
replaceIndex(request, kibanaIndexName, kibanaIndexInfo.toInternalIndexName(user), action);
replaceIndex(request, kibanaIndexInfo.originalName, kibanaIndexInfo.toInternalIndexName(user), action, user);
}
return ALLOW;
} else {
......@@ -164,7 +167,7 @@ public class PrivilegesInterceptorImpl extends PrivilegesInterceptor {
}
private void replaceIndex(final ActionRequest request, final String oldIndexName, final String newIndexName, final String action) {
private void replaceIndex(ActionRequest request, String oldIndexName, String newIndexName, String action, User user) {
boolean kibOk = false;
if (log.isDebugEnabled()) {
......@@ -248,6 +251,53 @@ public class PrivilegesInterceptorImpl extends PrivilegesInterceptor {
} else if (request instanceof Replaceable) {
Replaceable replaceableRequest = (Replaceable) request;
replaceableRequest.indices(newIndexNames);
kibOk = true;
} else if (request instanceof IndicesAliasesRequest) {
IndicesAliasesRequest indicesAliasesRequest = (IndicesAliasesRequest) request;
for (AliasActions aliasActions : indicesAliasesRequest.getAliasActions()) {
if (aliasActions.indices() == null || aliasActions.indices().length != 1) {
// This is guarded by replaceKibanaIndex()
// Only actions operating on a single Kibana index should arrive here.
log.warn("Unexpected AliasActions: " + aliasActions);
continue;
}
if (!aliasActions.indices()[0].equals(oldIndexName)) {
// This is guarded by replaceKibanaIndex()
// Only actions operating on a single Kibana index should arrive here.
log.warn("Unexpected AliasActions: " + aliasActions + "; expected index: " + oldIndexName);
continue;
}
aliasActions.index(newIndexName);
if (aliasActions.actionType() != AliasActions.Type.REMOVE_INDEX) {
if (aliasActions.aliases() == null) {
log.warn("Unexpected AliasActions: " + aliasActions);
continue;
}
String[] aliases = aliasActions.aliases();
String[] newAliases = new String[aliases.length];
for (int i = 0; i < aliases.length; i++) {
IndexInfo indexInfo = checkForExclusivelyUsedKibanaIndexOrAlias(aliases[i]);
if (indexInfo != null && indexInfo.isReplacementNeeded()) {
newAliases[i] = indexInfo.toInternalIndexName(user);
} else {
newAliases[i] = aliases[i];
}
}
aliasActions.aliases(newAliases);
}
if (log.isDebugEnabled()) {
log.debug("Rewritten IndicesAliasesRequest: " + indicesAliasesRequest.getAliasActions());
}
}
kibOk = true;
} else {
log.warn("Dont know what to do (1) with {}", request.getClass());
......@@ -259,23 +309,28 @@ public class PrivilegesInterceptorImpl extends PrivilegesInterceptor {
}
private IndexInfo checkForExclusivelyUsedKibanaIndexOrAlias(Resolved requestedResolved) {
String alias;
String aliasOrIndex;
if (requestedResolved.getAliases().size() == 1) {
alias = requestedResolved.getAliases().iterator().next();
aliasOrIndex = requestedResolved.getAliases().iterator().next();
} else if (requestedResolved.getAllIndices().size() == 1) {
alias = requestedResolved.getAllIndices().iterator().next();
aliasOrIndex = requestedResolved.getAllIndices().iterator().next();
} else {
return null;
}
if (alias.equals(kibanaIndexName)) {
return checkForExclusivelyUsedKibanaIndexOrAlias(aliasOrIndex);
}
private IndexInfo checkForExclusivelyUsedKibanaIndexOrAlias(String aliasOrIndex) {
if (aliasOrIndex.equals(kibanaIndexName)) {
// Pre 7.12: Just .kibana
return new IndexInfo(alias, kibanaIndexName, null);
return new IndexInfo(aliasOrIndex, kibanaIndexName, null);
}
if (alias.startsWith(kibanaIndexNamePrefix)) {
Matcher matcher = versionedKibanaIndexPattern.matcher(alias);
if (aliasOrIndex.startsWith(kibanaIndexNamePrefix)) {
Matcher matcher = versionedKibanaIndexPattern.matcher(aliasOrIndex);
if (matcher.matches()) {
// Post 7.12: .kibana_7.12.0
......@@ -283,20 +338,20 @@ public class PrivilegesInterceptorImpl extends PrivilegesInterceptor {
// Suffix will be: _7.12.0
if (matcher.group(1) == null) {
// Basic case
return new IndexInfo(alias, kibanaIndexName, matcher.group(2));
return new IndexInfo(aliasOrIndex, kibanaIndexName, matcher.group(2));
} else {
// We have here the case that the index replacement has been already applied.
// This can happen when internal ES operations trigger further operations, e.g. an index triggers an auto_create.
return new IndexInfo(alias, kibanaIndexName, matcher.group(2), matcher.group(1));
return new IndexInfo(aliasOrIndex, kibanaIndexName, matcher.group(2), matcher.group(1));
}
}
matcher = kibanaIndexPatternWithTenant.matcher(alias);
matcher = kibanaIndexPatternWithTenant.matcher(aliasOrIndex);
if (matcher.matches()) {
// Pre 7.12: .kibana_12345678_tenantname
return new IndexInfo(alias, kibanaIndexName, null, matcher.group(1));
return new IndexInfo(aliasOrIndex, kibanaIndexName, null, matcher.group(1));
}
}
......
......@@ -19,15 +19,24 @@ import java.util.Map;
import org.apache.http.HttpStatus;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.admin.indices.alias.Alias;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.IndicesAliasesRequest.AliasActions;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesRequest;
import org.elasticsearch.action.admin.indices.alias.get.GetAliasesResponse;
import org.elasticsearch.action.admin.indices.create.CreateIndexRequest;
import org.elasticsearch.action.admin.indices.delete.DeleteIndexRequest;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.get.MultiGetItemResponse;
import org.elasticsearch.action.get.MultiGetRequest;
import org.elasticsearch.action.get.MultiGetRequest.Item;
import org.elasticsearch.action.get.MultiGetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.support.WriteRequest.RefreshPolicy;
import org.elasticsearch.action.support.master.AcknowledgedResponse;
import org.elasticsearch.client.Client;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
......@@ -258,6 +267,43 @@ public class MultitenancyTests {
}
}
@Test
public void testAliasCreationKibana_7_12() throws Exception {
try {
try (RestHighLevelClient tenantClient = cluster.getRestHighLevelClient("admin", "admin", "kibana_7_12_alias_creation_test");
Client client = cluster.getInternalNodeClient()) {
IndexResponse indexResponse = tenantClient.index(new IndexRequest(".kibana_7.12.0_001").id("test")
.source(ImmutableMap.of("buildNum", 15460)).setRefreshPolicy(RefreshPolicy.IMMEDIATE), RequestOptions.DEFAULT);
Assert.assertEquals(indexResponse.toString(), indexResponse.getResult(), DocWriteResponse.Result.CREATED);
Assert.assertEquals(indexResponse.toString(), ".kibana_1482524924_kibana712aliascreationtest_7.12.0_001", indexResponse.getIndex());
AcknowledgedResponse ackResponse = tenantClient.indices().updateAliases(
new IndicesAliasesRequest().addAliasAction(AliasActions.add().index(".kibana_7.12.0_001").alias(".kibana_7.12.0")),
RequestOptions.DEFAULT);
Assert.assertTrue(ackResponse.toString(), ackResponse.isAcknowledged());
GetResponse getResponse = tenantClient.get(new GetRequest(".kibana_7.12.0", "test"), RequestOptions.DEFAULT);
Assert.assertEquals(getResponse.toString(), ".kibana_1482524924_kibana712aliascreationtest_7.12.0_001", getResponse.getIndex());
GetAliasesResponse getAliasesResponse = client.admin().indices()
.getAliases(new GetAliasesRequest(".kibana_1482524924_kibana712aliascreationtest_7.12.0")).actionGet();
Assert.assertNotNull(getAliasesResponse.getAliases().toString(),
getAliasesResponse.getAliases().get(".kibana_1482524924_kibana712aliascreationtest_7.12.0_001"));
Assert.assertEquals(getAliasesResponse.getAliases().toString(), ".kibana_1482524924_kibana712aliascreationtest_7.12.0",
getAliasesResponse.getAliases().get(".kibana_1482524924_kibana712aliascreationtest_7.12.0_001").get(0).alias());
}
} finally {
try (Client tc = cluster.getInternalNodeClient()) {
tc.admin().indices().delete(new DeleteIndexRequest(".kibana_1482524924_kibana712aliascreationtest_7.12.0_001")).actionGet();
} catch (Exception ignored) {
}
}
}
@Test
public void testMgetWithKibanaAlias() throws Exception {
String indexName = ".kibana_1592542611_humanresources";
......
......@@ -246,6 +246,7 @@ sg_all_access:
- "adm_tenant"
- "test_tenant_ro"
- "kibana_7_12_alias_test"
- "kibana_7_12_alias_creation_test"
allowed_actions:
- "SGS_KIBANA_ALL_WRITE"
sg_logstash:
......
......@@ -72,3 +72,6 @@ dept_05:
kibana_7_12_alias_test:
reserved: false
hidden: false
kibana_7_12_alias_creation_test:
reserved: false
hidden: false
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment