diff options
author | Vincent Ambo <tazjin@gmail.com> | 2017-02-08T11·58+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@gmail.com> | 2017-02-08T11·58+0100 |
commit | 7ac63613fb64c6cec3119afc51ba4bac91b81a94 (patch) | |
tree | 58927d534621fe94ea882628df372de7901007a5 | |
parent | 8fac7c1a415d6ea5e41c28f4e7ab5c1ef0883997 (diff) |
feat main: Add proper CLI support
Adds a basic CLI structure with a single "run" command that takes a --file (-f) and --limit (-l) flag. --limit can be used to only output certain resource sets. Closes #4
-rw-r--r-- | context/context.go | 3 | ||||
-rw-r--r-- | main.go | 72 | ||||
-rw-r--r-- | templater/templater.go | 70 |
3 files changed, 105 insertions, 40 deletions
diff --git a/context/context.go b/context/context.go index e842feae1dc5..612faa39acab 100644 --- a/context/context.go +++ b/context/context.go @@ -2,9 +2,10 @@ package context import ( "encoding/json" - "github.com/polydawn/meep" "io/ioutil" "path" + + "github.com/polydawn/meep" ) type ResourceSet struct { diff --git a/main.go b/main.go index 158c9a566a86..de734e8ac37d 100644 --- a/main.go +++ b/main.go @@ -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() - c, err := context.LoadContextFromFile(os.Args[1]) + app.Name = "kontemplate" + app.Usage = "simple Kubernetes resource templating" + app.Version = "0.0.1" - if err != nil { - fmt.Fprintf(os.Stderr, "%v\n", err) - os.Exit(1) + app.Commands = []cli.Command{ + ApplyCommand(), } - fmt.Fprintf(os.Stderr, "Applying cluster %s\n", c.Name) + app.Run(os.Args) +} + +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") + + if f == "" { + return meep.New( + &meep.ErrInvalidParam{ + Param: "file", + Reason: "Cluster config file must be specified", + }, + ) + } + + ctx, err := context.LoadContextFromFile(f) + + if err != nil { + return err + } + + resources, err := templater.LoadAndPrepareTemplates(&limit, ctx) - 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) + if err != nil { + return err + } - if err != nil { - fmt.Println(err) - } + for _, r := range resources { + fmt.Println(r) + } - for _, r := range resources { - fmt.Print(r) - } + return nil + }, } } diff --git a/templater/templater.go b/templater/templater.go index 27beff371e5c..a2c860c60d3d 100644 --- a/templater/templater.go +++ b/templater/templater.go @@ -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) + + if err != nil { + return + } + } + } - rp := path.Join(c.BaseDir, rs.Name) - files, err := ioutil.ReadDir(rp) + return +} - if err != nil { - return nil, meep.New( - &TemplateNotFoundError{Name: rs.Name}, - meep.Cause(err), - ) +func resourceSetIncluded(limit *[]string, resourceSetName *string) bool { + if len(*limit) == 0 { + return true + } + + for _, name := range *limit { + if name == *resourceSetName { + return true } + } + + return false +} - for _, file := range files { - if !file.IsDir() && isResourceFile(file) { - p := path.Join(rp, file.Name()) - o, err := templateFile(c, &rs, p) +func processResourceSet(c *context.Context, rs *context.ResourceSet, output *[]string) error { + fmt.Fprintf(os.Stderr, "Loading resources for %s\n", rs.Name) - if err != nil { - return nil, err - } + rp := path.Join(c.BaseDir, rs.Name) + files, err := ioutil.ReadDir(rp) - output = append(output, o) + 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 output, nil + return nil } func templateFile(c *context.Context, rs *context.ResourceSet, filename string) (string, error) { |