Fix nginx ingress controller bug around config map merging

* a config map bool value of false cannot overwritte a true value from
   defaults
 * implement merging in ReadConfig
 * remove helper function merge
 * adds tests to ensure config is read properly
This commit is contained in:
Christian Simon 2016-04-26 11:27:23 +01:00
parent 4159a40da4
commit 94e6702385
3 changed files with 130 additions and 23 deletions

View file

@ -59,18 +59,36 @@ func getDNSServers() []string {
return nameservers
}
// getConfigKeyToStructKeyMap returns a map with the ConfigMapKey as key and the StructName as value.
func getConfigKeyToStructKeyMap() map[string]string {
keyMap := map[string]string{}
n := &nginxConfiguration{}
val := reflect.Indirect(reflect.ValueOf(n))
for i := 0; i < val.Type().NumField(); i++ {
fieldSt := val.Type().Field(i)
configMapKey := strings.Split(fieldSt.Tag.Get("structs"), ",")[0]
structKey := fieldSt.Name
keyMap[configMapKey] = structKey
}
return keyMap
}
// ReadConfig obtains the configuration defined by the user merged with the defaults.
func (ngx *Manager) ReadConfig(config *api.ConfigMap) nginxConfiguration {
if len(config.Data) == 0 {
return newDefaultNginxCfg()
}
cfg := newDefaultNginxCfg()
cfgCM := nginxConfiguration{}
cfgDefault := newDefaultNginxCfg()
metadata := &mapstructure.Metadata{}
decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
TagName: "structs",
Result: &cfg,
Result: &cfgCM,
WeaklyTypedInput: true,
Metadata: metadata,
})
err = decoder.Decode(config.Data)
@ -78,7 +96,26 @@ func (ngx *Manager) ReadConfig(config *api.ConfigMap) nginxConfiguration {
glog.Infof("%v", err)
}
return cfg
keyMap := getConfigKeyToStructKeyMap()
valCM := reflect.Indirect(reflect.ValueOf(cfgCM))
for _, key := range metadata.Keys {
fieldName, ok := keyMap[key]
if !ok {
continue
}
valDefault := reflect.ValueOf(&cfgDefault).Elem().FieldByName(fieldName)
fieldCM := valCM.FieldByName(fieldName)
if valDefault.IsValid() {
valDefault.Set(fieldCM)
}
}
return cfgDefault
}
func (ngx *Manager) needsReload(data *bytes.Buffer) (bool, error) {
@ -143,21 +180,6 @@ func diff(b1, b2 []byte) (data []byte, err error) {
return
}
func merge(dst, src map[string]interface{}) map[string]interface{} {
for key, srcVal := range src {
if dstVal, ok := dst[key]; ok {
srcMap, srcMapOk := toMap(srcVal)
dstMap, dstMapOk := toMap(dstVal)
if srcMapOk && dstMapOk {
srcVal = merge(dstMap, srcMap)
}
}
dst[key] = srcVal
}
return dst
}
func toMap(iface interface{}) (map[string]interface{}, bool) {
value := reflect.ValueOf(iface)
if value.Kind() == reflect.Map {