in translator/cmdutil/translatorutil.go [108:220]
func GenerateMergedJsonConfigMap(ctx *context.Context) (map[string]interface{}, error) {
// we use a map instead of an array here because we need to override the config value
// for the append operation when the existing file name and new .tmp file name have diff
// only for the ".tmp" suffix, i.e. it is override operation even it says append.
var jsonConfigMapMap = make(map[string]map[string]interface{})
if ctx.MultiConfig() == "append" || ctx.MultiConfig() == "remove" {
// backwards compatible for the old json config file
// this backwards compatible file can be treated as existing files
jsonConfigMap, err := getJsonConfigMap(ctx.InputJsonFilePath(), ctx.Os())
if err != nil {
return nil, fmt.Errorf("unable to get old json config file with error: %v", err)
}
if jsonConfigMap != nil {
jsonConfigMapMap[ctx.InputJsonFilePath()] = jsonConfigMap
}
}
err := filepath.Walk(
ctx.InputJsonDirPath(),
func(path string, info os.FileInfo, err error) error {
if err != nil {
fmt.Printf("Cannot access %v: %v \n", path, err)
return err
}
if envconfig.IsWindowsHostProcessContainer() {
log.Printf("Skipping checking symbolic link for Windows host process containers %s. \n"+
"These symbolic links are skipped as valuating symlinks is common failures for Windows containers", path)
} else {
if info.Mode()&os.ModeSymlink != 0 {
log.Printf("Find symbolic link %s \n", path)
path, err := filepath.EvalSymlinks(path)
if err != nil {
log.Printf("Symbolic link %v will be ignored due to err: %v. \n", path, err)
return nil
}
info, err = os.Stat(path)
if err != nil {
log.Printf("Path %v will be ignored due to err: %v. \n", path, err)
}
}
if info.IsDir() {
return nil
}
}
ext := filepath.Ext(path)
if ext == constants.FileSuffixTmp {
key := strings.TrimSuffix(path, constants.FileSuffixTmp)
// .tmp files
ext = filepath.Ext(key)
// skip .yaml files
if ext == constants.FileSuffixYAML {
return nil
}
if ctx.MultiConfig() == "default" || ctx.MultiConfig() == "append" {
jsonConfigMap, err := getJsonConfigMap(path, ctx.Os())
if err != nil {
return err
}
if jsonConfigMap != nil {
jsonConfigMapMap[key] = jsonConfigMap
}
}
} else if ext == constants.FileSuffixYAML {
// skip .yaml files
return nil
} else {
// non .tmp / existing files
if ctx.MultiConfig() == "append" || ctx.MultiConfig() == "remove" {
jsonConfigMap, err := getJsonConfigMap(path, ctx.Os())
if err != nil {
return err
}
if jsonConfigMap != nil {
if _, ok := jsonConfigMapMap[path]; !ok {
jsonConfigMapMap[path] = jsonConfigMap
}
}
}
}
return nil
})
if err != nil {
log.Printf("unable to scan config dir %v with error: %v", ctx.InputJsonDirPath(), err)
}
if len(jsonConfigMapMap) == 0 {
// For containerized agent, try to read env variable only when json configuration file is absent
if jsonConfigContent, ok := os.LookupEnv(config.CWConfigContent); ok && os.Getenv(config.RUN_IN_CONTAINER) == config.RUN_IN_CONTAINER_TRUE {
log.Printf("Reading json config from from environment variable %v.", config.CWConfigContent)
jm, err := translatorUtil.GetJsonMapFromJsonBytes([]byte(jsonConfigContent))
if err != nil {
return nil, fmt.Errorf("unable to get json map from environment variable %v with error: %v", config.CWConfigContent, err)
}
jsonConfigMapMap[config.CWConfigContent] = jm
}
}
defaultConfig, err := translatorUtil.GetDefaultJsonConfigMap(ctx.Os(), ctx.Mode())
if err != nil {
return nil, err
}
mergedJsonConfigMap, err := jsonconfig.MergeJsonConfigMaps(jsonConfigMapMap, defaultConfig, ctx.MultiConfig())
if err != nil {
return nil, err
}
// Json Schema Validation by gojsonschema
checkSchema(mergedJsonConfigMap)
return mergedJsonConfigMap, nil
}