]>
Commit | Line | Data |
---|---|---|
107c1cdb ND |
1 | package lang |
2 | ||
3 | import ( | |
4 | "fmt" | |
5 | ||
6 | "github.com/zclconf/go-cty/cty" | |
7 | "github.com/zclconf/go-cty/cty/function" | |
8 | "github.com/zclconf/go-cty/cty/function/stdlib" | |
9 | ||
10 | "github.com/hashicorp/terraform/lang/funcs" | |
11 | ) | |
12 | ||
13 | var impureFunctions = []string{ | |
14 | "bcrypt", | |
15 | "timestamp", | |
16 | "uuid", | |
17 | } | |
18 | ||
19 | // Functions returns the set of functions that should be used to when evaluating | |
20 | // expressions in the receiving scope. | |
21 | func (s *Scope) Functions() map[string]function.Function { | |
22 | s.funcsLock.Lock() | |
23 | if s.funcs == nil { | |
24 | // Some of our functions are just directly the cty stdlib functions. | |
25 | // Others are implemented in the subdirectory "funcs" here in this | |
26 | // repository. New functions should generally start out their lives | |
27 | // in the "funcs" directory and potentially graduate to cty stdlib | |
28 | // later if the functionality seems to be something domain-agnostic | |
29 | // that would be useful to all applications using cty functions. | |
30 | ||
31 | s.funcs = map[string]function.Function{ | |
32 | "abs": stdlib.AbsoluteFunc, | |
33 | "basename": funcs.BasenameFunc, | |
34 | "base64decode": funcs.Base64DecodeFunc, | |
35 | "base64encode": funcs.Base64EncodeFunc, | |
36 | "base64gzip": funcs.Base64GzipFunc, | |
37 | "base64sha256": funcs.Base64Sha256Func, | |
38 | "base64sha512": funcs.Base64Sha512Func, | |
39 | "bcrypt": funcs.BcryptFunc, | |
40 | "ceil": funcs.CeilFunc, | |
41 | "chomp": funcs.ChompFunc, | |
42 | "cidrhost": funcs.CidrHostFunc, | |
43 | "cidrnetmask": funcs.CidrNetmaskFunc, | |
44 | "cidrsubnet": funcs.CidrSubnetFunc, | |
45 | "coalesce": funcs.CoalesceFunc, | |
46 | "coalescelist": funcs.CoalesceListFunc, | |
47 | "compact": funcs.CompactFunc, | |
48 | "concat": stdlib.ConcatFunc, | |
49 | "contains": funcs.ContainsFunc, | |
50 | "csvdecode": stdlib.CSVDecodeFunc, | |
51 | "dirname": funcs.DirnameFunc, | |
52 | "distinct": funcs.DistinctFunc, | |
53 | "element": funcs.ElementFunc, | |
54 | "chunklist": funcs.ChunklistFunc, | |
55 | "file": funcs.MakeFileFunc(s.BaseDir, false), | |
56 | "fileexists": funcs.MakeFileExistsFunc(s.BaseDir), | |
57 | "filebase64": funcs.MakeFileFunc(s.BaseDir, true), | |
58 | "filebase64sha256": funcs.MakeFileBase64Sha256Func(s.BaseDir), | |
59 | "filebase64sha512": funcs.MakeFileBase64Sha512Func(s.BaseDir), | |
60 | "filemd5": funcs.MakeFileMd5Func(s.BaseDir), | |
61 | "filesha1": funcs.MakeFileSha1Func(s.BaseDir), | |
62 | "filesha256": funcs.MakeFileSha256Func(s.BaseDir), | |
63 | "filesha512": funcs.MakeFileSha512Func(s.BaseDir), | |
64 | "flatten": funcs.FlattenFunc, | |
65 | "floor": funcs.FloorFunc, | |
66 | "format": stdlib.FormatFunc, | |
67 | "formatdate": stdlib.FormatDateFunc, | |
68 | "formatlist": stdlib.FormatListFunc, | |
69 | "indent": funcs.IndentFunc, | |
70 | "index": funcs.IndexFunc, | |
71 | "join": funcs.JoinFunc, | |
72 | "jsondecode": stdlib.JSONDecodeFunc, | |
73 | "jsonencode": stdlib.JSONEncodeFunc, | |
74 | "keys": funcs.KeysFunc, | |
75 | "length": funcs.LengthFunc, | |
76 | "list": funcs.ListFunc, | |
77 | "log": funcs.LogFunc, | |
78 | "lookup": funcs.LookupFunc, | |
79 | "lower": stdlib.LowerFunc, | |
80 | "map": funcs.MapFunc, | |
81 | "matchkeys": funcs.MatchkeysFunc, | |
82 | "max": stdlib.MaxFunc, | |
83 | "md5": funcs.Md5Func, | |
84 | "merge": funcs.MergeFunc, | |
85 | "min": stdlib.MinFunc, | |
86 | "pathexpand": funcs.PathExpandFunc, | |
87 | "pow": funcs.PowFunc, | |
88 | "replace": funcs.ReplaceFunc, | |
89 | "reverse": funcs.ReverseFunc, | |
90 | "rsadecrypt": funcs.RsaDecryptFunc, | |
91 | "setintersection": stdlib.SetIntersectionFunc, | |
92 | "setproduct": funcs.SetProductFunc, | |
93 | "setunion": stdlib.SetUnionFunc, | |
94 | "sha1": funcs.Sha1Func, | |
95 | "sha256": funcs.Sha256Func, | |
96 | "sha512": funcs.Sha512Func, | |
97 | "signum": funcs.SignumFunc, | |
98 | "slice": funcs.SliceFunc, | |
99 | "sort": funcs.SortFunc, | |
100 | "split": funcs.SplitFunc, | |
101 | "strrev": stdlib.ReverseFunc, | |
102 | "substr": stdlib.SubstrFunc, | |
103 | "timestamp": funcs.TimestampFunc, | |
104 | "timeadd": funcs.TimeAddFunc, | |
105 | "title": funcs.TitleFunc, | |
106 | "tostring": funcs.MakeToFunc(cty.String), | |
107 | "tonumber": funcs.MakeToFunc(cty.Number), | |
108 | "tobool": funcs.MakeToFunc(cty.Bool), | |
109 | "toset": funcs.MakeToFunc(cty.Set(cty.DynamicPseudoType)), | |
110 | "tolist": funcs.MakeToFunc(cty.List(cty.DynamicPseudoType)), | |
111 | "tomap": funcs.MakeToFunc(cty.Map(cty.DynamicPseudoType)), | |
112 | "transpose": funcs.TransposeFunc, | |
113 | "trimspace": funcs.TrimSpaceFunc, | |
114 | "upper": stdlib.UpperFunc, | |
115 | "urlencode": funcs.URLEncodeFunc, | |
116 | "uuid": funcs.UUIDFunc, | |
117 | "values": funcs.ValuesFunc, | |
118 | "zipmap": funcs.ZipmapFunc, | |
119 | } | |
120 | ||
121 | s.funcs["templatefile"] = funcs.MakeTemplateFileFunc(s.BaseDir, func() map[string]function.Function { | |
122 | // The templatefile function prevents recursive calls to itself | |
123 | // by copying this map and overwriting the "templatefile" entry. | |
124 | return s.funcs | |
125 | }) | |
126 | ||
127 | if s.PureOnly { | |
128 | // Force our few impure functions to return unknown so that we | |
129 | // can defer evaluating them until a later pass. | |
130 | for _, name := range impureFunctions { | |
131 | s.funcs[name] = function.Unpredictable(s.funcs[name]) | |
132 | } | |
133 | } | |
134 | } | |
135 | s.funcsLock.Unlock() | |
136 | ||
137 | return s.funcs | |
138 | } | |
139 | ||
140 | var unimplFunc = function.New(&function.Spec{ | |
141 | Type: func([]cty.Value) (cty.Type, error) { | |
142 | return cty.DynamicPseudoType, fmt.Errorf("function not yet implemented") | |
143 | }, | |
144 | Impl: func([]cty.Value, cty.Type) (cty.Value, error) { | |
145 | return cty.DynamicVal, fmt.Errorf("function not yet implemented") | |
146 | }, | |
147 | }) |