diff options
author | Vincent Ambo <tazjin@gmail.com> | 2017-02-08T14·32+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@gmail.com> | 2017-02-08T14·42+0100 |
commit | bc9fc9730dd30e2d302ce5f88cd93da9604eb6f0 (patch) | |
tree | e93d157b82e7b64833c302fe8fdbbaef1c04d091 | |
parent | 25f2a1616caf2a05199370998223f4a64bb55f81 (diff) |
feat main: Add apply command
This integrates support for actually calling out to `kubectl apply`. A dry-run flag is implemented, too. The `run` command has been renamed to `template`.
-rw-r--r-- | main.go | 118 |
1 files changed, 91 insertions, 27 deletions
diff --git a/main.go b/main.go index de734e8ac37d..c39972ff6010 100644 --- a/main.go +++ b/main.go @@ -3,6 +3,7 @@ package main import ( "fmt" "os" + "os/exec" "github.com/polydawn/meep" "github.com/tazjin/kontemplate/context" @@ -10,6 +11,10 @@ import ( "github.com/urfave/cli" ) +type KubeCtlError struct { + meep.AllTraits +} + func main() { app := cli.NewApp() @@ -18,56 +23,115 @@ func main() { app.Version = "0.0.1" app.Commands = []cli.Command{ - ApplyCommand(), + templateCommand(), + applyCommand(), } app.Run(os.Args) } -func ApplyCommand() cli.Command { +func templateCommand() cli.Command { return cli.Command{ - Name: "run", + Name: "template", 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", - }, - }, + Flags: commonFlags(), 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", - }, - ) + resources, err := templateResources(c) + + if err != nil { + return err } - ctx, err := context.LoadContextFromFile(f) + for _, r := range resources { + fmt.Println(r) + } + + return nil + }, + } +} + +func applyCommand() cli.Command { + dryRun := false + + return cli.Command{ + Name: "apply", + Usage: "Interpolate templates and run 'kubectl apply'", + Flags: append(commonFlags(), cli.BoolFlag{ + Name: "dry-run", + Usage: "Only print objects that would be sent, without sending them", + Destination: &dryRun, + }), + Action: func(c *cli.Context) error { + resources, err := templateResources(c) if err != nil { return err } - resources, err := templater.LoadAndPrepareTemplates(&limit, ctx) + var kubectl *exec.Cmd + if dryRun { + kubectl = exec.Command("kubectl", "apply", "-f", "-", "--dry-run") + } else { + kubectl = exec.Command("kubectl", "apply", "-f", "-") + } + stdin, err := kubectl.StdinPipe() if err != nil { - return err + return meep.New(&KubeCtlError{}, meep.Cause(err)) + } + + kubectl.Stdout = os.Stdout + kubectl.Stderr = os.Stderr + + if err = kubectl.Start(); err != nil { + return meep.New(&KubeCtlError{}, meep.Cause(err)) } for _, r := range resources { - fmt.Println(r) + fmt.Fprintln(stdin, r) } + stdin.Close() + + kubectl.Wait() + return nil }, } } + +func commonFlags() []cli.Flag { + return []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", + }, + } +} + +func templateResources(c *cli.Context) ([]string, error) { + limit := c.StringSlice("limit") + f := c.String("file") + + if f == "" { + return nil, meep.New( + &meep.ErrInvalidParam{ + Param: "file", + Reason: "Cluster config file must be specified", + }, + ) + } + + ctx, err := context.LoadContextFromFile(f) + + if err != nil { + return nil, err + } + + return templater.LoadAndPrepareTemplates(&limit, ctx) +} |