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

astefanutti pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-k.git

commit d1e9687f78b15fc78ef25c0978e3200376bc268e
Author: Antonin Stefanutti <anto...@stefanutti.fr>
AuthorDate: Wed Mar 1 12:51:00 2023 +0100

    feat(cli): Support setting maps in traits API
---
 pkg/cmd/trait_support.go   | 24 ++++++++++++++++++++----
 pkg/trait/trait_catalog.go |  6 +++++-
 pkg/util/util.go           | 19 +++++++++++++++----
 3 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/pkg/cmd/trait_support.go b/pkg/cmd/trait_support.go
index 6e8abfa22..a85cc2080 100644
--- a/pkg/cmd/trait_support.go
+++ b/pkg/cmd/trait_support.go
@@ -36,7 +36,7 @@ type optionMap map[string]map[string]interface{}
 // The list of known addons is used for handling backward compatibility.
 var knownAddons = []string{"keda", "master", "strimzi", "3scale", "tracing"}
 
-var traitConfigRegexp = 
regexp.MustCompile(`^([a-z0-9-]+)((?:\.[a-z0-9-]+)(?:\[[0-9]+\]|\.[A-Za-z0-9-_]+)*)=(.*)$`)
+var traitConfigRegexp = 
regexp.MustCompile(`^([a-z0-9-]+)((?:\.[a-z0-9-]+)(?:\[[0-9]+\]|\..+)*)=(.*)$`)
 
 func validateTraits(catalog *trait.Catalog, traits []string) error {
        tp := catalog.ComputeTraitsProperties()
@@ -46,7 +46,9 @@ func validateTraits(catalog *trait.Catalog, traits []string) 
error {
                if strings.Contains(prefix, "[") {
                        prefix = prefix[0:strings.Index(prefix, "[")]
                }
-               if !util.StringSliceExists(tp, prefix) {
+               if valid, err := validateTrait(tp, prefix); err != nil {
+                       return err
+               } else if !valid {
                        return fmt.Errorf("%s is not a valid trait property", t)
                }
        }
@@ -54,18 +56,32 @@ func validateTraits(catalog *trait.Catalog, traits 
[]string) error {
        return nil
 }
 
+func validateTrait(properties []string, item string) (bool, error) {
+       for i := 0; i < len(properties); i++ {
+               if strings.HasSuffix(properties[i], ".*") {
+                       if match, err := regexp.MatchString(properties[i], 
item); err != nil {
+                               return false, err
+                       } else if match {
+                               return true, nil
+                       }
+               } else if properties[i] == item {
+                       return true, nil
+               }
+       }
+
+       return false, nil
+}
+
 func configureTraits(options []string, traits interface{}, catalog 
trait.Finder) error {
        config, err := optionsToMap(options)
        if err != nil {
                return err
        }
 
-       //
        // Known addons need to be put aside here, as otherwise the deprecated 
addon fields on
        // Traits might be accidentally populated. The deprecated addon fields 
are preserved
        // for backward compatibility and should be populated only when the 
operator reads
        // existing CRs from the API server.
-       //
        addons := make(optionMap)
        for _, id := range knownAddons {
                if config[id] != nil {
diff --git a/pkg/trait/trait_catalog.go b/pkg/trait/trait_catalog.go
index 5acbaf94c..6992abd26 100644
--- a/pkg/trait/trait_catalog.go
+++ b/pkg/trait/trait_catalog.go
@@ -182,7 +182,11 @@ func (c *Catalog) processFields(fields []*structs.Field, 
processor func(string))
 
                if property != "" {
                        items := strings.Split(property, ",")
-                       processor(items[0])
+                       if f.Kind() == reflect.Map {
+                               processor(items[0] + ".*")
+                       } else {
+                               processor(items[0])
+                       }
                }
        }
 }
diff --git a/pkg/util/util.go b/pkg/util/util.go
index 750aada65..28de402f3 100644
--- a/pkg/util/util.go
+++ b/pkg/util/util.go
@@ -93,7 +93,7 @@ var QuarkusDependenciesBaseDirectory = "/quarkus-app"
 // These are sensitive values or values that may have different values 
depending on
 // where the integration is run (locally vs. the cloud). These environment 
variables
 // are evaluated at the time of the integration invocation.
-var ListOfLazyEvaluatedEnvVars = []string{}
+var ListOfLazyEvaluatedEnvVars []string
 
 // CLIEnvVars -- List of CLI provided environment variables. They take 
precedence over
 // any environment variables with the same name.
@@ -645,12 +645,14 @@ func WithTempDir(pattern string, consumer func(string) 
error) error {
        return multierr.Append(consumerErr, removeErr)
 }
 
-// Parses a property spec and returns its parts.
+var propertyRegex = regexp.MustCompile("'.+'|\".+\"|[^.]+")
+
+// ConfigTreePropertySplit Parses a property spec and returns its parts.
 func ConfigTreePropertySplit(property string) []string {
        var res = make([]string, 0)
-       initialParts := strings.Split(property, ".")
+       initialParts := propertyRegex.FindAllString(property, -1)
        for _, p := range initialParts {
-               cur := p
+               cur := trimQuotes(p)
                var tmp []string
                for strings.Contains(cur[1:], "[") && strings.HasSuffix(cur, 
"]") {
                        pos := strings.LastIndex(cur, "[")
@@ -667,6 +669,15 @@ func ConfigTreePropertySplit(property string) []string {
        return res
 }
 
+func trimQuotes(s string) string {
+       if len(s) >= 2 {
+               if c := s[len(s)-1]; s[0] == c && (c == '"' || c == '\'') {
+                       return s[1 : len(s)-1]
+               }
+       }
+       return s
+}
+
 // NavigateConfigTree switch to the element in the tree represented by the 
"nodes" spec and creates intermediary
 // nodes if missing. Nodes specs starting with "[" and ending in "]" are 
treated as slice indexes.
 func NavigateConfigTree(current interface{}, nodes []string) (interface{}, 
error) {

Reply via email to