-
Notifications
You must be signed in to change notification settings - Fork 35
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add LoadConfigFromFile Move config ops to a seperate file
- Loading branch information
1 parent
e0490a2
commit 626cbc1
Showing
3 changed files
with
218 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
package configoperations | ||
|
||
import ( | ||
"errors" | ||
"fmt" | ||
|
||
"sigs.k8s.io/yaml" | ||
) | ||
|
||
// ReplaceValue iterates through a map to a provided key path and replaces the value. | ||
func ReplaceValue(keyPath []string, replaceVal any, searchMap map[string]any) (map[string]any, error) { | ||
if len(keyPath) <= 1 { | ||
searchMap[keyPath[0]] = replaceVal | ||
|
||
return searchMap, nil | ||
} else { | ||
var err error | ||
|
||
if _, ok := searchMap[keyPath[0]].(map[string]any); ok { | ||
searchMap[keyPath[0]], err = ReplaceValue(keyPath[1:], replaceVal, searchMap[keyPath[0]].(map[string]any)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} else if _, ok := searchMap[keyPath[0]].([]any); ok { | ||
for i := range searchMap[keyPath[0]].([]any) { | ||
searchMap[keyPath[0]].([]any)[i], err = ReplaceValue(keyPath[1:], replaceVal, searchMap[keyPath[0]].([]any)[i].(map[string]any)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
} | ||
} | ||
|
||
return searchMap, nil | ||
} | ||
|
||
// GetValue iterates through a map to a provided key path and returns the value. | ||
func GetValue(keyPath []string, searchMap map[string]any) (any, error) { | ||
var err error | ||
var keypathvalues any | ||
if len(keyPath) == 1 { | ||
keypathvalues, ok := searchMap[keyPath[0]] | ||
if !ok { | ||
err = errors.New(fmt.Sprintf("expected key does not exist: %s", keyPath[0])) | ||
} | ||
return keypathvalues, err | ||
} else { | ||
if _, ok := searchMap[keyPath[0]].(map[string]any); ok { | ||
keypathvalues, err = GetValue(keyPath[1:], searchMap[keyPath[0]].(map[string]any)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} else if _, ok := searchMap[keyPath[0]].([]any); ok { | ||
for i := range searchMap[keyPath[0]].([]any) { | ||
keypathvalues, err = GetValue(keyPath[1:], searchMap[keyPath[0]].([]any)[i].(map[string]any)) | ||
if err != nil { | ||
return nil, err | ||
} | ||
} | ||
} | ||
} | ||
|
||
return keypathvalues, err | ||
} | ||
|
||
// LoadKeyFromMap unmarshals a specific key's value into a map[string]any | ||
func LoadKeyFromMap(key string, config map[string]any) map[string]any { | ||
keyConfig := config[key] | ||
scopedString, err := yaml.Marshal(keyConfig) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
var scopedMap map[string]any | ||
err = yaml.Unmarshal(scopedString, &scopedMap) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
return scopedMap | ||
} | ||
|
||
// LoadObjectFromMap unmarshals a specific key's value into an object | ||
func LoadObjectFromMap(key string, config map[string]any, object any) { | ||
keyConfig := config[key] | ||
scopedString, err := yaml.Marshal(keyConfig) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
err = yaml.Unmarshal(scopedString, &object) | ||
if err != nil { | ||
panic(err) | ||
} | ||
} |
107 changes: 107 additions & 0 deletions
107
extensions/configoperations/permutations/permutations.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
package permutations | ||
|
||
import ( | ||
"encoding/json" | ||
|
||
"github.com/rancher/shepherd/extensions/configoperations" | ||
) | ||
|
||
// 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"` | ||
} | ||
|
||
// Permutation structs are used to describe a single permutation | ||
type Permutation struct { | ||
KeyPath []string `json:"keyPath" yaml:"keyPath"` | ||
KeyPathValues []any `json:"keyPathValue" yaml:"keyPath"` | ||
KeyPathValueRelationships []Relationship `json:"keyPathValueRelationships" yaml:"KeyPathValueRelationships"` | ||
} | ||
|
||
// CreateRelationship is a constructor for the relationship struct | ||
func CreateRelationship(parentValue any, childKeyPath []string, childKeyPathValue any, childPermutations []Permutation) Relationship { | ||
return Relationship{ | ||
ParentValue: parentValue, | ||
ChildKeyPath: childKeyPath, | ||
ChildKeyPathValue: childKeyPathValue, | ||
ChildPermutations: childPermutations, | ||
} | ||
} | ||
|
||
// CreatePermutation is a constructor for the permutation struct | ||
func CreatePermutation(keyPath []string, keyPathValues []any, keyPathValueRelationships []Relationship) Permutation { | ||
return Permutation{ | ||
KeyPath: keyPath, | ||
KeyPathValues: keyPathValues, | ||
KeyPathValueRelationships: keyPathValueRelationships, | ||
} | ||
} | ||
|
||
// Permute iterates over a list of permutation structs and permutes the base config with each of the describe permutations | ||
func Permute(permutations []Permutation, baseConfig map[string]any) ([]map[string]any, string, error) { | ||
var configs []map[string]any | ||
var err error | ||
if len(permutations) == 0 { | ||
return configs, "", err | ||
} | ||
|
||
for _, keyPathValue := range permutations[0].KeyPathValues { | ||
marshaledConfig, err := json.Marshal(baseConfig) | ||
if err != nil { | ||
return nil, "", err | ||
} | ||
|
||
unmarshaledConfig := make(map[string]any) | ||
json.Unmarshal(marshaledConfig, &unmarshaledConfig) | ||
|
||
permutedConfig, err := configoperations.ReplaceValue(permutations[0].KeyPath, keyPathValue, unmarshaledConfig) | ||
if err != nil { | ||
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 = configoperations.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...) | ||
} | ||
} | ||
|
||
if !subPermutations { | ||
configs = append(configs, permutedConfig) | ||
} | ||
} | ||
|
||
var finalConfigs []map[string]any | ||
if len(permutations) == 1 { | ||
return configs, "", nil | ||
} else { | ||
for _, config := range configs { | ||
permutedConfigs, _, err := Permute(permutations[1:], config) | ||
if err != nil { | ||
return nil, "", err | ||
} | ||
|
||
finalConfigs = append(finalConfigs, permutedConfigs...) | ||
} | ||
} | ||
|
||
return finalConfigs, "", err | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters