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

Add support for environment variable injection in kibana.yml #16988

Merged
merged 1 commit into from
Apr 12, 2018

Conversation

fbaligand
Copy link
Contributor

@fbaligand fbaligand commented Mar 5, 2018

This PR lets support for environment variable injection in kibana.yml, using syntax ${MY_ENV_VAR}.

Fixes #6688

@elasticmachine
Copy link
Contributor

Since this is a community submitted pull request, a Jenkins build has not been kicked off automatically. Can an Elastic organization member please verify the contents of this patch and then kick off a build manually?

}

// attempt to validate the config value
this._commit(config);
}

_replaceEnvVars(value) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we add tests for all of these cases in addition to the env variable not being specified?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @tylersmalley

  • OK, I will add a test when env variable is not specified.
  • Then, for additional cases, currently, _.isString(value) and _.isArray(value) are covered. Only _.isPlainObject(value) is not covered. I will change the test to cover it.

@tylersmalley tylersmalley added the Team:Operations Team label for Operations Team label Mar 6, 2018
@@ -61,13 +61,25 @@ export class Config {
if (_.isPlainObject(key)) {
config = override(config, key);
Copy link
Contributor Author

@fbaligand fbaligand Mar 6, 2018

Choose a reason for hiding this comment

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

@tylersmalley

  • Question : should I replace override(config, key) by override(config, _replaceEnvVars(key)) ?

Copy link
Member

Choose a reason for hiding this comment

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

I'm not entirely sure what it's used for, maybe testing. @spalger do you know?

Copy link
Contributor

Choose a reason for hiding this comment

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

Not sure it is used. Gut feeling is it was just an "expected" behavior of a method like this.

Copy link
Contributor Author

@fbaligand fbaligand Apr 5, 2018

Choose a reason for hiding this comment

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

@spalger
So, should I replace override(config, key) by override(config, _replaceEnvVars(key)) ?

Copy link
Contributor

@spalger spalger Apr 5, 2018

Choose a reason for hiding this comment

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

My recommendation from #16988 (comment) is to move all of this into https://github.com/elastic/kibana/blob/master/src/cli/serve/read_yaml_config.js and do it once when reading kibana.yml from the file system

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@spalger
OK, I will do so.
Thanks for this first review.

@fbaligand
Copy link
Contributor Author

@tylersmalley
What behaviour do you wish when environment variable is not defined ?
Currently, it replaces env var reference by undefined

@fbaligand
Copy link
Contributor Author

Hi @tylersmalley,

  • I increased test coverage (all 'replaceEnvVars()' lines are covered)
  • I raise an error if referenced environment variable does not exist

Is it OK for you ?

@fbaligand
Copy link
Contributor Author

Hi @tylersmalley,
Could you review my changes ?

@tylersmalley
Copy link
Contributor

@fbaligand, thanks for the updates. Hope to get to reviewing this soon.

@fbaligand
Copy link
Contributor Author

fbaligand commented Mar 26, 2018

Thanks, I hope so too ! :)

@tylersmalley tylersmalley requested a review from jbudz April 3, 2018 16:43
@spalger
Copy link
Contributor

spalger commented Apr 5, 2018

Just took a cursory look, but think I'd prefer that this was implemented in https://github.com/elastic/kibana/blob/master/src/cli/serve/read_yaml_config.js so that replacement like this only occured when reading the config file. I would be quite surprised by this behavior if I was calling config.set() directly from just about anywhere.

@fbaligand fbaligand force-pushed the env-var-injection branch from 892b934 to 6c61584 Compare April 5, 2018 20:38
@fbaligand
Copy link
Contributor Author

fbaligand commented Apr 5, 2018

I just rebased my code to merge conflicts with master branch.

@fbaligand fbaligand force-pushed the env-var-injection branch from 6c61584 to 68e1da5 Compare April 7, 2018 18:06
@fbaligand
Copy link
Contributor Author

@spalger
I just moved the code to read_yaml_config.js as requested.
Could you review the code ?

Copy link
Contributor

@spalger spalger left a comment

Choose a reason for hiding this comment

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

I'm into it, LGTM

@fbaligand
Copy link
Contributor Author

Great @spalger !

=> @tylersmalley @jbudz could you review/approve the code ?

@spalger
Copy link
Contributor

spalger commented Apr 8, 2018

Jenkins, test this

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

function _replaceEnvVarRefs(val) {
return val.replace(/\$\{(\w+)\}/g, (match, envVarName) => {
if (process.env[envVarName] !== undefined) {
return process.env[envVarName];
Copy link
Member

Choose a reason for hiding this comment

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

I would prefer if we _.escaped this by default, and any configuration that needs it unescaped can do so. Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jbudz
So you want to replace return process.env[envVarName];
by return _.escape(process.env[envVarName]); ?

No problem for me, but can you explain me why ? I mean : at this point, the yaml file is already parsed.

Maybe it could be an issue for server.basePath option if user wants to use & character ?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I don't think we want to escape HTML entities in the config values. People using this feature need to take care that they inject the correct value and Joi will take care of ensuring that it's a valid value.

I was initially concerned about non-string values, but realized Joi also parses JSON values in an attempt to coerce the value to the desired type, so to set a boolean value you can do:

some.boolean: "${MY_ENV_VAR}"

and

MY_ENV_VAR=true bin/kibana

And Joi will correctly convert the valid JSON so that

config.get('some.boolean') === true

Copy link
Member

Choose a reason for hiding this comment

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

in practice I can't think of anything realistic, it's mostly how I operate. I'l defer on this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree with @spalger
In an option like elasticsearch.customHeaders, people want that the final value is exactly what they type. And value can contain some special characters like &.

@@ -19,6 +28,10 @@ export function merge(sources) {
return;
}

if (isString(val)) {
val = _replaceEnvVarRefs(val);
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like this line is mixing tabs and spaces. Also, would you mind just inlining the _replaceEnvVarRefs() function here or removing the leading _ from it's name?

@fbaligand
Copy link
Contributor Author

@spalger
You're right, there was a remaining tab, sorry for that, I thought that linting protects against this kind of mistake.
I removed the tab and removed the leading _ to replaceEnvVarRefs method.
Is it OK for you ?

Copy link
Contributor

@spalger spalger left a comment

Choose a reason for hiding this comment

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

LGTM

@fbaligand
Copy link
Contributor Author

fbaligand commented Apr 10, 2018

Hi @spalger @jbudz
I saw that the PR was in conflict with master => I rebased my code and migrated my test to the new test conventions.

=> Could you launch jenkins tests to check that everything is still OK ?

@jbudz
Copy link
Member

jbudz commented Apr 10, 2018

test it please

@elasticmachine
Copy link
Contributor

💚 Build Succeeded

@fbaligand
Copy link
Contributor Author

Jenkins build is OK => nice !

=> @tylersmalley, could you approve the PR ?

@tylersmalley
Copy link
Contributor

6.x/6.3: 6d70217

@tylersmalley
Copy link
Contributor

Thanks @fbaligand!

@fbaligand
Copy link
Contributor Author

Thanks @tylersmalley for the merge !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Team:Operations Team label for Operations Team v6.3.0 v7.0.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants