From 9d26c17f13240479ef3e12e9182aca3ac2e61901 Mon Sep 17 00:00:00 2001 From: Vincent Ambo Date: Thu, 22 Jun 2017 17:01:36 +0200 Subject: [PATCH] feat context: Add ability to import extra variables from files Kontemplate context specifications can now load extra variables from YAML or JSON files by specifying a list of files (relative to the context file) under the `import` key. --- context/context.go | 34 +++++++++++++++-- context/context_test.go | 44 ++++++++++++++++++++++ context/testdata/import-vars-override.yaml | 9 +++++ context/testdata/import-vars-simple.yaml | 5 +++ context/testdata/test-vars-override.yaml | 3 ++ context/testdata/test-vars.yaml | 5 +++ 6 files changed, 96 insertions(+), 4 deletions(-) create mode 100644 context/testdata/import-vars-override.yaml create mode 100644 context/testdata/import-vars-simple.yaml create mode 100644 context/testdata/test-vars-override.yaml create mode 100644 context/testdata/test-vars.yaml diff --git a/context/context.go b/context/context.go index 0dde59055..c812af8b2 100644 --- a/context/context.go +++ b/context/context.go @@ -17,10 +17,11 @@ type ResourceSet struct { } type Context struct { - Name string `json:"context"` - Global map[string]interface{} `json:"global"` - ResourceSets []ResourceSet `json:"include"` - BaseDir string + Name string `json:"context"` + Global map[string]interface{} `json:"global"` + ResourceSets []ResourceSet `json:"include"` + VariableImports []string `json:"import"` + BaseDir string } type ContextLoadingError struct { @@ -44,9 +45,34 @@ func LoadContextFromFile(filename string) (*Context, error) { c.BaseDir = path.Dir(filename) c.ResourceSets = loadAllDefaultValues(&c) + err = c.loadImportedVariables() + if err != nil { + return nil, meep.New( + &ContextLoadingError{Filename: filename}, + meep.Cause(err), + ) + } + return &c, nil } +// Kontemplate supports specifying additional variable files with the `import` keyword. This function loads those +// variable files and merges them together with the context's other global variables. +func (ctx *Context) loadImportedVariables() error { + for _, file := range ctx.VariableImports { + var importedVars map[string]interface{} + err := util.LoadJsonOrYaml(path.Join(ctx.BaseDir, file), &importedVars) + + if err != nil { + return err + } + + ctx.Global = *util.Merge(&ctx.Global, &importedVars) + } + + return nil +} + // Flattens resource set collections, i.e. resource sets that themselves have an additional 'include' field set. // Those will be regarded as a short-hand for including multiple resource sets from a subfolder. // See https://github.com/tazjin/kontemplate/issues/9 for more information. diff --git a/context/context_test.go b/context/context_test.go index c5b5e7f12..b6acf416e 100644 --- a/context/context_test.go +++ b/context/context_test.go @@ -159,3 +159,47 @@ func TestDefaultValuesLoading(t *testing.T) { t.Fail() } } + +func TestImportValuesLoading(t *testing.T) { + ctx, err := LoadContextFromFile("testdata/import-vars-simple.yaml") + if err != nil { + t.Error(err) + t.Fail() + } + + expected := map[string]interface{}{ + "override": "true", + "music": map[string]interface{}{ + "artist": "Pallida", + "track": "Tractor Beam", + }, + } + + if !reflect.DeepEqual(ctx.Global, expected) { + t.Error("Expected global values after loading imports did not match!") + t.Fail() + } +} + +func TestImportValuesOverride(t *testing.T) { + ctx, err := LoadContextFromFile("testdata/import-vars-override.yaml") + if err != nil { + t.Error(err) + t.Fail() + } + + expected := map[string]interface{}{ + "override": float64(3), + "music": map[string]interface{}{ + "artist": "Pallida", + "track": "Tractor Beam", + }, + "place": "Oslo", + "globalVar": "very global!", + } + + if !reflect.DeepEqual(ctx.Global, expected) { + t.Error("Expected global values after loading imports did not match!") + t.Fail() + } +} diff --git a/context/testdata/import-vars-override.yaml b/context/testdata/import-vars-override.yaml new file mode 100644 index 000000000..c3d47bcfc --- /dev/null +++ b/context/testdata/import-vars-override.yaml @@ -0,0 +1,9 @@ +--- +context: k8s.prod.mydomain.com +global: + globalVar: very global! + override: 1 +import: + - test-vars.yaml + - test-vars-override.yaml +include: [] diff --git a/context/testdata/import-vars-simple.yaml b/context/testdata/import-vars-simple.yaml new file mode 100644 index 000000000..12244e1ab --- /dev/null +++ b/context/testdata/import-vars-simple.yaml @@ -0,0 +1,5 @@ +--- +context: k8s.prod.mydomain.com +import: + - test-vars.yaml +include: [] diff --git a/context/testdata/test-vars-override.yaml b/context/testdata/test-vars-override.yaml new file mode 100644 index 000000000..5215c559c --- /dev/null +++ b/context/testdata/test-vars-override.yaml @@ -0,0 +1,3 @@ +--- +override: 3 +place: Oslo diff --git a/context/testdata/test-vars.yaml b/context/testdata/test-vars.yaml new file mode 100644 index 000000000..af27bdc45 --- /dev/null +++ b/context/testdata/test-vars.yaml @@ -0,0 +1,5 @@ +--- +override: 'true' +music: + artist: Pallida + track: Tractor Beam