Skip to content

Commit fc40a30

Browse files
committed
add plugins descriptor + policy parsing
1 parent 24d9709 commit fc40a30

File tree

2 files changed

+91
-6
lines changed

2 files changed

+91
-6
lines changed

server/src/main/java/org/elasticsearch/plugins/PluginDescriptor.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,31 @@ public static PluginDescriptor readFromProperties(final Path pluginDir) throws I
250250
return descriptor;
251251
}
252252

253+
/**
254+
* Reads the internal descriptor for a classic plugin.
255+
*
256+
* @param stream the InputStream from which to read the plugin data
257+
* @return the plugin info
258+
* @throws IOException if an I/O exception occurred reading the plugin descriptor
259+
*/
260+
public static PluginDescriptor readInternalDescriptor(InputStream stream) throws IOException {
261+
final Map<String, String> propsMap;
262+
{
263+
final Properties props = new Properties();
264+
props.load(stream);
265+
propsMap = props.stringPropertyNames().stream().collect(Collectors.toMap(Function.identity(), props::getProperty));
266+
}
267+
268+
PluginDescriptor descriptor = readerInternalDescriptor(propsMap, INTERNAL_DESCRIPTOR_FILENAME);
269+
String name = descriptor.getName();
270+
271+
if (propsMap.isEmpty() == false) {
272+
throw new IllegalArgumentException("Unknown properties for plugin [" + name + "] in plugin descriptor: " + propsMap.keySet());
273+
}
274+
275+
return descriptor;
276+
}
277+
253278
private static PluginDescriptor readerInternalDescriptor(Map<String, String> propsMap, String filename) {
254279
String name = readNonEmptyString(propsMap, filename, "name");
255280
String desc = readString(propsMap, name, "description");

test/framework/src/main/java/org/elasticsearch/entitlement/initialization/TestEntitlementInitialization.java

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,34 @@
99

1010
package org.elasticsearch.entitlement.initialization;
1111

12+
import org.elasticsearch.core.Strings;
13+
import org.elasticsearch.core.SuppressForbidden;
1214
import org.elasticsearch.entitlement.bridge.EntitlementChecker;
1315
import org.elasticsearch.entitlement.runtime.api.ElasticsearchEntitlementChecker;
1416
import org.elasticsearch.entitlement.runtime.policy.PathLookup;
1517
import org.elasticsearch.entitlement.runtime.policy.Policy;
1618
import org.elasticsearch.entitlement.runtime.policy.PolicyManager;
19+
import org.elasticsearch.entitlement.runtime.policy.PolicyParser;
20+
import org.elasticsearch.plugins.PluginDescriptor;
1721

22+
import java.io.IOException;
23+
import java.io.InputStream;
1824
import java.lang.instrument.Instrumentation;
1925
import java.lang.reflect.Constructor;
2026
import java.lang.reflect.InvocationTargetException;
27+
import java.net.URL;
28+
import java.util.ArrayList;
29+
import java.util.HashMap;
30+
import java.util.List;
2131
import java.util.Map;
2232
import java.util.Set;
33+
import java.util.function.Function;
2334

2435
/**
2536
* Test-only version of {@code EntitlementInitialization}
2637
*/
2738
public class TestEntitlementInitialization {
2839

29-
private static final Module ENTITLEMENTS_MODULE = PolicyManager.class.getModule();
30-
3140
private static ElasticsearchEntitlementChecker manager;
3241

3342
// Note: referenced by bridge reflectively
@@ -44,10 +53,61 @@ public static void initialize(Instrumentation inst) throws Exception {
4453
);
4554
}
4655

56+
private record TestPluginData(String pluginName, boolean isModular, boolean isExternalPlugin) {}
57+
58+
private static Map<String, Policy> parsePluginsPolicies(List<TestPluginData> pluginsData) {
59+
Map<String, Policy> policies = new HashMap<>();
60+
for (var pluginData : pluginsData) {
61+
String pluginName = pluginData.pluginName();
62+
var resourceName = Strings.format("META-INF/es-plugins/%s/entitlement-policy.yaml", pluginName);
63+
64+
var resource = TestEntitlementInitialization.class.getClassLoader().getResource(resourceName);
65+
if (resource != null) {
66+
try (var inputStream = getStream(resource)) {
67+
policies.put(pluginName, new PolicyParser(inputStream, pluginName, pluginData.isExternalPlugin()).parsePolicy());
68+
} catch (IOException e) {
69+
throw new IllegalArgumentException(Strings.format("Cannot read policy for plugin [%s]", pluginName), e);
70+
}
71+
}
72+
}
73+
return policies;
74+
}
75+
76+
private static List<PluginDescriptor> parsePluginsDescriptors(List<String> pluginNames) {
77+
List<PluginDescriptor> descriptors = new ArrayList<>();
78+
for (var pluginName : pluginNames) {
79+
var resourceName = Strings.format("META-INF/es-plugins/%s/plugin-descriptor.properties", pluginName);
80+
var resource = TestEntitlementInitialization.class.getClassLoader().getResource(resourceName);
81+
if (resource != null) {
82+
try (var inputStream = getStream(resource)) {
83+
descriptors.add(PluginDescriptor.readInternalDescriptor(inputStream));
84+
} catch (IOException e) {
85+
throw new IllegalArgumentException(Strings.format("Cannot read descriptor for plugin [%s]", pluginName), e);
86+
}
87+
}
88+
}
89+
return descriptors;
90+
}
91+
92+
@SuppressForbidden(reason = "URLs from class loader")
93+
private static InputStream getStream(URL resource) throws IOException {
94+
return resource.openStream();
95+
}
96+
4797
private static PolicyManager createPolicyManager() {
4898

49-
// TODO: parse policies. Locate them using help from TestBuildInfo
50-
Map<String, Policy> pluginPolicies = Map.of();
99+
// TODO: uncomment after merging https://github.com/elastic/elasticsearch/pull/127719
100+
// var pluginsTestBuildInfo = TestBuildInfoParser.parseAllPluginTestBuildInfo();
101+
// var serverTestBuildInfo = TestBuildInfoParser.parseServerTestBuildInfo();
102+
Function<Class<?>, PolicyManager.PolicyScope> scopeResolver = null; // TestScopeResolver.createScopeResolver(serverTestBuildInfo,
103+
// pluginsTestBuildInfo);
104+
List<String> pluginNames = List.of(); // = pluginsTestBuildInfo.stream().map(TestBuildInfo::componentName).toList();
105+
106+
var pluginDescriptors = parsePluginsDescriptors(pluginNames);
107+
var pluginsData = pluginDescriptors.stream()
108+
.map(descriptor -> new TestPluginData(descriptor.getName(), descriptor.isModular(), false))
109+
.toList();
110+
Map<String, Policy> pluginPolicies = parsePluginsPolicies(pluginsData);
51111

52112
// TODO: create here the test pathLookup
53113
PathLookup pathLookup = null;
@@ -58,9 +118,9 @@ private static PolicyManager createPolicyManager() {
58118
HardcodedEntitlements.serverPolicy(null, null),
59119
HardcodedEntitlements.agentEntitlements(),
60120
pluginPolicies,
61-
null, // TODO: replace with TestScopeResolver.createScopeResolver
121+
scopeResolver,
62122
Map.of(),
63-
ENTITLEMENTS_MODULE, // TODO: this will need to change -- encapsulate it when we extract isTriviallyAllowed
123+
null, // TODO: this will need to change -- encapsulate it when we extract isTriviallyAllowed
64124
pathLookup,
65125
Set.of()
66126
);

0 commit comments

Comments
 (0)