about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVincent Ambo <tazjin@gmail.com>2017-02-08T15·44+0100
committerVincent Ambo <tazjin@gmail.com>2017-02-08T15·53+0100
commit8e08a282eb4f29618c8de8090927b521ea0c9c2b (patch)
tree7a2731061681c8ddfc22a6d3af0255e8a33d12aa
parent11a5cf9e192b57eb594ce276ef7723693ff28014 (diff)
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
-rw-r--r--main.go23
-rw-r--r--templater/templater.go68
2 files changed, 62 insertions, 29 deletions
diff --git a/main.go b/main.go
index 1a775bf7c5fc..f6e4921435e9 100644
--- a/main.go
+++ b/main.go
@@ -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",
 		},
 	}
 }
diff --git a/templater/templater.go b/templater/templater.go
index 6e443c14bb07..bb65cd1df058 100644
--- a/templater/templater.go
+++ b/templater/templater.go
@@ -26,32 +26,18 @@ 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)
 
-	return
-}
-
-func resourceSetIncluded(limit *[]string, resourceSetName *string) bool {
-	if len(*limit) == 0 {
-		return true
-	}
-
-	for _, name := range *limit {
-		if name == *resourceSetName {
-			return true
+		if err != nil {
+			return
 		}
 	}
 
-	return false
+	return
 }
 
 func processResourceSet(c *context.Context, rs *context.ResourceSet, output *[]string) error {
@@ -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 {