about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2018-06-09T19·15+0200
committerVincent Ambo <github@tazj.in>2018-06-09T19·23+0200
commitc91cb21f70bbd4550bf216e64136816b42145392 (patch)
tree1c3a20c4a6f8fe748a085fa44de1df5a97349871
parent77ca5b47cf5d40fa53204633924e8ba30a517b3f (diff)
feat(templater): Support single-template resource sets
Supports resource sets in which the `path` is pointed at a single
template file.

The example has been updated with ... an example of this.

This closes #81.
-rw-r--r--example/other-config.yaml7
-rw-r--r--example/prod-cluster.yaml7
-rw-r--r--templater/templater.go64
3 files changed, 55 insertions, 23 deletions
diff --git a/example/other-config.yaml b/example/other-config.yaml
new file mode 100644
index 000000000000..87370569c46e
--- /dev/null
+++ b/example/other-config.yaml
@@ -0,0 +1,7 @@
+---
+apiVersion: extensions/v1beta1
+kind: ConfigMap
+metadata:
+  name: other-config
+data:
+  globalData: {{ .globalVar }}
diff --git a/example/prod-cluster.yaml b/example/prod-cluster.yaml
index dd7804f719c3..9f300a492080 100644
--- a/example/prod-cluster.yaml
+++ b/example/prod-cluster.yaml
@@ -3,8 +3,15 @@ context: k8s.prod.mydomain.com
 global:
   globalVar: lizards
 include:
+  # By default resource sets are included from a folder with the same
+  # name as the resource set's name
   - name: some-api
     values:
       version: 1.0-0e6884d
       importantFeature: true
       apiPort: 4567
+
+  # Paths can also be specified manually (and point at single template
+  # files!)
+  - name: other-config
+    path: other-config.yaml
diff --git a/templater/templater.go b/templater/templater.go
index 13ec9643eddd..192aac849804 100644
--- a/templater/templater.go
+++ b/templater/templater.go
@@ -58,43 +58,57 @@ func LoadAndApplyTemplates(include *[]string, exclude *[]string, c *context.Cont
 	return renderedResourceSets, nil
 }
 
-func processResourceSet(c *context.Context, rs *context.ResourceSet) (*RenderedResourceSet, error) {
+func processResourceSet(ctx *context.Context, rs *context.ResourceSet) (*RenderedResourceSet, error) {
 	fmt.Fprintf(os.Stderr, "Loading resources for %s\n", rs.Name)
 
-	rp := path.Join(c.BaseDir, rs.Path)
-
-	// Explicitly discard this error, which will give us an empty list of files instead.
-	// This will end up printing a warning to the user, but it won't stop the rest of the process.
-	files, _ := ioutil.ReadDir(rp)
-
-	resources, err := processFiles(c, rs, rp, files)
-
+	resourcePath := path.Join(ctx.BaseDir, rs.Path)
+	fileInfo, err := os.Stat(resourcePath)
 	if err != nil {
 		return nil, err
 	}
 
+	var files []os.FileInfo
+	var resources []RenderedResource
+
+	// Treat single-file resource paths separately from resource
+	// sets containing multiple templates
+	if fileInfo.IsDir() {
+		// Explicitly discard this error, which will give us an empty
+		// list of files instead.
+		// This will end up printing a warning to the user, but it
+		// won't stop the rest of the process.
+		files, _ = ioutil.ReadDir(resourcePath)
+		resources, err = processFiles(ctx, rs, files)
+		if err != nil {
+			return nil, err
+		}
+	} else {
+		resource, err := templateFile(ctx, rs, resourcePath)
+		if err != nil {
+			return nil, err
+		}
+
+		resources = []RenderedResource{resource}
+	}
+
 	return &RenderedResourceSet{
 		Name:      rs.Name,
 		Resources: resources,
 	}, nil
 }
 
-func processFiles(c *context.Context, rs *context.ResourceSet, rp string, files []os.FileInfo) ([]RenderedResource, error) {
+func processFiles(ctx *context.Context, rs *context.ResourceSet, files []os.FileInfo) ([]RenderedResource, error) {
 	resources := make([]RenderedResource, 0)
 
 	for _, file := range files {
 		if !file.IsDir() && isResourceFile(file) {
-			p := path.Join(rp, file.Name())
-			o, err := templateFile(c, rs, p)
+			path := path.Join(ctx.BaseDir, rs.Path, file.Name())
+			res, err := templateFile(ctx, rs, path)
 
 			if err != nil {
 				return resources, err
 			}
 
-			res := RenderedResource{
-				Filename: file.Name(),
-				Rendered: o,
-			}
 			resources = append(resources, res)
 		}
 	}
@@ -102,22 +116,26 @@ func processFiles(c *context.Context, rs *context.ResourceSet, rp string, files
 	return resources, nil
 }
 
-func templateFile(c *context.Context, rs *context.ResourceSet, filename string) (string, error) {
-	tpl, err := template.New(path.Base(filename)).Funcs(templateFuncs(c, rs)).Option(failOnMissingKeys).ParseFiles(filename)
+func templateFile(ctx *context.Context, rs *context.ResourceSet, filepath string) (RenderedResource, error) {
+	var resource RenderedResource
 
+	tpl, err := template.New(path.Base(filepath)).Funcs(templateFuncs(ctx, rs)).Option(failOnMissingKeys).ParseFiles(filepath)
 	if err != nil {
-		return "", fmt.Errorf("Template %s not found: %v", filename, err)
+		return resource, fmt.Errorf("Could not load template %s: %v", filepath, err)
 	}
 
 	var b bytes.Buffer
-
 	err = tpl.Execute(&b, rs.Values)
-
 	if err != nil {
-		return "", fmt.Errorf("Error while templating %s: %v", filename, err)
+		return resource, fmt.Errorf("Error while templating %s: %v", filepath, err)
+	}
+
+	resource = RenderedResource{
+		Filename: path.Base(filepath),
+		Rendered: b.String(),
 	}
 
-	return b.String(), nil
+	return resource, nil
 }
 
 // Applies the limits of explicitly included or excluded resources and returns the updated resource set.