From 0f32fd749ffeee34b403f3b1a569a00855e3a1bb Mon Sep 17 00:00:00 2001 From: Caleb Warren Date: Fri, 11 Oct 2024 10:03:42 -0700 Subject: [PATCH 1/3] add corralBastion back as a func --- clients/corral/corral.go | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/clients/corral/corral.go b/clients/corral/corral.go index 448f079f..931ebae7 100644 --- a/clients/corral/corral.go +++ b/clients/corral/corral.go @@ -18,10 +18,12 @@ import ( ) const ( - debugFlag = "--trace" - skipCleanupFlag = "--skip-cleanup" - corralPrivateSSHKey = "corral_private_key" - corralPublicSSHKey = "corral_public_key" + debugFlag = "--trace" + skipCleanupFlag = "--skip-cleanup" + corralPrivateSSHKey = "corral_private_key" + corralPublicSSHKey = "corral_public_key" + corralRegistryIP = "registry_ip" + corralRegistryPrivateIP = "registry_private_ip" ) // GetCorralEnvVar gets corral environment variables @@ -345,3 +347,23 @@ func SetCorralSSHKeys(corralName string) error { return UpdateCorralConfig(corralPublicSSHKey, publicSSHkey) } + +// SetCorralBastion is a helper function that will set the corral bastion private and pulic addresses previously generated by `corralName` +func SetCorralBastion(corralName string) error { + bastion_ip, err := GetCorralEnvVar(corralName, corralRegistryIP) + if err != nil { + return err + } + + err = UpdateCorralConfig(corralRegistryIP, bastion_ip) + if err != nil { + return err + } + + bastion_internal_ip, err := GetCorralEnvVar(corralName, corralRegistryPrivateIP) + if err != nil { + return err + } + + return UpdateCorralConfig(corralRegistryPrivateIP, bastion_internal_ip) +} From bda927ad898ee226d67bb50905cf97d859a6398c Mon Sep 17 00:00:00 2001 From: Sam Gartner Date: Fri, 23 Aug 2024 22:40:28 -0500 Subject: [PATCH 2/3] initial commit Add LoadConfigFromFile Move config ops to a seperate file fix typo Update permutations.go Update permutations.go Update configoperations.go Update permutations.go Update configoperations.go Create example_test.go Update example_test.go Update to address PR comments Update example_test.go update with correct locations update directory location update naming --- pkg/config/config.go | 16 +++ pkg/config/operations/operations.go | 95 ++++++++++++++++ .../operations/permutations/example_test.go | 38 +++++++ .../operations/permutations/permutations.go | 106 ++++++++++++++++++ 4 files changed, 255 insertions(+) create mode 100644 pkg/config/operations/operations.go create mode 100644 pkg/config/operations/permutations/example_test.go create mode 100644 pkg/config/operations/permutations/permutations.go diff --git a/pkg/config/config.go b/pkg/config/config.go index f5e2f5ac..c9758722 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -119,3 +119,19 @@ func WriteConfig(key string, config interface{}) error { return nil } + +// LoadConfigFromFile loads an entire yaml file into a map[string]any +func LoadConfigFromFile(filePath string) map[string]any { + allString, err := os.ReadFile(filePath) + if err != nil { + panic(err) + } + + var all map[string]any + err = yaml.Unmarshal(allString, &all) + if err != nil { + panic(err) + } + + return all +} diff --git a/pkg/config/operations/operations.go b/pkg/config/operations/operations.go new file mode 100644 index 00000000..21b48e8e --- /dev/null +++ b/pkg/config/operations/operations.go @@ -0,0 +1,95 @@ +package operations + +import ( + "encoding/json" + "errors" + "fmt" + + "sigs.k8s.io/yaml" +) + +// ReplaceValue recursively traverses keyPath, replacing the specified replaceVal in searchMap. +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 recursively traverses keyPath, returning the value of the specified keyPath in searchMap. +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 +} + +// 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) + } +} + +// DeepCopyMap creates a copy of the map that doesn't have any links to the original map +func DeepCopyMap(config map[string]any) (map[string]any, error) { + marshaledConfig, err := json.Marshal(config) + if err != nil { + return nil, err + } + + unmarshaledConfig := make(map[string]any) + err = json.Unmarshal(marshaledConfig, &unmarshaledConfig) + if err != nil { + return nil, err + } + + return unmarshaledConfig, nil +} diff --git a/pkg/config/operations/permutations/example_test.go b/pkg/config/operations/permutations/example_test.go new file mode 100644 index 00000000..802f3d04 --- /dev/null +++ b/pkg/config/operations/permutations/example_test.go @@ -0,0 +1,38 @@ +package permutations + +import ( + "fmt" + + mapOperations "github.com/rancher/shepherd/pkg/config/operations" +) + +// ExamplePermute is an example of how to use the permutation objects and the permute function. +func ExamplePermute() { + config := map[string]any{ + "foo1": map[string]any{ + "nested-foo1": []any{"bar1", "bar2"}, + }, + "foo2": []any{"bar3", "bar4"}, + } + + nestedFoo1Path := []string{"foo1", "nested-foo1"} + nestedFoo1Value, _ := mapOperations.GetValue(nestedFoo1Path, config) + foo1Permutation := CreatePermutation(nestedFoo1Path, nestedFoo1Value.([]any), []Relationship{}) + + nestedFoo2Path := []string{"foo2"} + nestedFoo2Value, _ := mapOperations.GetValue(nestedFoo2Path, config) + foo2Permutation := CreatePermutation(nestedFoo2Path, nestedFoo2Value.([]any), []Relationship{}) + + permutations := []Permutation{foo1Permutation, foo2Permutation} + permutedConfigs, _ := Permute(permutations, config) + + for _, permutedConfig := range permutedConfigs { + fmt.Println(permutedConfig) + //Output: + //map[foo1:map[nested-foo1:bar1] foo2:bar3] + //map[foo1:map[nested-foo1:bar1] foo2:bar4] + //map[foo1:map[nested-foo1:bar2] foo2:bar3] + //map[foo1:map[nested-foo1:bar2] foo2:bar4] + } + +} diff --git a/pkg/config/operations/permutations/permutations.go b/pkg/config/operations/permutations/permutations.go new file mode 100644 index 00000000..da9b889a --- /dev/null +++ b/pkg/config/operations/permutations/permutations.go @@ -0,0 +1,106 @@ +package permutations + +import ( + "errors" + + 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"` +} + +// 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 permutations +func Permute(permutations []Permutation, baseConfig map[string]any) ([]map[string]any, error) { + var configs []map[string]any + var err error + if len(permutations) == 0 { + err = errors.New("no permutations provided") + return configs, err + } + + for _, keyPathValue := range permutations[0].KeyPathValues { + permutedConfig, err := mapOperations.DeepCopyMap(baseConfig) + if err != nil { + return nil, err + } + + permutedConfig, err = mapOperations.ReplaceValue(permutations[0].KeyPath, keyPathValue, permutedConfig) + 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 = 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...) + } + } + + 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 +} From 33f98802b03656db7467ede927d163ab0b6314fd Mon Sep 17 00:00:00 2001 From: Brandon DePesa <21316915+bmdepesa@users.noreply.github.com> Date: Mon, 11 Nov 2024 09:07:58 -0700 Subject: [PATCH 3/3] Update CODEOWNERS --- CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index 53966180..8087a940 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,2 +1,2 @@ # RAFT Team -* @igomez06 @caliskanugur +* @caliskanugur @bmdepesa