diff --git a/x-pack/plugin/ilm/qa/with-security/src/test/java/org/elasticsearch/xpack/security/PermissionsIT.java b/x-pack/plugin/ilm/qa/with-security/src/test/java/org/elasticsearch/xpack/security/PermissionsIT.java index b773f0288a4..057fe4a4881 100644 --- a/x-pack/plugin/ilm/qa/with-security/src/test/java/org/elasticsearch/xpack/security/PermissionsIT.java +++ b/x-pack/plugin/ilm/qa/with-security/src/test/java/org/elasticsearch/xpack/security/PermissionsIT.java @@ -8,9 +8,11 @@ package org.elasticsearch.xpack.security; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; +import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchStatusException; import org.elasticsearch.action.admin.cluster.repositories.put.PutRepositoryRequest; -import org.elasticsearch.action.admin.cluster.snapshots.delete.DeleteSnapshotRequest; +import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsRequest; +import org.elasticsearch.action.admin.cluster.snapshots.get.GetSnapshotsResponse; import org.elasticsearch.client.Node; import org.elasticsearch.client.Request; import org.elasticsearch.client.RequestOptions; @@ -19,9 +21,11 @@ import org.elasticsearch.client.ResponseException; import org.elasticsearch.client.RestClient; import org.elasticsearch.client.RestClientBuilder; import org.elasticsearch.client.RestHighLevelClient; +import org.elasticsearch.client.core.AcknowledgedResponse; import org.elasticsearch.client.slm.DeleteSnapshotLifecyclePolicyRequest; import org.elasticsearch.client.slm.ExecuteSnapshotLifecyclePolicyRequest; import org.elasticsearch.client.slm.ExecuteSnapshotLifecyclePolicyResponse; +import org.elasticsearch.client.slm.ExecuteSnapshotLifecycleRetentionRequest; import org.elasticsearch.client.slm.GetSnapshotLifecyclePolicyRequest; import org.elasticsearch.client.slm.PutSnapshotLifecyclePolicyRequest; import org.elasticsearch.client.slm.SnapshotLifecyclePolicy; @@ -38,6 +42,7 @@ import org.elasticsearch.common.xcontent.json.JsonXContent; import org.elasticsearch.common.xcontent.support.XContentMapValues; import org.elasticsearch.repositories.fs.FsRepository; import org.elasticsearch.rest.RestStatus; +import org.elasticsearch.snapshots.SnapshotState; import org.elasticsearch.test.rest.ESRestTestCase; import org.elasticsearch.xpack.core.ilm.DeleteAction; import org.elasticsearch.xpack.core.ilm.LifecycleAction; @@ -56,8 +61,8 @@ import java.util.Map; import static java.util.Collections.singletonMap; import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder; import static org.elasticsearch.xpack.core.security.authc.support.UsernamePasswordToken.basicAuthHeaderValue; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; -import static org.hamcrest.Matchers.is; public class PermissionsIT extends ESRestTestCase { @@ -144,6 +149,7 @@ public class PermissionsIT extends ESRestTestCase { } public void testSLMWithPermissions() throws Exception { + String repo = "my_repository"; createIndexAsAdmin("index", Settings.builder().put("index.number_of_replicas", 0).build(), ""); // Set up two roles and users, one for reading SLM, another for managing SLM @@ -151,7 +157,7 @@ public class PermissionsIT extends ESRestTestCase { roleRequest.setJsonEntity("{ \"cluster\": [\"read_slm\"] }"); assertOK(adminClient().performRequest(roleRequest)); roleRequest = new Request("PUT", "/_security/role/slm-manage"); - roleRequest.setJsonEntity("{ \"cluster\": [\"manage_slm\", \"create_snapshot\"]," + + roleRequest.setJsonEntity("{ \"cluster\": [\"manage_slm\", \"cluster:admin/repository/*\", \"cluster:admin/snapshot/*\"]," + "\"indices\": [{ \"names\": [\".slm-history*\"],\"privileges\": [\"all\"] }] }"); assertOK(adminClient().performRequest(roleRequest)); @@ -181,7 +187,7 @@ public class PermissionsIT extends ESRestTestCase { Settings.Builder settingsBuilder = Settings.builder().put("location", "."); repoRequest.settings(settingsBuilder); - repoRequest.name("my_repository"); + repoRequest.name(repo); repoRequest.type(FsRepository.TYPE); org.elasticsearch.action.support.master.AcknowledgedResponse response = hlAdminClient.snapshot().createRepository(repoRequest, RequestOptions.DEFAULT); @@ -190,7 +196,8 @@ public class PermissionsIT extends ESRestTestCase { Map config = new HashMap<>(); config.put("indices", Collections.singletonList("index")); SnapshotLifecyclePolicy policy = new SnapshotLifecyclePolicy( - "policy_id", "name", "1 2 3 * * ?", "my_repository", config, SnapshotRetentionConfiguration.EMPTY); + "policy_id", "name", "1 2 3 * * ?", repo, config, + new SnapshotRetentionConfiguration(TimeValue.ZERO, null, null)); PutSnapshotLifecyclePolicyRequest request = new PutSnapshotLifecyclePolicyRequest(policy); expectThrows(ElasticsearchStatusException.class, @@ -208,6 +215,40 @@ public class PermissionsIT extends ESRestTestCase { ExecuteSnapshotLifecyclePolicyResponse executeResp = adminHLRC.indexLifecycle().executeSnapshotLifecyclePolicy(executeRequest, RequestOptions.DEFAULT); + final String snapName = executeResp.getSnapshotName(); + + assertBusy(() -> { + try { + logger.info("--> checking for snapshot to be created"); + GetSnapshotsRequest getSnaps = new GetSnapshotsRequest(repo); + getSnaps.snapshots(new String[]{snapName}); + GetSnapshotsResponse getResp = adminHLRC.snapshot().get(getSnaps, RequestOptions.DEFAULT); + assertThat(getResp.getSnapshots().get(0).state(), equalTo(SnapshotState.SUCCESS)); + } catch (ElasticsearchException e) { + fail("expected snapshot to exist but it does not: " + e.getDetailedMessage()); + } + }); + + ExecuteSnapshotLifecycleRetentionRequest executeRetention = new ExecuteSnapshotLifecycleRetentionRequest(); + expectThrows(ElasticsearchStatusException.class, () -> + readHlrc.indexLifecycle().executeSnapshotLifecycleRetention(executeRetention, RequestOptions.DEFAULT)); + + AcknowledgedResponse retentionResp = + adminHLRC.indexLifecycle().executeSnapshotLifecycleRetention(executeRetention, RequestOptions.DEFAULT); + assertTrue(retentionResp.isAcknowledged()); + + assertBusy(() -> { + try { + logger.info("--> checking for snapshot to be deleted"); + GetSnapshotsRequest getSnaps = new GetSnapshotsRequest(repo); + getSnaps.snapshots(new String[]{snapName}); + GetSnapshotsResponse getResp = adminHLRC.snapshot().get(getSnaps, RequestOptions.DEFAULT); + assertThat(getResp.getSnapshots().size(), equalTo(0)); + } catch (ElasticsearchException e) { + // great, we want it to not exist + assertThat(e.getDetailedMessage(), containsString("snapshot_missing_exception")); + } + }); DeleteSnapshotLifecyclePolicyRequest deleteRequest = new DeleteSnapshotLifecyclePolicyRequest("policy_id"); expectThrows(ElasticsearchStatusException.class, () -> @@ -215,18 +256,6 @@ public class PermissionsIT extends ESRestTestCase { adminHLRC.indexLifecycle().deleteSnapshotLifecyclePolicy(deleteRequest, RequestOptions.DEFAULT); - // Delete snapshot to clean up and make sure it's not on-going. - // This is inside an assertBusy because the snapshot may not - // yet exist (in which case it throws an error) - assertBusy(() -> { - try { - DeleteSnapshotRequest delReq = new DeleteSnapshotRequest("my_repository", executeResp.getSnapshotName()); - hlAdminClient.snapshot().delete(delReq, RequestOptions.DEFAULT); - } catch (ElasticsearchStatusException e) { - fail("got exception: " + e); - } - }); - hlAdminClient.close(); readHlrc.close(); adminHLRC.close();