[TEST] improved registered actions sanity check test
Shield needs to know about all the actions that are registered in core. We now check not only the external actions, meaning the classes that implement the Action interface, exposed via java api, but also all the transport handlers registered through the transport, which will contains all shard/node level actions plus the internal actions that are not exposed via java api. We maintain two files, one for external actions, and one for the internal ones, and we check whether actions have been added or removed to/from core, to make sure we know about those changes. Original commit: elastic/x-pack-elasticsearch@d6b68c44ee
This commit is contained in:
parent
5514201d4d
commit
bad27996f9
|
@ -1,84 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
|
||||||
* or more contributor license agreements. Licensed under the Elastic License;
|
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
|
||||||
*/
|
|
||||||
package org.elasticsearch.shield.authz;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableSet;
|
|
||||||
import com.google.common.reflect.ClassPath;
|
|
||||||
import org.elasticsearch.ElasticsearchIllegalStateException;
|
|
||||||
import org.elasticsearch.action.Action;
|
|
||||||
import org.elasticsearch.common.io.Streams;
|
|
||||||
import org.elasticsearch.common.util.Callback;
|
|
||||||
import org.elasticsearch.test.ElasticsearchTestCase;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.lang.reflect.Field;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
|
|
||||||
import static org.hamcrest.Matchers.hasItem;
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class KnownActionsSanityCheckTests extends ElasticsearchTestCase {
|
|
||||||
|
|
||||||
private ImmutableSet<String> knownActions;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void init() throws Exception {
|
|
||||||
final ImmutableSet.Builder<String> builder = ImmutableSet.builder();
|
|
||||||
try (InputStream input = KnownActionsSanityCheckTests.class.getResourceAsStream("actions")) {
|
|
||||||
Streams.readAllLines(input, new Callback<String>() {
|
|
||||||
@Override
|
|
||||||
public void handle(String action) {
|
|
||||||
builder.add(action);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
throw new ElasticsearchIllegalStateException("Could not load known actions", ioe);
|
|
||||||
}
|
|
||||||
knownActions = builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAllShieldActionsAreKnown() throws Exception {
|
|
||||||
ClassPath classPath = ClassPath.from(Action.class.getClassLoader());
|
|
||||||
ImmutableSet<ClassPath.ClassInfo> infos = classPath.getTopLevelClassesRecursive(Action.class.getPackage().getName());
|
|
||||||
for (ClassPath.ClassInfo info : infos) {
|
|
||||||
Class clazz = info.load();
|
|
||||||
if (Action.class.isAssignableFrom(clazz)) {
|
|
||||||
String name = extractActionName(clazz);
|
|
||||||
if (name != null) {
|
|
||||||
assertThat("elasticsearch core action [" + name + "] is unknown to shield", knownActions, hasItem(name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String extractActionName(Class clazz) throws Exception {
|
|
||||||
if (Modifier.isAbstract(clazz.getModifiers())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Field field = getField(clazz, "INSTANCE");
|
|
||||||
if (field == null || !Modifier.isStatic(field.getModifiers())) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
Action action = (Action) field.get(null);
|
|
||||||
return action.name();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Field getField(Class clazz, String name) {
|
|
||||||
try {
|
|
||||||
return clazz.getField(name);
|
|
||||||
} catch (NoSuchFieldException nsfe) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
/*
|
||||||
|
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||||
|
* or more contributor license agreements. Licensed under the Elastic License;
|
||||||
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
|
*/
|
||||||
|
package org.elasticsearch.transport;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.google.common.reflect.ClassPath;
|
||||||
|
import org.elasticsearch.ElasticsearchIllegalStateException;
|
||||||
|
import org.elasticsearch.action.Action;
|
||||||
|
import org.elasticsearch.common.io.Streams;
|
||||||
|
import org.elasticsearch.common.util.Callback;
|
||||||
|
import org.elasticsearch.shield.test.ShieldIntegrationTest;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.hasItems;
|
||||||
|
import static org.hamcrest.Matchers.hasItem;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
|
||||||
|
public class KnownActionsTests extends ShieldIntegrationTest {
|
||||||
|
|
||||||
|
private static ImmutableSet<String> knownActions;
|
||||||
|
private static ImmutableSet<String> knownHandlers;
|
||||||
|
private static ImmutableSet<String> coreActions;
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void init() throws Exception {
|
||||||
|
knownActions = loadKnownActions();
|
||||||
|
knownHandlers = loadKnownHandlers();
|
||||||
|
coreActions = loadCoreActions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllCoreTransportHandlersAreKnown() {
|
||||||
|
TransportService transportService = internalCluster().getInstance(TransportService.class);
|
||||||
|
for (String handler : transportService.serverHandlers.keySet()) {
|
||||||
|
if (!knownActions.contains(handler)) {
|
||||||
|
assertThat("elasticsearch core transport handler [" + handler + "] is unknown to shield", knownHandlers, hasItem(handler));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllCoreActionsAreKnown() throws Exception {
|
||||||
|
for (String action : coreActions) {
|
||||||
|
assertThat("elasticsearch core action [" + action + "] is unknown to shield", knownActions, hasItem(action));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllKnownActionsAreValid() {
|
||||||
|
for (String knownAction : knownActions) {
|
||||||
|
assertThat("shield known action [" + knownAction + "] is unknown to core", coreActions, hasItems(knownAction));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllKnownTransportHandlersAreValid() {
|
||||||
|
TransportService transportService = internalCluster().getInstance(TransportService.class);
|
||||||
|
for (String knownHandler : knownHandlers) {
|
||||||
|
assertThat("shield known action [" + knownHandler + "] is unknown to core", transportService.serverHandlers.keySet(), hasItems(knownHandler));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImmutableSet<String> loadKnownActions() {
|
||||||
|
final ImmutableSet.Builder<String> knownActionsBuilder = ImmutableSet.builder();
|
||||||
|
try (InputStream input = KnownActionsTests.class.getResourceAsStream("actions")) {
|
||||||
|
Streams.readAllLines(input, new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void handle(String action) {
|
||||||
|
knownActionsBuilder.add(action);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new ElasticsearchIllegalStateException("Could not load known actions", ioe);
|
||||||
|
}
|
||||||
|
return knownActionsBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImmutableSet<String> loadKnownHandlers() {
|
||||||
|
final ImmutableSet.Builder<String> knownHandlersBuilder = ImmutableSet.builder();
|
||||||
|
try (InputStream input = KnownActionsTests.class.getResourceAsStream("handlers")) {
|
||||||
|
Streams.readAllLines(input, new Callback<String>() {
|
||||||
|
@Override
|
||||||
|
public void handle(String action) {
|
||||||
|
knownHandlersBuilder.add(action);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
throw new ElasticsearchIllegalStateException("Could not load known handlers", ioe);
|
||||||
|
}
|
||||||
|
return knownHandlersBuilder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ImmutableSet<String> loadCoreActions() throws IOException, IllegalAccessException {
|
||||||
|
ImmutableSet.Builder<String> coreActionsBuilder = ImmutableSet.builder();
|
||||||
|
ClassPath classPath = ClassPath.from(Action.class.getClassLoader());
|
||||||
|
ImmutableSet<ClassPath.ClassInfo> infos = classPath.getTopLevelClassesRecursive(Action.class.getPackage().getName());
|
||||||
|
for (ClassPath.ClassInfo info : infos) {
|
||||||
|
Class clazz = info.load();
|
||||||
|
if (Action.class.isAssignableFrom(clazz)) {
|
||||||
|
if (!Modifier.isAbstract(clazz.getModifiers())) {
|
||||||
|
Field field = null;
|
||||||
|
try {
|
||||||
|
field = clazz.getField("INSTANCE");
|
||||||
|
} catch (NoSuchFieldException nsfe) {
|
||||||
|
fail("every action should have a static field called INSTANCE, missing in " + clazz.getName());
|
||||||
|
}
|
||||||
|
assertThat("every action should have a static field called INSTANCE, present but not static in " + clazz.getName(),
|
||||||
|
Modifier.isStatic(field.getModifiers()), is(true));
|
||||||
|
coreActionsBuilder.add(((Action) field.get(null)).name());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return coreActionsBuilder.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -50,9 +50,6 @@ indices:monitor/segments
|
||||||
indices:monitor/settings/get
|
indices:monitor/settings/get
|
||||||
indices:monitor/stats
|
indices:monitor/stats
|
||||||
indices:monitor/status
|
indices:monitor/status
|
||||||
indices:data/benchmark/abort
|
|
||||||
indices:data/benchmark/start
|
|
||||||
indices:data/benchmark/status
|
|
||||||
indices:data/read/count
|
indices:data/read/count
|
||||||
indices:data/read/exists
|
indices:data/read/exists
|
||||||
indices:data/read/explain
|
indices:data/read/explain
|
|
@ -0,0 +1,79 @@
|
||||||
|
cluster:admin/nodes/restart[n]
|
||||||
|
cluster:admin/nodes/shutdown[n]
|
||||||
|
cluster:admin/snapshot/status[nodes]
|
||||||
|
cluster:admin/snapshot/status[nodes][n]
|
||||||
|
cluster:monitor/nodes/hot_threads[n]
|
||||||
|
cluster:monitor/nodes/info[n]
|
||||||
|
cluster:monitor/nodes/stats[n]
|
||||||
|
cluster:monitor/stats[n]
|
||||||
|
indices:admin/analyze[s]
|
||||||
|
indices:admin/cache/clear[s]
|
||||||
|
indices:admin/flush[s]
|
||||||
|
indices:admin/mappings/fields/get[index][s]
|
||||||
|
indices:admin/optimize[s]
|
||||||
|
indices:admin/refresh[s]
|
||||||
|
indices:admin/validate/query[s]
|
||||||
|
indices:data/read/count[s]
|
||||||
|
indices:data/read/exists[s]
|
||||||
|
indices:data/read/explain[s]
|
||||||
|
indices:data/read/get[s]
|
||||||
|
indices:data/read/mget[shard][s]
|
||||||
|
indices:data/read/mpercolate[shard][s]
|
||||||
|
indices:data/read/mtv[shard][s]
|
||||||
|
indices:data/read/percolate[s]
|
||||||
|
indices:data/read/search[clear_scroll_contexts]
|
||||||
|
indices:data/read/search[free_context/scroll]
|
||||||
|
indices:data/read/search[free_context]
|
||||||
|
indices:data/read/search[phase/dfs]
|
||||||
|
indices:data/read/search[phase/fetch/id/scroll]
|
||||||
|
indices:data/read/search[phase/fetch/id]
|
||||||
|
indices:data/read/search[phase/query+fetch/scroll]
|
||||||
|
indices:data/read/search[phase/query+fetch]
|
||||||
|
indices:data/read/search[phase/query/id]
|
||||||
|
indices:data/read/search[phase/query/query+fetch]
|
||||||
|
indices:data/read/search[phase/query/scroll]
|
||||||
|
indices:data/read/search[phase/query]
|
||||||
|
indices:data/read/search[phase/scan/scroll]
|
||||||
|
indices:data/read/search[phase/scan]
|
||||||
|
indices:data/read/suggest[s]
|
||||||
|
indices:data/read/tv[s]
|
||||||
|
indices:data/write/bulk[s]
|
||||||
|
indices:data/write/bulk[s][r]
|
||||||
|
indices:data/write/delete/by_query[s]
|
||||||
|
indices:data/write/delete/by_query[s][r]
|
||||||
|
indices:data/write/delete[r]
|
||||||
|
indices:data/write/delete[s]
|
||||||
|
indices:data/write/delete[s][r]
|
||||||
|
indices:data/write/index[r]
|
||||||
|
indices:monitor/recovery[s]
|
||||||
|
indices:monitor/segments[s]
|
||||||
|
indices:monitor/stats[s]
|
||||||
|
indices:monitor/status[s]
|
||||||
|
internal:cluster/mapping_updated
|
||||||
|
internal:cluster/node/index/deleted
|
||||||
|
internal:cluster/node/index_store/deleted
|
||||||
|
internal:cluster/node/mapping/refresh
|
||||||
|
internal:cluster/nodes/indices/shard/store
|
||||||
|
internal:cluster/nodes/indices/shard/store[n]
|
||||||
|
internal:cluster/shard/failure
|
||||||
|
internal:cluster/shard/started
|
||||||
|
internal:cluster/snapshot/update_restore
|
||||||
|
internal:cluster/snapshot/update_snapshot
|
||||||
|
internal:discovery/zen/fd/master_ping
|
||||||
|
internal:discovery/zen/fd/ping
|
||||||
|
internal:discovery/zen/join
|
||||||
|
internal:discovery/zen/join/validate
|
||||||
|
internal:discovery/zen/leave
|
||||||
|
internal:discovery/zen/publish
|
||||||
|
internal:discovery/zen/rejoin
|
||||||
|
internal:discovery/zen/unicast
|
||||||
|
internal:discovery/zen/unicast_gte_1_4
|
||||||
|
internal:index/shard/exists
|
||||||
|
internal:index/shard/recovery/clean_files
|
||||||
|
internal:index/shard/recovery/file_chunk
|
||||||
|
internal:index/shard/recovery/filesInfo
|
||||||
|
internal:index/shard/recovery/finalize
|
||||||
|
internal:index/shard/recovery/prepare_translog
|
||||||
|
internal:index/shard/recovery/start_recovery
|
||||||
|
internal:index/shard/recovery/translog_ops
|
||||||
|
internal:river/state/publish
|
Loading…
Reference in New Issue