in the following code (which I re-used from previous question) we need to match objects according to matching keys values
The keys are the value of
From model internalConfig
type
From external config
app-type
In case we have 'match' (in the value) we need to replace the data from the external config and update the internal config
e.g. if for zone2 app-type=app1 is equal to internal config type=app1 we need to change the content from external config to be
from
- name: TEST
type: app1
target: ./
to (since app1 is equal in internal and external config- we are updating the data from external to internal)
- name: TEST
type: AZURE
target: ./
given the above data the internal config should look after the match like
At the end it should look like
- name: TEST
type: AZURE
target: ./
- name: TEST3
type: HEROKU
target: ./
- name: TEST2
type: app3
target: ./
- name: TEST2
type: AZURE
target: ./
Im trying the following but I wasn’t able to match all the objects in case I’ve more then one entry to the same key e.g. app1 “key” is in the first and the last entry, so my code is update only the first entry
- name: TEST
type: app1
target: ./
- name: TEST3
type: app2
target: ./
- name: TEST2
type: app3
target: ./
- name: TEST2
type: app1
target: ./
Any idea how could I resolve this ? this is what i've tried which works only on the first match
package main
import (
"fmt"
"gopkg.in/yaml.v2"
"log"
)
type InternalConfig struct {
Models []Imodel `yaml:"models"`
}
type Imodel struct {
Name string `yaml:"name"`
Type string `yaml:"type"`
Target string `yaml:"target"`
}
var internalConfig = []byte(`
models:
- name: TEST
type: app1
target: ./
- name: TEST3
type: app2
target: ./
- name: TEST2
type: app3
target: ./
- name: TEST2
type: app1
target: ./
`)
type ExternalConfig struct {
Landscape Zone `yaml:"Landscape"`
}
type Zone struct {
Zone string `yaml:"zone"`
Models []Emodel `yaml:"models"`
}
type Emodel struct {
AppType string `yaml:"app-type"`
ServiceType string `yaml:"service-type"`
}
var externalConfig = []byte(`
Landscape:
zone: zone1
models:
- app-type: app1
service-type: GCP
- app-type: app2
service-type: AMAZON
zone: zone2
models:
- app-type: app1
service-type: AZURE
- app-type: app2
service-type: HEROKU
`)
func main() {
iCfgYaml := InternalConfig{}
if err := yaml.Unmarshal(internalConfig, &iCfgYaml); err != nil {
log.Fatalf("error in model InternalConfig: %v", err)
}
eCfgYaml := ExternalConfig{}
if err := yaml.Unmarshal(externalConfig, &eCfgYaml); err != nil {
log.Fatalf("error in model ExternalConfig: %v", err)
}
if err := UpdateInternalState(&iCfgYaml, eCfgYaml, "zone2"); err != nil {
log.Fatalf("Error updating internal config: %v", err)
}
fmt.Printf("DBG: %+v
", iCfgYaml)
}
func UpdateInternalState(iCfg *InternalConfig, eCfg ExternalConfig, zone string) error {
ilm := make(map[string]int)
for i, v := range iCfg.Models {
ilm[v.Type] = i
}
for _, em := range eCfg.Landscape.Models {
if eCfg.Landscape.Zone == zone {
if i, ok := ilm[em.AppType]; ok {
iCfg.Models[i].Type = em.ServiceType
}
}
}
return nil
}
if you run the code above, this is the data you will get
{Models:[
{Name:TEST Type:app1 Target:./}
{Name:TEST3 Type:HEROKU Target:./}
{Name:TEST2 Type:app3 Target:./}
{Name:TEST2 Type:AZURE Target:./}]}
The first entry doesn't updated
https://play.golang.org/p/5f3Ad9Z7fqY
If needs more clarification please let me know