From 0a18d91d7c7cd6d368d148b5310863292ed70101 Mon Sep 17 00:00:00 2001 From: Sam Gartner Date: Wed, 18 Dec 2024 15:38:34 -0600 Subject: [PATCH] Update permutations.go Update permutations.go Update permutations.go --- .../operations/permutations/permutations.go | 72 ++++++++++++------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/pkg/config/operations/permutations/permutations.go b/pkg/config/operations/permutations/permutations.go index da9b889a..6fa35e13 100644 --- a/pkg/config/operations/permutations/permutations.go +++ b/pkg/config/operations/permutations/permutations.go @@ -3,14 +3,13 @@ package permutations import ( "errors" + "github.com/rancher/shepherd/pkg/config/operations" mapOperations "github.com/rancher/shepherd/pkg/config/operations" ) // Relationship structs are used to create an association between a parent value and either a set of permutations or the value of a different key type Relationship struct { ParentValue any `json:"parentValue" yaml:"parentValue"` - ChildKeyPath []string `json:"childKeyPath" yaml:"childkeyPath"` - ChildKeyPathValue any `json:"childKeyPathValue" yaml:"childkeyPathValue"` ChildPermutations []Permutation `json:"childPermutations" yaml:"childPermutations"` } @@ -25,8 +24,6 @@ type Permutation struct { func CreateRelationship(parentValue any, childKeyPath []string, childKeyPathValue any, childPermutations []Permutation) Relationship { return Relationship{ ParentValue: parentValue, - ChildKeyPath: childKeyPath, - ChildKeyPathValue: childKeyPathValue, ChildPermutations: childPermutations, } } @@ -60,32 +57,15 @@ func Permute(permutations []Permutation, baseConfig map[string]any) ([]map[strin return nil, err } - subPermutations := false - for _, relationship := range permutations[0].KeyPathValueRelationships { - if relationship.ParentValue == keyPathValue { - if len(relationship.ChildKeyPath) > 1 && relationship.ChildKeyPathValue != nil { - permutedConfig, err = mapOperations.ReplaceValue(relationship.ChildKeyPath, relationship.ChildKeyPathValue, permutedConfig) - if err != nil { - return nil, err - } - } - - var relationshipPermutedConfigs []map[string]any - if len(relationship.ChildPermutations) > 0 { - subPermutations = true - relationshipPermutedConfigs, err = Permute(relationship.ChildPermutations, permutedConfig) - if err != nil { - return nil, err - } - } - - configs = append(configs, relationshipPermutedConfigs...) + relationshipConfigs := []map[string]any{permutedConfig} + if len(permutations[0].KeyPathValueRelationships) != 0 && permutations[0].KeyPathValueRelationships != nil { + relationshipConfigs, err = applyRelationships(permutedConfig, permutations[0].KeyPathValueRelationships, keyPathValue) + if err != nil { + return nil, err } } - if !subPermutations { - configs = append(configs, permutedConfig) - } + configs = append(configs, relationshipConfigs...) } var finalConfigs []map[string]any @@ -104,3 +84,41 @@ func Permute(permutations []Permutation, baseConfig map[string]any) ([]map[strin return finalConfigs, err } + +// applyRelationships iterates over a list of relationships structs and applies them to a config +func applyRelationships(config map[string]any, relationships []Relationship, keyPathValue any) ([]map[string]any, error) { + var relationshipConfigs []map[string]any + + relationshipConfig, err := operations.DeepCopyMap(config) + if err != nil { + return nil, err + } + + permutedConfigs := []map[string]any{relationshipConfig} + if (len(relationships[0].ChildPermutations) > 0) && (relationships[0].ParentValue == keyPathValue) { + + permutedConfigs, err = Permute(relationships[0].ChildPermutations, relationshipConfig) + if err != nil { + return nil, err + } + + } + + relationshipConfigs = append(relationshipConfigs, permutedConfigs...) + + var finalConfigs []map[string]any + if len(relationships) == 1 { + return relationshipConfigs, nil + } else { + for _, config := range relationshipConfigs { + relationshipConfigs, err = applyRelationships(config, relationships[1:], keyPathValue) + if err != nil { + return nil, err + } + finalConfigs = append(finalConfigs, relationshipConfigs...) + } + } + + return finalConfigs, nil + +}