github.com/chalford/terraform@v0.3.7-0.20150113080010-a78c69a8c81f/config/interpolate_funcs.go (about) 1 package config 2 3 import ( 4 "bytes" 5 "fmt" 6 "io/ioutil" 7 "strconv" 8 "strings" 9 ) 10 11 // Funcs is the mapping of built-in functions for configuration. 12 var Funcs map[string]InterpolationFunc 13 14 func init() { 15 Funcs = map[string]InterpolationFunc{ 16 "concat": interpolationFuncConcat, 17 "file": interpolationFuncFile, 18 "join": interpolationFuncJoin, 19 "lookup": interpolationFuncLookup, 20 "element": interpolationFuncElement, 21 } 22 } 23 24 // interpolationFuncConcat implements the "concat" function that allows 25 // strings to be joined together. 26 func interpolationFuncConcat( 27 vs map[string]string, args ...string) (string, error) { 28 var buf bytes.Buffer 29 30 for _, a := range args { 31 if _, err := buf.WriteString(a); err != nil { 32 return "", err 33 } 34 } 35 36 return buf.String(), nil 37 } 38 39 // interpolationFuncFile implements the "file" function that allows 40 // loading contents from a file. 41 func interpolationFuncFile( 42 vs map[string]string, args ...string) (string, error) { 43 if len(args) != 1 { 44 return "", fmt.Errorf( 45 "file expects 1 arguments, got %d", len(args)) 46 } 47 48 data, err := ioutil.ReadFile(args[0]) 49 if err != nil { 50 return "", err 51 } 52 53 return string(data), nil 54 } 55 56 // interpolationFuncJoin implements the "join" function that allows 57 // multi-variable values to be joined by some character. 58 func interpolationFuncJoin( 59 vs map[string]string, args ...string) (string, error) { 60 if len(args) < 2 { 61 return "", fmt.Errorf("join expects 2 arguments") 62 } 63 64 var list []string 65 for _, arg := range args[1:] { 66 parts := strings.Split(arg, InterpSplitDelim) 67 list = append(list, parts...) 68 } 69 70 return strings.Join(list, args[0]), nil 71 } 72 73 // interpolationFuncLookup implements the "lookup" function that allows 74 // dynamic lookups of map types within a Terraform configuration. 75 func interpolationFuncLookup( 76 vs map[string]string, args ...string) (string, error) { 77 if len(args) != 2 { 78 return "", fmt.Errorf( 79 "lookup expects 2 arguments, got %d", len(args)) 80 } 81 82 k := fmt.Sprintf("var.%s", strings.Join(args, ".")) 83 v, ok := vs[k] 84 if !ok { 85 return "", fmt.Errorf( 86 "lookup in '%s' failed to find '%s'", 87 args[0], args[1]) 88 } 89 90 return v, nil 91 } 92 93 // interpolationFuncElement implements the "element" function that allows 94 // a specific index to be looked up in a multi-variable value. Note that this will 95 // wrap if the index is larger than the number of elements in the multi-variable value. 96 func interpolationFuncElement( 97 vs map[string]string, args ...string) (string, error) { 98 if len(args) != 2 { 99 return "", fmt.Errorf( 100 "element expects 2 arguments, got %d", len(args)) 101 } 102 103 list := strings.Split(args[0], InterpSplitDelim) 104 105 index, err := strconv.Atoi(args[1]) 106 if err != nil { 107 return "", fmt.Errorf( 108 "invalid number for index, got %s", args[1]) 109 } 110 111 v := list[index % len(list)] 112 113 return v, nil 114 }