feat templater: Add ability to exclude resource sets

* renamed --limit to --include (-i)
* added --exclude (-e)

Kontemplate users can now explicitly include and exclude certain resource sets.
Excludes always override includes.

Closes #11
This commit is contained in:
Vincent Ambo 2017-02-08 16:44:55 +01:00
parent 11a5cf9e19
commit 8e08a282eb
2 changed files with 62 additions and 29 deletions

23
main.go
View file

@ -37,9 +37,10 @@ func templateCommand() cli.Command {
Usage: "Interpolate and print templates",
Flags: commonFlags(),
Action: func(c *cli.Context) error {
limit := c.StringSlice("limit")
include := c.StringSlice("include")
exclude := c.StringSlice("exclude")
ctx, err := loadContext(c)
resources, err := templater.LoadAndPrepareTemplates(&limit, ctx)
resources, err := templater.LoadAndPrepareTemplates(&include, &exclude, ctx)
if err != nil {
return err
@ -66,9 +67,10 @@ func applyCommand() cli.Command {
Destination: &dryRun,
}),
Action: func(c *cli.Context) error {
limit := c.StringSlice("limit")
include := c.StringSlice("include")
exclude := c.StringSlice("exclude")
ctx, err := loadContext(c)
resources, err := templater.LoadAndPrepareTemplates(&limit, ctx)
resources, err := templater.LoadAndPrepareTemplates(&include, &exclude, ctx)
if err != nil {
return err
@ -92,9 +94,10 @@ func replaceCommand() cli.Command {
Usage: "Interpolate templates and run 'kubectl replace'",
Flags: commonFlags(),
Action: func(c *cli.Context) error {
limit := c.StringSlice("limit")
include := c.StringSlice("include")
exclude := c.StringSlice("exclude")
ctx, err := loadContext(c)
resources, err := templater.LoadAndPrepareTemplates(&limit, ctx)
resources, err := templater.LoadAndPrepareTemplates(&include, &exclude, ctx)
if err != nil {
return err
@ -140,8 +143,12 @@ func commonFlags() []cli.Flag {
Usage: "Cluster configuration file to use",
},
cli.StringSliceFlag{
Name: "limit, l",
Usage: "Limit templating to certain resource sets",
Name: "include, i",
Usage: "Limit templating to explicitly included resource sets",
},
cli.StringSliceFlag{
Name: "exclude, e",
Usage: "Exclude certain resource sets from templating",
},
}
}

View file

@ -26,34 +26,20 @@ type TemplatingError struct {
meep.AllTraits
}
func LoadAndPrepareTemplates(limit *[]string, c *context.Context) (output []string, err error) {
for _, rs := range c.ResourceSets {
if resourceSetIncluded(limit, &rs.Name) {
err = processResourceSet(c, &rs, &output)
func LoadAndPrepareTemplates(include *[]string, exclude *[]string, c *context.Context) (output []string, err error) {
limitedResourceSets := applyLimits(&c.ResourceSets, include, exclude)
if err != nil {
return
}
for _, rs := range *limitedResourceSets {
err = processResourceSet(c, &rs, &output)
if err != nil {
return
}
}
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)
@ -125,6 +111,46 @@ func templateFile(c *context.Context, rs *context.ResourceSet, filename string)
return b.String(), nil
}
// Applies the limits of explicitly included or excluded resources and returns the updated resource set.
// Exclude takes priority over include
func applyLimits(rs *[]context.ResourceSet, include *[]string, exclude *[]string) *[]context.ResourceSet {
if len(*include) == 0 && len(*exclude) == 0 {
return rs
}
// Exclude excluded resource sets
excluded := make([]context.ResourceSet, 0)
for _, r := range *rs {
if !contains(exclude, &r.Name) {
excluded = append(excluded, r)
}
}
// Include included resource sets
if len(*include) == 0 {
return &excluded
}
included := make([]context.ResourceSet, 0)
for _, r := range excluded {
if contains(include, &r.Name) {
included = append(included, r)
}
}
return &included
}
// Check whether a certain string is contained in a string slice
func contains(s *[]string, v *string) bool {
for _, r := range *s {
if r == *v {
return true
}
}
return false
}
func templateFuncs() template.FuncMap {
m := sprig.TxtFuncMap()
m["json"] = func(data interface{}) string {