Skip to content

Commit 3e461cc

Browse files
sharathkanakaSharath Kanaka
andauthored
Add plugin system indices to the default restorable list (#6691)
Signed-off-by: Sharath Kanaka <sharatcr@amazon.com> Co-authored-by: Sharath Kanaka <sharatcr@amazon.com>
1 parent 0f07289 commit 3e461cc

5 files changed

Lines changed: 52 additions & 18 deletions

File tree

‎README.md‎

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,17 @@ The Security plugin protects system indices registered by OpenSearch plugins. Th
134134
indices through `SystemIndexPlugin.getSystemIndexDescriptors`.
135135

136136
Users whose mapped roles are listed in `plugins.security.restapi.roles_enabled` can restore only the system indices matched by
137-
`plugins.security.system_indices.restore.indices`. The default list is empty today. System indices will be added to it as their
138-
plugin owners confirm they restore safely. An operator sets the list in `opensearch.yml`. To also allow changing it at runtime
139-
with `PUT _cluster/settings`, set `plugins.security.system_indices.restore.dynamic.enabled: true` in `opensearch.yml`; the runtime
140-
value then takes precedence over the file. A configured value replaces the default list and is not merged
141-
with it. The Security configuration index can never be restored this way:
137+
`plugins.security.system_indices.restore.indices`. By default it holds plugin system indices that restore correctly onto a new
138+
cluster. To see the default list, run:
139+
140+
```
141+
GET _cluster/settings?include_defaults=true&filter_path=defaults.plugins.security.system_indices.restore.indices
142+
```
143+
144+
An operator can override the list in `opensearch.yml`, and a configured value replaces the default list rather than adding to
145+
it. To also allow changing it at runtime with `PUT _cluster/settings`, set `plugins.security.system_indices.restore.dynamic.enabled: true`
146+
in `opensearch.yml`; the runtime value then takes precedence over the file. The Security configuration index can never be
147+
restored this way:
142148

143149
```
144150
plugins.security.system_indices.restore.indices:

‎src/integrationTest/java/org/opensearch/security/privileges/int_tests/SystemIndexRestoreDefaultIntTests.java‎

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,18 +26,19 @@
2626

2727
import static org.hamcrest.MatcherAssert.assertThat;
2828
import static org.hamcrest.Matchers.containsString;
29-
import static org.hamcrest.Matchers.not;
3029
import static org.opensearch.security.privileges.int_tests.SystemIndexRestoreIntTests.ELIGIBLE;
30+
import static org.opensearch.security.privileges.int_tests.SystemIndexRestoreIntTests.NOT_ELIGIBLE;
3131
import static org.opensearch.security.privileges.int_tests.SystemIndexRestoreIntTests.REST_ADMIN;
3232
import static org.opensearch.security.privileges.int_tests.SystemIndexRestoreIntTests.cleanup;
3333
import static org.opensearch.security.privileges.int_tests.SystemIndexRestoreIntTests.createIndicesAndSnapshot;
3434
import static org.opensearch.security.privileges.int_tests.SystemIndexRestoreIntTests.restorePath;
3535
import static org.opensearch.test.framework.cluster.TestRestClient.json;
3636
import static org.opensearch.test.framework.matcher.RestMatchers.isForbidden;
37+
import static org.opensearch.test.framework.matcher.RestMatchers.isOk;
3738

3839
/**
39-
* With {@code plugins.security.system_indices.restore.indices} left at its empty default, a REST admin cannot
40-
* restore any system index, for both the legacy and the V4 privilege evaluation.
40+
* With {@code plugins.security.system_indices.restore.indices} left at its default, a REST admin can restore the system
41+
* indices in the default list and no others, for both the legacy and the V4 privilege evaluation.
4142
*/
4243
@RunWith(Parameterized.class)
4344
public class SystemIndexRestoreDefaultIntTests {
@@ -50,18 +51,29 @@ public class SystemIndexRestoreDefaultIntTests {
5051
final LocalCluster cluster;
5152

5253
@Test
53-
public void restAdmin_cannotRestoreSystemIndexWhenNoneConfigured() {
54+
public void restAdmin_restoresSystemIndicesInDefaultList() {
5455
createIndicesAndSnapshot(cluster, "snap_default", ELIGIBLE);
5556
try (TestRestClient client = cluster.getRestClient(REST_ADMIN)) {
5657
TestRestClient.HttpResponse response = client.post(restorePath("snap_default"), json("indices", List.of(ELIGIBLE)));
57-
assertThat(response, isForbidden());
58-
assertThat(response.getBody(), containsString("[" + ELIGIBLE + "] are not eligible for restore."));
59-
assertThat(response.getBody(), not(containsString("Restorable system indices")));
58+
assertThat(response, isOk());
6059
} finally {
6160
cleanup(cluster, "snap_default", ELIGIBLE);
6261
}
6362
}
6463

64+
@Test
65+
public void restAdmin_cannotRestoreSystemIndexOutsideDefaultList() {
66+
createIndicesAndSnapshot(cluster, "snap_not_in_default", NOT_ELIGIBLE);
67+
try (TestRestClient client = cluster.getRestClient(REST_ADMIN)) {
68+
TestRestClient.HttpResponse response = client.post(restorePath("snap_not_in_default"), json("indices", List.of(NOT_ELIGIBLE)));
69+
assertThat(response, isForbidden());
70+
assertThat(response.getBody(), containsString("[" + NOT_ELIGIBLE + "] are not eligible for restore."));
71+
assertThat(response.getBody(), containsString("Restorable system indices: [" + ELIGIBLE));
72+
} finally {
73+
cleanup(cluster, "snap_not_in_default", NOT_ELIGIBLE);
74+
}
75+
}
76+
6577
@Parameters(name = "{0}")
6678
public static Collection<Object[]> params() {
6779
List<Object[]> result = new ArrayList<>();

‎src/integrationTest/java/org/opensearch/security/privileges/int_tests/SystemIndexRestoreIntTests.java‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
public class SystemIndexRestoreIntTests {
5353

5454
static final String ELIGIBLE = ".opendistro-alerting-config";
55-
static final String NOT_ELIGIBLE = ".opendistro-alerting-alerts";
55+
static final String NOT_ELIGIBLE = ".opensearch-alerting-queries";
5656
static final String HISTORY_PATTERN = ".opendistro-alerting-alert-history-*";
5757
static final String HISTORY_1 = ".opendistro-alerting-alert-history-2026.10.27-1";
5858
static final String HISTORY_2 = ".opendistro-alerting-alert-history-2026.10.28-000002";
@@ -92,7 +92,7 @@ static LocalCluster.Builder dynamicClusterBuilder() {
9292
}
9393

9494
/**
95-
* Cluster with {@code plugins.security.system_indices.restore.indices} left at its empty default.
95+
* Cluster with {@code plugins.security.system_indices.restore.indices} left at its default.
9696
*/
9797
static LocalCluster.Builder defaultClusterBuilder() {
9898
return new LocalCluster.Builder().clusterManager(ClusterManager.SINGLENODE)

‎src/main/java/org/opensearch/security/support/ConfigConstants.java‎

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,17 @@ public class ConfigConstants {
415415
public static final String SECURITY_SYSTEM_INDICES_KEY = SECURITY_SETTINGS_PREFIX + "system_indices.indices";
416416
public static final List<String> SECURITY_SYSTEM_INDICES_DEFAULT = Collections.emptyList();
417417
public static final String SECURITY_SYSTEM_INDICES_RESTORE_INDICES_KEY = SECURITY_SETTINGS_PREFIX + "system_indices.restore.indices";
418-
public static final List<String> SECURITY_SYSTEM_INDICES_RESTORE_INDICES_DEFAULT = Collections.emptyList();
418+
/**
419+
* System indices that restore correctly onto a new cluster, covered by restore tests in each plugin's repo
420+
* (same OpenSearch version).
421+
*/
422+
public static final List<String> SECURITY_SYSTEM_INDICES_RESTORE_INDICES_DEFAULT = List.of(
423+
".opendistro-alerting-config",
424+
".opendistro-alerting-alerts",
425+
".opendistro-alerting-alert-history-*",
426+
".opendistro-ism-config",
427+
".ltrstore*"
428+
);
419429
public static final String SECURITY_SYSTEM_INDICES_RESTORE_DYNAMIC_ENABLED_KEY = SECURITY_SETTINGS_PREFIX
420430
+ "system_indices.restore.dynamic.enabled";
421431
public static final boolean SECURITY_SYSTEM_INDICES_RESTORE_DYNAMIC_ENABLED_DEFAULT = false;

‎src/test/java/org/opensearch/security/privileges/SystemIndexRestoreEligibilityHelperTest.java‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,12 @@ public void isEligible_matchesConfiguredIndicesAndPatterns() {
112112
}
113113

114114
@Test
115-
public void isEligible_nothingByDefault() {
116-
assertThat(helperWithDefaults.isEligible(ALERTING_CONFIG), is(false));
115+
public void isEligible_defaultListCoversConfirmedPluginIndices() {
116+
for (final String index : ConfigConstants.SECURITY_SYSTEM_INDICES_RESTORE_INDICES_DEFAULT) {
117+
assertThat(index, helperWithDefaults.isEligible(index), is(true));
118+
}
117119
assertThat(helperWithDefaults.isEligible(REPORTS_DEFINITIONS), is(false));
120+
assertThat(helperWithDefaults.isEligible(SECURITY_INDEX), is(false));
118121
}
119122

120123
@Test
@@ -140,7 +143,10 @@ public void denialReason_listsNonEligibleAndTheRestorableIndices() {
140143

141144
@Test
142145
public void denialReason_omitsRestorableIndicesWhenNoneConfigured() {
143-
Optional<String> reason = helperWithDefaults.denialReason(restore(ALERTING_CONFIG), Set.of(ALERTING_CONFIG));
146+
SystemIndexRestoreEligibilityHelper noneConfigured = helper(
147+
Settings.builder().putList(ConfigConstants.SECURITY_SYSTEM_INDICES_RESTORE_INDICES_KEY, List.of()).build()
148+
);
149+
Optional<String> reason = noneConfigured.denialReason(restore(ALERTING_CONFIG), Set.of(ALERTING_CONFIG));
144150
assertThat(
145151
reason.get(),
146152
equalTo("System index restore denied: System indices [" + ALERTING_CONFIG + "] are not eligible for restore.")

0 commit comments

Comments
 (0)