about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPhillip Johnsen <johphi@gmail.com>2018-05-30T19·43+0200
committerVincent Ambo <github@tazj.in>2018-06-09T17·16+0200
commit5cf9d53e80accaeede1b4e38772d7d53c0190549 (patch)
treed41b60612f1993387267c4c17085c67a18cabe4f
parent09869cf8fca09d3b1076e4ee558b8ca9fc91b733 (diff)
feat(context): allow explicit variables to be defined as argument
These changes allows variables to be defined when executing
`kontemplate` via one or more `--variable` arguments.

With this in place one can either define new variables or override
existing variables loaded from a file:

```
$ kontemplate apply --variable version=v1.0 example/fancy-app.yaml
```

This avoids the need to write variables into a temporary file that is
only needed to provide "external variables" into resource sets.

Closes https://github.com/tazjin/kontemplate/issues/122
-rw-r--r--context/context.go21
-rw-r--r--context/context_test.go22
-rw-r--r--main.go6
3 files changed, 49 insertions, 0 deletions
diff --git a/context/context.go b/context/context.go
index 9996f31faa5f..1a2e5c88cc09 100644
--- a/context/context.go
+++ b/context/context.go
@@ -12,6 +12,7 @@ package context
 import (
 	"fmt"
 	"path"
+	"strings"
 
 	"github.com/tazjin/kontemplate/util"
 )
@@ -158,3 +159,23 @@ func loadDefaultValues(rs *ResourceSet, c *Context) *map[string]interface{} {
 	// errors here.
 	return &rs.Values
 }
+
+// New variables can be defined or default values overridden with command line arguments when executing kontemplate.
+func (ctx *Context) SetVariablesFromArguments(vars *[]string) error {
+	// Resource set files might not have defined any global variables, if so we have to
+	// create that a map before potentially writing variables into it
+	if ctx.Global == nil {
+		ctx.Global = make(map[string]interface{}, len(*vars))
+	}
+
+	for _, v := range *vars {
+		varParts := strings.Split(v, "=")
+		if len(varParts) != 2 {
+			return fmt.Errorf(`invalid explicit variable provided (%s), name and value should be divided with "="`, v)
+		}
+
+		ctx.Global[varParts[0]] = varParts[1]
+	}
+
+	return nil
+}
diff --git a/context/context_test.go b/context/context_test.go
index 38b6a76e7aff..6dc27466a579 100644
--- a/context/context_test.go
+++ b/context/context_test.go
@@ -280,3 +280,25 @@ func TestExplicitSubresourcePathLoading(t *testing.T) {
 		t.Fail()
 	}
 }
+
+func TestSetVariablesFromArguments(t *testing.T) {
+	vars := []string{"version=some-service-version"}
+	ctx, _ := LoadContextFromFile("testdata/default-loading.yaml")
+
+	if err := ctx.SetVariablesFromArguments(&vars); err != nil {
+		t.Error(err)
+	}
+
+	if version := ctx.Global["version"]; version != "some-service-version" {
+		t.Errorf(`Expected variable "version" to have value "some-service-version" but was "%s"`, version)
+	}
+}
+
+func TestSetInvalidVariablesFromArguments(t *testing.T) {
+	vars := []string{"version: some-service-version"}
+	ctx, _ := LoadContextFromFile("testdata/default-loading.yaml")
+
+	if err := ctx.SetVariablesFromArguments(&vars); err == nil {
+		t.Error("Expected invalid variable to return an error")
+	}
+}
diff --git a/main.go b/main.go
index 13aabd248d2d..ee70bdae55a8 100644
--- a/main.go
+++ b/main.go
@@ -37,6 +37,7 @@ var (
 	// Global flags
 	includes = app.Flag("include", "Resource sets to include explicitly").Short('i').Strings()
 	excludes = app.Flag("exclude", "Resource sets to exclude explicitly").Short('e').Strings()
+	variables = app.Flag("var", "Provide variables to templates explicitly").Strings()
 
 	// Commands
 	template          = app.Command("template", "Template resource sets and print them")
@@ -188,6 +189,11 @@ func loadContextAndResources(file *string) (*context.Context, *[]templater.Rende
 		app.Fatalf("Error loading context: %v\n", err)
 	}
 
+	err = ctx.SetVariablesFromArguments(variables)
+	if err != nil {
+		app.Fatalf("Error setting explicit variables in context: %v\n", err)
+	}
+
 	resources, err := templater.LoadAndApplyTemplates(includes, excludes, ctx)
 	if err != nil {
 		app.Fatalf("Error templating resource sets: %v\n", err)