Skip to content

Commit

Permalink
template: add filter, ignore and join string helpers
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Yastrebov <alexander.yastrebov@zalando.de>
  • Loading branch information
AlexanderYastrebov committed Oct 18, 2022
1 parent 2b9f3b9 commit 79912f9
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 1 deletion.
40 changes: 40 additions & 0 deletions provisioner/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net"
"net/url"
"path"
"regexp"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -107,6 +108,9 @@ func renderTemplate(context *templateContext, file string) (string, error) {
"azID": azID,
"azCount": azCount,
"split": split,
"join": join,
"filter": filter,
"ignore": ignore,
"mountUnitName": mountUnitName,
"accountID": accountID,
"portRanges": portRanges,
Expand Down Expand Up @@ -274,6 +278,42 @@ func split(s string, d string) []string {
return strings.Split(s, d)
}

// join is a template function that returns a single string of slice elements joined with a separator.
func join(sep string, elems []string) string {
// arguments in reverse order to enable piped calls
return strings.Join(elems, sep)
}

// filter is a template function that takes a regexp, a slice of strings and returns the slice of matching elements.
func filter(pattern string, elems []string) ([]string, error) {
var result []string
for _, e := range elems {
matched, err := regexp.MatchString(pattern, e)
if err != nil {
return nil, err
}
if matched {
result = append(result, e)
}
}
return result, nil
}

// ignore is a template function that takes a regexp, a slice of strings and returns the slice of non-matching elements.
func ignore(pattern string, elems []string) ([]string, error) {
var result []string
for _, e := range elems {
matched, err := regexp.MatchString(pattern, e)
if err != nil {
return nil, err
}
if !matched {
result = append(result, e)
}
}
return result, nil
}

// accountID returns just the ID part of an account
func accountID(account string) (string, error) {
items := strings.Split(account, ":")
Expand Down
39 changes: 38 additions & 1 deletion provisioner/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -943,7 +943,7 @@ CWeOoA==
require.Equal(t, "2022-06-10T10:06:43Z", res)
}

func TestSubQuantity(t *testing.T) {
func TestSumQuantities(t *testing.T) {
for _, tc := range []struct {
name string
template string
Expand Down Expand Up @@ -998,3 +998,40 @@ func TestAWSValidID(t *testing.T) {
require.NoError(t, err)
require.Equal(t, "aws__12345678910__eu-central-1__kube-1", result)
}

func TestJoinFilterIgnore(t *testing.T) {
for _, tc := range []struct {
name string
template string
data interface{}
expected string
}{
{
name: "filter",
template: `{{ split "k8s.io/foo,zalando.org/bar,k8s.io/baz,zalando.org/qux" "," | filter "^zalando[.]org" | join "," }}`,
expected: "zalando.org/bar,zalando.org/qux",
},
{
name: "lines to comma-separated double-quoted list",
template: `{{ split .Values.data.lines "\n" | ignore "^#" | ignore "^\\s*$" | join "\", \"" | printf "\"%s\"" }}`,
data: map[string]interface{}{
"lines": `
# comments like this are ignored
foo
bar
# empty line above and white spaces below are also ignored
baz
`,
},
expected: `"foo", "bar", "baz"`,
},
} {
t.Run(tc.name, func(t *testing.T) {
res, err := renderSingle(t, tc.template, tc.data)
require.NoError(t, err)
require.Equal(t, tc.expected, res)
})
}
}

0 comments on commit 79912f9

Please sign in to comment.