[7.5][Transform] introduce new roles and deprecate old ones (#47780) (#47819)

deprecate data_frame_transforms_{user,admin} roles and introduce transform_{user,admin} roles as replacement
This commit is contained in:
Hendrik Muhs 2019-10-10 10:31:24 +02:00 committed by GitHub
parent fbbe04b801
commit 0e7869128a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 205 additions and 96 deletions

View File

@ -24,8 +24,8 @@ import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.xcontent.ConstructingObjectParser;
import org.elasticsearch.common.xcontent.XContentParser;
import org.elasticsearch.common.xcontent.ObjectParser.ValueType;
import org.elasticsearch.common.xcontent.XContentParser;
import java.util.Arrays;
import java.util.Collection;
@ -299,12 +299,14 @@ public final class Role {
public static final String NONE = "none";
public static final String ALL = "all";
public static final String MONITOR = "monitor";
public static final String MONITOR_DATA_FRAME_TRANSFORMS = "monitor_data_frame_transforms";
public static final String MONITOR_TRANSFORM_DEPRECATED = "monitor_data_frame_transforms";
public static final String MONITOR_TRANSFORM = "monitor_transform";
public static final String MONITOR_ML = "monitor_ml";
public static final String MONITOR_WATCHER = "monitor_watcher";
public static final String MONITOR_ROLLUP = "monitor_rollup";
public static final String MANAGE = "manage";
public static final String MANAGE_DATA_FRAME_TRANSFORMS = "manage_data_frame_transforms";
public static final String MANAGE_TRANSFORM_DEPRECATED = "manage_data_frame_transforms";
public static final String MANAGE_TRANSFORM = "manage_transform";
public static final String MANAGE_ML = "manage_ml";
public static final String MANAGE_WATCHER = "manage_watcher";
public static final String MANAGE_ROLLUP = "manage_rollup";
@ -320,8 +322,8 @@ public final class Role {
public static final String READ_CCR = "read_ccr";
public static final String MANAGE_ILM = "manage_ilm";
public static final String READ_ILM = "read_ilm";
public static final String[] ALL_ARRAY = new String[] { NONE, ALL, MONITOR, MONITOR_DATA_FRAME_TRANSFORMS, MONITOR_ML,
MONITOR_WATCHER, MONITOR_ROLLUP, MANAGE, MANAGE_DATA_FRAME_TRANSFORMS,
public static final String[] ALL_ARRAY = new String[] { NONE, ALL, MONITOR, MONITOR_TRANSFORM_DEPRECATED, MONITOR_TRANSFORM,
MONITOR_ML, MONITOR_WATCHER, MONITOR_ROLLUP, MANAGE, MANAGE_TRANSFORM_DEPRECATED, MANAGE_TRANSFORM,
MANAGE_ML, MANAGE_WATCHER, MANAGE_ROLLUP, MANAGE_INDEX_TEMPLATES, MANAGE_INGEST_PIPELINES, TRANSPORT_CLIENT,
MANAGE_SECURITY, MANAGE_SAML, MANAGE_OIDC, MANAGE_TOKEN, MANAGE_PIPELINE, MANAGE_CCR, READ_CCR, MANAGE_ILM, READ_ILM};
}

View File

@ -28,6 +28,7 @@ import org.elasticsearch.client.ESRestHighLevelClientTestCase;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.client.security.AuthenticateResponse;
import org.elasticsearch.client.security.AuthenticateResponse.RealmInfo;
import org.elasticsearch.client.security.ChangePasswordRequest;
import org.elasticsearch.client.security.ClearRealmCacheRequest;
import org.elasticsearch.client.security.ClearRealmCacheResponse;
@ -79,7 +80,6 @@ import org.elasticsearch.client.security.PutUserRequest;
import org.elasticsearch.client.security.PutUserResponse;
import org.elasticsearch.client.security.RefreshPolicy;
import org.elasticsearch.client.security.TemplateRoleName;
import org.elasticsearch.client.security.AuthenticateResponse.RealmInfo;
import org.elasticsearch.client.security.support.ApiKey;
import org.elasticsearch.client.security.support.CertificateInfo;
import org.elasticsearch.client.security.support.expressiondsl.RoleMapperExpression;
@ -99,8 +99,6 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.util.set.Sets;
import org.hamcrest.Matchers;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
@ -120,6 +118,9 @@ import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.hamcrest.Matchers.containsString;
@ -679,8 +680,8 @@ public class SecurityDocumentationIT extends ESRestHighLevelClientTestCase {
List<Role> roles = response.getRoles();
assertNotNull(response);
// 27 system roles plus the three we created
assertThat(roles.size(), equalTo(30));
// 29 system roles plus the three we created
assertThat(roles.size(), equalTo(32));
}
{

View File

@ -80,11 +80,13 @@ A successful call returns an object with "cluster" and "index" fields.
"manage_security",
"manage_slm",
"manage_token",
"manage_transform",
"manage_watcher",
"monitor",
"monitor_data_frame_transforms",
"monitor_ml",
"monitor_rollup",
"monitor_transform",
"monitor_watcher",
"none",
"read_ccr",

View File

@ -50,7 +50,7 @@ public class ClusterPrivilegeResolver {
private static final Set<String> MANAGE_TOKEN_PATTERN = Collections.singleton("cluster:admin/xpack/security/token/*");
private static final Set<String> MANAGE_API_KEY_PATTERN = Collections.singleton("cluster:admin/xpack/security/api_key/*");
private static final Set<String> MONITOR_PATTERN = Collections.singleton("cluster:monitor/*");
private static final Set<String> MONITOR_DATA_FRAME_PATTERN = Collections.unmodifiableSet(
private static final Set<String> MONITOR_TRANSFORM_PATTERN = Collections.unmodifiableSet(
Sets.newHashSet("cluster:monitor/data_frame/*", "cluster:monitor/transform/*"));
private static final Set<String> MONITOR_ML_PATTERN = Collections.singleton("cluster:monitor/xpack/ml/*");
private static final Set<String> MONITOR_WATCHER_PATTERN = Collections.singleton("cluster:monitor/xpack/watcher/*");
@ -59,7 +59,7 @@ public class ClusterPrivilegeResolver {
Sets.newHashSet("cluster:*", "indices:admin/template/*"));
private static final Set<String> MANAGE_ML_PATTERN = Collections.unmodifiableSet(
Sets.newHashSet("cluster:admin/xpack/ml/*", "cluster:monitor/xpack/ml/*"));
private static final Set<String> MANAGE_DATA_FRAME_PATTERN = Collections.unmodifiableSet(
private static final Set<String> MANAGE_TRANSFORM_PATTERN = Collections.unmodifiableSet(
Sets.newHashSet("cluster:admin/data_frame/*", "cluster:monitor/data_frame/*",
"cluster:monitor/transform/*", "cluster:admin/transform/*"));
private static final Set<String> MANAGE_WATCHER_PATTERN = Collections.unmodifiableSet(
@ -89,14 +89,18 @@ public class ClusterPrivilegeResolver {
public static final NamedClusterPrivilege ALL = new ActionClusterPrivilege("all", ALL_CLUSTER_PATTERN);
public static final NamedClusterPrivilege MONITOR = new ActionClusterPrivilege("monitor", MONITOR_PATTERN);
public static final NamedClusterPrivilege MONITOR_ML = new ActionClusterPrivilege("monitor_ml", MONITOR_ML_PATTERN);
public static final NamedClusterPrivilege MONITOR_DATA_FRAME =
new ActionClusterPrivilege("monitor_data_frame_transforms", MONITOR_DATA_FRAME_PATTERN);
public static final NamedClusterPrivilege MONITOR_TRANSFORM_DEPRECATED =
new ActionClusterPrivilege("monitor_data_frame_transforms", MONITOR_TRANSFORM_PATTERN);
public static final NamedClusterPrivilege MONITOR_TRANSFORM =
new ActionClusterPrivilege("monitor_transform", MONITOR_TRANSFORM_PATTERN);
public static final NamedClusterPrivilege MONITOR_WATCHER = new ActionClusterPrivilege("monitor_watcher", MONITOR_WATCHER_PATTERN);
public static final NamedClusterPrivilege MONITOR_ROLLUP = new ActionClusterPrivilege("monitor_rollup", MONITOR_ROLLUP_PATTERN);
public static final NamedClusterPrivilege MANAGE = new ActionClusterPrivilege("manage", ALL_CLUSTER_PATTERN, ALL_SECURITY_PATTERN);
public static final NamedClusterPrivilege MANAGE_ML = new ActionClusterPrivilege("manage_ml", MANAGE_ML_PATTERN);
public static final NamedClusterPrivilege MANAGE_DATA_FRAME =
new ActionClusterPrivilege("manage_data_frame_transforms", MANAGE_DATA_FRAME_PATTERN);
public static final NamedClusterPrivilege MANAGE_TRANSFORM_DEPRECATED =
new ActionClusterPrivilege("manage_data_frame_transforms", MANAGE_TRANSFORM_PATTERN);
public static final NamedClusterPrivilege MANAGE_TRANSFORM =
new ActionClusterPrivilege("manage_transform", MANAGE_TRANSFORM_PATTERN);
public static final NamedClusterPrivilege MANAGE_TOKEN = new ActionClusterPrivilege("manage_token", MANAGE_TOKEN_PATTERN);
public static final NamedClusterPrivilege MANAGE_WATCHER = new ActionClusterPrivilege("manage_watcher", MANAGE_WATCHER_PATTERN);
public static final NamedClusterPrivilege MANAGE_ROLLUP = new ActionClusterPrivilege("manage_rollup", MANAGE_ROLLUP_PATTERN);
@ -131,12 +135,14 @@ public class ClusterPrivilegeResolver {
ALL,
MONITOR,
MONITOR_ML,
MONITOR_DATA_FRAME,
MONITOR_TRANSFORM_DEPRECATED,
MONITOR_TRANSFORM,
MONITOR_WATCHER,
MONITOR_ROLLUP,
MANAGE,
MANAGE_ML,
MANAGE_DATA_FRAME,
MANAGE_TRANSFORM_DEPRECATED,
MANAGE_TRANSFORM,
MANAGE_TOKEN,
MANAGE_WATCHER,
MANAGE_IDX_TEMPLATES,

View File

@ -17,6 +17,7 @@ import org.elasticsearch.xpack.core.security.authz.privilege.ConfigurableCluster
import org.elasticsearch.xpack.core.security.support.MetadataUtils;
import org.elasticsearch.xpack.core.security.user.KibanaUser;
import org.elasticsearch.xpack.core.security.user.UsernamesField;
import org.elasticsearch.xpack.core.transform.transforms.persistence.TransformInternalIndexConstants;
import org.elasticsearch.xpack.core.watcher.execution.TriggeredWatchStoreField;
import org.elasticsearch.xpack.core.watcher.history.HistoryStoreField;
import org.elasticsearch.xpack.core.watcher.watch.Watch;
@ -179,28 +180,52 @@ public class ReservedRolesStore implements BiConsumer<Set<String>, ActionListene
.application("kibana-*").resources("*").privileges("reserved_ml").build()
},
null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, null))
// DEPRECATED: to be removed in 9.0.0
.put("data_frame_transforms_admin", new RoleDescriptor("data_frame_transforms_admin",
new String[] { "manage_data_frame_transforms" },
new RoleDescriptor.IndicesPrivileges[]{
RoleDescriptor.IndicesPrivileges.builder()
.indices(".data-frame-notifications*")
.indices(TransformInternalIndexConstants.AUDIT_INDEX_PATTERN,
TransformInternalIndexConstants.AUDIT_INDEX_PATTERN_DEPRECATED,
TransformInternalIndexConstants.AUDIT_INDEX_READ_ALIAS)
.privileges("view_index_metadata", "read").build()
},
new RoleDescriptor.ApplicationResourcePrivileges[] {
RoleDescriptor.ApplicationResourcePrivileges.builder()
.application("kibana-*").resources("*").privileges("reserved_ml").build()
}, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, null))
// DEPRECATED: to be removed in 9.0.0
.put("data_frame_transforms_user", new RoleDescriptor("data_frame_transforms_user",
new String[] { "monitor_data_frame_transforms" },
new RoleDescriptor.IndicesPrivileges[]{
RoleDescriptor.IndicesPrivileges.builder()
.indices(".data-frame-notifications*")
.indices(TransformInternalIndexConstants.AUDIT_INDEX_PATTERN,
TransformInternalIndexConstants.AUDIT_INDEX_PATTERN_DEPRECATED,
TransformInternalIndexConstants.AUDIT_INDEX_READ_ALIAS)
.privileges("view_index_metadata", "read").build()
},
new RoleDescriptor.ApplicationResourcePrivileges[] {
RoleDescriptor.ApplicationResourcePrivileges.builder()
.application("kibana-*").resources("*").privileges("reserved_ml").build()
}, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, null))
.put("transform_admin", new RoleDescriptor("transform_admin",
new String[] { "manage_transform" },
new RoleDescriptor.IndicesPrivileges[]{
RoleDescriptor.IndicesPrivileges.builder()
.indices(TransformInternalIndexConstants.AUDIT_INDEX_PATTERN,
TransformInternalIndexConstants.AUDIT_INDEX_PATTERN_DEPRECATED,
TransformInternalIndexConstants.AUDIT_INDEX_READ_ALIAS)
.privileges("view_index_metadata", "read").build()
}, null, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, null))
.put("transform_user", new RoleDescriptor("transform_user",
new String[] { "monitor_transform" },
new RoleDescriptor.IndicesPrivileges[]{
RoleDescriptor.IndicesPrivileges.builder()
.indices(TransformInternalIndexConstants.AUDIT_INDEX_PATTERN,
TransformInternalIndexConstants.AUDIT_INDEX_PATTERN_DEPRECATED,
TransformInternalIndexConstants.AUDIT_INDEX_READ_ALIAS)
.privileges("view_index_metadata", "read").build()
}, null, null, null, MetadataUtils.DEFAULT_RESERVED_METADATA, null))
.put("watcher_admin", new RoleDescriptor("watcher_admin", new String[] { "manage_watcher" },
new RoleDescriptor.IndicesPrivileges[] {
RoleDescriptor.IndicesPrivileges.builder().indices(Watch.INDEX, TriggeredWatchStoreField.INDEX_NAME,

View File

@ -30,7 +30,11 @@ public final class TransformInternalIndexConstants {
// audit index
public static final String AUDIT_TEMPLATE_VERSION = "1";
public static final String AUDIT_INDEX_PREFIX = ".data-frame-notifications-";
public static final String AUDIT_INDEX_PREFIX = ".transform-notifications-";
public static final String AUDIT_INDEX_PATTERN = AUDIT_INDEX_PREFIX + "*";
public static final String AUDIT_INDEX_PATTERN_DEPRECATED = ".data-frame-notifications-*";
public static final String AUDIT_INDEX_READ_ALIAS = ".transform-notifications-read";
public static final String AUDIT_INDEX = AUDIT_INDEX_PREFIX + AUDIT_TEMPLATE_VERSION;
private TransformInternalIndexConstants() {

View File

@ -186,6 +186,8 @@ public class ReservedRolesStoreTests extends ESTestCase {
assertThat(ReservedRolesStore.isReserved("machine_learning_admin"), is(true));
assertThat(ReservedRolesStore.isReserved("data_frame_transforms_user"), is(true));
assertThat(ReservedRolesStore.isReserved("data_frame_transforms_admin"), is(true));
assertThat(ReservedRolesStore.isReserved("transform_user"), is(true));
assertThat(ReservedRolesStore.isReserved("transform_admin"), is(true));
assertThat(ReservedRolesStore.isReserved("watcher_user"), is(true));
assertThat(ReservedRolesStore.isReserved("watcher_admin"), is(true));
assertThat(ReservedRolesStore.isReserved("kibana_dashboard_only_user"), is(true));
@ -1121,82 +1123,108 @@ public class ReservedRolesStoreTests extends ESTestCase {
new ApplicationPrivilege(otherApplication, "app-reserved_ml", "reserved_ml"), "*"), is(false));
}
public void testDataFrameTransformsAdminRole() {
public void testTransformAdminRole() {
final TransportRequest request = mock(TransportRequest.class);
final Authentication authentication = mock(Authentication.class);
RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("data_frame_transforms_admin");
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
RoleDescriptor[] roleDescriptors = {
new ReservedRolesStore().roleDescriptor("data_frame_transforms_admin"),
new ReservedRolesStore().roleDescriptor("transform_admin")
};
Role role = Role.builder(roleDescriptor, null).build();
assertThat(role.cluster().check(DeleteTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(GetTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(GetTransformStatsAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(PreviewTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(PutTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(StartTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(StopTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(DelegatePkiAuthenticationAction.NAME, request, authentication), is(false));
for (RoleDescriptor roleDescriptor : roleDescriptors) {
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false));
Role role = Role.builder(roleDescriptor, null).build();
assertThat(role.cluster().check(DeleteTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(GetTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(GetTransformStatsAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(PreviewTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(PutTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(StartTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(StopTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(DelegatePkiAuthenticationAction.NAME, request, authentication), is(false));
assertOnlyReadAllowed(role, TransformInternalIndexConstants.AUDIT_INDEX);
assertNoAccessAllowed(role, "foo");
assertNoAccessAllowed(role, TransformInternalIndexConstants.LATEST_INDEX_NAME); // internal use only
assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false));
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
assertOnlyReadAllowed(role, TransformInternalIndexConstants.AUDIT_INDEX_READ_ALIAS);
assertOnlyReadAllowed(role, TransformInternalIndexConstants.AUDIT_INDEX_PATTERN);
assertOnlyReadAllowed(role, TransformInternalIndexConstants.AUDIT_INDEX_PATTERN_DEPRECATED);
assertNoAccessAllowed(role, "foo");
assertNoAccessAllowed(role, TransformInternalIndexConstants.LATEST_INDEX_NAME); // internal use only
final String kibanaApplicationWithRandomIndex = "kibana-" + randomFrom(randomAlphaOfLengthBetween(8, 24), ".kibana");
assertThat(role.application().grants(
new ApplicationPrivilege(kibanaApplicationWithRandomIndex, "app-foo", "foo"), "*"), is(false));
assertThat(role.application().grants(
new ApplicationPrivilege(kibanaApplicationWithRandomIndex, "app-reserved_ml", "reserved_ml"), "*"), is(true));
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
final String otherApplication = "logstash-" + randomAlphaOfLengthBetween(8, 24);
assertThat(role.application().grants(
new ApplicationPrivilege(otherApplication, "app-foo", "foo"), "*"), is(false));
assertThat(role.application().grants(
new ApplicationPrivilege(otherApplication, "app-reserved_ml", "reserved_ml"), "*"), is(false));
final String kibanaApplicationWithRandomIndex = "kibana-" + randomFrom(randomAlphaOfLengthBetween(8, 24), ".kibana");
assertThat(role.application().grants(
new ApplicationPrivilege(kibanaApplicationWithRandomIndex, "app-foo", "foo"), "*"), is(false));
if (roleDescriptor.getName().equals("data_frame_transforms_admin")) {
assertThat(role.application()
.grants(new ApplicationPrivilege(kibanaApplicationWithRandomIndex, "app-reserved_ml", "reserved_ml"), "*"), is(true));
}
final String otherApplication = "logstash-" + randomAlphaOfLengthBetween(8, 24);
assertThat(role.application().grants(
new ApplicationPrivilege(otherApplication, "app-foo", "foo"), "*"), is(false));
if (roleDescriptor.getName().equals("data_frame_transforms_admin")) {
assertThat(role.application().grants(
new ApplicationPrivilege(otherApplication, "app-reserved_ml", "reserved_ml"), "*"), is(false));
}
}
}
public void testDataFrameTransformsUserRole() {
final TransportRequest request = mock(TransportRequest.class);
final Authentication authentication = mock(Authentication.class);
RoleDescriptor roleDescriptor = new ReservedRolesStore().roleDescriptor("data_frame_transforms_user");
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
RoleDescriptor[] roleDescriptors = {
new ReservedRolesStore().roleDescriptor("data_frame_transforms_user"),
new ReservedRolesStore().roleDescriptor("transform_user")
};
Role role = Role.builder(roleDescriptor, null).build();
assertThat(role.cluster().check(DeleteTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(GetTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(GetTransformStatsAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(PreviewTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(PutTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(StartTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(StopTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(DelegatePkiAuthenticationAction.NAME, request, authentication), is(false));
for (RoleDescriptor roleDescriptor : roleDescriptors) {
assertNotNull(roleDescriptor);
assertThat(roleDescriptor.getMetadata(), hasEntry("_reserved", true));
assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false));
Role role = Role.builder(roleDescriptor, null).build();
assertThat(role.cluster().check(DeleteTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(GetTransformAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(GetTransformStatsAction.NAME, request, authentication), is(true));
assertThat(role.cluster().check(PreviewTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(PutTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(StartTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(StopTransformAction.NAME, request, authentication), is(false));
assertThat(role.cluster().check(DelegatePkiAuthenticationAction.NAME, request, authentication), is(false));
assertOnlyReadAllowed(role, TransformInternalIndexConstants.AUDIT_INDEX);
assertNoAccessAllowed(role, "foo");
assertNoAccessAllowed(role, TransformInternalIndexConstants.LATEST_INDEX_NAME);
assertThat(role.runAs().check(randomAlphaOfLengthBetween(1, 30)), is(false));
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
assertOnlyReadAllowed(role, TransformInternalIndexConstants.AUDIT_INDEX_READ_ALIAS);
assertOnlyReadAllowed(role, TransformInternalIndexConstants.AUDIT_INDEX_PATTERN);
assertOnlyReadAllowed(role, TransformInternalIndexConstants.AUDIT_INDEX_PATTERN_DEPRECATED);
assertNoAccessAllowed(role, "foo");
assertNoAccessAllowed(role, TransformInternalIndexConstants.LATEST_INDEX_NAME);
final String kibanaApplicationWithRandomIndex = "kibana-" + randomFrom(randomAlphaOfLengthBetween(8, 24), ".kibana");
assertThat(role.application().grants(
new ApplicationPrivilege(kibanaApplicationWithRandomIndex, "app-foo", "foo"), "*"), is(false));
assertThat(role.application().grants(
new ApplicationPrivilege(kibanaApplicationWithRandomIndex, "app-reserved_ml", "reserved_ml"), "*"), is(true));
assertNoAccessAllowed(role, RestrictedIndicesNames.RESTRICTED_NAMES);
final String otherApplication = "logstash-" + randomAlphaOfLengthBetween(8, 24);
assertThat(role.application().grants(
new ApplicationPrivilege(otherApplication, "app-foo", "foo"), "*"), is(false));
assertThat(role.application().grants(
new ApplicationPrivilege(otherApplication, "app-reserved_ml", "reserved_ml"), "*"), is(false));
final String kibanaApplicationWithRandomIndex = "kibana-" + randomFrom(randomAlphaOfLengthBetween(8, 24), ".kibana");
assertThat(role.application().grants(
new ApplicationPrivilege(kibanaApplicationWithRandomIndex, "app-foo", "foo"), "*"), is(false));
if (roleDescriptor.getName().equals("data_frame_transforms_user")) {
assertThat(role.application().grants(
new ApplicationPrivilege(kibanaApplicationWithRandomIndex, "app-reserved_ml", "reserved_ml"), "*"), is(true));
}
final String otherApplication = "logstash-" + randomAlphaOfLengthBetween(8, 24);
assertThat(role.application().grants(
new ApplicationPrivilege(otherApplication, "app-foo", "foo"), "*"), is(false));
if (roleDescriptor.getName().equals("data_frame_transforms_user")) {
assertThat(role.application().grants(
new ApplicationPrivilege(otherApplication, "app-reserved_ml", "reserved_ml"), "*"), is(false));
}
}
}
public void testWatcherAdminRole() {

View File

@ -15,5 +15,5 @@ setup:
# This is fragile - it needs to be updated every time we add a new cluster/index privilege
# I would much prefer we could just check that specific entries are in the array, but we don't have
# an assertion for that
- length: { "cluster" : 30 }
- length: { "cluster" : 32 }
- length: { "index" : 17 }

View File

@ -53,8 +53,15 @@ public class TransformGetAndGetStatsIT extends TransformRestTestCase {
createReviewsIndex();
indicesCreated = true;
setupUser(TEST_USER_NAME, Collections.singletonList("data_frame_transforms_user"));
setupUser(TEST_ADMIN_USER_NAME, Collections.singletonList("data_frame_transforms_admin"));
// at random test the old deprecated roles, to be removed in 9.0.0
if (randomBoolean()) {
setupUser(TEST_USER_NAME, Collections.singletonList("transform_user"));
setupUser(TEST_ADMIN_USER_NAME, Collections.singletonList("transform_admin"));
} else {
setupUser(TEST_USER_NAME, Collections.singletonList("data_frame_transforms_user"));
setupUser(TEST_ADMIN_USER_NAME, Collections.singletonList("data_frame_transforms_admin"));
}
}
@After

View File

@ -50,7 +50,13 @@ public class TransformPivotRestIT extends TransformRestTestCase {
createReviewsIndex();
indicesCreated = true;
setupDataAccessRole(DATA_ACCESS_ROLE, REVIEWS_INDEX_NAME);
setupUser(TEST_USER_NAME, Arrays.asList("data_frame_transforms_admin", DATA_ACCESS_ROLE));
// at random test the old deprecated roles, to be removed in 9.0.0
if (randomBoolean()) {
setupUser(TEST_USER_NAME, Arrays.asList("transform_admin", DATA_ACCESS_ROLE));
} else {
setupUser(TEST_USER_NAME, Arrays.asList("data_frame_transforms_admin", DATA_ACCESS_ROLE));
}
}
public void testSimplePivot() throws Exception {

View File

@ -25,6 +25,7 @@ import org.elasticsearch.client.transform.transforms.pivot.PivotConfig;
import org.elasticsearch.client.transform.transforms.pivot.TermsGroupSource;
import org.elasticsearch.common.Booleans;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.common.xcontent.DeprecationHandler;
@ -35,21 +36,25 @@ import org.elasticsearch.common.xcontent.XContentType;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.AggregatorFactories;
import org.elasticsearch.xpack.test.rest.XPackRestTestConstants;
import org.junit.Before;
import java.io.IOException;
import java.time.Instant;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.xpack.test.rest.XPackRestTestConstants.TRANSFORM_INTERNAL_INDEX_PREFIX;
import static org.elasticsearch.xpack.test.rest.XPackRestTestConstants.TRANSFORM_INTERNAL_INDEX_PREFIX_DEPRECATED;
import static org.elasticsearch.xpack.test.rest.XPackRestTestConstants.TRANSFORM_NOTIFICATIONS_INDEX_PREFIX;
import static org.elasticsearch.xpack.test.rest.XPackRestTestConstants.TRANSFORM_NOTIFICATIONS_INDEX_PREFIX_DEPRECATED;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.greaterThanOrEqualTo;
@ -72,14 +77,38 @@ public class TransformSurvivesUpgradeIT extends AbstractUpgradeTestCase {
.map(TimeValue::timeValueMinutes)
.collect(Collectors.toList());
@Override
protected Collection<String> templatesToWaitFor() {
if (UPGRADE_FROM_VERSION.onOrAfter(Version.V_7_4_0)) {
return Stream.concat(XPackRestTestConstants.DATA_FRAME_TEMPLATES.stream(),
super.templatesToWaitFor().stream()).collect(Collectors.toSet());
} else {
return Collections.emptySet();
@Before
public void waitForTemplates() throws Exception {
// no transform before 7.2
if (UPGRADE_FROM_VERSION.before(Version.V_7_2_0)) {
return;
}
assertBusy(() -> {
final Request catRequest = new Request("GET", "_cat/templates?h=n&s=n");
final Response catResponse = adminClient().performRequest(catRequest);
final SortedSet<String> templates = new TreeSet<>(Streams.readAllLines(catResponse.getEntity().getContent()));
// match templates, independent of the version, at least 2 should exist
SortedSet<String> internalDeprecated = templates.tailSet(TRANSFORM_INTERNAL_INDEX_PREFIX_DEPRECATED);
SortedSet<String> internal = templates.tailSet(TRANSFORM_INTERNAL_INDEX_PREFIX);
SortedSet<String> notificationsDeprecated = templates
.tailSet(TRANSFORM_NOTIFICATIONS_INDEX_PREFIX_DEPRECATED);
SortedSet<String> notifications = templates.tailSet(TRANSFORM_NOTIFICATIONS_INDEX_PREFIX);
int foundTemplates = 0;
foundTemplates += internalDeprecated.isEmpty() ? 0
: internalDeprecated.first().startsWith(TRANSFORM_INTERNAL_INDEX_PREFIX_DEPRECATED) ? 1 : 0;
foundTemplates += internal.isEmpty() ? 0 : internal.first().startsWith(TRANSFORM_INTERNAL_INDEX_PREFIX) ? 1 : 0;
foundTemplates += notificationsDeprecated.isEmpty() ? 0
: notificationsDeprecated.first().startsWith(TRANSFORM_NOTIFICATIONS_INDEX_PREFIX_DEPRECATED) ? 1 : 0;
foundTemplates += notifications.isEmpty() ? 0 : notifications.first().startsWith(TRANSFORM_NOTIFICATIONS_INDEX_PREFIX) ? 1 : 0;
if (foundTemplates < 2) {
fail("Transform index templates not found. The templates that exist are: " + templates);
}
});
}
protected static void waitForPendingDataFrameTasks() throws Exception {

View File

@ -38,12 +38,11 @@ public final class XPackRestTestConstants {
RESULTS_INDEX_PREFIX,
CONFIG_INDEX));
// Data Frame constants:
public static final String DATA_FRAME_INTERNAL_INDEX = ".data-frame-internal-2";
public static final String DATA_FRAME_NOTIFICATIONS_INDEX = ".data-frame-notifications-1";
public static final List<String> DATA_FRAME_TEMPLATES =
Collections.unmodifiableList(Arrays.asList(DATA_FRAME_INTERNAL_INDEX, DATA_FRAME_NOTIFICATIONS_INDEX));
// Transform constants:
public static final String TRANSFORM_INTERNAL_INDEX_PREFIX = ".transform-internal-";
public static final String TRANSFORM_NOTIFICATIONS_INDEX_PREFIX = ".transform-notifications-";
public static final String TRANSFORM_INTERNAL_INDEX_PREFIX_DEPRECATED = ".data-frame-internal-";
public static final String TRANSFORM_NOTIFICATIONS_INDEX_PREFIX_DEPRECATED = ".data-frame-notifications-";
private XPackRestTestConstants() {
}