2017-02-08 11:50:49 +01:00
|
|
|
package templater
|
|
|
|
|
|
|
|
import (
|
2017-02-08 11:55:59 +01:00
|
|
|
"bytes"
|
2017-02-08 11:50:49 +01:00
|
|
|
"fmt"
|
|
|
|
"io/ioutil"
|
|
|
|
"os"
|
|
|
|
"path"
|
2017-02-08 11:55:59 +01:00
|
|
|
"strings"
|
2017-02-08 11:50:49 +01:00
|
|
|
"text/template"
|
|
|
|
|
|
|
|
"github.com/polydawn/meep"
|
2017-02-08 11:55:59 +01:00
|
|
|
"github.com/tazjin/kontemplate/context"
|
2017-02-08 11:50:49 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
// Error that is caused by non-existent template files being specified
|
|
|
|
type TemplateNotFoundError struct {
|
|
|
|
meep.AllTraits
|
|
|
|
Name string
|
|
|
|
}
|
|
|
|
|
|
|
|
// Error that is caused during templating, e.g. required value being absent or invalid template format
|
|
|
|
type TemplatingError struct {
|
|
|
|
meep.AllTraits
|
|
|
|
}
|
|
|
|
|
2017-02-08 12:58:53 +01:00
|
|
|
func LoadAndPrepareTemplates(limit *[]string, c *context.Context) (output []string, err error) {
|
2017-02-08 11:50:49 +01:00
|
|
|
for _, rs := range c.ResourceSets {
|
2017-02-08 12:58:53 +01:00
|
|
|
if resourceSetIncluded(limit, &rs.Name) {
|
|
|
|
err = processResourceSet(c, &rs, &output)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-02-08 11:50:49 +01:00
|
|
|
|
2017-02-08 12:58:53 +01:00
|
|
|
return
|
|
|
|
}
|
2017-02-08 11:50:49 +01:00
|
|
|
|
2017-02-08 12:58:53 +01:00
|
|
|
func resourceSetIncluded(limit *[]string, resourceSetName *string) bool {
|
|
|
|
if len(*limit) == 0 {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, name := range *limit {
|
|
|
|
if name == *resourceSetName {
|
|
|
|
return true
|
2017-02-08 11:50:49 +01:00
|
|
|
}
|
2017-02-08 12:58:53 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|
2017-02-08 11:50:49 +01:00
|
|
|
|
2017-02-08 12:58:53 +01:00
|
|
|
func processResourceSet(c *context.Context, rs *context.ResourceSet, output *[]string) error {
|
|
|
|
fmt.Fprintf(os.Stderr, "Loading resources for %s\n", rs.Name)
|
2017-02-08 11:50:49 +01:00
|
|
|
|
2017-02-08 12:58:53 +01:00
|
|
|
rp := path.Join(c.BaseDir, rs.Name)
|
|
|
|
files, err := ioutil.ReadDir(rp)
|
2017-02-08 11:50:49 +01:00
|
|
|
|
2017-02-08 12:58:53 +01:00
|
|
|
err = processFiles(c, rs, rp, files, output)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return meep.New(
|
|
|
|
&TemplateNotFoundError{Name: rs.Name},
|
|
|
|
meep.Cause(err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func processFiles(c *context.Context, rs *context.ResourceSet, rp string, files []os.FileInfo, output *[]string) error {
|
|
|
|
for _, file := range files {
|
|
|
|
if !file.IsDir() && isResourceFile(file) {
|
|
|
|
p := path.Join(rp, file.Name())
|
|
|
|
o, err := templateFile(c, rs, p)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2017-02-08 11:50:49 +01:00
|
|
|
}
|
2017-02-08 12:58:53 +01:00
|
|
|
|
|
|
|
*output = append(*output, o)
|
2017-02-08 11:50:49 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-08 12:58:53 +01:00
|
|
|
return nil
|
2017-02-08 11:50:49 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
func templateFile(c *context.Context, rs *context.ResourceSet, filename string) (string, error) {
|
|
|
|
tpl, err := template.ParseFiles(filename)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", meep.New(
|
|
|
|
&TemplateNotFoundError{Name: filename},
|
|
|
|
meep.Cause(err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
var b bytes.Buffer
|
|
|
|
|
|
|
|
// Merge global and resourceset-specific values (don't override from global)
|
|
|
|
for k, v := range c.Global {
|
|
|
|
if _, ok := rs.Values[k]; !ok {
|
|
|
|
rs.Values[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
err = tpl.Execute(&b, rs.Values)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
return "", meep.New(
|
|
|
|
&TemplatingError{},
|
|
|
|
meep.Cause(err),
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
return b.String(), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Checks whether a file is a resource file (i.e. is YAML or JSON)
|
|
|
|
func isResourceFile(f os.FileInfo) bool {
|
|
|
|
return strings.HasSuffix(f.Name(), "yaml") ||
|
|
|
|
strings.HasSuffix(f.Name(), "yml") ||
|
|
|
|
strings.HasSuffix(f.Name(), "json")
|
|
|
|
}
|