Expand env vars in Values/StringValues [#34]

This commit is contained in:
Erin Call 2020-01-21 15:37:59 -08:00
parent 713dcd8317
commit e843b26759
No known key found for this signature in database
GPG key ID: 4071FF6C15B8DAD1
3 changed files with 55 additions and 0 deletions

View file

@ -95,6 +95,26 @@ values_files: [ "./over_9,000.yml" ]
values_files: [ "./over_9", "000.yml" ]
```
### Interpolating secrets into the `values` and `string_values` settings
If you want to send secrets to your charts, you can use syntax similar to shell variable interpolation--either `$VARNAME` or `$${VARNAME}`. The double dollar-sign is necessary when using curly brackets; using curly brackets with a single dollar-sign will trigger Drone's string substitution (which can't use arbitrary environment variables). If an environment variable is not set, it will be treated as if it were set to the empty string.
```yaml
environment:
DB_PASSWORD:
from_secret: db_password
SESSION_KEY:
from_secret: session_key
settings:
values:
- db_password=$DB_PASSWORD # db_password will be set to the contents of the db_password secret
- db_pass=$DB_PASS # db_pass will be set to "" since $DB_PASS is not set
- session_key=$${SESSION_KEY} # session_key will be set to the contents of the session_key secret
- sess_key=${SESSION_KEY} # sess_key will be set to "" by Drone's variable substitution
```
Variables intended for interpolation must be set in the `environment` section, not `settings`.
### Backward-compatibility aliases
Some settings have alternate names, for backward-compatibility with drone-helm. We recommend using the canonical name unless you require the backward-compatible form.

View file

@ -93,11 +93,31 @@ func NewConfig(stdout, stderr io.Writer) (*Config, error) {
cfg.logDebug()
}
cfg.loadValuesSecrets()
cfg.deprecationWarn()
return &cfg, nil
}
func (cfg *Config) loadValuesSecrets() {
findVar := regexp.MustCompile(`\$\{?(\w+)\}?`)
replacer := func(varName string) string {
sigils := regexp.MustCompile(`[${}]`)
varName = sigils.ReplaceAllString(varName, "")
if value, ok := os.LookupEnv(varName); ok {
return value
}
return ""
}
cfg.Values = findVar.ReplaceAllStringFunc(cfg.Values, replacer)
cfg.StringValues = findVar.ReplaceAllStringFunc(cfg.StringValues, replacer)
}
func (cfg Config) logDebug() {
if cfg.KubeToken != "" {
cfg.KubeToken = "(redacted)"

View file

@ -183,6 +183,21 @@ func (suite *ConfigTestSuite) TestLogDebugCensorsKubeToken() {
suite.Equal(kubeToken, cfg.KubeToken) // The actual config value should be left unchanged
}
func (suite *ConfigTestSuite) TestNewConfigWithValuesSecrets() {
suite.unsetenv("VALUES")
suite.unsetenv("STRING_VALUES")
suite.setenv("SECRET_FIRE", "Eru_Ilúvatar")
suite.setenv("SECRET_RINGS", "1")
suite.setenv("PLUGIN_VALUES", "fire=$SECRET_FIRE,water=${SECRET_WATER}")
suite.setenv("PLUGIN_STRING_VALUES", "rings=${SECRET_RINGS}")
cfg, err := NewConfig(&strings.Builder{}, &strings.Builder{})
suite.Require().NoError(err)
suite.Equal("fire=Eru_Ilúvatar,water=", cfg.Values)
suite.Equal("rings=1", cfg.StringValues)
}
func (suite *ConfigTestSuite) setenv(key, val string) {
orig, ok := os.LookupEnv(key)
if ok {