This is an automated email from the ASF dual-hosted git repository.

heneveld pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/brooklyn-server.git

commit 7aa849dd04ea7e2a3293965a6ed0e8ab97727e6c
Author: Alex Heneveld <[email protected]>
AuthorDate: Thu Sep 14 16:31:50 2023 +0100

    better handling for quotes when passing container args; also support list
---
 .../tasks/kubectl/ContainerWorkflowStep.java        | 21 +++++++++++++++++----
 .../brooklyn/util/text/QuotedStringTokenizer.java   |  2 +-
 .../util/text/QuotedStringTokenizerTest.java        | 10 ++++++++++
 3 files changed, 28 insertions(+), 5 deletions(-)

diff --git 
a/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerWorkflowStep.java
 
b/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerWorkflowStep.java
index 5ff670d8d0..1d5938f4ab 100644
--- 
a/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerWorkflowStep.java
+++ 
b/software/base/src/main/java/org/apache/brooklyn/tasks/kubectl/ContainerWorkflowStep.java
@@ -30,10 +30,12 @@ import org.apache.brooklyn.util.collections.MutableMap;
 import org.apache.brooklyn.util.core.json.ShellEnvironmentSerializer;
 import org.apache.brooklyn.util.core.predicates.DslPredicates;
 import org.apache.brooklyn.util.core.task.DynamicTasks;
+import org.apache.brooklyn.util.javalang.Boxing;
 import org.apache.brooklyn.util.text.QuotedStringTokenizer;
 import org.apache.brooklyn.util.text.Strings;
 
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
@@ -45,7 +47,7 @@ public class ContainerWorkflowStep extends 
WorkflowStepDefinition {
 
     public static final ConfigKey<String> IMAGE = 
ConfigKeys.newStringConfigKey("image");
     public static final ConfigKey<String> COMMAND = 
ConfigKeys.newStringConfigKey("command");
-    public static final ConfigKey<String> ARGS = 
ConfigKeys.newStringConfigKey("args");
+    public static final ConfigKey<Object> ARGS = 
ConfigKeys.newConfigKey(Object.class, "args", "Arguments as a string, split 
into words respecting quoted phrases, or as a list of strings");
     public static final ConfigKey<List<String>> COMMANDS = 
ConfigKeys.newConfigKey(new TypeToken<List<String>>() {}, "commands");
     public static final ConfigKey<List<String>> RAW_COMMAND = 
ConfigKeys.newConfigKey(new TypeToken<List<String>>() {}, "raw_command");
     public static final ConfigKey<PullPolicy> PULL_POLICY = 
ConfigKeys.newConfigKey(PullPolicy.class, "pull_policy", 
ContainerCommons.CONTAINER_IMAGE_PULL_POLICY.getDescription(), 
ContainerCommons.CONTAINER_IMAGE_PULL_POLICY.getDefaultValue());
@@ -94,9 +96,20 @@ public class ContainerWorkflowStep extends 
WorkflowStepDefinition {
             throw new IllegalStateException("Incompatible command 
specification, max 1, received: "+commandTypesSet);
         }
 
-        String args = context.getInput(ARGS);
-        if (Strings.isNonBlank(args)) {
-            tf.arguments(new QuotedStringTokenizer(args).remainderAsList());
+        Object args = context.getInput(ARGS);
+        if (args instanceof String && Strings.isNonBlank((String)args)) {
+            // unquote things here since we convert it to a list
+            
tf.arguments(QuotedStringTokenizer.builder().includeQuotes(false).keepInternalQuotes(true).buildList((String)args));
+        } else if (args instanceof Collection) {
+            List<String> result = MutableList.of();
+            ((Collection)args).forEach(x -> {
+                if (x instanceof String) result.add((String)x);
+                else if (Boxing.isPrimitiveOrBoxedObject(x)) 
result.add(x.toString());
+                else throw new IllegalArgumentException("Argument '"+x+"' not 
supported; should be a string");
+            });
+            tf.arguments(result);
+        } else if (args!=null) {
+            throw new IllegalArgumentException("args must be a string or a 
list");
         }
 
         Map<String, Object> env = context.getInput(ENV);
diff --git 
a/utils/common/src/main/java/org/apache/brooklyn/util/text/QuotedStringTokenizer.java
 
b/utils/common/src/main/java/org/apache/brooklyn/util/text/QuotedStringTokenizer.java
index dbd1d928e4..9fe05eff38 100644
--- 
a/utils/common/src/main/java/org/apache/brooklyn/util/text/QuotedStringTokenizer.java
+++ 
b/utils/common/src/main/java/org/apache/brooklyn/util/text/QuotedStringTokenizer.java
@@ -93,7 +93,7 @@ public class QuotedStringTokenizer {
             return new QuotedStringTokenizer(stringToTokenize, quoteChars, 
includeQuotes, delimiterChars, includeDelimiters, expectQuotesDelimited, 
failOnOpenQuote);
         }
         public List<String> buildList(String stringToTokenize) {
-            return new QuotedStringTokenizer(stringToTokenize, quoteChars, 
includeQuotes, delimiterChars, includeDelimiters, expectQuotesDelimited, 
failOnOpenQuote).remainderAsList();
+            return build(stringToTokenize).remainderAsList();
         }
         
         public Builder quoteChars(String quoteChars) { this.quoteChars = 
quoteChars; return this; }
diff --git 
a/utils/common/src/test/java/org/apache/brooklyn/util/text/QuotedStringTokenizerTest.java
 
b/utils/common/src/test/java/org/apache/brooklyn/util/text/QuotedStringTokenizerTest.java
index 3f1230a6a9..241b2add61 100644
--- 
a/utils/common/src/test/java/org/apache/brooklyn/util/text/QuotedStringTokenizerTest.java
+++ 
b/utils/common/src/test/java/org/apache/brooklyn/util/text/QuotedStringTokenizerTest.java
@@ -204,4 +204,14 @@ public class QuotedStringTokenizerTest {
         // note: backslashed escapes are not handled at present; ideally it 
would give us back this:
                 //MutableList.of("This", "is", "a", "test\\ of", "spaces", 
"and", "\"some in quotes\"", "too"));
     }
+
+    @Test
+    public void testForArgsList() throws Exception {
+        // per above, ideally note: backslashed escapes are not handled at 
present; ideally it would give us back this:
+        Asserts.assertEquals(new QuotedStringTokenizer("test \"quoted 
phrases\" and [\"embedded_quotes\"]", false).remainderAsList(),
+                MutableList.of("test", "quoted phrases", "and", 
"[embedded_quotes]"));
+        // above is the same as includeQuotes below; but for args lists we 
will usually want to keepInternalQuotes
+        
Asserts.assertEquals(QuotedStringTokenizer.builder().includeQuotes(false).keepInternalQuotes(true).buildList("test
 \"quoted phrases\" and [\"embedded_quotes\"]"),
+                MutableList.of("test", "quoted phrases", "and", 
"[\"embedded_quotes\"]"));
+    }
 }

Reply via email to