Skip to content

Commit

Permalink
add sprig template functions
Browse files Browse the repository at this point in the history
fixes prometheus#3726
fixes prometheus#3762
fixes prometheus#603

Signed-off-by: Christoph Maser <christoph.maser+github@gmail.com>
  • Loading branch information
TheMeier committed Mar 24, 2024
1 parent 14cbe63 commit 189905b
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 5 deletions.
26 changes: 23 additions & 3 deletions docs/notifications.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,8 @@ In addition to direct access of data (labels and annotations) stored as KV, ther

# Functions

Note the [default
functions](http://golang.org/pkg/text/template/#hdr-Functions) also provided by Go
templating.
For templating the [default functions](http://golang.org/pkg/text/template/#hdr-Functions) are provided by Go
templating and the following custom functions.

## Strings

Expand All @@ -95,3 +94,24 @@ templating.
| join | sep string, s []string | [strings.Join](http://golang.org/pkg/strings/#Join), concatenates the elements of s to create a single string. The separator string sep is placed between elements in the resulting string. (note: argument order inverted for easier pipelining in templates.) |
| safeHtml | text string | [html/template.HTML](https://golang.org/pkg/html/template/#HTML), Marks string as HTML not requiring auto-escaping. |
| stringSlice | ...string | Returns the passed strings as a slice of strings. |

Additionally a selection of functions provided by the [sprig library](https://masterminds.github.io/sprig/) is available.
The selection list of theses functinons is the following:

```text
"ago", "date", "dateInZone", "dateModify", "duration", "durationRound", "htmlDate", "htmlDateInZone", "toDate",
"unixEpoch", "abbrev", "abbrevboth", "trunc", "untitle", "substr", "repeat", "trimAll", "trimSuffix", "trimPrefix", "nospace",
"initials", "randAlphaNum", "randAlpha", "randAscii", "randNumeric", "swapcase", "shuffle", "snakecase", "camelcase",
"kebabcase", "wrap", "wrapWith", "contains", "hasPrefix", "hasSuffix", "quote", "squote", "cat", "indent", "nindent",
"replace", "plural", "sha1sum", "sha256sum", "adler32sum", "toString", "atoi", "int64", "int", "float64", "seq", "toDecimal",
"split", "splitList", "splitn", "toStrings", "until", "untilStep", "add1", "add", "sub", "div", "mod", "mul", "randInt",
"add1f", "addf", "subf", "divf", "mulf", "biggest", "max", "min", "maxf", "minf", "ceil", "floor", "round", "sortAlpha",
"default", "empty", "coalesce", "all", "any", "compact", "fromJson", "toJson", "toPrettyJson", "toRawJson", "ternary",
"deepCopy", "typeOf", "typeIs", "typeIsLike", "kindOf", "kindIs", "deepEqual", "b64enc", "b64dec", "b32enc", "b32dec", "tuple",
"list", "dict", "get", "set", "unset", "hasKey", "pluck", "keys", "pick", "omit", "merge", "mergeOverwrite", "values", "prepend",
"first", "rest", "last", "initial", "reverse", "uniq", "without", "has", "concat", "dig", "chunk", "randBytes", "uuidv4",
"semver", "semverCompare", "regexFindAll", "regexFind", "regexReplaceAll", "regexReplaceAllLiteral", "regexSplit",
"regexQuoteMeta", "urlParse", "urlJoin",
```

When using sprig date functions it is advised to always use its timezone aware versions, like `dateInZone` or `htmlDateInZone`.
9 changes: 9 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/prometheus/alertmanager
go 1.21

require (
github.com/Masterminds/sprig/v3 v3.2.1
github.com/alecthomas/kingpin/v2 v2.4.0
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137
github.com/aws/aws-sdk-go v1.50.29
Expand Down Expand Up @@ -48,6 +49,8 @@ require (
)

require (
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.1.1 // indirect
github.com/armon/go-metrics v0.3.10 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
Expand All @@ -67,19 +70,25 @@ require (
github.com/hashicorp/go-msgpack v0.5.3 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/huandu/xstrings v1.3.2 // indirect
github.com/imdario/mergo v0.3.11 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/jpillora/backoff v1.0.0 // indirect
github.com/julienschmidt/httprouter v1.3.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/miekg/dns v1.1.41 // indirect
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mitchellh/reflectwalk v1.0.0 // indirect
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.5.0 // indirect
github.com/prometheus/procfs v0.12.0 // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
go.mongodb.org/mongo-driver v1.13.1 // indirect
go.opentelemetry.io/otel v1.17.0 // indirect
Expand Down
22 changes: 22 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
github.com/Masterminds/sprig/v3 v3.2.1 h1:n6EPaDyLSvCEa3frruQvAiHuNp2dhBlMSmkEr+HuzGc=
github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjHpqDjYY=
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
Expand Down Expand Up @@ -133,6 +139,7 @@ github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5Kwzbycv
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps=
github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
Expand Down Expand Up @@ -261,6 +268,7 @@ github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU=
github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
Expand Down Expand Up @@ -315,8 +323,13 @@ github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR
github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0=
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.11 h1:3tnifQM4i+fbajXKBHXWEH+KvNHqojZ778UH75j3bGA=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
Expand Down Expand Up @@ -378,13 +391,17 @@ github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju
github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY=
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
Expand Down Expand Up @@ -458,6 +475,8 @@ github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb
github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749 h1:bUGsEnyNbVPw06Bs80sCeARAlK8lhwqGyi6UT8ymuGk=
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 h1:pXY9qYc/MP5zdvqWEUH6SjNiu7VhSjuVFTFiTcphaLU=
Expand All @@ -467,6 +486,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo=
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
Expand Down Expand Up @@ -534,6 +555,7 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
Expand Down
31 changes: 29 additions & 2 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ import (
"path"
"path/filepath"
"regexp"
"slices"
"sort"
"strings"
tmpltext "text/template"
"time"

"github.com/Masterminds/sprig/v3"
"github.com/prometheus/common/model"
"golang.org/x/text/cases"
"golang.org/x/text/language"
Expand Down Expand Up @@ -58,8 +60,8 @@ func New(options ...Option) (*Template, error) {
o(t.text, t.html)
}

t.text.Funcs(tmpltext.FuncMap(DefaultFuncs))
t.html.Funcs(tmplhtml.FuncMap(DefaultFuncs))
t.text.Funcs(tmpltext.FuncMap(DefaultFuncs)).Funcs(tmpltext.FuncMap(filteredSprigFuncMap()))
t.html.Funcs(tmplhtml.FuncMap(DefaultFuncs)).Funcs(tmplhtml.FuncMap(filteredSprigFuncMap()))

return t, nil
}
Expand Down Expand Up @@ -408,3 +410,28 @@ func (t *Template) Data(recv string, groupLabels model.LabelSet, alerts ...*type

return data
}

func filteredSprigFuncMap() tmpltext.FuncMap {
allowlist := []string{
"ago", "date", "dateInZone", "dateModify", "duration", "durationRound", "htmlDate", "htmlDateInZone", "toDate",
"unixEpoch", "abbrev", "abbrevboth", "trunc", "untitle", "substr", "repeat", "trimAll", "trimSuffix", "trimPrefix", "nospace",
"initials", "randAlphaNum", "randAlpha", "randAscii", "randNumeric", "swapcase", "shuffle", "snakecase", "camelcase",
"kebabcase", "wrap", "wrapWith", "contains", "hasPrefix", "hasSuffix", "quote", "squote", "cat", "indent", "nindent",
"replace", "plural", "sha1sum", "sha256sum", "adler32sum", "toString", "atoi", "int64", "int", "float64", "seq", "toDecimal",
"split", "splitList", "splitn", "toStrings", "until", "untilStep", "add1", "add", "sub", "div", "mod", "mul", "randInt",
"add1f", "addf", "subf", "divf", "mulf", "biggest", "max", "min", "maxf", "minf", "ceil", "floor", "round", "sortAlpha",
"default", "empty", "coalesce", "all", "any", "compact", "fromJson", "toJson", "toPrettyJson", "toRawJson", "ternary",
"deepCopy", "typeOf", "typeIs", "typeIsLike", "kindOf", "kindIs", "deepEqual", "b64enc", "b64dec", "b32enc", "b32dec", "tuple",
"list", "dict", "get", "set", "unset", "hasKey", "pluck", "keys", "pick", "omit", "merge", "mergeOverwrite", "values", "prepend",
"first", "rest", "last", "initial", "reverse", "uniq", "without", "has", "concat", "dig", "chunk", "randBytes", "uuidv4",
"semver", "semverCompare", "regexFindAll", "regexFind", "regexReplaceAll", "regexReplaceAllLiteral", "regexSplit",
"regexQuoteMeta", "urlParse", "urlJoin",
}
sprigFuncMap := sprig.FuncMap()
for function := range sprigFuncMap {
if !slices.Contains(allowlist, function) {
delete(sprigFuncMap, function)
}
}
return sprigFuncMap
}
38 changes: 38 additions & 0 deletions template/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,10 @@ func TestTemplateFuncs(t *testing.T) {
title: "Template using reReplaceAll",
in: `{{ reReplaceAll "ab" "AB" "abc" }}`,
exp: "ABc",
}, {
title: "Template using a sprig function",
in: `{{ list 1 2 3 4 5 }}`,
exp: "[1 2 3 4 5]",
}} {
tc := tc
t.Run(tc.title, func(t *testing.T) {
Expand All @@ -523,3 +527,37 @@ func TestTemplateFuncs(t *testing.T) {
})
}
}

func TestDisallowedTemplateFuncs(t *testing.T) {
tmpl, err := FromGlobs([]string{})
require.NoError(t, err)

for _, tc := range []struct {
title string
in string
data interface{}
exp string
}{{
title: "Template using env",
in: `{{ env "HOME" }}`,
exp: "ABC",
}, {
title: "Template using expandenv",
in: `{{ expandenv "Your path is set to $PATH"}}`,
exp: "abc",
}} {
tc := tc
t.Run(tc.title, func(t *testing.T) {
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
_, err := tmpl.ExecuteTextString(tc.in, tc.data)
require.ErrorContainsf(t, err, "not defined", "error message %s", "formatted")
}()
}
wg.Wait()
})
}
}

0 comments on commit 189905b

Please sign in to comment.