diff --git a/distribution/tools/plugin-cli/src/main/java/org/opensearch/plugins/InstallPluginCommand.java b/distribution/tools/plugin-cli/src/main/java/org/opensearch/plugins/InstallPluginCommand.java index 979327014efb0..b4e568313f7b4 100644 --- a/distribution/tools/plugin-cli/src/main/java/org/opensearch/plugins/InstallPluginCommand.java +++ b/distribution/tools/plugin-cli/src/main/java/org/opensearch/plugins/InstallPluginCommand.java @@ -60,7 +60,6 @@ import org.opensearch.common.SuppressForbidden; import org.opensearch.common.collect.Tuple; import org.opensearch.common.hash.MessageDigests; -import org.opensearch.common.settings.Setting; import org.opensearch.common.settings.Settings; import org.opensearch.common.util.io.IOUtils; import org.opensearch.env.Environment; @@ -103,10 +102,12 @@ import java.util.Objects; import java.util.Set; import java.util.TreeSet; -import java.util.function.Function; import java.util.stream.Collectors; import static org.opensearch.cli.Terminal.Verbosity.VERBOSE; +import static org.opensearch.plugins.PluginInfo.CLUSTER_ACTIONS_SETTING; +import static org.opensearch.plugins.PluginInfo.DESCRIPTION_SETTING; +import static org.opensearch.plugins.PluginInfo.INDEX_ACTIONS_SETTING; /** * A command for the plugin cli to install a plugin into opensearch. @@ -196,16 +197,6 @@ class InstallPluginCommand extends EnvironmentAwareCommand { static final Set PLUGIN_DIR_PERMS; static final Set PLUGIN_FILES_PERMS; - static final Setting> CLUSTER_ACTIONS_SETTING = Setting.listSetting( - "cluster.actions", - Collections.emptyList(), - Function.identity() - ); - - static final Setting INDEX_ACTIONS_SETTING = Setting.groupSetting("index.actions."); - - static final Setting DESCRIPTION_SETTING = Setting.simpleString("description"); - static { // Bin directory get chmod 755 BIN_DIR_PERMS = Collections.unmodifiableSet(PosixFilePermissions.fromString("rwxr-xr-x")); diff --git a/server/src/main/java/org/opensearch/plugins/PluginInfo.java b/server/src/main/java/org/opensearch/plugins/PluginInfo.java index c00fe0f92933e..7817dd0b9b6d8 100644 --- a/server/src/main/java/org/opensearch/plugins/PluginInfo.java +++ b/server/src/main/java/org/opensearch/plugins/PluginInfo.java @@ -38,6 +38,7 @@ import org.opensearch.Version; import org.opensearch.bootstrap.JarHell; import org.opensearch.common.annotation.PublicApi; +import org.opensearch.common.settings.Setting; import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.json.JsonXContentParser; import org.opensearch.core.common.Strings; @@ -57,6 +58,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; @@ -80,6 +82,16 @@ public class PluginInfo implements Writeable, ToXContentObject { true ); + public static final Setting> CLUSTER_ACTIONS_SETTING = Setting.listSetting( + "cluster.actions", + Collections.emptyList(), + Function.identity() + ); + + public static final Setting INDEX_ACTIONS_SETTING = Setting.groupSetting("index.actions."); + + public static final Setting DESCRIPTION_SETTING = Setting.simpleString("description"); + private final String name; private final String description; private final String version; @@ -217,8 +229,7 @@ public PluginInfo(final StreamInput in) throws IOException { this.customFolderName = in.readString(); this.extendedPlugins = in.readStringList(); this.hasNativeController = in.readBoolean(); - // TODO switch this to 2.X version this change will be released in after backport - if (in.getVersion().onOrAfter(Version.CURRENT)) { + if (in.getVersion().onOrAfter(Version.V_2_19_0)) { this.requestedActions = Settings.readSettingsFromStream(in); } else { this.requestedActions = Settings.EMPTY; @@ -248,7 +259,7 @@ This works for currently supported range notations (=,~) } out.writeStringCollection(extendedPlugins); out.writeBoolean(hasNativeController); - if (out.getVersion().onOrAfter(Version.CURRENT)) { + if (out.getVersion().onOrAfter(Version.V_2_19_0)) { Settings.writeSettingsToStream(requestedActions, out); } } @@ -510,12 +521,30 @@ public String getTargetFolderName() { } /** - * Returns actions requested by this plugin in the plugin-permissions.yml file + * Returns cluster actions requested by this plugin in the plugin-permissions.yml file + * + * @return A list of cluster actions contained within the plugin-permissions.yml file + */ + public List getClusterActions() { + return CLUSTER_ACTIONS_SETTING.get(requestedActions); + } + + /** + * Returns index actions requested by this plugin in the plugin-permissions.yml file * - * @return A settings object containing the contents of plugin-permissions.yml file + * @return A list of index actions contained within the plugin-permissions.yml file. This method returns a map + * of index pattern -> list of actions that apply on the index pattern */ - public Settings getRequestedActions() { - return requestedActions; + public Map> getIndexActions() { + final Map> indexActions = new HashMap<>(); + final Settings requestedIndexActionsGroup = INDEX_ACTIONS_SETTING.get(requestedActions); + if (!requestedIndexActionsGroup.keySet().isEmpty()) { + for (String indexPattern : requestedIndexActionsGroup.keySet()) { + List indexActionsForPattern = requestedIndexActionsGroup.getAsList(indexPattern); + indexActions.put(indexPattern, indexActionsForPattern); + } + } + return indexActions; } @Override @@ -531,6 +560,10 @@ public XContentBuilder toXContent(XContentBuilder builder, Params params) throws builder.field("custom_foldername", customFolderName); builder.field("extended_plugins", extendedPlugins); builder.field("has_native_controller", hasNativeController); + if (!Settings.EMPTY.equals(requestedActions)) { + builder.field("cluster.actions", getClusterActions()); + builder.field("index.actions", getIndexActions()); + } } builder.endObject(); diff --git a/server/src/test/java/org/opensearch/plugins/PluginInfoTests.java b/server/src/test/java/org/opensearch/plugins/PluginInfoTests.java index 8e0932889ea95..192f8eda305a0 100644 --- a/server/src/test/java/org/opensearch/plugins/PluginInfoTests.java +++ b/server/src/test/java/org/opensearch/plugins/PluginInfoTests.java @@ -35,7 +35,9 @@ import com.fasterxml.jackson.core.JsonParseException; import org.opensearch.Version; +import org.opensearch.action.admin.cluster.health.ClusterHealthAction; import org.opensearch.action.admin.cluster.node.info.PluginsAndModules; +import org.opensearch.action.index.IndexAction; import org.opensearch.common.io.stream.BytesStreamOutput; import org.opensearch.common.settings.Settings; import org.opensearch.common.xcontent.json.JsonXContent; @@ -48,6 +50,7 @@ import java.nio.ByteBuffer; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.stream.Collectors; @@ -387,6 +390,7 @@ public void testToXContent() throws Exception { ); XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); String prettyPrint = info.toXContent(builder, ToXContent.EMPTY_PARAMS).prettyPrint().toString(); + prettyPrint = Arrays.stream(prettyPrint.split("\n")).map(String::trim).collect(Collectors.joining("")); assertTrue(prettyPrint.contains("\"name\" : \"fake\"")); assertTrue(prettyPrint.contains("\"version\" : \"dummy\"")); assertTrue(prettyPrint.contains("\"opensearch_version\" : \"" + Version.CURRENT)); @@ -398,6 +402,38 @@ public void testToXContent() throws Exception { assertTrue(prettyPrint.contains("\"has_native_controller\" : false")); } + public void testToXContentWithRequestedActions() throws Exception { + PluginInfo info = new PluginInfo( + "fake", + "foo", + "dummy", + Version.CURRENT, + "1.8", + "dummyClass", + "folder", + Collections.emptyList(), + false, + Settings.builder() + .putList("cluster.actions", List.of(ClusterHealthAction.NAME)) + .putList("index.actions.my-index", List.of(IndexAction.NAME)) + .build() + ); + XContentBuilder builder = JsonXContent.contentBuilder().prettyPrint(); + String prettyPrint = info.toXContent(builder, ToXContent.EMPTY_PARAMS).prettyPrint().toString(); + prettyPrint = Arrays.stream(prettyPrint.split("\n")).map(String::trim).collect(Collectors.joining("")); + assertTrue(prettyPrint.contains("\"name\" : \"fake\"")); + assertTrue(prettyPrint.contains("\"version\" : \"dummy\"")); + assertTrue(prettyPrint.contains("\"opensearch_version\" : \"" + Version.CURRENT)); + assertTrue(prettyPrint.contains("\"java_version\" : \"1.8\"")); + assertTrue(prettyPrint.contains("\"description\" : \"foo\"")); + assertTrue(prettyPrint.contains("\"classname\" : \"dummyClass\"")); + assertTrue(prettyPrint.contains("\"custom_foldername\" : \"folder\"")); + assertTrue(prettyPrint.contains("\"extended_plugins\" : [ ]")); + assertTrue(prettyPrint.contains("\"has_native_controller\" : false")); + assertTrue(prettyPrint.contains("\"cluster.actions\" : [\"" + ClusterHealthAction.NAME + "\"]")); + assertTrue(prettyPrint.contains("\"index.actions\" : {\"my-index\" : [\"" + IndexAction.NAME + "\"]}")); + } + public void testPluginListSorted() { List plugins = new ArrayList<>(); plugins.add(new PluginInfo("c", "foo", "dummy", Version.CURRENT, "1.8", "dummyclass", Collections.emptyList(), randomBoolean()));