in agent/envoy_bootstrap/envoy_bootstrap.go [1284:1361]
func mergeCustomConfigs(bootYaml []byte, fileUtil FileUtil) ([]byte, error) {
// Merge any custom configs specified via env variable without any protobuf validations
bootConfig := make(map[string]interface{})
if bootYaml != nil {
if err := yaml.Unmarshal(bootYaml, &bootConfig); err != nil {
return nil, err
}
}
envVariables := [...]string{
"ENVOY_TRACING_CFG_FILE", // tracing
"ENVOY_STATS_CONFIG_FILE", // stats
"ENVOY_STATS_SINKS_CFG_FILE", // stats sinks
}
for _, envVar := range envVariables {
if v := env.Get(envVar); v != "" {
log.Infof("%s is defined as %s, merging it with the envoy config.", envVar, v)
data, err := fileUtil.Read(v)
if err != nil {
return nil, err
}
var customConfig map[string]interface{}
if err := yaml.Unmarshal(data, &customConfig); err != nil {
return nil, fmt.Errorf("failure to parse %s %s for the reason: %w", envVar, v, err)
}
if len(customConfig) == 0 {
return nil, fmt.Errorf("Specified %s %s is empty.", envVar, v)
}
// We have found some users putting unrelated configs in these files, so we
// best treat it like generic envoy config.
bootConfig, err = mergeCustomConfigMaps(bootConfig, customConfig)
if err != nil {
return nil, fmt.Errorf("failure to merge %s %s into envoy config for the reason: %w", envVar, v, err)
}
// Any special handling are done in below switch statement
switch envVar {
case "ENVOY_STATS_SINKS_CFG_FILE":
// TODO: Does it make sense to always error here?
if _, ok := bootConfig[statsSinksKey]; !ok {
return nil, fmt.Errorf("%s was specified as %s, but contained no valid stats_sinks configuration.", envVar, v)
}
}
}
}
// Check if explicit resources are supplied via ENVOY_RESOURCES_CONFIG_FILE
// This block doesn't have to be inside the above 'for' loop since we treat missing config differently. But
// TODO: if you feel like this can be inside the 'for' loop feel free move it in: always 'less code' ==> 'less bugs'.
envVar := "ENVOY_RESOURCES_CONFIG_FILE"
if v := env.Get(envVar); v != "" {
log.Infof("Explicitly appending supplied Envoy resources %s %s.", envVar, v)
data, err := fileUtil.Read(v)
if err != nil {
return nil, err
}
var resourcesConfig map[string]interface{}
if err := yaml.Unmarshal(data, &resourcesConfig); err != nil {
return nil, fmt.Errorf("failure to parse %s %s for the reason: %w", envVar, v, err)
}
if len(resourcesConfig) == 0 {
log.Warnf("Specified %s %s is empty, but will ignore and continue.", envVar, v)
} else {
bootConfig, err = mergeCustomConfigMaps(bootConfig, resourcesConfig)
if err != nil {
return nil, fmt.Errorf("failure to merge %s %s into envoy config for the reason: %w", envVar, v, err)
}
}
}
bootYaml, err := yaml.Marshal(bootConfig)
if err != nil {
return nil, err
}
return bootYaml, nil
}