diff --git a/example/directory/index.html b/example/directory/index.html
new file mode 100644
index 0000000..21711b5
--- /dev/null
+++ b/example/directory/index.html
@@ -0,0 +1,2 @@
+
+
*
diff --git a/example/directory/nginx.$.yml b/example/directory/nginx.$.yml
new file mode 100644
index 0000000..07e3600
--- /dev/null
+++ b/example/directory/nginx.$.yml
@@ -0,0 +1,32 @@
+# kubetpl:syntax:$
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: $NAME
+data:
+ index.html: "$MESSAGE"
+---
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ name: $NAME
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: $NAME
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:1.7.9
+ ports:
+ - containerPort: 80
+ volumeMounts:
+ - name: $NAME-volume
+ mountPath: /usr/share/nginx/html
+ volumes:
+ - name: $NAME-volume
+ configMap:
+ name: $NAME
diff --git a/example/directory/nginx.go-template.yml b/example/directory/nginx.go-template.yml
new file mode 100644
index 0000000..a240593
--- /dev/null
+++ b/example/directory/nginx.go-template.yml
@@ -0,0 +1,32 @@
+# kubetpl:syntax:go-template
+
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ .NAME }}
+data:
+ index.html: {{ .MESSAGE | quote }}
+---
+apiVersion: apps/v1beta1
+kind: Deployment
+metadata:
+ name: {{ .NAME }}
+spec:
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ app: {{ .NAME }}
+ spec:
+ containers:
+ - name: nginx
+ image: nginx:1.7.9
+ ports:
+ - containerPort: 80
+ volumeMounts:
+ - name: {{ .NAME }}-volume
+ mountPath: /usr/share/nginx/html
+ volumes:
+ - name: {{ .NAME }}-volume
+ configMap:
+ name: {{ .NAME }}
diff --git a/kubetpl.go b/kubetpl.go
index 1392b5b..2321eb2 100644
--- a/kubetpl.go
+++ b/kubetpl.go
@@ -16,6 +16,7 @@ import (
"net/http"
"os"
"path/filepath"
+ "sort"
"strings"
)
@@ -270,7 +271,55 @@ type renderOpts struct {
ignoreUnset bool
}
+func expandDirectories(templateFiles []string, userSupplied bool) ([]string, error) {
+ var templates []string
+
+ extensions := sort.StringSlice{".yaml", ".yml", ".json"}
+ extensionCount := len(extensions)
+ sort.Strings(extensions)
+
+ for _, filename := range templateFiles {
+ fileInfo, err := os.Lstat(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ if !fileInfo.Mode().IsDir() {
+ ext := filepath.Ext(filename)
+ idx := extensions.Search(ext)
+ if userSupplied || idx < extensionCount && extensions[idx] == ext {
+ templates = append(templates, filename)
+ }
+ continue
+ }
+
+ subfiles, err := ioutil.ReadDir(filename)
+ if err != nil {
+ return nil, err
+ }
+
+ var files []string
+ for _, file := range subfiles {
+ full := filepath.Join(filename, file.Name())
+ files = append(files, full)
+ }
+
+ files, err = expandDirectories(files, false)
+ if err != nil {
+ return nil, err
+ }
+
+ templates = append(templates, files...)
+ }
+
+ return templates, nil
+}
+
func render(templateFiles []string, data map[string]interface{}, opts renderOpts) ([]byte, error) {
+ templateFiles, err := expandDirectories(templateFiles, true)
+ if err != nil {
+ return nil, err
+ }
objs, err := renderTemplates(templateFiles, data, opts)
if err != nil {
return nil, err
diff --git a/kubetpl_test.go b/kubetpl_test.go
index e287870..bf86045 100644
--- a/kubetpl_test.go
+++ b/kubetpl_test.go
@@ -36,6 +36,21 @@ func TestRender(t *testing.T) {
}
}
+func TestRenderDirectory(t *testing.T) {
+ cfg := map[string]interface{}{
+ "NAME": "nm",
+ "MESSAGE": "msg",
+ }
+ opts := renderOpts{}
+ renderedSh, err := render([]string{"example/directory"}, cfg, opts)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if len(renderedSh) == 0 {
+ t.Fatal("len(rendered) == 0")
+ }
+}
+
func TestRenderWithDataFromFile(t *testing.T) {
// todo: test secret ("data" must be base64-encoded)
src := []string{"example/nginx-with-data-from-file.yml"}