Skip to content

Commit

Permalink
feat(cli): Support setting maps in traits API
Browse files Browse the repository at this point in the history
  • Loading branch information
astefanutti committed Mar 6, 2023
1 parent bcacff5 commit f0663bf
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 9 deletions.
24 changes: 20 additions & 4 deletions pkg/cmd/trait_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand All @@ -46,26 +46,42 @@ 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)
}
}

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 {
Expand Down
6 changes: 5 additions & 1 deletion pkg/trait/trait_catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -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])
}
}
}
}
Expand Down
19 changes: 15 additions & 4 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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, "[")
Expand All @@ -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) {
Expand Down

0 comments on commit f0663bf

Please sign in to comment.