diff --git a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java index bafcec0bef06f..4e0495e5df5e9 100644 --- a/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java +++ b/plugins/repository-azure/src/main/java/org/elasticsearch/repositories/azure/AzureRepository.java @@ -71,7 +71,7 @@ public static final class Repository { public static final Setting CHUNK_SIZE_SETTING = Setting.byteSizeSetting("chunk_size", MAX_CHUNK_SIZE, MIN_CHUNK_SIZE, MAX_CHUNK_SIZE, Property.NodeScope); public static final Setting COMPRESS_SETTING = Setting.boolSetting("compress", false, Property.NodeScope); - public static final Setting READONLY_SETTING = Setting.boolSetting("readonly", false, Property.NodeScope); + public static final Setting READONLY_SETTING = Setting.boolSetting(READONLY_SETTING_KEY, false, Property.NodeScope); } private final BlobPath basePath; diff --git a/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureRepositorySettingsTests.java b/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureRepositorySettingsTests.java index 0c475a5b48515..a8bb5adc41cf2 100644 --- a/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureRepositorySettingsTests.java +++ b/plugins/repository-azure/src/test/java/org/elasticsearch/repositories/azure/AzureRepositorySettingsTests.java @@ -31,6 +31,7 @@ import org.elasticsearch.repositories.blobstore.BlobStoreTestUtil; import org.elasticsearch.test.ESTestCase; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.nullValue; import static org.mockito.Mockito.mock; @@ -57,7 +58,7 @@ public void testReadonlyDefault() { public void testReadonlyDefaultAndReadonlyOn() { assertThat(azureRepository(Settings.builder() - .put("readonly", true) + .put(READONLY_SETTING_KEY, true) .build()).isReadOnly(), is(true)); } @@ -70,35 +71,35 @@ public void testReadonlyWithPrimaryOnly() { public void testReadonlyWithPrimaryOnlyAndReadonlyOn() { assertThat(azureRepository(Settings.builder() .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.PRIMARY_ONLY.name()) - .put("readonly", true) + .put(READONLY_SETTING_KEY, true) .build()).isReadOnly(), is(true)); } public void testReadonlyWithSecondaryOnlyAndReadonlyOn() { assertThat(azureRepository(Settings.builder() .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.SECONDARY_ONLY.name()) - .put("readonly", true) + .put(READONLY_SETTING_KEY, true) .build()).isReadOnly(), is(true)); } public void testReadonlyWithSecondaryOnlyAndReadonlyOff() { assertThat(azureRepository(Settings.builder() .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.SECONDARY_ONLY.name()) - .put("readonly", false) + .put(READONLY_SETTING_KEY, false) .build()).isReadOnly(), is(false)); } public void testReadonlyWithPrimaryAndSecondaryOnlyAndReadonlyOn() { assertThat(azureRepository(Settings.builder() .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.PRIMARY_THEN_SECONDARY.name()) - .put("readonly", true) + .put(READONLY_SETTING_KEY, true) .build()).isReadOnly(), is(true)); } public void testReadonlyWithPrimaryAndSecondaryOnlyAndReadonlyOff() { assertThat(azureRepository(Settings.builder() .put(AzureRepository.Repository.LOCATION_MODE_SETTING.getKey(), LocationMode.PRIMARY_THEN_SECONDARY.name()) - .put("readonly", false) + .put(READONLY_SETTING_KEY, false) .build()).isReadOnly(), is(false)); } diff --git a/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java b/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java index caba391ae9921..5ec88e5b135d7 100644 --- a/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java +++ b/qa/repository-multi-version/src/test/java/org/elasticsearch/upgrades/MultiVersionRepositoryAccessIT.java @@ -47,6 +47,7 @@ import java.util.Map; import java.util.stream.Collectors; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasSize; import static org.hamcrest.Matchers.is; @@ -285,8 +286,8 @@ private void ensureSnapshotRestoreWorks(String repoName, String name, int shards private static void createRepository(RestHighLevelClient client, String repoName, boolean readOnly) throws IOException { assertThat(client.snapshot().createRepository(new PutRepositoryRequest(repoName).type("fs").settings( - Settings.builder().put("location", "./" + repoName).put("readonly", readOnly)), RequestOptions.DEFAULT).isAcknowledged(), - is(true)); + Settings.builder().put("location", "./" + repoName).put(READONLY_SETTING_KEY, readOnly)), RequestOptions.DEFAULT) + .isAcknowledged(), is(true)); } private static void createSnapshot(RestHighLevelClient client, String repoName, String name, String index) throws IOException { diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MultiClusterRepoAccessIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MultiClusterRepoAccessIT.java index a48c9ed1dbd66..d7d1d0e6724f1 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MultiClusterRepoAccessIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/MultiClusterRepoAccessIT.java @@ -39,6 +39,7 @@ import java.util.Arrays; import java.util.function.Function; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; @@ -126,7 +127,7 @@ public void testConcurrentWipeAndRecreateFromOtherCluster() throws InterruptedEx secondCluster.startDataOnlyNode(); assertAcked(secondCluster.client().admin().cluster().preparePutRepository(repoName) .setType("fs") - .setSettings(Settings.builder().put("location", repoPath).put("readonly", true))); + .setSettings(Settings.builder().put("location", repoPath).put(READONLY_SETTING_KEY, true))); assertThat(secondCluster.client().admin().cluster().prepareGetRepositories(repoName).get().repositories() .stream().filter(r -> r.name().equals(repoName)).findFirst().get().uuid(), equalTo(repoUuid)); diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/RepositoriesIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/RepositoriesIT.java index 7654b4a33fd25..75592ada6aac7 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/RepositoriesIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/RepositoriesIT.java @@ -36,6 +36,7 @@ import java.nio.file.Path; import java.util.List; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertRequestBuilderThrows; import static org.hamcrest.Matchers.containsString; @@ -183,7 +184,7 @@ public void testRepositoryVerification() throws Exception { .put("location", randomRepoPath()) .put("random_control_io_exception_rate", 1.0).build(); Settings readonlySettings = Settings.builder().put(settings) - .put("readonly", true).build(); + .put(READONLY_SETTING_KEY, true).build(); logger.info("--> creating repository that cannot write any files - should fail"); assertRequestBuilderThrows(client.admin().cluster().preparePutRepository("test-repo-1") .setType("mock").setSettings(settings), diff --git a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java index 995a9aeaa215d..3abf613361753 100644 --- a/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java +++ b/server/src/internalClusterTest/java/org/elasticsearch/snapshots/SharedClusterSnapshotRestoreIT.java @@ -91,6 +91,7 @@ import static org.elasticsearch.index.IndexSettings.INDEX_SOFT_DELETES_SETTING; import static org.elasticsearch.index.shard.IndexShardTests.getEngineFromShard; import static org.elasticsearch.indices.recovery.RecoverySettings.INDICES_RECOVERY_MAX_BYTES_PER_SEC_SETTING; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAllSuccessful; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; @@ -912,7 +913,7 @@ public void testReadonlyRepository() throws Exception { createRepository("readonly-repo", "fs", Settings.builder() .put("location", repositoryLocation) .put("compress", randomBoolean()) - .put("readonly", true) + .put(READONLY_SETTING_KEY, true) .put("chunk_size", randomIntBetween(100, 1000), ByteSizeUnit.BYTES)); logger.info("--> restore index after deletion"); RestoreSnapshotResponse restoreSnapshotResponse = client.admin().cluster().prepareRestoreSnapshot("readonly-repo", "test-snap") diff --git a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java index a45c48717cbdc..1d611ab3237a5 100644 --- a/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java +++ b/server/src/main/java/org/elasticsearch/repositories/blobstore/BlobStoreRepository.java @@ -188,6 +188,11 @@ public abstract class BlobStoreRepository extends AbstractLifecycleComponent imp private static final String UPLOADED_DATA_BLOB_PREFIX = "__"; + /** + * All {@link BlobStoreRepository} implementations can be made read-only by setting this key to {@code true} in their settings. + */ + public static final String READONLY_SETTING_KEY = "readonly"; + /** * Prefix used for the identifiers of data blobs that were not actually written to the repository physically because their contents are * already stored in the metadata referencing them, i.e. in {@link BlobStoreIndexShardSnapshot} and @@ -337,7 +342,7 @@ protected BlobStoreRepository( this.supportURLRepo = SUPPORT_URL_REPO.get(metadata.settings()); snapshotRateLimiter = getRateLimiter(metadata.settings(), "max_snapshot_bytes_per_sec", new ByteSizeValue(40, ByteSizeUnit.MB)); restoreRateLimiter = getRateLimiter(metadata.settings(), "max_restore_bytes_per_sec", ByteSizeValue.ZERO); - readOnly = metadata.settings().getAsBoolean("readonly", false); + readOnly = metadata.settings().getAsBoolean(READONLY_SETTING_KEY, false); cacheRepositoryData = CACHE_REPOSITORY_DATA.get(metadata.settings()); bufferSize = Math.toIntExact(BUFFER_SIZE_SETTING.get(metadata.settings()).getBytes()); this.maxSnapshotCount = MAX_SNAPSHOTS_SETTING.get(metadata.settings()); diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java index 9fae32ff61f3c..118490f88bda5 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESBlobStoreRepositoryIntegTestCase.java @@ -59,6 +59,7 @@ import java.util.Map; import java.util.Set; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.hamcrest.Matchers.equalTo; @@ -101,7 +102,7 @@ protected final String createRepository(final String name, final Settings settin internalCluster().getDataOrMasterNodeInstances(RepositoriesService.class).forEach(repositories -> { assertThat(repositories.repository(name), notNullValue()); assertThat(repositories.repository(name), instanceOf(BlobStoreRepository.class)); - assertThat(repositories.repository(name).isReadOnly(), is(settings.getAsBoolean("readonly", false))); + assertThat(repositories.repository(name).isReadOnly(), is(settings.getAsBoolean(READONLY_SETTING_KEY, false))); BlobStore blobStore = ((BlobStoreRepository) repositories.repository(name)).getBlobStore(); assertThat("blob store has to be lazy initialized", blobStore, verify ? is(notNullValue()) : is(nullValue())); }); diff --git a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESFsBasedRepositoryIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESFsBasedRepositoryIntegTestCase.java index 3a8501d65e95a..5bd0053e3e49c 100644 --- a/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESFsBasedRepositoryIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/repositories/blobstore/ESFsBasedRepositoryIntegTestCase.java @@ -33,6 +33,7 @@ import java.nio.file.Path; import java.util.stream.Stream; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.hamcrest.Matchers.instanceOf; @@ -76,7 +77,7 @@ public void testMissingDirectoriesNotCreatedInReadonlyRepository() throws IOExce } assertFalse(Files.exists(deletedPath)); - createRepository(repoName, Settings.builder().put(repoSettings).put("readonly", true).build(), randomBoolean()); + createRepository(repoName, Settings.builder().put(repoSettings).put(READONLY_SETTING_KEY, true).build(), randomBoolean()); final ElasticsearchException exception = expectThrows(ElasticsearchException.class, () -> client().admin().cluster().prepareRestoreSnapshot(repoName, snapshotName).setWaitForCompletion(randomBoolean()).get()); @@ -90,7 +91,7 @@ public void testReadOnly() throws Exception { final Path repoPath = randomRepoPath(); final Settings repoSettings = Settings.builder() .put(repositorySettings(repoName)) - .put("readonly", true) + .put(READONLY_SETTING_KEY, true) .put(FsRepository.LOCATION_SETTING.getKey(), repoPath) .put(BlobStoreRepository.BUFFER_SIZE_SETTING.getKey(), String.valueOf(randomIntBetween(1, 8) * 1024) + "kb") .build(); @@ -107,7 +108,7 @@ public void testReadOnly() throws Exception { assertFalse(Files.exists(storePath)); } - createRepository(repoName, Settings.builder().put(repoSettings).put("readonly", false).build(), false); + createRepository(repoName, Settings.builder().put(repoSettings).put(READONLY_SETTING_KEY, false).build(), false); try (BlobStore store = newBlobStore(repoName)) { assertTrue(Files.exists(repoPath)); diff --git a/test/framework/src/main/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java b/test/framework/src/main/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java index 026ba8edb0fef..fbee0356e2258 100644 --- a/test/framework/src/main/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java +++ b/test/framework/src/main/java/org/elasticsearch/snapshots/AbstractSnapshotIntegTestCase.java @@ -89,6 +89,7 @@ import java.util.function.Predicate; import java.util.stream.StreamSupport; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.empty; import static org.hamcrest.Matchers.equalTo; @@ -139,7 +140,7 @@ public void assertRepoConsistency() { if (skipRepoConsistencyCheckReason == null) { clusterAdmin().prepareGetRepositories().get().repositories().forEach(repositoryMetadata -> { final String name = repositoryMetadata.name(); - if (repositoryMetadata.settings().getAsBoolean("readonly", false) == false) { + if (repositoryMetadata.settings().getAsBoolean(READONLY_SETTING_KEY, false) == false) { clusterAdmin().prepareDeleteSnapshot(name, OLD_VERSION_SNAPSHOT_PREFIX + "*").get(); clusterAdmin().prepareCleanupRepository(name).get(); } diff --git a/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedFSBlobStoreRepositoryIntegTests.java b/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedFSBlobStoreRepositoryIntegTests.java index 0e0766b10ca75..5eeb54574f230 100644 --- a/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedFSBlobStoreRepositoryIntegTests.java +++ b/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedFSBlobStoreRepositoryIntegTests.java @@ -33,6 +33,7 @@ import java.util.Locale; import java.util.stream.Stream; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.repositories.encrypted.EncryptedRepository.getEncryptedBlobByteLength; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.hamcrest.Matchers.containsString; @@ -137,7 +138,7 @@ public void testTamperedEncryptionMetadata() throws Exception { }); } - final Settings settings = Settings.builder().put(repoSettings).put("readonly", randomBoolean()).build(); + final Settings settings = Settings.builder().put(repoSettings).put(READONLY_SETTING_KEY, randomBoolean()).build(); final boolean verifyOnCreate = randomBoolean(); if (verifyOnCreate) { diff --git a/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java b/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java index 4a52a2a29e4fa..9c9ee5c51f495 100644 --- a/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java +++ b/x-pack/plugin/repository-encrypted/src/internalClusterTest/java/org/elasticsearch/repositories/encrypted/EncryptedRepositorySecretIntegTests.java @@ -46,6 +46,7 @@ import java.util.stream.Collectors; import static org.elasticsearch.cluster.metadata.IndexMetadata.SETTING_NUMBER_OF_SHARDS; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.hamcrest.Matchers.contains; @@ -740,7 +741,7 @@ protected String createRepository(final String name, final Settings settings, fi internalCluster().getDataOrMasterNodeInstances(RepositoriesService.class).forEach(repositories -> { assertThat(repositories.repository(name), notNullValue()); assertThat(repositories.repository(name), instanceOf(BlobStoreRepository.class)); - assertThat(repositories.repository(name).isReadOnly(), is(settings.getAsBoolean("readonly", false))); + assertThat(repositories.repository(name).isReadOnly(), is(settings.getAsBoolean(READONLY_SETTING_KEY, false))); }); return name; diff --git a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshotsIntegTests.java b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshotsIntegTests.java index ef6413596332c..fb66968621c81 100644 --- a/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshotsIntegTests.java +++ b/x-pack/plugin/searchable-snapshots/src/internalClusterTest/java/org/elasticsearch/xpack/searchablesnapshots/SearchableSnapshotsIntegTests.java @@ -86,6 +86,7 @@ import static org.elasticsearch.cluster.metadata.IndexMetadata.INDEX_NUMBER_OF_SHARDS_SETTING; import static org.elasticsearch.index.IndexSettings.INDEX_SOFT_DELETES_SETTING; import static org.elasticsearch.index.query.QueryBuilders.matchQuery; +import static org.elasticsearch.repositories.blobstore.BlobStoreRepository.READONLY_SETTING_KEY; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked; import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount; import static org.elasticsearch.xpack.searchablesnapshots.SearchableSnapshots.DATA_TIERS_PREFERENCE; @@ -942,7 +943,7 @@ public void testSnapshotOfSearchableSnapshotIncludesNoDataButCanBeRestored() thr assertAcked(client().admin().cluster().prepareDeleteRepository(repositoryName)); final Settings.Builder settings = Settings.builder().put(repositoryMetadata.settings()); if (randomBoolean()) { - settings.put("readonly", "true"); + settings.put(READONLY_SETTING_KEY, "true"); } assertAcked( clusterAdmin().preparePutRepository(newRepositoryName)