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

Enable string interpolation for hash-type parameters #4385

Closed
ChiliJohnson opened this issue Jan 17, 2024 · 8 comments · Fixed by #4580
Closed

Enable string interpolation for hash-type parameters #4385

ChiliJohnson opened this issue Jan 17, 2024 · 8 comments · Fixed by #4580
Labels
enhancement Feature request or improve operations

Comments

@ChiliJohnson
Copy link

Is your feature request related to a problem? Please describe.

The FAQ mentions that you can use string interpolation to configure parameters using environment variables, e.g. some_field "#{ENV['FOO_HOME']}", but this doesn't seem to apply to keys or values in hash-type parameters.

Describe the solution you'd like

It would be nice if string values (or keys for that matter) in hash parameters could also get interpolated in the way string parameters already do. For example let's say I want to use an HTTP output with an authorization header that includes a token passed in through the environment:

<match>
  @type http
  headers {"Authorization": "Bearer #{ENV['SOME_ENV_VAR']}"}
</match>

Describe alternatives you've considered

For my particular example, a first-class feature to support bearer tokens in the HTTP output plugin (#3587) would likely solve my immediate problem, but also implementing more general-purpose string interpolation for hash parameters would remove the need for updates to that output plugin

Additional context

No response

@ashie ashie added feature request *Deprecated Label* Use enhancement label in general and removed waiting-for-triage labels Jan 23, 2024
@kenhys kenhys added enhancement Feature request or improve operations and removed feature request *Deprecated Label* Use enhancement label in general labels Jul 31, 2024
@Athishpranav2003
Copy link
Contributor

I was checking about this issue
"{\"Authorization\":\"Bearer \#{ENV['TEST_PORT']}\"}" This is the format in which json.parse is invoked in https://github.com/fluent/fluentd/blob/master/lib/fluent/config/types.rb#L204

Ideally we would need "{\"Authorization\":\"Bearer #{ENV['TEST_PORT']}\"}" to be passed to json parser.
I am checking if there is a clean way to make sure the # is not getting escaped for jsons

@Athishpranav2003
Copy link
Contributor

For this there can be different ways in which this can be done

  1. Instead of JSON.parse we use eval but this is dangerous and not advised as arbitrary code execution can happen
  2. Manually extract the interpolated parts and substitute it with the values(seems reasonable)

For now i will work on the 2nd approach
incase if there is different suggestion for same please ping me

@ashie @kenhys

@daipom
Copy link
Contributor

daipom commented Aug 6, 2024

@Athishpranav2003 Thanks! I'm seeing this.

Ideally we would need "{\"Authorization\":\"Bearer #{ENV['TEST_PORT']}\"}" to be passed to json parser. I am checking if there is a clean way to make sure the # is not getting escaped for jsons

I see.
Looks like we need double quotes for the entire value.

<source>
  @type sample
  tag test
  sample "{\"k1\":\"v1\",\"k2\":\"#{ENV['FOO']}\"}"
</source>

<match test>
  @type stdout
</match>
$ FOO=foo bundle exec fluentd -c test.conf
...
2024-08-06 16:32:53.054415966 +0900 test: {"k1":"v1","k2":"foo"}
...

I think the issue is whether this could be made easier, am I right?

@Athishpranav2003
Copy link
Contributor

Yah @daipom
Either this PR will solve this or we change the FAQ in fluentd-docs to highlight about this case of string interpolation in case of hash and arrays alone

@daipom
Copy link
Contributor

daipom commented Aug 6, 2024

Thanks! I see!
I'm seeing #4580.

@daipom
Copy link
Contributor

daipom commented Aug 6, 2024

We need to consider this as an issue of Embedded Ruby Code.
Using environment variables is just one way of it.

Embedded Ruby Code feature is implemented in LiteralParser:

def eval_embedded_code(code)
if @eval_context.nil?
parse_error! "embedded code is not allowed in this file"
end
# Add hostname and worker_id to code for preventing unused warnings
code = <<EOM + code
hostname = Socket.gethostname
worker_id = ENV['SERVERENGINE_WORKER_ID'] || ''
EOM
begin
@eval_context.instance_eval(code)
rescue SetNil
nil
rescue SetDefault
:default
end
end

elsif skip(/\#\{/)
string << eval_embedded_code(scan_embedded_code)
skip(/\}/)

Since it is for double_quoted_string, we need to use double quotes for the entire value to use this feature.

It may be possible to address this as a types problem, as in #4580, but the specifications in LiteralParser need to be carefully considered.

@Athishpranav2003
Copy link
Contributor

Also @daipom
I haven't considered the case for hostname variable in string interpolation.

I tried looking literal_parser.rb, seems like scan_double_quoted_string is handling the env variable case but very specific to string input. Maybe a change in this code might be needed to handle the interpolated strings present in any other value of config file other than only in string types

@daipom
Copy link
Contributor

daipom commented Aug 6, 2024

The logic of literal_parser.rb is for the very early stage of parsing.
At this stage, there is no need to consider the type of each config param.

The reason is unclear, but it seems that it only cares whether the string is JSON or not (regardless of the parameter type).
I think it is because we want to parse the following multiline setting.
However, It should be noted that JSON or string in LiteralParser is not related to the type of each config param.

<source>
  @type sample
  tag test
  sample {
          "k1":"v1",
          "k2":"v2"
         }
</source> 

<match test>
  @type stdout
</match>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Feature request or improve operations
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants