Skip to content

Commit

Permalink
Make command.action.args field object-type (#209)
Browse files Browse the repository at this point in the history
* Update command template

* Add an Args model class to handle undetermined command.action.args types

* Improve parsing logic to handle lists, objects and primitive values

* Revert to a simpler model that looks for key-value pairs

* Make setup plugin mapping dynamic

* Update openapi.yml definition

* Fix JavaDocs

---------

Co-authored-by: Álex Ruiz <[email protected]>
  • Loading branch information
f-galland and AlexRuiz7 authored Jan 10, 2025
1 parent 9879492 commit 610f0d9
Show file tree
Hide file tree
Showing 5 changed files with 100 additions and 21 deletions.
9 changes: 5 additions & 4 deletions plugins/command-manager/openapi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,11 @@ components:
type: string
example: "restart"
args:
type: array
items:
type: string
example: "/path/to/executable/arg6"
type: object
properties:
arg1:
type: string
example: "/path/to/executable/arg6"
version:
type: string
example: "v4"
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,14 @@
import org.opensearch.core.xcontent.XContentParser;

import java.io.IOException;
import java.util.List;

/** Command's action fields. */
public class Action implements ToXContentObject {
public static final String ACTION = "action";
public static final String NAME = "name";
public static final String ARGS = "args";
public static final String VERSION = "version";
private final String name;
private final List<String> args;
private final Args args;
private final String version;

/**
Expand All @@ -40,7 +38,7 @@ public class Action implements ToXContentObject {
* @param args actual command.
* @param version version of the action.
*/
public Action(String name, List<String> args, String version) {
public Action(String name, Args args, String version) {
this.name = name;
this.args = args;
this.version = version;
Expand All @@ -55,7 +53,7 @@ public Action(String name, List<String> args, String version) {
*/
public static Action parse(XContentParser parser) throws IOException {
String name = "";
List<Object> args = List.of();
Args args = null;
String version = "";

while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
Expand All @@ -65,8 +63,8 @@ public static Action parse(XContentParser parser) throws IOException {
case NAME:
name = parser.text();
break;
case ARGS:
args = parser.list();
case Args.ARGS:
args = Args.parse(parser);
break;
case VERSION:
version = parser.text();
Expand All @@ -77,16 +75,14 @@ public static Action parse(XContentParser parser) throws IOException {
}
}

// Cast args field Object list to String list
List<String> convertedArgsFields = (List<String>) (List<?>) (args);
return new Action(name, convertedArgsFields, version);
return new Action(name, args, version);
}

@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(ACTION);
builder.field(NAME, this.name);
builder.field(ARGS, this.args);
this.args.toXContent(builder, ToXContentObject.EMPTY_PARAMS);
builder.field(VERSION, this.version);
return builder.endObject();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright (C) 2024, Wazuh Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.wazuh.commandmanager.model;

import org.opensearch.core.xcontent.ToXContentObject;
import org.opensearch.core.xcontent.XContentBuilder;
import org.opensearch.core.xcontent.XContentParser;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/** Handles the command.action.args object */
public class Args implements ToXContentObject {

public static final String ARGS = "args";
private final Map<String, Object> args;

/**
* Constructor method
*
* @param args Initializes the args object
*/
public Args(Map<String, Object> args) {
this.args = args;
}

/**
* Parses an args XContentParser into an Args object. A {@code Map<String,Object>} is created
* with the fields and values from the command.action.args object
*
* @param parser An XContentParser containing an args to be deserialized
* @return An Args object
* @throws IOException Rethrows the exception from list() and objectText() methods
*/
public static Args parse(XContentParser parser) throws IOException {
Map<String, Object> args = new HashMap<>();
while (parser.nextToken() != XContentParser.Token.END_OBJECT) {
String fieldName = parser.currentName();
parser.nextToken();
args.put(fieldName, parser.objectText());
}
return new Args(args);
}

/**
* Builds an Args XContentBuilder. Iterates over the args map adding key-value pairs
*
* @param builder This is received from the parent object
* @param params Not used
* @return A complete args XContentBuilder object
* @throws IOException rethrown from XContentBuilder objects within
*/
@Override
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
builder.startObject(Args.ARGS);
for (String key : this.args.keySet()) {
builder.field(key, this.args.get(key));
}
return builder.endObject();
}

/**
* @return a String representation of the contents of the Args object
*/
@Override
public String toString() {
return "Args{" + "args='" + args + '\'' + '}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
],
"mappings": {
"date_detection": false,
"dynamic": "strict",
"dynamic": "true",
"properties": {
"@timestamp": {
"type": "date"
Expand All @@ -22,8 +22,7 @@
"action": {
"properties": {
"args": {
"ignore_above": 1024,
"type": "keyword"
"type": "object"
},
"name": {
"ignore_above": 1024,
Expand Down
5 changes: 2 additions & 3 deletions plugins/setup/src/main/resources/index-template-commands.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
],
"mappings": {
"date_detection": false,
"dynamic": "strict",
"dynamic": "true",
"properties": {
"@timestamp": {
"type": "date"
Expand All @@ -22,8 +22,7 @@
"action": {
"properties": {
"args": {
"ignore_above": 1024,
"type": "keyword"
"type": "object"
},
"name": {
"ignore_above": 1024,
Expand Down

0 comments on commit 610f0d9

Please sign in to comment.