mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-03-09 17:09:29 +00:00
Several packages are only used while running the e2e suite. These packages are less important to update, as the they can not influence the final executable that is part of the Ceph-CSI container-image. By moving these dependencies out of the main Ceph-CSI go.mod, it is easier to identify if a reported CVE affects Ceph-CSI, or only the testing (like most of the Kubernetes CVEs). Signed-off-by: Niels de Vos <ndevos@ibm.com>
318 lines
8.1 KiB
Go
318 lines
8.1 KiB
Go
package sprig
|
|
|
|
import (
|
|
"errors"
|
|
"html/template"
|
|
"math/rand"
|
|
"os"
|
|
"path"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strconv"
|
|
"strings"
|
|
ttemplate "text/template"
|
|
"time"
|
|
)
|
|
|
|
// FuncMap produces the function map.
|
|
//
|
|
// Use this to pass the functions into the template engine:
|
|
//
|
|
// tpl := template.New("foo").Funcs(sprig.FuncMap()))
|
|
//
|
|
func FuncMap() template.FuncMap {
|
|
return HtmlFuncMap()
|
|
}
|
|
|
|
// HermeticTxtFuncMap returns a 'text/template'.FuncMap with only repeatable functions.
|
|
func HermeticTxtFuncMap() ttemplate.FuncMap {
|
|
r := TxtFuncMap()
|
|
for _, name := range nonhermeticFunctions {
|
|
delete(r, name)
|
|
}
|
|
return r
|
|
}
|
|
|
|
// HermeticHtmlFuncMap returns an 'html/template'.Funcmap with only repeatable functions.
|
|
func HermeticHtmlFuncMap() template.FuncMap {
|
|
r := HtmlFuncMap()
|
|
for _, name := range nonhermeticFunctions {
|
|
delete(r, name)
|
|
}
|
|
return r
|
|
}
|
|
|
|
// TxtFuncMap returns a 'text/template'.FuncMap
|
|
func TxtFuncMap() ttemplate.FuncMap {
|
|
return ttemplate.FuncMap(GenericFuncMap())
|
|
}
|
|
|
|
// HtmlFuncMap returns an 'html/template'.Funcmap
|
|
func HtmlFuncMap() template.FuncMap {
|
|
return template.FuncMap(GenericFuncMap())
|
|
}
|
|
|
|
// GenericFuncMap returns a copy of the basic function map as a map[string]interface{}.
|
|
func GenericFuncMap() map[string]interface{} {
|
|
gfm := make(map[string]interface{}, len(genericMap))
|
|
for k, v := range genericMap {
|
|
gfm[k] = v
|
|
}
|
|
return gfm
|
|
}
|
|
|
|
// These functions are not guaranteed to evaluate to the same result for given input, because they
|
|
// refer to the environment or global state.
|
|
var nonhermeticFunctions = []string{
|
|
// Date functions
|
|
"date",
|
|
"date_in_zone",
|
|
"date_modify",
|
|
"now",
|
|
"htmlDate",
|
|
"htmlDateInZone",
|
|
"dateInZone",
|
|
"dateModify",
|
|
|
|
// Strings
|
|
"randAlphaNum",
|
|
"randAlpha",
|
|
"randAscii",
|
|
"randNumeric",
|
|
"randBytes",
|
|
"uuidv4",
|
|
|
|
// OS
|
|
"env",
|
|
"expandenv",
|
|
|
|
// Network
|
|
"getHostByName",
|
|
}
|
|
|
|
var genericMap = map[string]interface{}{
|
|
"hello": func() string { return "Hello!" },
|
|
|
|
// Date functions
|
|
"ago": dateAgo,
|
|
"date": date,
|
|
"date_in_zone": dateInZone,
|
|
"date_modify": dateModify,
|
|
"dateInZone": dateInZone,
|
|
"dateModify": dateModify,
|
|
"duration": duration,
|
|
"durationRound": durationRound,
|
|
"htmlDate": htmlDate,
|
|
"htmlDateInZone": htmlDateInZone,
|
|
"must_date_modify": mustDateModify,
|
|
"mustDateModify": mustDateModify,
|
|
"mustToDate": mustToDate,
|
|
"now": time.Now,
|
|
"toDate": toDate,
|
|
"unixEpoch": unixEpoch,
|
|
|
|
// Strings
|
|
"trunc": trunc,
|
|
"trim": strings.TrimSpace,
|
|
"upper": strings.ToUpper,
|
|
"lower": strings.ToLower,
|
|
"title": strings.Title,
|
|
"substr": substring,
|
|
// Switch order so that "foo" | repeat 5
|
|
"repeat": func(count int, str string) string { return strings.Repeat(str, count) },
|
|
// Deprecated: Use trimAll.
|
|
"trimall": func(a, b string) string { return strings.Trim(b, a) },
|
|
// Switch order so that "$foo" | trimall "$"
|
|
"trimAll": func(a, b string) string { return strings.Trim(b, a) },
|
|
"trimSuffix": func(a, b string) string { return strings.TrimSuffix(b, a) },
|
|
"trimPrefix": func(a, b string) string { return strings.TrimPrefix(b, a) },
|
|
// Switch order so that "foobar" | contains "foo"
|
|
"contains": func(substr string, str string) bool { return strings.Contains(str, substr) },
|
|
"hasPrefix": func(substr string, str string) bool { return strings.HasPrefix(str, substr) },
|
|
"hasSuffix": func(substr string, str string) bool { return strings.HasSuffix(str, substr) },
|
|
"quote": quote,
|
|
"squote": squote,
|
|
"cat": cat,
|
|
"indent": indent,
|
|
"nindent": nindent,
|
|
"replace": replace,
|
|
"plural": plural,
|
|
"sha1sum": sha1sum,
|
|
"sha256sum": sha256sum,
|
|
"adler32sum": adler32sum,
|
|
"toString": strval,
|
|
|
|
// Wrap Atoi to stop errors.
|
|
"atoi": func(a string) int { i, _ := strconv.Atoi(a); return i },
|
|
"int64": toInt64,
|
|
"int": toInt,
|
|
"float64": toFloat64,
|
|
"seq": seq,
|
|
"toDecimal": toDecimal,
|
|
|
|
//"gt": func(a, b int) bool {return a > b},
|
|
//"gte": func(a, b int) bool {return a >= b},
|
|
//"lt": func(a, b int) bool {return a < b},
|
|
//"lte": func(a, b int) bool {return a <= b},
|
|
|
|
// split "/" foo/bar returns map[int]string{0: foo, 1: bar}
|
|
"split": split,
|
|
"splitList": func(sep, orig string) []string { return strings.Split(orig, sep) },
|
|
// splitn "/" foo/bar/fuu returns map[int]string{0: foo, 1: bar/fuu}
|
|
"splitn": splitn,
|
|
"toStrings": strslice,
|
|
|
|
"until": until,
|
|
"untilStep": untilStep,
|
|
|
|
// VERY basic arithmetic.
|
|
"add1": func(i interface{}) int64 { return toInt64(i) + 1 },
|
|
"add": func(i ...interface{}) int64 {
|
|
var a int64 = 0
|
|
for _, b := range i {
|
|
a += toInt64(b)
|
|
}
|
|
return a
|
|
},
|
|
"sub": func(a, b interface{}) int64 { return toInt64(a) - toInt64(b) },
|
|
"div": func(a, b interface{}) int64 { return toInt64(a) / toInt64(b) },
|
|
"mod": func(a, b interface{}) int64 { return toInt64(a) % toInt64(b) },
|
|
"mul": func(a interface{}, v ...interface{}) int64 {
|
|
val := toInt64(a)
|
|
for _, b := range v {
|
|
val = val * toInt64(b)
|
|
}
|
|
return val
|
|
},
|
|
"randInt": func(min, max int) int { return rand.Intn(max-min) + min },
|
|
"biggest": max,
|
|
"max": max,
|
|
"min": min,
|
|
"maxf": maxf,
|
|
"minf": minf,
|
|
"ceil": ceil,
|
|
"floor": floor,
|
|
"round": round,
|
|
|
|
// string slices. Note that we reverse the order b/c that's better
|
|
// for template processing.
|
|
"join": join,
|
|
"sortAlpha": sortAlpha,
|
|
|
|
// Defaults
|
|
"default": dfault,
|
|
"empty": empty,
|
|
"coalesce": coalesce,
|
|
"all": all,
|
|
"any": any,
|
|
"compact": compact,
|
|
"mustCompact": mustCompact,
|
|
"fromJson": fromJson,
|
|
"toJson": toJson,
|
|
"toPrettyJson": toPrettyJson,
|
|
"toRawJson": toRawJson,
|
|
"mustFromJson": mustFromJson,
|
|
"mustToJson": mustToJson,
|
|
"mustToPrettyJson": mustToPrettyJson,
|
|
"mustToRawJson": mustToRawJson,
|
|
"ternary": ternary,
|
|
|
|
// Reflection
|
|
"typeOf": typeOf,
|
|
"typeIs": typeIs,
|
|
"typeIsLike": typeIsLike,
|
|
"kindOf": kindOf,
|
|
"kindIs": kindIs,
|
|
"deepEqual": reflect.DeepEqual,
|
|
|
|
// OS:
|
|
"env": os.Getenv,
|
|
"expandenv": os.ExpandEnv,
|
|
|
|
// Network:
|
|
"getHostByName": getHostByName,
|
|
|
|
// Paths:
|
|
"base": path.Base,
|
|
"dir": path.Dir,
|
|
"clean": path.Clean,
|
|
"ext": path.Ext,
|
|
"isAbs": path.IsAbs,
|
|
|
|
// Filepaths:
|
|
"osBase": filepath.Base,
|
|
"osClean": filepath.Clean,
|
|
"osDir": filepath.Dir,
|
|
"osExt": filepath.Ext,
|
|
"osIsAbs": filepath.IsAbs,
|
|
|
|
// Encoding:
|
|
"b64enc": base64encode,
|
|
"b64dec": base64decode,
|
|
"b32enc": base32encode,
|
|
"b32dec": base32decode,
|
|
|
|
// Data Structures:
|
|
"tuple": list, // FIXME: with the addition of append/prepend these are no longer immutable.
|
|
"list": list,
|
|
"dict": dict,
|
|
"get": get,
|
|
"set": set,
|
|
"unset": unset,
|
|
"hasKey": hasKey,
|
|
"pluck": pluck,
|
|
"keys": keys,
|
|
"pick": pick,
|
|
"omit": omit,
|
|
"values": values,
|
|
|
|
"append": push, "push": push,
|
|
"mustAppend": mustPush, "mustPush": mustPush,
|
|
"prepend": prepend,
|
|
"mustPrepend": mustPrepend,
|
|
"first": first,
|
|
"mustFirst": mustFirst,
|
|
"rest": rest,
|
|
"mustRest": mustRest,
|
|
"last": last,
|
|
"mustLast": mustLast,
|
|
"initial": initial,
|
|
"mustInitial": mustInitial,
|
|
"reverse": reverse,
|
|
"mustReverse": mustReverse,
|
|
"uniq": uniq,
|
|
"mustUniq": mustUniq,
|
|
"without": without,
|
|
"mustWithout": mustWithout,
|
|
"has": has,
|
|
"mustHas": mustHas,
|
|
"slice": slice,
|
|
"mustSlice": mustSlice,
|
|
"concat": concat,
|
|
"dig": dig,
|
|
"chunk": chunk,
|
|
"mustChunk": mustChunk,
|
|
|
|
// Flow Control:
|
|
"fail": func(msg string) (string, error) { return "", errors.New(msg) },
|
|
|
|
// Regex
|
|
"regexMatch": regexMatch,
|
|
"mustRegexMatch": mustRegexMatch,
|
|
"regexFindAll": regexFindAll,
|
|
"mustRegexFindAll": mustRegexFindAll,
|
|
"regexFind": regexFind,
|
|
"mustRegexFind": mustRegexFind,
|
|
"regexReplaceAll": regexReplaceAll,
|
|
"mustRegexReplaceAll": mustRegexReplaceAll,
|
|
"regexReplaceAllLiteral": regexReplaceAllLiteral,
|
|
"mustRegexReplaceAllLiteral": mustRegexReplaceAllLiteral,
|
|
"regexSplit": regexSplit,
|
|
"mustRegexSplit": mustRegexSplit,
|
|
"regexQuoteMeta": regexQuoteMeta,
|
|
|
|
// URLs:
|
|
"urlParse": urlParse,
|
|
"urlJoin": urlJoin,
|
|
}
|