Fix and test multi-env-template loading

This commit is contained in:
Michael Schurter
2017-05-25 17:13:33 -07:00
parent 572ca97967
commit be959a4e63
2 changed files with 114 additions and 29 deletions

View File

@@ -196,12 +196,12 @@ WAIT:
}
// Read environment variables from env templates
for _, t := range tm.templates {
if err := loadTemplateEnv(envBuilder, taskDir, t); err != nil {
tm.hook.Kill("consul-template", err.Error(), true)
return
}
envMap, err := loadTemplateEnv(tm.templates, taskDir)
if err != nil {
tm.hook.Kill("consul-template", err.Error(), true)
return
}
envBuilder.SetTemplateEnv(envMap)
allRenderedTime = time.Now()
tm.hook.UnblockStart("consul-template")
@@ -253,13 +253,15 @@ WAIT:
return
}
for _, tmpl := range tmpls {
// Read environment variables from templates
if err := loadTemplateEnv(envBuilder, taskDir, tmpl); err != nil {
tm.hook.Kill("consul-template", err.Error(), true)
return
}
// Read environment variables from templates
envMap, err := loadTemplateEnv(tmpls, taskDir)
if err != nil {
tm.hook.Kill("consul-template", err.Error(), true)
return
}
envBuilder.SetTemplateEnv(envMap)
for _, tmpl := range tmpls {
switch tmpl.ChangeMode {
case structs.TemplateChangeModeSignal:
signals[tmpl.ChangeSignal] = struct{}{}
@@ -508,26 +510,29 @@ func runnerConfig(config *config.Config, vaultToken string) (*ctconf.Config, err
return conf, nil
}
// loadTemplateEnv loads task environment variables from templates.
func loadTemplateEnv(builder *env.Builder, taskDir string, t *structs.Template) error {
if !t.Envvars {
return nil
}
f, err := os.Open(filepath.Join(taskDir, t.DestPath))
if err != nil {
return fmt.Errorf("error opening env template: %v", err)
}
defer f.Close()
// loadTemplateEnv loads task environment variables from all templates.
func loadTemplateEnv(tmpls []*structs.Template, taskDir string) (map[string]string, error) {
all := make(map[string]string, 50)
for _, t := range tmpls {
if !t.Envvars {
continue
}
f, err := os.Open(filepath.Join(taskDir, t.DestPath))
if err != nil {
return nil, fmt.Errorf("error opening env template: %v", err)
}
defer f.Close()
// Parse environment fil
vars, err := parseEnvFile(f)
if err != nil {
return fmt.Errorf("error parsing env template %q: %v", t.DestPath, err)
// Parse environment fil
vars, err := parseEnvFile(f)
if err != nil {
return nil, fmt.Errorf("error parsing env template %q: %v", t.DestPath, err)
}
for k, v := range vars {
all[k] = v
}
}
// Set the environment variables
builder.SetTemplateEnv(vars)
return nil
return all, nil
}
// parseEnvFile and return a map of the environment variables suitable for

View File

@@ -953,3 +953,83 @@ ANYTHING-goes=Spaces are=ok!
t.Errorf("expected ANYTHING_GOES='Spaces are ok!' but found %q", env["ANYTHING_goes"])
}
}
// TestTaskTemplateManager_Env_Missing asserts the core env
// template processing function returns errors when files don't exist
func TestTaskTemplateManager_Env_Missing(t *testing.T) {
d, err := ioutil.TempDir("", "ct_env_missing")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(d)
// Fake writing the file so we don't have to run the whole template manager
err = ioutil.WriteFile(filepath.Join(d, "exists.env"), []byte("FOO=bar\n"), 0644)
if err != nil {
t.Fatalf("error writing template file: %v", err)
}
templates := []*structs.Template{
{
EmbeddedTmpl: "FOO=bar\n",
DestPath: "exists.env",
Envvars: true,
},
{
EmbeddedTmpl: "WHAT=ever\n",
DestPath: "missing.env",
Envvars: true,
},
}
if vars, err := loadTemplateEnv(templates, d); err == nil {
t.Fatalf("expected an error but instead got env vars: %#v", vars)
}
}
// TestTaskTemplateManager_Env_Multi asserts the core env
// template processing function returns combined env vars from multiple
// templates correctly.
func TestTaskTemplateManager_Env_Multi(t *testing.T) {
d, err := ioutil.TempDir("", "ct_env_missing")
if err != nil {
t.Fatalf("err: %v", err)
}
defer os.RemoveAll(d)
// Fake writing the files so we don't have to run the whole template manager
err = ioutil.WriteFile(filepath.Join(d, "zzz.env"), []byte("FOO=bar\nSHARED=nope\n"), 0644)
if err != nil {
t.Fatalf("error writing template file 1: %v", err)
}
err = ioutil.WriteFile(filepath.Join(d, "aaa.env"), []byte("BAR=foo\nSHARED=yup\n"), 0644)
if err != nil {
t.Fatalf("error writing template file 2: %v", err)
}
// Templates will get loaded in order (not alpha sorted)
templates := []*structs.Template{
{
DestPath: "zzz.env",
Envvars: true,
},
{
DestPath: "aaa.env",
Envvars: true,
},
}
vars, err := loadTemplateEnv(templates, d)
if err != nil {
t.Fatalf("expected an error but instead got env vars: %#v", vars)
}
if vars["FOO"] != "bar" {
t.Error("expected FOO=bar but found %q", vars["FOO"])
}
if vars["BAR"] != "foo" {
t.Error("expected BAR=foo but found %q", vars["BAR"])
}
if vars["SHARED"] != "yup" {
t.Error("expected FOO=bar but found %q", vars["yup"])
}
}