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`.
This commit is contained in:
		
							parent
							
								
									25f2a1616c
								
							
						
					
					
						commit
						bc9fc9730d
					
				
					 1 changed files with 96 additions and 32 deletions
				
			
		
							
								
								
									
										128
									
								
								main.go
									
										
									
									
									
								
							
							
						
						
									
										128
									
								
								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,46 +23,20 @@ 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", | ||||
| 					}, | ||||
| 				) | ||||
| 			} | ||||
| 
 | ||||
| 			ctx, err := context.LoadContextFromFile(f) | ||||
| 
 | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			resources, err := templater.LoadAndPrepareTemplates(&limit, ctx) | ||||
| 			resources, err := templateResources(c) | ||||
| 
 | ||||
| 			if err != nil { | ||||
| 				return err | ||||
|  | @ -71,3 +50,88 @@ func ApplyCommand() cli.Command { | |||
| 		}, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| 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 | ||||
| 			} | ||||
| 
 | ||||
| 			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 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.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) | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue