Documentation
¶
Overview ¶
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. * * This product includes software developed at Datadog (https://www.datadoghq.com) Copyright 2024 Datadog, Inc.
Index ¶
- Variables
- func ContextVariables(moduleDir, rootDir string) map[string]cty.Value
- func EvalFuncs(baseDir string, fsys vfs.FS) map[string]function.Function
- func EvalFuncsWithRoot(baseDir, rootDir string, fsys vfs.FS) map[string]function.Function
- func MakeAbsPathFunc(baseDir string) function.Function
- type ScanFS
Constants ¶
This section is empty.
Variables ¶
var ( // ToSetFunc - https://developer.hashicorp.com/terraform/language/functions/toset ToSetFunc = collectionConvertFunc(collectionKindSet) // ToListFunc - https://developer.hashicorp.com/terraform/language/functions/tolist ToListFunc = collectionConvertFunc(collectionKindList) // ToMapFunc - https://developer.hashicorp.com/terraform/language/functions/tomap ToMapFunc = collectionConvertFunc(collectionKindMap) )
var ( Md5Func = hashHexFunc(md5.New) Sha1Func = hashHexFunc(sha1.New) Sha256Func = hashHexFunc(sha256.New) Sha512Func = hashHexFunc(sha512.New) Base64Sha256Func = hashBase64Func(sha256.New) Base64Sha512Func = hashBase64Func(sha512.New) )
var AbsPathFunc = function.New(&function.Spec{ Params: []function.Parameter{{Name: "path", Type: cty.String}}, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { abs, err := filepath.Abs(args[0].AsString()) if err != nil { return cty.NilVal, err } return cty.StringVal(filepath.ToSlash(abs)), nil }, })
var AllTrueFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "list", Type: cty.List(cty.Bool), }}, Type: function.StaticReturnType(cty.Bool), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { hasUnknown := false for it := args[0].ElementIterator(); it.Next(); { _, v := it.Element() if !v.IsKnown() { hasUnknown = true continue } if v.IsNull() || v.False() { return cty.False, nil } } if hasUnknown { return cty.UnknownVal(cty.Bool), nil } return cty.True, nil }, })
var AnyTrueFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "list", Type: cty.List(cty.Bool), }}, Type: function.StaticReturnType(cty.Bool), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { result := cty.False hasUnknown := false for it := args[0].ElementIterator(); it.Next(); { _, v := it.Element() if !v.IsKnown() { hasUnknown = true continue } if v.IsNull() { continue } result = result.Or(v) if result.True() { return cty.True, nil } } if hasUnknown { return cty.UnknownVal(cty.Bool), nil } return result, nil }, })
var Base64DecodeFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "str", Type: cty.String, }}, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { s := args[0].AsString() decoded, err := base64.StdEncoding.DecodeString(s) if err != nil { decoded, err = base64.RawStdEncoding.DecodeString(s) if err != nil { return cty.NilVal, function.NewArgErrorf(0, "invalid base64: %s", err) } } if !utf8.Valid(decoded) { return cty.NilVal, function.NewArgErrorf(0, "the result of decoding the provided string is not valid UTF-8") } return cty.StringVal(string(decoded)), nil }, })
var Base64EncodeFunc = function.New(&function.Spec{ Params: []function.Parameter{ { Name: "val", Type: cty.DynamicPseudoType, AllowDynamicType: true, AllowNull: true, }, }, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { val := args[0] if !val.IsWhollyKnown() { return cty.UnknownVal(retType), nil } if val.IsNull() { return cty.StringVal("null"), nil } encoded := base64.StdEncoding.EncodeToString([]byte(val.AsString())) return cty.StringVal(encoded), nil }, })
Base64EncodeFunc - https://www.terraform.io/docs/language/functions/base64encode.html
var Base64GzipFunc = function.New(&function.Spec{ Params: []function.Parameter{{Name: "str", Type: cty.String}}, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { var buf bytes.Buffer gz := gzip.NewWriter(&buf) gz.ModTime = time.Unix(0, 0) if _, err := gz.Write([]byte(args[0].AsString())); err != nil { return cty.NilVal, err } if err := gz.Flush(); err != nil { return cty.NilVal, err } if err := gz.Close(); err != nil { return cty.NilVal, err } return cty.StringVal(base64.StdEncoding.EncodeToString(buf.Bytes())), nil }, })
var BasenameFunc = function.New(&function.Spec{ Params: []function.Parameter{{Name: "path", Type: cty.String}}, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { return cty.StringVal(filepath.Base(args[0].AsString())), nil }, })
var CidrHostFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "prefix", Type: cty.String}, {Name: "hostnum", Type: cty.Number}, }, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { prefix, err := parsePrefix(args[0].AsString()) if err != nil { return cty.NilVal, err } var hostNum big.Int if err := gocty.FromCtyValue(args[1], &hostNum); err != nil { return cty.NilVal, function.NewArgError(1, err) } addr, err := cidrHost(prefix, &hostNum) if err != nil { return cty.NilVal, err } return cty.StringVal(addr.String()), nil }, })
var CidrNetmaskFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "prefix", Type: cty.String, }}, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { prefix, err := parsePrefix(args[0].AsString()) if err != nil { return cty.NilVal, err } if !prefix.Addr().Is4() { return cty.NilVal, function.NewArgErrorf(0, "cidrnetmask only supports IPv4") } mask := net.CIDRMask(prefix.Bits(), prefix.Addr().BitLen()) return cty.StringVal(net.IP(mask).String()), nil }, })
var CidrSubnetFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "prefix", Type: cty.String}, {Name: "newbits", Type: cty.Number}, {Name: "netnum", Type: cty.Number}, }, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { prefix, err := parsePrefix(args[0].AsString()) if err != nil { return cty.NilVal, err } var newbits int var netnum big.Int if err := gocty.FromCtyValue(args[1], &newbits); err != nil { return cty.NilVal, function.NewArgError(1, err) } if err := gocty.FromCtyValue(args[2], &netnum); err != nil { return cty.NilVal, function.NewArgError(2, err) } out, err := cidrSubnet(prefix, newbits, &netnum) if err != nil { return cty.NilVal, err } return cty.StringVal(out.String()), nil }, })
var CidrSubnetsFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "prefix", Type: cty.String, }}, VarParam: &function.Parameter{ Name: "newbits", Type: cty.Number, }, Type: function.StaticReturnType(cty.List(cty.String)), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { prefix, err := parsePrefix(args[0].AsString()) if err != nil { return cty.NilVal, err } if len(args) == 1 { return cty.ListValEmpty(cty.String), nil } newbits := make([]int, len(args)-1) for i, arg := range args[1:] { if err := gocty.FromCtyValue(arg, &newbits[i]); err != nil { return cty.NilVal, function.NewArgError(i+1, err) } } subs, err := cidrSubnets(prefix, newbits) if err != nil { return cty.NilVal, err } vals := make([]cty.Value, len(subs)) for i, sub := range subs { vals[i] = cty.StringVal(sub) } return cty.ListVal(vals), nil }, })
var CoalesceFunc = function.New(&function.Spec{ Params: []function.Parameter{}, VarParam: &function.Parameter{ Name: "vals", Type: cty.DynamicPseudoType, AllowUnknown: true, AllowDynamicType: true, AllowNull: true, }, Type: func(args []cty.Value) (cty.Type, error) { argTypes := make([]cty.Type, len(args)) for i, val := range args { argTypes[i] = val.Type() } retType, _ := ctyconvert.UnifyUnsafe(argTypes) if retType == cty.NilType { return cty.NilType, errors.New("all arguments must have the same type") } return retType, nil }, Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { for _, argVal := range args { converted, err := ctyconvert.Convert(argVal, retType) if err != nil { return cty.NilVal, err } if !converted.IsKnown() { return cty.UnknownVal(retType), nil } if converted.IsNull() { continue } if retType == cty.String && converted.RawEquals(cty.StringVal("")) { continue } return converted, nil } return cty.NilVal, errors.New("no non-null, non-empty-string arguments") }, })
CoalesceFunc matches Terraform: first non-null, non-empty-string argument.
var DirnameFunc = function.New(&function.Spec{ Params: []function.Parameter{{Name: "path", Type: cty.String}}, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { return cty.StringVal(filepath.Dir(args[0].AsString())), nil }, })
var EndsWithFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "str", Type: cty.String}, {Name: "suffix", Type: cty.String}, }, Type: function.StaticReturnType(cty.Bool), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { return cty.BoolVal(strings.HasSuffix(args[0].AsString(), args[1].AsString())), nil }, })
var IndexFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "list", Type: cty.DynamicPseudoType}, {Name: "value", Type: cty.DynamicPseudoType}, }, Type: function.StaticReturnType(cty.Number), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { list := args[0] if !list.Type().IsListType() && !list.Type().IsTupleType() { return cty.NilVal, errors.New("argument must be a list or tuple") } if !list.IsKnown() { return cty.UnknownVal(cty.Number), nil } if list.LengthInt() == 0 { return cty.NilVal, errors.New("cannot search an empty list") } for it := list.ElementIterator(); it.Next(); { i, v := it.Element() eq, err := stdlib.Equal(v, args[1]) if err != nil { return cty.NilVal, err } if !eq.IsKnown() { return cty.UnknownVal(cty.Number), nil } if eq.True() { return i, nil } } return cty.NilVal, errors.New("item not found") }, })
IndexFunc matches Terraform: first index of value in a list or tuple.
var LengthFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "value", Type: cty.DynamicPseudoType, AllowDynamicType: true, AllowUnknown: true, AllowMarked: true, }}, Type: function.StaticReturnType(cty.Number), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { val := args[0] ty := val.Type() switch { case ty == cty.String: return stdlib.Strlen(val) case ty.IsObjectType(): if !val.IsKnown() { return cty.UnknownVal(cty.Number), nil } return cty.NumberIntVal(int64(len(ty.AttributeTypes()))), nil default: return stdlib.Length(val) } }, })
LengthFunc matches Terraform: strings, collections, and objects.
var LookupFunc = function.New(&function.Spec{ Params: []function.Parameter{ { Name: "inputMap", Type: cty.DynamicPseudoType, AllowMarked: true, AllowUnknown: true, }, { Name: "key", Type: cty.String, AllowMarked: true, AllowUnknown: true, }, }, VarParam: &function.Parameter{ Name: "default", Type: cty.DynamicPseudoType, AllowUnknown: true, AllowDynamicType: true, AllowNull: true, AllowMarked: true, }, Type: func(args []cty.Value) (cty.Type, error) { if len(args) > 3 { return cty.NilType, fmt.Errorf("lookup() takes two or three arguments, got %d", len(args)) } ty := args[0].Type() switch { case ty.IsObjectType(): if !args[1].IsKnown() { return cty.DynamicPseudoType, nil } keyVal, _ := args[1].Unmark() key := keyVal.AsString() if ty.HasAttribute(key) { return args[0].GetAttr(key).Type(), nil } if len(args) == 3 { return args[2].Type(), nil } return cty.DynamicPseudoType, function.NewArgErrorf(0, "the given object has no attribute %q", key) case ty.IsMapType(): if len(args) == 3 { if _, err := ctyconvert.Convert(args[2], ty.ElementType()); err != nil { return cty.NilType, function.NewArgErrorf(2, "the default value must have the same type as the map elements") } } return ty.ElementType(), nil default: return cty.NilType, function.NewArgErrorf(0, "lookup() requires a map as the first argument") } }, Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { mapVar, mapMarks := args[0].Unmark() keyVal, keyMarks := args[1].Unmark() if !mapVar.IsKnown() || !keyVal.IsKnown() { return cty.UnknownVal(retType).WithMarks(mapMarks, keyMarks), nil } lookupKey := keyVal.AsString() found := cty.NilVal switch { case mapVar.Type().IsObjectType() && mapVar.Type().HasAttribute(lookupKey): found = mapVar.GetAttr(lookupKey) case mapVar.Type().IsMapType() && mapVar.HasIndex(cty.StringVal(lookupKey)) == cty.True: found = mapVar.Index(cty.StringVal(lookupKey)) } if found != cty.NilVal { return found.WithMarks(mapMarks, keyMarks), nil } if len(args) == 3 { defaultVal, err := ctyconvert.Convert(args[2], retType) if err != nil { return cty.NilVal, err } return defaultVal.WithMarks(mapMarks, keyMarks), nil } return cty.NilVal, fmt.Errorf("lookup failed to find key %s", lookupKey) }, })
LookupFunc matches Terraform: optional default, maps and objects.
var MatchkeysFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "values", Type: cty.List(cty.DynamicPseudoType)}, {Name: "keys", Type: cty.List(cty.DynamicPseudoType)}, {Name: "searchset", Type: cty.List(cty.DynamicPseudoType)}, }, Type: func(args []cty.Value) (cty.Type, error) { if ty, _ := ctyconvert.UnifyUnsafe([]cty.Type{args[1].Type(), args[2].Type()}); ty == cty.NilType { return cty.NilType, errors.New("keys and searchset must be of the same type") } return args[0].Type(), nil }, Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { values, keys, searchset := args[0], args[1], args[2] if !values.IsKnown() || !keys.IsKnown() || !searchset.IsKnown() { return cty.UnknownVal(retType), nil } if values.LengthInt() != keys.LengthInt() { return cty.NilVal, errors.New("length of keys and values should be equal") } if searchset.LengthInt() == 0 { return cty.ListValEmpty(retType.ElementType()), nil } if !values.IsWhollyKnown() || !keys.IsWhollyKnown() { return cty.UnknownVal(retType), nil } var out []cty.Value i := 0 for it := keys.ElementIterator(); it.Next(); { _, key := it.Element() for sit := searchset.ElementIterator(); sit.Next(); { _, search := sit.Element() eq, err := stdlib.Equal(key, search) if err != nil { return cty.NilVal, err } if !eq.IsKnown() { return cty.UnknownVal(retType), nil } if eq.True() { out = append(out, values.Index(cty.NumberIntVal(int64(i)))) break } } i++ } if len(out) == 0 { return cty.ListValEmpty(retType.ElementType()), nil } return cty.ListVal(out), nil }, })
var OneFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "list", Type: cty.DynamicPseudoType, }}, Type: func(args []cty.Value) (cty.Type, error) { ty := args[0].Type() switch { case ty.IsListType(), ty.IsSetType(): return ty.ElementType(), nil case ty.IsTupleType(): etys := ty.TupleElementTypes() switch len(etys) { case 0: return cty.DynamicPseudoType, nil case 1: return etys[0], nil } } return cty.NilType, function.NewArgErrorf(0, "must be a list, set, or tuple value with either zero or one elements") }, Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { val := args[0] if !val.IsKnown() { return cty.UnknownVal(retType), nil } length := val.Length() if !length.IsKnown() { return cty.UnknownVal(retType), nil } var n int if err := gocty.FromCtyValue(length, &n); err != nil { return cty.NilVal, err } switch n { case 0: return cty.NullVal(retType), nil case 1: for it := val.ElementIterator(); it.Next(); { _, elem := it.Element() return elem, nil } } return cty.NilVal, function.NewArgErrorf(0, "must be a list, set, or tuple value with either zero or one elements") }, })
var PathExpandFunc = function.New(&function.Spec{ Params: []function.Parameter{{Name: "path", Type: cty.String}}, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { p := args[0].AsString() if p == "~" || strings.HasPrefix(p, "~/") || strings.HasPrefix(p, `~\`) { home, err := os.UserHomeDir() if err != nil { return cty.NilVal, err } if p == "~" { return cty.StringVal(home), nil } return cty.StringVal(filepath.Join(home, p[2:])), nil } return cty.StringVal(p), nil }, })
var ReplaceFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "str", Type: cty.String}, {Name: "substr", Type: cty.String}, {Name: "replace", Type: cty.String}, }, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { substr := args[1].AsString() if len(substr) > 1 && strings.HasPrefix(substr, "/") && strings.HasSuffix(substr, "/") { pattern := cty.StringVal(substr[1 : len(substr)-1]) return stdlib.RegexReplace(args[0], pattern, args[2]) } return stdlib.Replace(args[0], args[1], args[2]) }, })
ReplaceFunc matches Terraform: /pattern/ is a regular expression.
var StartsWithFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "str", Type: cty.String}, {Name: "prefix", Type: cty.String}, }, Type: function.StaticReturnType(cty.Bool), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { return cty.BoolVal(strings.HasPrefix(args[0].AsString(), args[1].AsString())), nil }, })
var StrContainsFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "str", Type: cty.String}, {Name: "substr", Type: cty.String}, }, Type: function.StaticReturnType(cty.Bool), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { return cty.BoolVal(strings.Contains(args[0].AsString(), args[1].AsString())), nil }, })
var SumFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "list", Type: cty.DynamicPseudoType, }}, Type: function.StaticReturnType(cty.Number), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { list := args[0] ty := list.Type() if !ty.IsListType() && !ty.IsSetType() && !ty.IsTupleType() { return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple") } if !list.IsWhollyKnown() { return cty.UnknownVal(cty.Number), nil } if list.LengthInt() == 0 { return cty.NilVal, function.NewArgErrorf(0, "cannot sum an empty list") } elems := list.AsValueSlice() total, err := ctyconvert.Convert(elems[0], cty.Number) if err != nil || total.IsNull() { return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple of number values") } for _, elem := range elems[1:] { n, convErr := ctyconvert.Convert(elem, cty.Number) if convErr != nil || n.IsNull() { return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple of number values") } total = total.Add(n) } return total, nil }, })
var TerraformFuncs = func() map[string]function.Function { funcs := map[string]function.Function{ "abs": stdlib.AbsoluteFunc, "abspath": AbsPathFunc, "alltrue": AllTrueFunc, "anytrue": AnyTrueFunc, "base64decode": Base64DecodeFunc, "base64encode": Base64EncodeFunc, "base64gzip": Base64GzipFunc, "base64sha256": Base64Sha256Func, "base64sha512": Base64Sha512Func, "basename": BasenameFunc, "can": tryfunc.CanFunc, "cidrhost": CidrHostFunc, "cidrnetmask": CidrNetmaskFunc, "cidrsubnet": CidrSubnetFunc, "cidrsubnets": CidrSubnetsFunc, "ceil": stdlib.CeilFunc, "chomp": stdlib.ChompFunc, "coalesce": CoalesceFunc, "coalescelist": stdlib.CoalesceListFunc, "compact": stdlib.CompactFunc, "concat": stdlib.ConcatFunc, "contains": stdlib.ContainsFunc, "csvdecode": stdlib.CSVDecodeFunc, "dirname": DirnameFunc, "distinct": stdlib.DistinctFunc, "endswith": EndsWithFunc, "element": stdlib.ElementFunc, "chunklist": stdlib.ChunklistFunc, "flatten": stdlib.FlattenFunc, "floor": stdlib.FloorFunc, "format": stdlib.FormatFunc, "formatdate": stdlib.FormatDateFunc, "formatlist": stdlib.FormatListFunc, "indent": stdlib.IndentFunc, "index": IndexFunc, "join": stdlib.JoinFunc, "jsondecode": stdlib.JSONDecodeFunc, "jsonencode": stdlib.JSONEncodeFunc, "keys": stdlib.KeysFunc, "length": LengthFunc, "log": stdlib.LogFunc, "lookup": LookupFunc, "lower": stdlib.LowerFunc, "matchkeys": MatchkeysFunc, "max": stdlib.MaxFunc, "md5": Md5Func, "merge": stdlib.MergeFunc, "min": stdlib.MinFunc, "one": OneFunc, "parseint": stdlib.ParseIntFunc, "pathexpand": PathExpandFunc, "pow": stdlib.PowFunc, "range": stdlib.RangeFunc, "regex": stdlib.RegexFunc, "regexall": stdlib.RegexAllFunc, "replace": ReplaceFunc, "reverse": stdlib.ReverseListFunc, "setintersection": stdlib.SetIntersectionFunc, "setproduct": stdlib.SetProductFunc, "setsubtract": stdlib.SetSubtractFunc, "setunion": stdlib.SetUnionFunc, "sha1": Sha1Func, "sha256": Sha256Func, "sha512": Sha512Func, "signum": stdlib.SignumFunc, "slice": stdlib.SliceFunc, "sort": stdlib.SortFunc, "split": stdlib.SplitFunc, "startswith": StartsWithFunc, "strcontains": StrContainsFunc, "strrev": stdlib.ReverseFunc, "substr": stdlib.SubstrFunc, "sum": SumFunc, "textdecodebase64": TextDecodeBase64Func, "textencodebase64": TextEncodeBase64Func, "timeadd": stdlib.TimeAddFunc, "timecmp": TimeCmpFunc, "title": stdlib.TitleFunc, "tobool": stdlib.MakeToFunc(cty.Bool), "tolist": ToListFunc, "tomap": ToMapFunc, "tonumber": stdlib.MakeToFunc(cty.Number), "toset": ToSetFunc, "tostring": stdlib.MakeToFunc(cty.String), "transpose": TransposeFunc, "trim": stdlib.TrimFunc, "trimprefix": stdlib.TrimPrefixFunc, "trimspace": stdlib.TrimSpaceFunc, "trimsuffix": stdlib.TrimSuffixFunc, "try": tryfunc.TryFunc, "upper": stdlib.UpperFunc, "urlencode": URLEncodeFunc, "uuidv5": UUIDV5Func, "values": stdlib.ValuesFunc, "yamldecode": ctyyaml.YAMLDecodeFunc, "yamlencode": ctyyaml.YAMLEncodeFunc, "zipmap": stdlib.ZipmapFunc, } funcs["templatestring"] = makeTemplateStringFunc(func() map[string]function.Function { return funcs }) return funcs }()
TerraformFuncs contains all functions, overriding any conflicting built-ins it should create a file in this package and add/change this function key here
var TextDecodeBase64Func = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "source", Type: cty.String}, {Name: "encoding", Type: cty.String}, }, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { enc, err := ianaindex.IANA.Encoding(args[1].AsString()) if err != nil || enc == nil { return cty.NilVal, function.NewArgErrorf(1, "%q is not a supported IANA encoding name", args[1].AsString()) } raw, err := base64.StdEncoding.DecodeString(args[0].AsString()) if err != nil { return cty.NilVal, function.NewArgErrorf(0, "invalid base64: %s", err) } decoded, err := enc.NewDecoder().Bytes(raw) if err != nil { return cty.NilVal, function.NewArgErrorf(0, "the given string contains symbols that are not defined for %s", args[1].AsString()) } return cty.StringVal(string(decoded)), nil }, })
var TextEncodeBase64Func = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "string", Type: cty.String}, {Name: "encoding", Type: cty.String}, }, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { enc, err := ianaindex.IANA.Encoding(args[1].AsString()) if err != nil || enc == nil { return cty.NilVal, function.NewArgErrorf(1, "%q is not a supported IANA encoding name", args[1].AsString()) } encoded, err := enc.NewEncoder().Bytes([]byte(args[0].AsString())) if err != nil { return cty.NilVal, function.NewArgErrorf(0, "the given string cannot be represented in %s", args[1].AsString()) } return cty.StringVal(base64.StdEncoding.EncodeToString(encoded)), nil }, })
var TimeCmpFunc = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "timestamp_a", Type: cty.String}, {Name: "timestamp_b", Type: cty.String}, }, Type: function.StaticReturnType(cty.Number), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { a, err := time.Parse(time.RFC3339, args[0].AsString()) if err != nil { return cty.NilVal, function.NewArgErrorf(0, "not a valid RFC3339 timestamp: %s", args[0].AsString()) } b, err := time.Parse(time.RFC3339, args[1].AsString()) if err != nil { return cty.NilVal, function.NewArgErrorf(1, "not a valid RFC3339 timestamp: %s", args[1].AsString()) } switch { case a.Equal(b): return cty.NumberIntVal(0), nil case a.Before(b): return cty.NumberIntVal(-1), nil default: return cty.NumberIntVal(1), nil } }, })
var TransposeFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "values", Type: cty.Map(cty.List(cty.String)), }}, Type: function.StaticReturnType(cty.Map(cty.List(cty.String))), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { input := args[0] if !input.IsWhollyKnown() { return cty.UnknownVal(retType), nil } tmp := make(map[string][]string) for it := input.ElementIterator(); it.Next(); { inKey, inVal := it.Element() if inVal.IsNull() { return cty.NilVal, errors.New("input must not contain null list") } for vit := inVal.ElementIterator(); vit.Next(); { _, val := vit.Element() if val.IsNull() { return cty.NilVal, errors.New("input list must not contain null string") } outKey := val.AsString() tmp[outKey] = append(tmp[outKey], inKey.AsString()) } } if len(tmp) == 0 { return cty.MapValEmpty(cty.List(cty.String)), nil } out := make(map[string]cty.Value, len(tmp)) for k, vs := range tmp { sort.Strings(vs) elems := make([]cty.Value, len(vs)) for i, v := range vs { elems[i] = cty.StringVal(v) } out[k] = cty.ListVal(elems) } return cty.MapVal(out), nil }, })
var URLEncodeFunc = function.New(&function.Spec{ Params: []function.Parameter{{ Name: "str", Type: cty.String, }}, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { return cty.StringVal(url.QueryEscape(args[0].AsString())), nil }, })
var UUIDV5Func = function.New(&function.Spec{ Params: []function.Parameter{ {Name: "namespace", Type: cty.String}, {Name: "name", Type: cty.String}, }, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { ns, err := uuidNamespace(args[0].AsString()) if err != nil { return cty.NilVal, function.NewArgError(0, err) } return cty.StringVal(uuid.NewSHA1(ns, []byte(args[1].AsString())).String()), nil }, })
Functions ¶
func ContextVariables ¶ added in v1.15.0
func EvalFuncs ¶ added in v1.15.0
EvalFuncs returns TerraformFuncs plus filesystem functions rooted at baseDir. When fsys is nil and baseDir is empty the static map is returned unchanged.