Merge pull request #7 from tazjin/feat/travis

Enable Travis.CI builds
This commit is contained in:
Vincent Ambo 2017-02-08 13:04:18 +01:00 committed by GitHub
commit c58ce7e2ab
5 changed files with 113 additions and 45 deletions

1
.travis.yml Normal file
View file

@ -0,0 +1 @@
language: go

View file

@ -1,6 +1,8 @@
KonTemplate - A simple Kubernetes templater
===========================================
[![Build Status](https://travis-ci.org/tazjin/kontemplate.svg?branch=master)](https://travis-ci.org/tazjin/kontemplate)
I made this tool out of frustration with the available ways to template Kubernetes resource files. All I want out of
such a tool is a way to specify lots of resources with placeholders that get filled in with specific values, based on
which context (i.e. k8s cluster) is specified.

View file

@ -2,9 +2,10 @@ package context
import (
"encoding/json"
"github.com/polydawn/meep"
"io/ioutil"
"path"
"github.com/polydawn/meep"
)
type ResourceSet struct {

72
main.go
View file

@ -4,36 +4,70 @@ import (
"fmt"
"os"
"github.com/polydawn/meep"
"github.com/tazjin/kontemplate/context"
"github.com/tazjin/kontemplate/templater"
"github.com/urfave/cli"
)
func main() {
args := os.Args[1:]
if len(args) == 0 {
fmt.Fprintln(os.Stderr, "Usage: kontemplate <cluster-config>")
os.Exit(1)
app := cli.NewApp()
app.Name = "kontemplate"
app.Usage = "simple Kubernetes resource templating"
app.Version = "0.0.1"
app.Commands = []cli.Command{
ApplyCommand(),
}
c, err := context.LoadContextFromFile(os.Args[1])
app.Run(os.Args)
}
if err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
func ApplyCommand() cli.Command {
return cli.Command{
Name: "run",
Usage: "Interpolate and print templates",
Flags: []cli.Flag{
cli.StringFlag{
Name: "file, f",
Usage: "Cluster configuration file to use",
},
cli.StringSliceFlag{
Name: "limit, l",
Usage: "Limit templating to certain resource sets",
},
},
Action: func(c *cli.Context) error {
limit := c.StringSlice("limit")
f := c.String("file")
fmt.Fprintf(os.Stderr, "Applying cluster %s\n", c.Name)
if f == "" {
return meep.New(
&meep.ErrInvalidParam{
Param: "file",
Reason: "Cluster config file must be specified",
},
)
}
for _, rs := range c.ResourceSets {
fmt.Fprintf(os.Stderr, "Applying resource %s with values %v\n", rs.Name, rs.Values)
resources, err := templater.LoadAndPrepareTemplates(c)
ctx, err := context.LoadContextFromFile(f)
if err != nil {
fmt.Println(err)
}
if err != nil {
return err
}
for _, r := range resources {
fmt.Print(r)
}
resources, err := templater.LoadAndPrepareTemplates(&limit, ctx)
if err != nil {
return err
}
for _, r := range resources {
fmt.Println(r)
}
return nil
},
}
}

View file

@ -24,37 +24,67 @@ type TemplatingError struct {
meep.AllTraits
}
func LoadAndPrepareTemplates(c *context.Context) ([]string, error) {
output := make([]string, 0)
func LoadAndPrepareTemplates(limit *[]string, c *context.Context) (output []string, err error) {
for _, rs := range c.ResourceSets {
fmt.Fprintf(os.Stderr, "Loading resources for %s\n", rs.Name)
if resourceSetIncluded(limit, &rs.Name) {
err = processResourceSet(c, &rs, &output)
rp := path.Join(c.BaseDir, rs.Name)
files, err := ioutil.ReadDir(rp)
if err != nil {
return nil, meep.New(
&TemplateNotFoundError{Name: rs.Name},
meep.Cause(err),
)
}
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 nil, err
}
output = append(output, o)
if err != nil {
return
}
}
}
return output, nil
return
}
func resourceSetIncluded(limit *[]string, resourceSetName *string) bool {
if len(*limit) == 0 {
return true
}
for _, name := range *limit {
if name == *resourceSetName {
return true
}
}
return false
}
func processResourceSet(c *context.Context, rs *context.ResourceSet, output *[]string) error {
fmt.Fprintf(os.Stderr, "Loading resources for %s\n", rs.Name)
rp := path.Join(c.BaseDir, rs.Name)
files, err := ioutil.ReadDir(rp)
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
}
*output = append(*output, o)
}
}
return nil
}
func templateFile(c *context.Context, rs *context.ResourceSet, filename string) (string, error) {