Enables security to work with index aliases (elastic/x-pack-elasticsearch#1496)
This commit enables security to work with an index named .security (as it could before) OR an alias named .security that points to a concrete index by a different name that has the security index. This prepares the ability to migrate from a 5.x to 6.x security index that allows changing and re-indexing the underlying security index while maintaining a .security alias that points to the underlying updated index. relates elastic/x-pack-elasticsearch#1216 Original commit: elastic/x-pack-elasticsearch@9fee12e5a0
This commit is contained in:
parent
521b7a1940
commit
ec175debd0
|
@ -23,7 +23,6 @@ import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
|
|||
import org.elasticsearch.xpack.security.authc.esnative.NativeRealmMigrator;
|
||||
import org.elasticsearch.xpack.security.support.IndexLifecycleManager;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Predicate;
|
||||
|
|
|
@ -18,9 +18,11 @@ import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateReque
|
|||
import org.elasticsearch.action.admin.indices.template.put.PutIndexTemplateResponse;
|
||||
import org.elasticsearch.cluster.ClusterChangedEvent;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.AliasOrIndex;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MappingMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.routing.IndexRoutingTable;
|
||||
import org.elasticsearch.common.bytes.BytesArray;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
|
@ -38,12 +40,14 @@ import org.elasticsearch.xpack.template.TemplateUtils;
|
|||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.elasticsearch.common.xcontent.XContentHelper.convertToMap;
|
||||
|
||||
|
@ -64,8 +68,7 @@ public class IndexLifecycleManager extends AbstractComponent {
|
|||
private final AtomicBoolean templateCreationPending = new AtomicBoolean(false);
|
||||
private final AtomicBoolean updateMappingPending = new AtomicBoolean(false);
|
||||
|
||||
final AtomicReference<UpgradeState> migrateDataState =
|
||||
new AtomicReference<>(UpgradeState.NOT_STARTED);
|
||||
private final AtomicReference<UpgradeState> migrateDataState = new AtomicReference<>(UpgradeState.NOT_STARTED);
|
||||
|
||||
private volatile boolean templateIsUpToDate;
|
||||
private volatile boolean indexExists;
|
||||
|
@ -136,7 +139,7 @@ public class IndexLifecycleManager extends AbstractComponent {
|
|||
|
||||
public void clusterChanged(ClusterChangedEvent event) {
|
||||
final ClusterState state = event.state();
|
||||
this.indexExists = event.state().metaData().indices().get(indexName) != null;
|
||||
this.indexExists = resolveConcreteIndex(indexName, event.state().metaData()) != null;
|
||||
this.indexAvailable = checkIndexAvailable(state);
|
||||
this.templateIsUpToDate = checkTemplateExistsAndIsUpToDate(state);
|
||||
this.mappingIsUpToDate = checkIndexMappingUpToDate(state);
|
||||
|
@ -167,11 +170,11 @@ public class IndexLifecycleManager extends AbstractComponent {
|
|||
* Returns the routing-table for this index, or <code>null</code> if the index does not exist.
|
||||
*/
|
||||
private IndexRoutingTable getIndexRoutingTable(ClusterState clusterState) {
|
||||
IndexMetaData metaData = clusterState.metaData().index(indexName);
|
||||
IndexMetaData metaData = resolveConcreteIndex(indexName, clusterState.metaData());
|
||||
if (metaData == null) {
|
||||
return null;
|
||||
} else {
|
||||
return clusterState.routingTable().index(indexName);
|
||||
return clusterState.routingTable().index(metaData.getIndex());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -249,7 +252,7 @@ public class IndexLifecycleManager extends AbstractComponent {
|
|||
private static Set<Version> loadIndexMappingVersions(String indexName,
|
||||
ClusterState clusterState, Logger logger) {
|
||||
Set<Version> versions = new HashSet<>();
|
||||
IndexMetaData indexMetaData = clusterState.metaData().getIndices().get(indexName);
|
||||
IndexMetaData indexMetaData = resolveConcreteIndex(indexName, clusterState.metaData());
|
||||
if (indexMetaData != null) {
|
||||
for (Object object : indexMetaData.getMappings().values().toArray()) {
|
||||
MappingMetaData mappingMetaData = (MappingMetaData) object;
|
||||
|
@ -262,6 +265,23 @@ public class IndexLifecycleManager extends AbstractComponent {
|
|||
return versions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves a concrete index name or alias to a {@link IndexMetaData} instance. Requires
|
||||
* that if supplied with an alias, the alias resolves to at most one concrete index.
|
||||
*/
|
||||
private static IndexMetaData resolveConcreteIndex(final String indexOrAliasName, final MetaData metaData) {
|
||||
final AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(indexOrAliasName);
|
||||
if (aliasOrIndex != null) {
|
||||
final List<IndexMetaData> indices = aliasOrIndex.getIndices();
|
||||
if (aliasOrIndex.isAlias() && indices.size() > 1) {
|
||||
throw new IllegalStateException("Alias [" + indexOrAliasName + "] points to more than one index: " +
|
||||
indices.stream().map(imd -> imd.getIndex().getName()).collect(Collectors.toList()));
|
||||
}
|
||||
return indices.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Version readMappingVersion(String indexName, MappingMetaData mappingMetaData,
|
||||
Logger logger) {
|
||||
try {
|
||||
|
|
|
@ -14,6 +14,8 @@ import org.elasticsearch.client.Client;
|
|||
import org.elasticsearch.client.node.NodeClient;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.health.ClusterHealthStatus;
|
||||
import org.elasticsearch.cluster.metadata.AliasOrIndex;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.routing.IndexRoutingTable;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.network.NetworkAddress;
|
||||
|
@ -21,6 +23,7 @@ import org.elasticsearch.common.settings.SecureString;
|
|||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.transport.TransportAddress;
|
||||
import org.elasticsearch.gateway.GatewayService;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.IndexNotFoundException;
|
||||
import org.elasticsearch.plugins.Plugin;
|
||||
import org.elasticsearch.xpack.XPackClient;
|
||||
|
@ -442,9 +445,12 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
|
|||
ClusterState clusterState = clusterService.state();
|
||||
assertFalse(clusterState.blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK));
|
||||
assertTrue(securityIndexMappingAndTemplateSufficientToRead(clusterState, logger));
|
||||
IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(SecurityLifecycleService.SECURITY_INDEX_NAME);
|
||||
if (indexRoutingTable != null) {
|
||||
assertTrue(indexRoutingTable.allPrimaryShardsActive());
|
||||
Index securityIndex = resolveSecurityIndex(clusterState.metaData());
|
||||
if (securityIndex != null) {
|
||||
IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(securityIndex);
|
||||
if (indexRoutingTable != null) {
|
||||
assertTrue(indexRoutingTable.allPrimaryShardsActive());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -456,9 +462,12 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
|
|||
ClusterState clusterState = clusterService.state();
|
||||
assertFalse(clusterState.blocks().hasGlobalBlock(GatewayService.STATE_NOT_RECOVERED_BLOCK));
|
||||
assertTrue(securityIndexMappingAndTemplateUpToDate(clusterState, logger));
|
||||
IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(SecurityLifecycleService.SECURITY_INDEX_NAME);
|
||||
if (indexRoutingTable != null) {
|
||||
assertTrue(indexRoutingTable.allPrimaryShardsActive());
|
||||
Index securityIndex = resolveSecurityIndex(clusterState.metaData());
|
||||
if (securityIndex != null) {
|
||||
IndexRoutingTable indexRoutingTable = clusterState.routingTable().index(securityIndex);
|
||||
if (indexRoutingTable != null) {
|
||||
assertTrue(indexRoutingTable.allPrimaryShardsActive());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -472,4 +481,12 @@ public abstract class SecurityIntegTestCase extends ESIntegTestCase {
|
|||
// ignore it since not all tests create this index...
|
||||
}
|
||||
}
|
||||
|
||||
private static Index resolveSecurityIndex(MetaData metaData) {
|
||||
final AliasOrIndex aliasOrIndex = metaData.getAliasAndIndexLookup().get(SecurityLifecycleService.SECURITY_INDEX_NAME);
|
||||
if (aliasOrIndex != null) {
|
||||
return aliasOrIndex.getIndices().get(0).getIndex();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,9 +32,7 @@ import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
|||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNode;
|
||||
import org.elasticsearch.cluster.node.DiscoveryNodes;
|
||||
import org.elasticsearch.cluster.routing.RoutingTable;
|
||||
import org.elasticsearch.cluster.service.ClusterService;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.common.xcontent.XContentType;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
|
@ -64,22 +62,19 @@ import static org.mockito.Mockito.mock;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class SecurityLifecycleServiceTests extends ESTestCase {
|
||||
private InternalClient client;
|
||||
private TransportClient transportClient;
|
||||
private ThreadPool threadPool;
|
||||
private ClusterService clusterService;
|
||||
private NativeRealmMigrator nativeRealmMigrator;
|
||||
private SecurityLifecycleService securityLifecycleService;
|
||||
private static final ClusterState EMPTY_CLUSTER_STATE =
|
||||
new ClusterState.Builder(new ClusterName("test-cluster")).build();
|
||||
|
||||
CopyOnWriteArrayList<ActionListener> listeners;
|
||||
private CopyOnWriteArrayList<ActionListener> listeners;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
DiscoveryNode localNode = mock(DiscoveryNode.class);
|
||||
when(localNode.getHostAddress()).thenReturn(buildNewFakeTransportAddress().toString());
|
||||
clusterService = mock(ClusterService.class);
|
||||
ClusterService clusterService = mock(ClusterService.class);
|
||||
when(clusterService.localNode()).thenReturn(localNode);
|
||||
|
||||
threadPool = new TestThreadPool("security template service tests");
|
||||
|
@ -106,7 +101,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
return null;
|
||||
}).when(nativeRealmMigrator).performUpgrade(any(Version.class), any(ActionListener.class));
|
||||
|
||||
client = new IClient(transportClient);
|
||||
InternalClient client = new IClient(transportClient);
|
||||
securityLifecycleService = new SecurityLifecycleService(Settings.EMPTY, clusterService,
|
||||
threadPool, client, nativeRealmMigrator, mock(IndexAuditTrail.class));
|
||||
listeners = new CopyOnWriteArrayList<>();
|
||||
|
@ -155,8 +150,9 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
|
||||
final int numberOfSecurityIndices = 1; // .security
|
||||
|
||||
final ClusterState clusterState = clusterStateBuilder.build();
|
||||
securityLifecycleService.clusterChanged(new ClusterChangedEvent("test-event",
|
||||
clusterStateBuilder.build(), EMPTY_CLUSTER_STATE));
|
||||
clusterState, EMPTY_CLUSTER_STATE));
|
||||
assertThat(securityLifecycleService.securityIndex().isTemplateUpToDate(), equalTo(false));
|
||||
assertThat(listeners.size(), equalTo(numberOfSecurityIndices));
|
||||
assertTrue(securityLifecycleService.securityIndex().isTemplateCreationPending());
|
||||
|
@ -165,7 +161,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
ActionListener listener = listeners.get(0);
|
||||
listeners.clear();
|
||||
securityLifecycleService.clusterChanged(new ClusterChangedEvent("test-event",
|
||||
clusterStateBuilder.build(), EMPTY_CLUSTER_STATE));
|
||||
clusterState, EMPTY_CLUSTER_STATE));
|
||||
assertThat(securityLifecycleService.securityIndex().isTemplateUpToDate(), equalTo(false));
|
||||
assertThat(listeners.size(), equalTo(0));
|
||||
assertTrue(securityLifecycleService.securityIndex().isTemplateCreationPending());
|
||||
|
@ -177,7 +173,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
|
||||
// ... we should be able to send a new update
|
||||
securityLifecycleService.clusterChanged(new ClusterChangedEvent("test-event",
|
||||
clusterStateBuilder.build(), EMPTY_CLUSTER_STATE));
|
||||
clusterState, EMPTY_CLUSTER_STATE));
|
||||
assertThat(securityLifecycleService.securityIndex().isTemplateUpToDate(), equalTo(false));
|
||||
assertThat(listeners.size(), equalTo(1));
|
||||
assertTrue(securityLifecycleService.securityIndex().isTemplateCreationPending());
|
||||
|
@ -192,7 +188,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
// and now let's see what happens if we get back a response
|
||||
listeners.clear();
|
||||
securityLifecycleService.clusterChanged(new ClusterChangedEvent("test-event",
|
||||
clusterStateBuilder.build(), EMPTY_CLUSTER_STATE));
|
||||
clusterState, EMPTY_CLUSTER_STATE));
|
||||
assertThat(securityLifecycleService.securityIndex().isTemplateUpToDate(), equalTo(false));
|
||||
assertTrue(securityLifecycleService.securityIndex().isTemplateCreationPending());
|
||||
assertThat(listeners.size(), equalTo(1));
|
||||
|
@ -202,13 +198,9 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
}
|
||||
|
||||
public void testMissingIndexTemplateIsIdentifiedAsMissing() throws IOException {
|
||||
ClusterState.Builder clusterStateBuilder = new ClusterState.Builder(state());
|
||||
// add the correct mapping
|
||||
String mappingString = "/" + SECURITY_TEMPLATE_NAME + ".json";
|
||||
IndexMetaData.Builder indexMeta = createIndexMetadata(SECURITY_INDEX_NAME, mappingString);
|
||||
MetaData.Builder builder = new MetaData.Builder(clusterStateBuilder.build().getMetaData());
|
||||
builder.put(indexMeta);
|
||||
clusterStateBuilder.metaData(builder);
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMapping(mappingString);
|
||||
checkTemplateUpdateWorkCorrectly(clusterStateBuilder);
|
||||
}
|
||||
|
||||
|
@ -221,7 +213,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
public void testOutdatedMappingIsIdentifiedAsNotUpToDate() throws IOException {
|
||||
String templateString = "/wrong-version-" + SECURITY_TEMPLATE_NAME + ".json";
|
||||
final Version wrongVersion = Version.fromString("4.0.0");
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMapping(templateString);
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMappingAndTemplate(templateString);
|
||||
final ClusterState clusterState = clusterStateBuilder.build();
|
||||
assertFalse(securityIndexMappingAndTemplateUpToDate(clusterState, logger));
|
||||
assertFalse(securityIndexMappingAndTemplateSufficientToRead(clusterState, logger));
|
||||
|
@ -305,8 +297,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
|
||||
public void testUpToDateMappingsAreIdentifiedAsUpToDate() throws IOException {
|
||||
String securityTemplateString = "/" + SECURITY_TEMPLATE_NAME + ".json";
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMapping(
|
||||
securityTemplateString);
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMappingAndTemplate(securityTemplateString);
|
||||
securityLifecycleService.clusterChanged(new ClusterChangedEvent("test-event",
|
||||
clusterStateBuilder.build(), EMPTY_CLUSTER_STATE));
|
||||
assertTrue(securityLifecycleService.securityIndex().isMappingUpToDate());
|
||||
|
@ -315,8 +306,7 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
|
||||
public void testMappingVersionMatching() throws IOException {
|
||||
String templateString = "/" + SECURITY_TEMPLATE_NAME + ".json";
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMapping(templateString
|
||||
);
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMappingAndTemplate(templateString);
|
||||
securityLifecycleService.clusterChanged(new ClusterChangedEvent("test-event",
|
||||
clusterStateBuilder.build(), EMPTY_CLUSTER_STATE));
|
||||
final IndexLifecycleManager securityIndex = securityLifecycleService.securityIndex();
|
||||
|
@ -326,12 +316,12 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
|
||||
public void testMissingVersionMappingThrowsError() throws IOException {
|
||||
String templateString = "/missing-version-" + SECURITY_TEMPLATE_NAME + ".json";
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMapping(templateString
|
||||
);
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMappingAndTemplate(templateString);
|
||||
final ClusterState clusterState = clusterStateBuilder.build();
|
||||
IllegalStateException exception = expectThrows(IllegalStateException.class,
|
||||
() -> securityIndexMappingAndTemplateUpToDate(clusterState, logger));
|
||||
assertEquals(exception.getMessage(), "Cannot read security-version string in index " + SECURITY_INDEX_NAME);
|
||||
assertEquals("Cannot read security-version string in index " + SECURITY_INDEX_NAME,
|
||||
exception.getMessage());
|
||||
}
|
||||
|
||||
public void testMissingIndexIsIdentifiedAsUpToDate() throws IOException {
|
||||
|
@ -350,24 +340,22 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private ClusterState.Builder createClusterStateWithMapping(String securityTemplateString) throws IOException {
|
||||
ImmutableOpenMap.Builder mapBuilder = ImmutableOpenMap.builder();
|
||||
IndexMetaData securityIndex = createIndexMetadata(SECURITY_INDEX_NAME, securityTemplateString).build();
|
||||
mapBuilder.put(SECURITY_INDEX_NAME, securityIndex);
|
||||
MetaData.Builder metaDataBuilder = new MetaData.Builder();
|
||||
metaDataBuilder.indices(mapBuilder.build());
|
||||
final ClusterState clusterState = createClusterStateWithIndex(securityTemplateString).build();
|
||||
final String indexName = clusterState.metaData().getAliasAndIndexLookup()
|
||||
.get(SECURITY_INDEX_NAME).getIndices().get(0).getIndex().getName();
|
||||
return ClusterState.builder(clusterState).routingTable(SecurityTestUtils.buildIndexRoutingTable(indexName));
|
||||
}
|
||||
|
||||
private ClusterState.Builder createClusterStateWithMappingAndTemplate(String securityTemplateString) throws IOException {
|
||||
ClusterState.Builder clusterStateBuilder = createClusterStateWithMapping(securityTemplateString);
|
||||
MetaData.Builder metaDataBuilder = new MetaData.Builder(clusterStateBuilder.build().metaData());
|
||||
String securityMappingString = "/" + SECURITY_TEMPLATE_NAME + ".json";
|
||||
IndexTemplateMetaData.Builder securityTemplateMeta = getIndexTemplateMetaData(SECURITY_TEMPLATE_NAME, securityMappingString);
|
||||
metaDataBuilder.put(securityTemplateMeta);
|
||||
|
||||
ClusterState.Builder clusterStateBuilder = ClusterState.builder(state());
|
||||
final RoutingTable routingTable = SecurityTestUtils.buildSecurityIndexRoutingTable();
|
||||
clusterStateBuilder.metaData(metaDataBuilder.build()).routingTable(routingTable);
|
||||
return clusterStateBuilder;
|
||||
return clusterStateBuilder.metaData(metaDataBuilder);
|
||||
}
|
||||
|
||||
private static IndexMetaData.Builder createIndexMetadata(
|
||||
String indexName, String templateString) throws IOException {
|
||||
private static IndexMetaData.Builder createIndexMetadata(String indexName, String templateString) throws IOException {
|
||||
String template = TemplateUtils.loadTemplate(templateString, Version.CURRENT.toString(),
|
||||
IndexLifecycleManager.TEMPLATE_VERSION_PATTERN);
|
||||
PutIndexTemplateRequest request = new PutIndexTemplateRequest();
|
||||
|
@ -385,19 +373,30 @@ public class SecurityLifecycleServiceTests extends ESTestCase {
|
|||
return indexMetaData;
|
||||
}
|
||||
|
||||
public static ClusterState.Builder createClusterStateWithTemplate(String securityTemplateString) throws IOException {
|
||||
MetaData.Builder metaDataBuilder = new MetaData.Builder();
|
||||
|
||||
IndexTemplateMetaData.Builder securityTemplateBuilder =
|
||||
getIndexTemplateMetaData(SECURITY_TEMPLATE_NAME, securityTemplateString);
|
||||
metaDataBuilder.put(securityTemplateBuilder);
|
||||
public ClusterState.Builder createClusterStateWithTemplate(String securityTemplateString) throws IOException {
|
||||
// add the correct mapping no matter what the template
|
||||
String securityMappingString = "/" + SECURITY_TEMPLATE_NAME + ".json";
|
||||
IndexMetaData.Builder securityIndexMeta =
|
||||
createIndexMetadata(SECURITY_INDEX_NAME, securityMappingString);
|
||||
metaDataBuilder.put(securityIndexMeta);
|
||||
ClusterState clusterState = createClusterStateWithIndex("/" + SECURITY_TEMPLATE_NAME + ".json").build();
|
||||
final MetaData.Builder metaDataBuilder = new MetaData.Builder(clusterState.metaData());
|
||||
metaDataBuilder.put(getIndexTemplateMetaData(SECURITY_TEMPLATE_NAME, securityTemplateString));
|
||||
return ClusterState.builder(clusterState).metaData(metaDataBuilder);
|
||||
}
|
||||
|
||||
return ClusterState.builder(state()).metaData(metaDataBuilder.build());
|
||||
private ClusterState.Builder createClusterStateWithIndex(String securityTemplate) throws IOException {
|
||||
final MetaData.Builder metaDataBuilder = new MetaData.Builder();
|
||||
final boolean withAlias = randomBoolean();
|
||||
final String securityIndexName = SECURITY_INDEX_NAME + (withAlias ? "-" + randomAlphaOfLength(5) : "");
|
||||
metaDataBuilder.put(createIndexMetadata(securityIndexName, securityTemplate));
|
||||
|
||||
ClusterState.Builder clusterStateBuilder = ClusterState.builder(state());
|
||||
if (withAlias) {
|
||||
// try with .security index as an alias
|
||||
clusterStateBuilder.metaData(SecurityTestUtils.addAliasToMetaData(metaDataBuilder.build(), securityIndexName));
|
||||
} else {
|
||||
// try with .security index as a concrete index
|
||||
clusterStateBuilder.metaData(metaDataBuilder);
|
||||
}
|
||||
|
||||
return clusterStateBuilder;
|
||||
}
|
||||
|
||||
private static IndexTemplateMetaData.Builder getIndexTemplateMetaData(
|
||||
|
|
|
@ -55,6 +55,7 @@ import org.elasticsearch.xpack.security.authz.permission.FieldPermissionsCache;
|
|||
import org.elasticsearch.xpack.security.authz.permission.Role;
|
||||
import org.elasticsearch.xpack.security.authz.store.CompositeRolesStore;
|
||||
import org.elasticsearch.xpack.security.authz.store.ReservedRolesStore;
|
||||
import org.elasticsearch.xpack.security.test.SecurityTestUtils;
|
||||
import org.elasticsearch.xpack.security.user.AnonymousUser;
|
||||
import org.elasticsearch.xpack.security.user.User;
|
||||
import org.elasticsearch.xpack.security.user.XPackUser;
|
||||
|
@ -66,6 +67,7 @@ import java.util.HashSet;
|
|||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
|
||||
import static org.hamcrest.Matchers.arrayContaining;
|
||||
import static org.hamcrest.Matchers.arrayContainingInAnyOrder;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
|
@ -101,7 +103,10 @@ public class IndicesAndAliasesResolverTests extends ESTestCase {
|
|||
.build();
|
||||
|
||||
indexNameExpressionResolver = new IndexNameExpressionResolver(Settings.EMPTY);
|
||||
metaData = MetaData.builder()
|
||||
|
||||
final boolean withAlias = randomBoolean();
|
||||
final String securityIndexName = SECURITY_INDEX_NAME + (withAlias ? "-" + randomAlphaOfLength(5) : "");
|
||||
MetaData metaData = MetaData.builder()
|
||||
.put(indexBuilder("foo").putAlias(AliasMetaData.builder("foofoobar")).settings(settings))
|
||||
.put(indexBuilder("foobar").putAlias(AliasMetaData.builder("foofoobar")).settings(settings))
|
||||
.put(indexBuilder("closed").state(IndexMetaData.State.CLOSE)
|
||||
|
@ -117,7 +122,12 @@ public class IndicesAndAliasesResolverTests extends ESTestCase {
|
|||
.put(indexBuilder("-index11").settings(settings))
|
||||
.put(indexBuilder("-index20").settings(settings))
|
||||
.put(indexBuilder("-index21").settings(settings))
|
||||
.put(indexBuilder(SecurityLifecycleService.SECURITY_INDEX_NAME).settings(settings)).build();
|
||||
.put(indexBuilder(securityIndexName).settings(settings)).build();
|
||||
|
||||
if (withAlias) {
|
||||
metaData = SecurityTestUtils.addAliasToMetaData(metaData, securityIndexName);
|
||||
}
|
||||
this.metaData = metaData;
|
||||
|
||||
user = new User("user", "role");
|
||||
userDashIndices = new User("dash", "dash");
|
||||
|
|
|
@ -42,6 +42,7 @@ import org.elasticsearch.xpack.security.action.role.PutRoleRequest;
|
|||
import org.elasticsearch.xpack.security.audit.index.IndexAuditTrail;
|
||||
import org.elasticsearch.xpack.security.authz.RoleDescriptor;
|
||||
import org.elasticsearch.xpack.security.authz.RoleDescriptor.IndicesPrivileges;
|
||||
import org.elasticsearch.xpack.security.test.SecurityTestUtils;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
|
||||
|
@ -55,6 +56,7 @@ import java.util.UUID;
|
|||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.elasticsearch.cluster.routing.RecoverySource.StoreRecoverySource.EXISTING_STORE_INSTANCE;
|
||||
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
|
@ -242,18 +244,26 @@ public class NativeRolesStoreTests extends ESTestCase {
|
|||
}
|
||||
|
||||
private ClusterState getClusterStateWithSecurityIndex() {
|
||||
final boolean withAlias = randomBoolean();
|
||||
final String securityIndexName = SECURITY_INDEX_NAME + (withAlias ? "-" + randomAlphaOfLength(5) : "");
|
||||
|
||||
Settings settings = Settings.builder()
|
||||
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
|
||||
.build();
|
||||
MetaData metaData = MetaData.builder()
|
||||
.put(IndexMetaData.builder(SecurityLifecycleService.SECURITY_INDEX_NAME).settings(settings))
|
||||
.put(IndexMetaData.builder(securityIndexName).settings(settings))
|
||||
.put(new IndexTemplateMetaData(SecurityLifecycleService.SECURITY_TEMPLATE_NAME, 0, 0,
|
||||
Collections.singletonList(SecurityLifecycleService.SECURITY_INDEX_NAME), Settings.EMPTY, ImmutableOpenMap.of(),
|
||||
Collections.singletonList(securityIndexName), Settings.EMPTY, ImmutableOpenMap.of(),
|
||||
ImmutableOpenMap.of(), ImmutableOpenMap.of()))
|
||||
.build();
|
||||
Index index = new Index(SecurityLifecycleService.SECURITY_INDEX_NAME, UUID.randomUUID().toString());
|
||||
|
||||
if (withAlias) {
|
||||
metaData = SecurityTestUtils.addAliasToMetaData(metaData, securityIndexName);
|
||||
}
|
||||
|
||||
Index index = new Index(securityIndexName, UUID.randomUUID().toString());
|
||||
ShardRouting shardRouting = ShardRouting.newUnassigned(new ShardId(index, 0), true, EXISTING_STORE_INSTANCE,
|
||||
new UnassignedInfo(Reason.INDEX_CREATED, ""));
|
||||
IndexShardRoutingTable table = new IndexShardRoutingTable.Builder(new ShardId(index, 0))
|
||||
|
@ -266,10 +276,12 @@ public class NativeRolesStoreTests extends ESTestCase {
|
|||
.build())
|
||||
.build();
|
||||
|
||||
return ClusterState.builder(new ClusterName(NativeRolesStoreTests.class.getName()))
|
||||
ClusterState clusterState = ClusterState.builder(new ClusterName(NativeRolesStoreTests.class.getName()))
|
||||
.metaData(metaData)
|
||||
.routingTable(routingTable)
|
||||
.build();
|
||||
|
||||
return clusterState;
|
||||
}
|
||||
|
||||
private ClusterState getEmptyClusterState() {
|
||||
|
|
|
@ -6,36 +6,29 @@
|
|||
package org.elasticsearch.xpack.security.test;
|
||||
|
||||
import org.elasticsearch.ElasticsearchException;
|
||||
import org.elasticsearch.Version;
|
||||
import org.elasticsearch.cluster.ClusterName;
|
||||
import org.elasticsearch.cluster.ClusterState;
|
||||
import org.elasticsearch.cluster.metadata.AliasMetaData;
|
||||
import org.elasticsearch.cluster.metadata.IndexMetaData;
|
||||
import org.elasticsearch.cluster.metadata.IndexTemplateMetaData;
|
||||
import org.elasticsearch.cluster.metadata.MetaData;
|
||||
import org.elasticsearch.cluster.routing.IndexRoutingTable;
|
||||
import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
|
||||
import org.elasticsearch.cluster.routing.RoutingTable;
|
||||
import org.elasticsearch.cluster.routing.ShardRouting;
|
||||
import org.elasticsearch.cluster.routing.UnassignedInfo;
|
||||
import org.elasticsearch.common.collect.ImmutableOpenMap;
|
||||
import org.elasticsearch.common.io.FileSystemUtils;
|
||||
import org.elasticsearch.common.io.Streams;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.index.Index;
|
||||
import org.elasticsearch.index.shard.ShardId;
|
||||
import org.elasticsearch.test.ESTestCase;
|
||||
import org.elasticsearch.xpack.security.SecurityLifecycleService;
|
||||
import org.elasticsearch.xpack.security.authz.store.NativeRolesStoreTests;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.elasticsearch.cluster.routing.RecoverySource.StoreRecoverySource.EXISTING_STORE_INSTANCE;
|
||||
import static org.elasticsearch.xpack.security.SecurityLifecycleService.SECURITY_INDEX_NAME;
|
||||
|
||||
public class SecurityTestUtils {
|
||||
|
||||
|
@ -72,30 +65,6 @@ public class SecurityTestUtils {
|
|||
return writeFile(folder, name, content.getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
public static ClusterState getClusterStateWithSecurityIndex() {
|
||||
Settings settings = Settings.builder()
|
||||
.put(IndexMetaData.SETTING_VERSION_CREATED, Version.CURRENT)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_SHARDS, 1)
|
||||
.put(IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
|
||||
.build();
|
||||
MetaData metaData = MetaData.builder()
|
||||
.put(IndexMetaData.builder(SecurityLifecycleService.SECURITY_INDEX_NAME).settings(settings))
|
||||
.put(new IndexTemplateMetaData(SecurityLifecycleService.SECURITY_TEMPLATE_NAME, 0, 0,
|
||||
Collections.singletonList(SecurityLifecycleService.SECURITY_INDEX_NAME), Settings.EMPTY, ImmutableOpenMap.of(),
|
||||
ImmutableOpenMap.of(), ImmutableOpenMap.of()))
|
||||
.build();
|
||||
RoutingTable routingTable = buildSecurityIndexRoutingTable();
|
||||
|
||||
return ClusterState.builder(new ClusterName(NativeRolesStoreTests.class.getName()))
|
||||
.metaData(metaData)
|
||||
.routingTable(routingTable)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static RoutingTable buildSecurityIndexRoutingTable() {
|
||||
return buildIndexRoutingTable(SecurityLifecycleService.SECURITY_INDEX_NAME);
|
||||
}
|
||||
|
||||
public static RoutingTable buildIndexRoutingTable(String indexName) {
|
||||
Index index = new Index(indexName, UUID.randomUUID().toString());
|
||||
ShardRouting shardRouting = ShardRouting.newUnassigned(new ShardId(index, 0), true, EXISTING_STORE_INSTANCE,
|
||||
|
@ -108,4 +77,16 @@ public class SecurityTestUtils {
|
|||
.add(IndexRoutingTable.builder(index).addIndexShard(table).build())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the index alias {@code .security} to the underlying concrete index.
|
||||
*/
|
||||
public static MetaData addAliasToMetaData(MetaData metaData, String indexName) {
|
||||
AliasMetaData aliasMetaData = AliasMetaData.newAliasMetaDataBuilder(SECURITY_INDEX_NAME).build();
|
||||
MetaData.Builder metaDataBuilder = new MetaData.Builder(metaData);
|
||||
IndexMetaData indexMetaData = metaData.index(indexName);
|
||||
metaDataBuilder.put(IndexMetaData.builder(indexMetaData).putAlias(aliasMetaData));
|
||||
return metaDataBuilder.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue