Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug requiring $$ when using config source variables #1058

Closed
wants to merge 2 commits into from

Conversation

pmcollins
Copy link
Contributor

@pmcollins pmcollins commented Dec 21, 2021

Previously, if a user wanted to use a config source variable (which have the
form ${env:MY_ENV_VAR}) they would have to use two dollar signs, like
$${env:MY_ENV_VAR}. This was because the expandMapProvider, which lives in
core and expands ${MY_ENV_VAR}-style variables, would run before the config
source providers, and would replace any ${env:MY_ENV_VAR}s with "" but
convert any $${env:MY_ENV_VAR}s to ${env:MY_ENV_VAR}. The fix proposed here
is to reverse the order in which these providers run: now the config source
providers run first, then expandMapProvider runs. In addition, this change
fixes up any $${env:MY_ENV_VAR} workarounds users may have put in place.

Previously, if a user wanted to use a config source variable (which have the
form ${env:MY_ENV_VAR}) they would have to use two dollar signs, like
$${env:MY_ENV_VAR}. This is because the expandMapProvider, which lives in
core and expands ${MY_ENV_VAR} -style variables, would run before the config
source providers, and it would replace any ${env:MY_ENV_VAR}s with "" but
convert any $${env:MY_ENV_VAR} to ${env:MY_ENV_VAR}. The fix proposed here
is to reverse the order in which these providers run: now the config source
providers run first, then expandMapProvider runs. In addition, this change
fixes up any $${env:MY_ENV_VAR} workarounds users may have put in place.
@rmfitzpatrick
Copy link
Contributor

There's an existing integration test that would need to be updated/could prove useful for this: https://github.com/signalfx/splunk-otel-collector/blob/main/tests/general/envvar_config_source_test.go#L33

@pmcollins pmcollins marked this pull request as ready for review December 21, 2021 16:52
@pmcollins pmcollins requested review from a team as code owners December 21, 2021 16:52
}

func dollarDollarRegex() *regexp.Regexp {
return regexp.MustCompile(`\$\${(.+?:.+?)}`)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it preferable to obtain via a function and not a global var?

Copy link
Contributor

@dmitryax dmitryax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for fixing it!

Comment on lines +24 to +27
// ReplaceDollarDollar replaces any $${foo:MY_VAR} config source variables with
// ${foo:MY_VAR}. These might exist because of customers working around a bug
// in how the Collector expanded these variables.
func ReplaceDollarDollar(m *config.Map) *config.Map {
Copy link
Contributor

@dmitryax dmitryax Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not only ${foo:MY_VAR} that is affected. Any env variables added to the config currently has to have the following $${ENV_VAR} format to work properly, and, if user wants to have a dollar sign, it must be escaped as $$$$.

I'm not sure if we want to implicitly translate any of the use cases.

I would suggest just adding a warning message for any encountered value with $${ and $$$$ but do not change them implicitly. Also we should make a clear statement about fixing this bug as a breaking change, add a line to changelog and to the upgrade guideline.

@pmcollins @rmfitzpatrick WDYT?

Copy link
Contributor

@dmitryax dmitryax Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added comment assuming that the use cases I outlined are fixed as well, let me know if it's not the case

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not only ${foo:MY_VAR} that is affected. Any env variables added to the config currently has to have the following $${ENV_VAR} format to work properly, and, if user wants to have a dollar sign, it must be escaped as $$$$.

I don't think this is accurate and $ENVVAR and ${ENVVAR} should be functional as is and after these changes (for example https://github.com/signalfx/splunk-otel-collector/blob/main/tests/general/testdata/config_with_envvars.yaml#L9 and https://github.com/signalfx/splunk-otel-collector/blob/main/cmd/otelcol/config/collector/agent_config.yaml#L25).

If users want to have a $ literal I think it makes sense that they'd need to escape it somehow and $$ makes the most sense to me. This should be clearly documented and ideally vetted with unit/integration tests.

Copy link
Contributor

@dmitryax dmitryax Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is accurate and $ENVVAR and ${ENVVAR} should be functional as is and after these changes (for example https://github.com/signalfx/splunk-otel-collector/blob/main/tests/general/testdata/config_with_envvars.yaml#L9 and https://github.com/signalfx/splunk-otel-collector/blob/main/cmd/otelcol/config/collector/agent_config.yaml#L25).

The bug is that any env var is evaluated twice. So ${ENV_VAR} and $${ENV_VAR} both have the same result. Once ${ENV_VAR} evaluated first, second evaluation is skipped because then it's just a string.

If users want to have a $ literal I think it makes sense that they'd need to escape it somehow and $$ makes the most sense to me. This should be clearly documented and ideally vetted with unit/integration tests.

Yes, it should be $$ not $$$$ which we have to set because of this bug in the helm chart but it's not needed when contrib image is used

Copy link
Contributor

@dmitryax dmitryax Dec 21, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably we can keep the implicit translation for some time, it shouldn't break existing configs, but in order to cover all the use cases we probably should just convert $$ -> $.

I would still clearly mark it in the changelog and translation guidelines and set expectation when this translation is removed. Let's say in 0.45.0?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

local testing with these changes:

config_sources:
  env:
    defaults:
      HOST_METRICS_SCRAPERS_TO_EXPAND: {}
      HOST_METRICS_SCRAPERS_DEFAULT_TO_USE: { cpu: null }

receivers:
  hostmetrics:
    collection_interval: $$HOST_METRICS_COLLECTION_INTERVAL
    scrapers: ${env:HOST_METRICS_SCRAPERS_TO_EXPAND}
  hostmetrics/default-env-config-source:
    collection_interval: $${HOST_METRICS_COLLECTION_INTERVAL}
    scrapers: $${env:HOST_METRICS_SCRAPERS_DEFAULT_TO_USE}

http://localhost:55554/debug/configz/effective:

receivers:
  hostmetrics:
    collection_interval: $HOST_METRICS_COLLECTION_INTERVAL
    scrapers:
      cpu: {}
      disk: {}
      filesystem: {}
      load: {}
      memory: {}
      network: {}
      paging: {}
      processes: {}
  hostmetrics/default-env-config-source:
    collection_interval: ${HOST_METRICS_COLLECTION_INTERVAL}
    scrapers:
      cpu: null

What should the expected behavior be if not this?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIR from my testing sometime ago http://localhost:55554/debug/configz/effective doesn't show results of the second evaluation

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

collector should not be able to start with the following part using contrib build

receivers:
  hostmetrics:
    collection_interval: $$HOST_METRICS_COLLECTION_INTERVAL

Copy link
Contributor

@dmitryax dmitryax left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to make sure we solve the problem uniformly not just for config source and decide if we want to keep backward compatibility and for how long.

@dmitryax
Copy link
Contributor

Given the double evaluation is fixed in #1099, i'm ok if we keep keep only $${<source>:<val>} -> ${<source>:<val>} backward compatibility translation. This PR needs to go after 1099

@dmitryax dmitryax self-requested a review January 12, 2022 07:21
@dmitryax
Copy link
Contributor

Superseded by #1099

@dmitryax dmitryax closed this Jan 15, 2022
@pjanotti pjanotti deleted the dollar-dollar branch January 22, 2024 21:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants