about summary refs log tree commit diff
path: root/context
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2017-04-04T12·28+0200
committerVincent Ambo <tazjin@gmail.com>2017-04-04T18·06+0200
commit11cfc80020010ff949de767698124cc5719361e0 (patch)
treec5db424c0b8b7574029d53b033b06e4baa029618 /context
parent4eadb588412af8f2028ed5a71037c45f7caff269 (diff)
feat context: Support resource set default values
This adds functionality to specify default values directly in resource sets.

The idea is that users can create a file called `values.yaml` or `values.json`
in a resource set's folder and have all variables specified in that file be
automatically merged into the resource set variables with the lowest priority.

This fixes #25
This fixes #30 (to a degree)
Diffstat (limited to 'context')
-rw-r--r--context/context.go46
-rw-r--r--context/context_test.go14
-rw-r--r--context/testdata/default-loading.yaml6
-rw-r--r--context/testdata/default/default.yaml2
4 files changed, 65 insertions, 3 deletions
diff --git a/context/context.go b/context/context.go
index 520070d88f..ad3d00693b 100644
--- a/context/context.go
+++ b/context/context.go
@@ -64,8 +64,9 @@ func LoadContextFromFile(filename string) (*Context, error) {
 		)
 	}
 
-	c.ResourceSets = *flattenResourceSetCollections(&c.ResourceSets)
+	c.ResourceSets = flattenResourceSetCollections(&c.ResourceSets)
 	c.BaseDir = path.Dir(filename)
+	c.ResourceSets = loadAllDefaultValues(&c)
 
 	return &c, nil
 }
@@ -73,7 +74,7 @@ func LoadContextFromFile(filename string) (*Context, error) {
 // 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.
-func flattenResourceSetCollections(rs *[]ResourceSet) *[]ResourceSet {
+func flattenResourceSetCollections(rs *[]ResourceSet) []ResourceSet {
 	flattened := make([]ResourceSet, 0)
 
 	for _, r := range *rs {
@@ -89,5 +90,44 @@ func flattenResourceSetCollections(rs *[]ResourceSet) *[]ResourceSet {
 		}
 	}
 
-	return &flattened
+	return flattened
+}
+
+func loadAllDefaultValues(c *Context) []ResourceSet {
+	updated := make([]ResourceSet, len(c.ResourceSets))
+
+	for i, rs := range c.ResourceSets {
+		merged := loadDefaultValues(&rs, c)
+		rs.Values = *merged
+		updated[i] = rs
+	}
+
+	return updated
+}
+
+// Loads and merges default values for a resource set collection from path/to/set/default.{json|yaml}.
+// YAML takes precedence over JSON.
+// Default values in resource set collections have the lowest priority possible.
+func loadDefaultValues(rs *ResourceSet, c *Context) *map[string]interface{} {
+	var defaultVars map[string]interface{}
+
+	// Attempt to load YAML values
+	y, err := ioutil.ReadFile(path.Join(c.BaseDir, rs.Name, "default.yaml"))
+	if err == nil {
+		yaml.Unmarshal(y, &defaultVars)
+		return util.Merge(&defaultVars, &rs.Values)
+	}
+
+	// Attempt to load JSON values
+	j, err := ioutil.ReadFile(path.Join(c.BaseDir, rs.Name, "default.json"))
+	if err == nil {
+		json.Unmarshal(j, &defaultVars)
+		return util.Merge(&defaultVars, &rs.Values)
+	}
+
+	// The actual error is not inspected here. The reasoning for this is that in case of serious problems (e.g.
+	// permission issues with the folder / folder not existing) failure will occur a bit later anyways.
+	// Otherwise we'd have to differentiate between file-not-found-errors (no default values specified) and other
+	// errors here.
+	return &rs.Values
 }
diff --git a/context/context_test.go b/context/context_test.go
index 4c95f058c0..8da30c9a89 100644
--- a/context/context_test.go
+++ b/context/context_test.go
@@ -140,3 +140,17 @@ func TestSubresourceVariableInheritanceOverride(t *testing.T) {
 		t.Fail()
 	}
 }
+
+func TestDefaultValuesLoading(t *testing.T) {
+	ctx, err := LoadContextFromFile("testdata/default-loading.yaml")
+	if err != nil {
+		t.Error(err)
+		t.Fail()
+	}
+
+	rs := ctx.ResourceSets[0]
+	if rs.Values["defaultValues"] != "loaded" {
+		t.Errorf("Default values not loaded from YAML file")
+		t.Fail()
+	}
+}
diff --git a/context/testdata/default-loading.yaml b/context/testdata/default-loading.yaml
new file mode 100644
index 0000000000..d589c99b4e
--- /dev/null
+++ b/context/testdata/default-loading.yaml
@@ -0,0 +1,6 @@
+---
+context: default-loading
+include:
+  - name: default
+    values:
+      override: notAtAll
\ No newline at end of file
diff --git a/context/testdata/default/default.yaml b/context/testdata/default/default.yaml
new file mode 100644
index 0000000000..0ffa3cd81f
--- /dev/null
+++ b/context/testdata/default/default.yaml
@@ -0,0 +1,2 @@
+defaultValues: loaded
+override: noop
\ No newline at end of file