funcs

package
v0.12.0-alpha4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 7, 2018 License: MPL-2.0 Imports: 33 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
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()
		sDec, err := base64.StdEncoding.DecodeString(s)
		if err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("failed to decode base64 data '%s'", s)
		}
		if !utf8.Valid([]byte(sDec)) {
			log.Printf("[DEBUG] the result of decoding the the provided string is not valid UTF-8: %s", sDec)
			return cty.UnknownVal(cty.String), fmt.Errorf("the result of decoding the the provided string is not valid UTF-8")
		}
		return cty.StringVal(string(sDec)), nil
	},
})

Base64DecodeFunc constructs a function that decodes a string containing a base64 sequence.

View Source
var Base64EncodeFunc = 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(base64.StdEncoding.EncodeToString([]byte(args[0].AsString()))), nil
	},
})

Base64EncodeFunc constructs a function that encodes a string to a base64 sequence.

View Source
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) {
		s := args[0].AsString()

		var b bytes.Buffer
		gz := gzip.NewWriter(&b)
		if _, err := gz.Write([]byte(s)); err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("failed to write gzip raw data: '%s'", s)
		}
		if err := gz.Flush(); err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("failed to flush gzip writer: '%s'", s)
		}
		if err := gz.Close(); err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("failed to close gzip writer: '%s'", s)
		}
		return cty.StringVal(base64.StdEncoding.EncodeToString(b.Bytes())), nil
	},
})

Base64GzipFunc constructs a function that compresses a string with gzip and then encodes the result in Base64 encoding.

View Source
var Base64Sha256Func = 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) (ret cty.Value, err error) {
		s := args[0].AsString()
		h := sha256.New()
		h.Write([]byte(s))
		shaSum := h.Sum(nil)
		return cty.StringVal(base64.StdEncoding.EncodeToString(shaSum[:])), nil
	},
})

Base64Sha256Func constructs a function that computes the SHA256 hash of a given string and encodes it with Base64.

View Source
var Base64Sha512Func = 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) (ret cty.Value, err error) {
		s := args[0].AsString()
		h := sha512.New()
		h.Write([]byte(s))
		shaSum := h.Sum(nil)
		return cty.StringVal(base64.StdEncoding.EncodeToString(shaSum[:])), nil
	},
})

Base64Sha512Func constructs a function that computes the SHA256 hash of a given string and encodes it with Base64.

View Source
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
	},
})

BasenameFunc constructs a function that takes a string containing a filesystem path and removes all except the last portion from it.

View Source
var BcryptFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "str",
			Type: cty.String,
		},
	},
	VarParam: &function.Parameter{
		Name: "cost",
		Type: cty.Number,
	},
	Type: function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		defaultCost := 10

		if len(args) > 1 {
			var val int
			if err := gocty.FromCtyValue(args[1], &val); err != nil {
				return cty.UnknownVal(cty.String), err
			}
			defaultCost = val
		}

		if len(args) > 2 {
			return cty.UnknownVal(cty.String), fmt.Errorf("bcrypt() takes no more than two arguments")
		}

		input := args[0].AsString()
		out, err := bcrypt.GenerateFromPassword([]byte(input), defaultCost)
		if err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("error occured generating password %s", err.Error())
		}

		return cty.StringVal(string(out)), nil
	},
})

BcryptFunc constructs a function that computes a hash of the given string using the Blowfish cipher.

View Source
var CeilFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "num",
			Type: cty.Number,
		},
	},
	Type: function.StaticReturnType(cty.Number),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		var val float64
		if err := gocty.FromCtyValue(args[0], &val); err != nil {
			return cty.UnknownVal(cty.String), err
		}
		return cty.NumberIntVal(int64(math.Ceil(val))), nil
	},
})

CeilFunc contructs a function that returns the closest whole number greater than or equal to the given value.

View Source
var ChompFunc = 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) (ret cty.Value, err error) {
		newlines := regexp.MustCompile(`(?:\r\n?|\n)*\z`)
		return cty.StringVal(newlines.ReplaceAllString(args[0].AsString(), "")), nil
	},
})

ChompFunc constructions a function that removes newline characters at the end of a string.

View Source
var ChunklistFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "list",
			Type: cty.List(cty.DynamicPseudoType),
		},
		{
			Name: "size",
			Type: cty.Number,
		},
	},
	Type: func(args []cty.Value) (cty.Type, error) {
		return cty.List(args[0].Type()), nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		listVal := args[0]
		if !listVal.IsWhollyKnown() {
			return cty.UnknownVal(retType), nil
		}

		var size int
		err = gocty.FromCtyValue(args[1], &size)
		if err != nil {
			return cty.NilVal, fmt.Errorf("invalid index: %s", err)
		}

		if size < 0 {
			return cty.NilVal, fmt.Errorf("the size argument must be positive")
		}

		output := make([]cty.Value, 0)

		if size == 0 {
			output = append(output, listVal)
			return cty.ListVal(output), nil
		}

		chunk := make([]cty.Value, 0)

		l := args[0].LengthInt()
		i := 0

		for it := listVal.ElementIterator(); it.Next(); {
			_, v := it.Element()
			chunk = append(chunk, v)

			if (i+1)%size == 0 || (i+1) == l {
				output = append(output, cty.ListVal(chunk))
				chunk = make([]cty.Value, 0)
			}
			i++
		}

		return cty.ListVal(output), nil
	},
})

ChunklistFunc contructs a function that splits a single list into fixed-size chunks, returning a list of lists.

View Source
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) (ret cty.Value, err error) {
		var hostNum int
		if err := gocty.FromCtyValue(args[1], &hostNum); err != nil {
			return cty.UnknownVal(cty.String), err
		}
		_, network, err := net.ParseCIDR(args[0].AsString())
		if err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
		}

		ip, err := cidr.Host(network, hostNum)
		if err != nil {
			return cty.UnknownVal(cty.String), err
		}

		return cty.StringVal(ip.String()), nil
	},
})

CidrHostFunc contructs a function that calculates a full host IP address within a given IP network address prefix.

View Source
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) (ret cty.Value, err error) {
		_, network, err := net.ParseCIDR(args[0].AsString())
		if err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
		}

		return cty.StringVal(net.IP(network.Mask).String()), nil
	},
})

CidrNetmaskFunc contructs a function that converts an IPv4 address prefix given in CIDR notation into a subnet mask address.

View Source
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) (ret cty.Value, err error) {
		var newbits int
		if err := gocty.FromCtyValue(args[1], &newbits); err != nil {
			return cty.UnknownVal(cty.String), err
		}
		var netnum int
		if err := gocty.FromCtyValue(args[2], &netnum); err != nil {
			return cty.UnknownVal(cty.String), err
		}

		_, network, err := net.ParseCIDR(args[0].AsString())
		if err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
		}

		if newbits > 32 {
			return cty.UnknownVal(cty.String), fmt.Errorf("may not extend prefix by more than 32 bits")
		}

		newNetwork, err := cidr.Subnet(network, newbits, netnum)
		if err != nil {
			return cty.UnknownVal(cty.String), err
		}

		return cty.StringVal(newNetwork.String()), nil
	},
})

CidrSubnetFunc contructs a function that calculates a subnet address within a given IP network address prefix.

View Source
var CoalesceListFunc = function.New(&function.Spec{
	Params: []function.Parameter{},
	VarParam: &function.Parameter{
		Name:             "vals",
		Type:             cty.List(cty.DynamicPseudoType),
		AllowUnknown:     true,
		AllowDynamicType: true,
		AllowNull:        true,
	},
	Type: func(args []cty.Value) (ret cty.Type, err error) {
		if len(args) == 0 {
			return cty.NilType, fmt.Errorf("at least one argument is required")
		}

		argTypes := make([]cty.Type, len(args))

		for i, arg := range args {
			argTypes[i] = arg.Type()
		}

		retType, _ := convert.UnifyUnsafe(argTypes)
		if retType == cty.NilType {
			return cty.NilType, fmt.Errorf("all arguments must have the same type")
		}

		return retType, nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {

		vals := make([]cty.Value, 0, len(args))
		for _, arg := range args {
			if !arg.IsKnown() {

				return cty.UnknownVal(retType), nil
			}

			arg, _ = convert.Convert(arg, retType)

			it := arg.ElementIterator()
			for it.Next() {
				_, v := it.Element()
				vals = append(vals, v)
			}

			if len(vals) > 0 {
				return cty.ListVal(vals), nil
			}
		}

		return cty.NilVal, fmt.Errorf("no non-null arguments")
	},
})

CoalesceListFunc contructs a function that takes any number of list arguments and returns the first one that isn't empty.

View Source
var CompactFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "list",
			Type: cty.List(cty.String),
		},
	},
	Type: function.StaticReturnType(cty.List(cty.String)),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		listVal := args[0]
		if !listVal.IsWhollyKnown() {

			return cty.UnknownVal(retType), nil
		}

		var outputList []cty.Value

		for it := listVal.ElementIterator(); it.Next(); {
			_, v := it.Element()
			if v.AsString() == "" {
				continue
			}
			outputList = append(outputList, v)
		}

		if len(outputList) == 0 {
			return cty.ListValEmpty(cty.String), nil
		}

		return cty.ListVal(outputList), nil
	},
})

CompactFunc contructs a function that takes a list of strings and returns a new list with any empty string elements removed.

View Source
var ContainsFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "list",
			Type: cty.List(cty.DynamicPseudoType),
		},
		{
			Name: "value",
			Type: cty.DynamicPseudoType,
		},
	},
	Type: function.StaticReturnType(cty.Bool),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {

		_, err = Index(args[0], args[1])
		if err != nil {
			return cty.False, nil
		}

		return cty.True, nil
	},
})

ContainsFunc contructs a function that determines whether a given list contains a given single value as one of its elements.

View Source
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
	},
})

DirnameFunc constructs a function that takes a string containing a filesystem path and removes the last portion from it.

View Source
var DistinctFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "list",
			Type: cty.List(cty.DynamicPseudoType),
		},
	},
	Type: func(args []cty.Value) (cty.Type, error) {
		return args[0].Type(), nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		listVal := args[0]

		if !listVal.IsWhollyKnown() {
			return cty.UnknownVal(retType), nil
		}
		var list []cty.Value

		for it := listVal.ElementIterator(); it.Next(); {
			_, v := it.Element()
			list, err = appendIfMissing(list, v)
			if err != nil {
				return cty.NilVal, err
			}
		}

		return cty.ListVal(list), nil
	},
})

DistinctFunc contructs a function that takes a list and returns a new list with any duplicate elements removed.

View Source
var ElementFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "list",
			Type: cty.DynamicPseudoType,
		},
		{
			Name: "index",
			Type: cty.Number,
		},
	},
	Type: func(args []cty.Value) (cty.Type, error) {
		list := args[0]
		listTy := list.Type()
		switch {
		case listTy.IsListType():
			return listTy.ElementType(), nil
		case listTy.IsTupleType():
			if !args[1].IsKnown() {

				return cty.DynamicPseudoType, nil
			}

			etys := listTy.TupleElementTypes()
			var index int
			err := gocty.FromCtyValue(args[1], &index)
			if err != nil {

				return cty.DynamicPseudoType, fmt.Errorf("invalid index: %s", err)
			}
			if len(etys) == 0 {
				return cty.DynamicPseudoType, fmt.Errorf("cannot use element function with an empty list")
			}
			index = index % len(etys)
			return etys[index], nil
		default:
			return cty.DynamicPseudoType, fmt.Errorf("cannot read elements from %s", listTy.FriendlyName())
		}
	},
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		var index int
		err := gocty.FromCtyValue(args[1], &index)
		if err != nil {

			return cty.DynamicVal, fmt.Errorf("invalid index: %s", err)
		}

		if !args[0].IsKnown() {
			return cty.UnknownVal(retType), nil
		}

		l := args[0].LengthInt()
		if l == 0 {
			return cty.DynamicVal, fmt.Errorf("cannot use element function with an empty list")
		}
		index = index % l

		return args[0].Index(cty.NumberIntVal(int64(index))), nil
	},
})
View Source
var FlattenFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "list",
			Type: cty.List(cty.DynamicPseudoType),
		},
	},
	Type: function.StaticReturnType(cty.List(cty.DynamicPseudoType)),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		inputList := args[0]
		if !inputList.IsWhollyKnown() {
			return cty.UnknownVal(retType), nil
		}

		if inputList.LengthInt() == 0 {
			return cty.ListValEmpty(retType.ElementType()), nil
		}
		outputList := make([]cty.Value, 0)

		return cty.ListVal(flattener(outputList, inputList)), nil
	},
})

FlattenFunc contructs a function that takes a list and replaces any elements that are lists with a flattened sequence of the list contents.

View Source
var FloorFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "num",
			Type: cty.Number,
		},
	},
	Type: function.StaticReturnType(cty.Number),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		var val float64
		if err := gocty.FromCtyValue(args[0], &val); err != nil {
			return cty.UnknownVal(cty.String), err
		}
		return cty.NumberIntVal(int64(math.Floor(val))), nil
	},
})

FloorFunc contructs a function that returns the closest whole number lesser than or equal to the given value.

View Source
var IndentFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "spaces",
			Type: cty.Number,
		},
		{
			Name: "str",
			Type: cty.String,
		},
	},
	Type: function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		var spaces int
		if err := gocty.FromCtyValue(args[0], &spaces); err != nil {
			return cty.UnknownVal(cty.String), err
		}
		data := args[1].AsString()
		pad := strings.Repeat(" ", spaces)
		return cty.StringVal(strings.Replace(data, "\n", "\n"+pad, -1)), nil
	},
})

IndentFunc constructions a function that adds a given number of spaces to the beginnings of all but the first line in a given multi-line string.

View Source
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) (ret cty.Value, err error) {
		if !(args[0].Type().IsListType() || args[0].Type().IsTupleType()) {
			return cty.NilVal, fmt.Errorf("argument must be a list or tuple")
		}

		if !args[0].IsKnown() {
			return cty.UnknownVal(cty.Number), nil
		}

		if args[0].LengthInt() == 0 {
			return cty.NilVal, fmt.Errorf("cannot search an empty list")
		}

		for it := args[0].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, fmt.Errorf("item not found")

	},
})

IndexFunc contructs a function that finds the element index for a given value in a list.

View Source
var JoinFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "separator",
			Type: cty.String,
		},
	},
	VarParam: &function.Parameter{
		Name: "lists",
		Type: cty.List(cty.String),
	},
	Type: function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		sep := args[0].AsString()
		listVals := args[1:]
		if len(listVals) < 1 {
			return cty.UnknownVal(cty.String), fmt.Errorf("at least one list is required")
		}

		l := 0
		for _, list := range listVals {
			if !list.IsWhollyKnown() {
				return cty.UnknownVal(cty.String), nil
			}
			l += list.LengthInt()
		}

		items := make([]string, 0, l)
		for _, list := range listVals {
			for it := list.ElementIterator(); it.Next(); {
				_, val := it.Element()
				items = append(items, val.AsString())
			}
		}

		return cty.StringVal(strings.Join(items, sep)), nil
	},
})
View Source
var KeysFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name:         "inputMap",
			Type:         cty.DynamicPseudoType,
			AllowUnknown: true,
		},
	},
	Type: func(args []cty.Value) (cty.Type, error) {
		ty := args[0].Type()
		switch {
		case ty.IsMapType():
			return cty.List(cty.String), nil
		case ty.IsObjectType():
			atys := ty.AttributeTypes()
			if len(atys) == 0 {
				return cty.EmptyTuple, nil
			}

			etys := make([]cty.Type, len(atys))
			for i := range etys {
				etys[i] = cty.String
			}
			return cty.Tuple(etys), nil
		default:
			return cty.DynamicPseudoType, function.NewArgErrorf(0, "must have map or object type")
		}
	},
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		m := args[0]
		var keys []cty.Value

		switch {
		case m.Type().IsObjectType():
			// In this case we allow unknown values so we must work only with
			// the attribute _types_, not with the value itself.
			var names []string
			for name := range m.Type().AttributeTypes() {
				names = append(names, name)
			}
			sort.Strings(names)
			if len(names) == 0 {
				return cty.EmptyTupleVal, nil
			}
			keys = make([]cty.Value, len(names))
			for i, name := range names {
				keys[i] = cty.StringVal(name)
			}
			return cty.TupleVal(keys), nil
		default:
			if !m.IsKnown() {
				return cty.UnknownVal(retType), nil
			}

			for it := args[0].ElementIterator(); it.Next(); {
				k, _ := it.Element()
				keys = append(keys, k)
			}
			if len(keys) == 0 {
				return cty.ListValEmpty(cty.String), nil
			}
			return cty.ListVal(keys), nil
		}
	},
})

KeysFunc contructs a function that takes a map and returns a sorted list of the map keys.

View Source
var LengthFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name:             "value",
			Type:             cty.DynamicPseudoType,
			AllowDynamicType: true,
			AllowUnknown:     true,
		},
	},
	Type: func(args []cty.Value) (cty.Type, error) {
		collTy := args[0].Type()
		switch {
		case collTy == cty.String || collTy.IsTupleType() || collTy.IsObjectType() || collTy.IsListType() || collTy.IsMapType() || collTy.IsSetType() || collTy == cty.DynamicPseudoType:
			return cty.Number, nil
		default:
			return cty.Number, fmt.Errorf("argument must be a string, a collection type, or a structural type")
		}
	},
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		coll := args[0]
		collTy := args[0].Type()
		switch {
		case collTy == cty.DynamicPseudoType:
			return cty.UnknownVal(cty.Number), nil
		case collTy.IsTupleType():
			l := len(collTy.TupleElementTypes())
			return cty.NumberIntVal(int64(l)), nil
		case collTy.IsObjectType():
			l := len(collTy.AttributeTypes())
			return cty.NumberIntVal(int64(l)), nil
		case collTy == cty.String:

			return stdlib.Strlen(coll)
		case collTy.IsListType() || collTy.IsSetType() || collTy.IsMapType():
			return coll.Length(), nil
		default:

			return cty.UnknownVal(cty.Number), fmt.Errorf("impossible value type for length(...)")
		}
	},
})
View Source
var ListFunc = 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) (ret cty.Type, err error) {
		if len(args) == 0 {
			return cty.NilType, fmt.Errorf("at least one argument is required")
		}

		argTypes := make([]cty.Type, len(args))

		for i, arg := range args {
			argTypes[i] = arg.Type()
		}

		retType, _ := convert.UnifyUnsafe(argTypes)
		if retType == cty.NilType {
			return cty.NilType, fmt.Errorf("all arguments must have the same type")
		}

		return cty.List(retType), nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		newList := make([]cty.Value, 0, len(args))

		for _, arg := range args {

			arg, _ = convert.Convert(arg, retType.ElementType())
			newList = append(newList, arg)
		}

		return cty.ListVal(newList), nil
	},
})

ListFunc contructs a function that takes an arbitrary number of arguments and returns a list containing those values in the same order.

This function is deprecated in Terraform v0.12

View Source
var LogFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "num",
			Type: cty.Number,
		},
		{
			Name: "base",
			Type: cty.Number,
		},
	},
	Type: function.StaticReturnType(cty.Number),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		var num float64
		if err := gocty.FromCtyValue(args[0], &num); err != nil {
			return cty.UnknownVal(cty.String), err
		}

		var base float64
		if err := gocty.FromCtyValue(args[1], &base); err != nil {
			return cty.UnknownVal(cty.String), err
		}

		return cty.NumberFloatVal(math.Log(num) / math.Log(base)), nil
	},
})

LogFunc contructs a function that returns the logarithm of a given number in a given base.

View Source
var LookupFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "inputMap",
			Type: cty.DynamicPseudoType,
		},
		{
			Name: "key",
			Type: cty.String,
		},
	},
	VarParam: &function.Parameter{
		Name:             "default",
		Type:             cty.DynamicPseudoType,
		AllowUnknown:     true,
		AllowDynamicType: true,
		AllowNull:        true,
	},
	Type: func(args []cty.Value) (ret cty.Type, err error) {
		if len(args) < 1 || 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
			}

			key := args[1].AsString()
			if ty.HasAttribute(key) {
				return args[0].GetAttr(key).Type(), nil
			} else 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():
			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) (ret cty.Value, err error) {
		var defaultVal cty.Value
		defaultValueSet := false

		if len(args) == 3 {
			defaultVal = args[2]
			defaultValueSet = true
		}

		mapVar := args[0]
		lookupKey := args[1].AsString()

		if !mapVar.IsWhollyKnown() {
			return cty.UnknownVal(retType), nil
		}

		if mapVar.Type().IsObjectType() {
			if mapVar.Type().HasAttribute(lookupKey) {
				return mapVar.GetAttr(lookupKey), nil
			}
		} else if mapVar.HasIndex(cty.StringVal(lookupKey)) == cty.True {
			v := mapVar.Index(cty.StringVal(lookupKey))
			if ty := v.Type(); !ty.Equals(cty.NilType) {
				switch {
				case ty.Equals(cty.String):
					return cty.StringVal(v.AsString()), nil
				case ty.Equals(cty.Number):
					return cty.NumberVal(v.AsBigFloat()), nil
				default:
					return cty.NilVal, fmt.Errorf("lookup() can only be used with flat lists")
				}
			}
		}

		if defaultValueSet {
			defaultVal, err = convert.Convert(defaultVal, retType)
			if err != nil {
				return cty.NilVal, err
			}
			return defaultVal, nil
		}

		return cty.UnknownVal(cty.DynamicPseudoType), fmt.Errorf(
			"lookup failed to find '%s'", lookupKey)
	},
})

LookupFunc contructs a function that performs dynamic lookups of map types.

View Source
var MapFunc = 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) (ret cty.Type, err error) {
		if len(args) < 2 || len(args)%2 != 0 {
			return cty.NilType, fmt.Errorf("map requires an even number of two or more arguments, got %d", len(args))
		}

		argTypes := make([]cty.Type, len(args)/2)
		index := 0

		for i := 0; i < len(args); i += 2 {
			argTypes[index] = args[i+1].Type()
			index++
		}

		valType, _ := convert.UnifyUnsafe(argTypes)
		if valType == cty.NilType {
			return cty.NilType, fmt.Errorf("all arguments must have the same type")
		}

		return cty.Map(valType), nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		for _, arg := range args {
			if !arg.IsWhollyKnown() {
				return cty.UnknownVal(retType), nil
			}
		}

		outputMap := make(map[string]cty.Value)

		for i := 0; i < len(args); i += 2 {

			key := args[i].AsString()

			err := gocty.FromCtyValue(args[i], &key)
			if err != nil {
				return cty.NilVal, err
			}

			val := args[i+1]

			var variable cty.Value
			err = gocty.FromCtyValue(val, &variable)
			if err != nil {
				return cty.NilVal, err
			}

			variable, _ = convert.Convert(variable, retType.ElementType())

			if _, ok := outputMap[key]; ok {
				return cty.NilVal, fmt.Errorf("argument %d is a duplicate key: %q", i+1, key)
			}
			outputMap[key] = variable
		}

		return cty.MapVal(outputMap), nil
	},
})

MapFunc contructs a function that takes an even number of arguments and returns a map whose elements are constructed from consecutive pairs of arguments.

This function is deprecated in Terraform v0.12

View Source
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 !args[1].Type().Equals(args[2].Type()) {
			return cty.NilType, fmt.Errorf("lists must be of the same type")
		}

		return args[0].Type(), nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		if !args[0].IsKnown() {
			return cty.UnknownVal(cty.List(retType.ElementType())), nil
		}

		if args[0].LengthInt() != args[1].LengthInt() {
			return cty.ListValEmpty(retType.ElementType()), fmt.Errorf("length of keys and values should be equal")
		}

		output := make([]cty.Value, 0)

		values := args[0]
		keys := args[1]
		searchset := args[2]

		if searchset.LengthInt() == 0 {
			return cty.ListValEmpty(retType.ElementType()), nil
		}

		if !values.IsWhollyKnown() || !keys.IsWhollyKnown() {
			return cty.UnknownVal(retType), nil
		}

		i := 0
		for it := keys.ElementIterator(); it.Next(); {
			_, key := it.Element()
			for iter := searchset.ElementIterator(); iter.Next(); {
				_, search := iter.Element()
				eq, err := stdlib.Equal(key, search)
				if err != nil {
					return cty.NilVal, err
				}
				if !eq.IsKnown() {
					return cty.ListValEmpty(retType.ElementType()), nil
				}
				if eq.True() {
					v := values.Index(cty.NumberIntVal(int64(i)))
					output = append(output, v)
					break
				}
			}
			i++
		}

		if len(output) == 0 {
			return cty.ListValEmpty(retType.ElementType()), nil
		}
		return cty.ListVal(output), nil
	},
})

MatchkeysFunc contructs a function that constructs a new list by taking a subset of elements from one list whose indexes match the corresponding indexes of values in another list.

View Source
var Md5Func = 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) (ret cty.Value, err error) {
		s := args[0].AsString()
		h := md5.New()
		h.Write([]byte(s))
		hash := hex.EncodeToString(h.Sum(nil))
		return cty.StringVal(hash), nil
	},
})

Md5Func constructs a function that computes the MD5 hash of a given string and encodes it with hexadecimal digits.

View Source
var MergeFunc = function.New(&function.Spec{
	Params: []function.Parameter{},
	VarParam: &function.Parameter{
		Name:             "maps",
		Type:             cty.DynamicPseudoType,
		AllowDynamicType: true,
		AllowNull:        true,
	},
	Type: function.StaticReturnType(cty.DynamicPseudoType),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		outputMap := make(map[string]cty.Value)

		for _, arg := range args {
			if !arg.IsWhollyKnown() {
				return cty.UnknownVal(retType), nil
			}
			if !arg.Type().IsObjectType() && !arg.Type().IsMapType() {
				return cty.NilVal, fmt.Errorf("arguments must be maps or objects, got %#v", arg.Type().FriendlyName())
			}
			for it := arg.ElementIterator(); it.Next(); {
				k, v := it.Element()
				outputMap[k.AsString()] = v
			}
		}
		return cty.ObjectVal(outputMap), nil
	},
})

MergeFunc contructs a function that takes an arbitrary number of maps and returns a single map that contains a merged set of elements from all of the maps.

If more than one given map defines the same key then the one that is later in the argument sequence takes precedence.

View Source
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) {

		homePath, err := homedir.Expand(args[0].AsString())
		return cty.StringVal(homePath), err
	},
})

PathExpandFunc constructs a function that expands a leading ~ character to the current user's home directory.

View Source
var PowFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "num",
			Type: cty.Number,
		},
		{
			Name: "power",
			Type: cty.Number,
		},
	},
	Type: function.StaticReturnType(cty.Number),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		var num float64
		if err := gocty.FromCtyValue(args[0], &num); err != nil {
			return cty.UnknownVal(cty.String), err
		}

		var power float64
		if err := gocty.FromCtyValue(args[1], &power); err != nil {
			return cty.UnknownVal(cty.String), err
		}

		return cty.NumberFloatVal(math.Pow(num, power)), nil
	},
})

PowFunc contructs a function that returns the logarithm of a given number in a given base.

View Source
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) (ret cty.Value, err error) {
		str := args[0].AsString()
		substr := args[1].AsString()
		replace := args[2].AsString()

		if len(substr) > 1 && substr[0] == '/' && substr[len(substr)-1] == '/' {
			re, err := regexp.Compile(substr[1 : len(substr)-1])
			if err != nil {
				return cty.UnknownVal(cty.String), err
			}

			return cty.StringVal(re.ReplaceAllString(str, replace)), nil
		}

		return cty.StringVal(strings.Replace(str, substr, replace, -1)), nil
	},
})

ReplaceFunc constructions a function that searches a given string for another given substring, and replaces each occurence with a given replacement string.

View Source
var RsaDecryptFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "ciphertext",
			Type: cty.String,
		},
		{
			Name: "privatekey",
			Type: cty.String,
		},
	},
	Type: function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		s := args[0].AsString()
		key := args[1].AsString()

		b, err := base64.StdEncoding.DecodeString(s)
		if err != nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("failed to decode input %q: cipher text must be base64-encoded", s)
		}

		block, _ := pem.Decode([]byte(key))
		if block == nil {
			return cty.UnknownVal(cty.String), fmt.Errorf("failed to parse key: no key found")
		}
		if block.Headers["Proc-Type"] == "4,ENCRYPTED" {
			return cty.UnknownVal(cty.String), fmt.Errorf(
				"failed to parse key: password protected keys are not supported. Please decrypt the key prior to use",
			)
		}

		x509Key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
		if err != nil {
			return cty.UnknownVal(cty.String), err
		}

		out, err := rsa.DecryptPKCS1v15(nil, x509Key, b)
		if err != nil {
			return cty.UnknownVal(cty.String), err
		}

		return cty.StringVal(string(out)), nil
	},
})

RsaDecryptFunc constructs a function that decrypts an RSA-encrypted ciphertext.

View Source
var Sha1Func = 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) (ret cty.Value, err error) {
		s := args[0].AsString()
		h := sha1.New()
		h.Write([]byte(s))
		hash := hex.EncodeToString(h.Sum(nil))
		return cty.StringVal(hash), nil
	},
})

Sha1Func contructs a function that computes the SHA1 hash of a given string and encodes it with hexadecimal digits.

View Source
var Sha256Func = 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) (ret cty.Value, err error) {
		s := args[0].AsString()
		h := sha256.New()
		h.Write([]byte(s))
		hash := hex.EncodeToString(h.Sum(nil))
		return cty.StringVal(hash), nil
	},
})

Sha256Func contructs a function that computes the SHA256 hash of a given string and encodes it with hexadecimal digits.

View Source
var Sha512Func = 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) (ret cty.Value, err error) {
		s := args[0].AsString()
		h := sha256.New()
		h.Write([]byte(s))
		hash := hex.EncodeToString(h.Sum(nil))
		return cty.StringVal(hash), nil
	},
})

Sha512Func contructs a function that computes the SHA256 hash of a given string and encodes it with hexadecimal digits.

View Source
var SignumFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "num",
			Type: cty.Number,
		},
	},
	Type: function.StaticReturnType(cty.Number),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		var num int
		if err := gocty.FromCtyValue(args[0], &num); err != nil {
			return cty.UnknownVal(cty.String), err
		}
		switch {
		case num < 0:
			return cty.NumberIntVal(-1), nil
		case num > 0:
			return cty.NumberIntVal(+1), nil
		default:
			return cty.NumberIntVal(0), nil
		}
	},
})

SignumFunc contructs a function that returns the closest whole number greater than or equal to the given value.

View Source
var SliceFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "list",
			Type: cty.List(cty.DynamicPseudoType),
		},
		{
			Name: "startIndex",
			Type: cty.Number,
		},
		{
			Name: "endIndex",
			Type: cty.Number,
		},
	},
	Type: func(args []cty.Value) (cty.Type, error) {
		return args[0].Type(), nil
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		inputList := args[0]
		if !inputList.IsWhollyKnown() {
			return cty.UnknownVal(retType), nil
		}
		var startIndex, endIndex int

		if err = gocty.FromCtyValue(args[1], &startIndex); err != nil {
			return cty.NilVal, fmt.Errorf("invalid start index: %s", err)
		}
		if err = gocty.FromCtyValue(args[2], &endIndex); err != nil {
			return cty.NilVal, fmt.Errorf("invalid start index: %s", err)
		}

		if startIndex < 0 {
			return cty.NilVal, fmt.Errorf("from index must be >= 0")
		}
		if endIndex > inputList.LengthInt() {
			return cty.NilVal, fmt.Errorf("to index must be <= length of the input list")
		}
		if startIndex > endIndex {
			return cty.NilVal, fmt.Errorf("from index must be <= to index")
		}

		var outputList []cty.Value

		i := 0
		for it := inputList.ElementIterator(); it.Next(); {
			_, v := it.Element()
			if i >= startIndex && i < endIndex {
				outputList = append(outputList, v)
			}
			i++
		}

		if len(outputList) == 0 {
			return cty.ListValEmpty(retType.ElementType()), nil
		}
		return cty.ListVal(outputList), nil
	},
})

SliceFunc contructs a function that extracts some consecutive elements from within a list.

View Source
var SortFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "list",
			Type: cty.List(cty.String),
		},
	},
	Type: function.StaticReturnType(cty.List(cty.String)),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		listVal := args[0]

		if !listVal.IsWhollyKnown() {

			return cty.UnknownVal(retType), nil
		}
		if listVal.LengthInt() == 0 {
			return listVal, nil
		}

		list := make([]string, 0, listVal.LengthInt())
		for it := listVal.ElementIterator(); it.Next(); {
			iv, v := it.Element()
			if v.IsNull() {
				return cty.UnknownVal(retType), fmt.Errorf("given list element %s is null; a null string cannot be sorted", iv.AsBigFloat().String())
			}
			list = append(list, v.AsString())
		}

		sort.Strings(list)
		retVals := make([]cty.Value, len(list))
		for i, s := range list {
			retVals[i] = cty.StringVal(s)
		}
		return cty.ListVal(retVals), nil
	},
})
View Source
var SplitFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "separator",
			Type: cty.String,
		},
		{
			Name: "str",
			Type: cty.String,
		},
	},
	Type: function.StaticReturnType(cty.List(cty.String)),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		sep := args[0].AsString()
		str := args[1].AsString()
		elems := strings.Split(str, sep)
		elemVals := make([]cty.Value, len(elems))
		for i, s := range elems {
			elemVals[i] = cty.StringVal(s)
		}
		if len(elemVals) == 0 {
			return cty.ListValEmpty(cty.String), nil
		}
		return cty.ListVal(elemVals), nil
	},
})
View Source
var TimeAddFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "timestamp",
			Type: cty.String,
		},
		{
			Name: "duration",
			Type: cty.String,
		},
	},
	Type: function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		ts, err := time.Parse(time.RFC3339, args[0].AsString())
		if err != nil {
			return cty.UnknownVal(cty.String), err
		}
		duration, err := time.ParseDuration(args[1].AsString())
		if err != nil {
			return cty.UnknownVal(cty.String), err
		}

		return cty.StringVal(ts.Add(duration).Format(time.RFC3339)), nil
	},
})

TimeAddFunc constructs a function that adds a duration to a timestamp, returning a new timestamp.

View Source
var TimestampFunc = function.New(&function.Spec{
	Params: []function.Parameter{},
	Type:   function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
		return cty.StringVal(time.Now().UTC().Format(time.RFC3339)), nil
	},
})

TimestampFunc constructs a function that returns a string representation of the current date and time.

View Source
var TitleFunc = 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) (ret cty.Value, err error) {
		return cty.StringVal(strings.Title(args[0].AsString())), nil
	},
})

TitleFunc constructions a function that converts the first letter of each word in the given string to uppercase.

View Source
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) (ret cty.Value, err error) {
		inputMap := args[0]
		if !inputMap.IsWhollyKnown() {
			return cty.UnknownVal(retType), nil
		}

		outputMap := make(map[string]cty.Value)
		tmpMap := make(map[string][]string)

		for it := inputMap.ElementIterator(); it.Next(); {
			inKey, inVal := it.Element()
			for iter := inVal.ElementIterator(); iter.Next(); {
				_, val := iter.Element()
				if !val.Type().Equals(cty.String) {
					return cty.MapValEmpty(cty.List(cty.String)), fmt.Errorf("input must be a map of lists of strings")
				}

				outKey := val.AsString()
				if _, ok := tmpMap[outKey]; !ok {
					tmpMap[outKey] = make([]string, 0)
				}
				outVal := tmpMap[outKey]
				outVal = append(outVal, inKey.AsString())
				sort.Strings(outVal)
				tmpMap[outKey] = outVal
			}
		}

		for outKey, outVal := range tmpMap {
			values := make([]cty.Value, 0)
			for _, v := range outVal {
				values = append(values, cty.StringVal(v))
			}
			outputMap[outKey] = cty.ListVal(values)
		}

		return cty.MapVal(outputMap), nil
	},
})

TransposeFunc contructs a function that takes a map of lists of strings and swaps the keys and values to produce a new map of lists of strings.

View Source
var TrimSpaceFunc = 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) (ret cty.Value, err error) {
		return cty.StringVal(strings.TrimSpace(args[0].AsString())), nil
	},
})

TrimSpaceFunc constructions a function that removes any space characters from the start and end of the given string.

View Source
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
	},
})

URLEncodeFunc constructs a function that applies URL encoding to a given string.

View Source
var UUIDFunc = function.New(&function.Spec{
	Params: []function.Parameter{},
	Type:   function.StaticReturnType(cty.String),
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		result, err := uuid.GenerateUUID()
		if err != nil {
			return cty.UnknownVal(cty.String), err
		}
		return cty.StringVal(result), nil
	},
})
View Source
var ValuesFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "values",
			Type: cty.DynamicPseudoType,
		},
	},
	Type: func(args []cty.Value) (ret cty.Type, err error) {
		ty := args[0].Type()
		if ty.IsMapType() {
			return cty.List(ty.ElementType()), nil
		} else if ty.IsObjectType() {

			atys := ty.AttributeTypes()
			if len(atys) == 0 {
				return cty.EmptyTuple, nil
			}
			attrNames := make([]string, 0, len(atys))
			for name := range atys {
				attrNames = append(attrNames, name)
			}
			sort.Strings(attrNames)

			tys := make([]cty.Type, len(attrNames))
			for i, name := range attrNames {
				tys[i] = atys[name]
			}
			return cty.Tuple(tys), nil
		}
		return cty.NilType, fmt.Errorf("values() requires a map as the first argument")
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		mapVar := args[0]

		// We can just iterate the map/object value here because cty guarantees
		// that these types always iterate in key lexicographical order.
		var values []cty.Value
		for it := mapVar.ElementIterator(); it.Next(); {
			_, val := it.Element()
			values = append(values, val)
		}

		if retType.IsTupleType() {
			return cty.TupleVal(values), nil
		}
		if len(values) == 0 {
			return cty.ListValEmpty(retType.ElementType()), nil
		}
		return cty.ListVal(values), nil
	},
})

ValuesFunc contructs a function that returns a list of the map values, in the order of the sorted keys.

View Source
var ZipmapFunc = function.New(&function.Spec{
	Params: []function.Parameter{
		{
			Name: "keys",
			Type: cty.List(cty.String),
		},
		{
			Name: "values",
			Type: cty.DynamicPseudoType,
		},
	},
	Type: func(args []cty.Value) (ret cty.Type, err error) {
		keys := args[0]
		values := args[1]
		valuesTy := values.Type()

		switch {
		case valuesTy.IsListType():
			return cty.Map(values.Type().ElementType()), nil
		case valuesTy.IsTupleType():
			if !keys.IsWhollyKnown() {

				return cty.DynamicPseudoType, nil
			}

			keysRaw := keys.AsValueSlice()
			valueTypesRaw := valuesTy.TupleElementTypes()
			if len(keysRaw) != len(valueTypesRaw) {
				return cty.NilType, fmt.Errorf("number of keys (%d) does not match number of values (%d)", len(keysRaw), len(valueTypesRaw))
			}
			atys := make(map[string]cty.Type, len(valueTypesRaw))
			for i, keyVal := range keysRaw {
				if keyVal.IsNull() {
					return cty.NilType, fmt.Errorf("keys list has null value at index %d", i)
				}
				key := keyVal.AsString()
				atys[key] = valueTypesRaw[i]
			}
			return cty.Object(atys), nil

		default:
			return cty.NilType, fmt.Errorf("values argument must be a list or tuple value")
		}
	},
	Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
		keys := args[0]
		values := args[1]

		if !keys.IsWhollyKnown() {

			return cty.UnknownVal(retType), nil
		}

		if keys.LengthInt() != values.LengthInt() {
			return cty.NilVal, fmt.Errorf("number of keys (%d) does not match number of values (%d)", keys.LengthInt(), values.LengthInt())
		}

		output := make(map[string]cty.Value)

		i := 0
		for it := keys.ElementIterator(); it.Next(); {
			_, v := it.Element()
			val := values.Index(cty.NumberIntVal(int64(i)))
			output[v.AsString()] = val
			i++
		}

		switch {
		case retType.IsMapType():
			if len(output) == 0 {
				return cty.MapValEmpty(retType.ElementType()), nil
			}
			return cty.MapVal(output), nil
		case retType.IsObjectType():
			return cty.ObjectVal(output), nil
		default:

			return cty.NilVal, fmt.Errorf("internally selected incorrect result type %s (this is a bug)", retType.FriendlyName())
		}
	},
})

ZipmapFunc contructs a function that constructs a map from a list of keys and a corresponding list of values.

Functions

func Base64Decode

func Base64Decode(str cty.Value) (cty.Value, error)

Base64Decode decodes a string containing a base64 sequence.

Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.

Strings in the Terraform language are sequences of unicode characters rather than bytes, so this function will also interpret the resulting bytes as UTF-8. If the bytes after Base64 decoding are _not_ valid UTF-8, this function produces an error.

func Base64Encode

func Base64Encode(str cty.Value) (cty.Value, error)

Base64Encode applies Base64 encoding to a string.

Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.

Strings in the Terraform language are sequences of unicode characters rather than bytes, so this function will first encode the characters from the string as UTF-8, and then apply Base64 encoding to the result.

func Base64Gzip

func Base64Gzip(str cty.Value) (cty.Value, error)

Base64Gzip compresses a string with gzip and then encodes the result in Base64 encoding.

Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.

Strings in the Terraform language are sequences of unicode characters rather than bytes, so this function will first encode the characters from the string as UTF-8, then apply gzip compression, and then finally apply Base64 encoding.

func Base64Sha256

func Base64Sha256(str cty.Value) (cty.Value, error)

Base64Sha256 computes the SHA256 hash of a given string and encodes it with Base64.

The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied as defined in RFC 4634. The raw hash is then encoded with Base64 before returning. Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.

func Base64Sha512

func Base64Sha512(str cty.Value) (cty.Value, error)

Base64Sha512 computes the SHA512 hash of a given string and encodes it with Base64.

The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied as defined in RFC 4634. The raw hash is then encoded with Base64 before returning. Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4

func Basename

func Basename(path cty.Value) (cty.Value, error)

Basename takes a string containing a filesystem path and removes all except the last portion from it.

The underlying function implementation works only with the path string and does not access the filesystem itself. It is therefore unable to take into account filesystem features such as symlinks.

If the path is empty then the result is ".", representing the current working directory.

func Bcrypt

func Bcrypt(str cty.Value, cost ...cty.Value) (cty.Value, error)

Bcrypt computes a hash of the given string using the Blowfish cipher, returning a string in the Modular Crypt Format usually expected in the shadow password file on many Unix systems.

func Ceil

func Ceil(num cty.Value) (cty.Value, error)

Ceil returns the closest whole number greater than or equal to the given value.

func Chomp

func Chomp(str cty.Value) (cty.Value, error)

Chomp removes newline characters at the end of a string.

func Chunklist

func Chunklist(list, size cty.Value) (cty.Value, error)

Chunklist splits a single list into fixed-size chunks, returning a list of lists.

func CidrHost

func CidrHost(prefix, hostnum cty.Value) (cty.Value, error)

CidrHost calculates a full host IP address within a given IP network address prefix.

func CidrNetmask

func CidrNetmask(prefix cty.Value) (cty.Value, error)

CidrNetmask converts an IPv4 address prefix given in CIDR notation into a subnet mask address.

func CidrSubnet

func CidrSubnet(prefix, newbits, netnum cty.Value) (cty.Value, error)

CidrSubnet calculates a subnet address within a given IP network address prefix.

func CoalesceList

func CoalesceList(args ...cty.Value) (cty.Value, error)

CoalesceList takes any number of list arguments and returns the first one that isn't empty.

func Compact

func Compact(list cty.Value) (cty.Value, error)

Compact takes a list of strings and returns a new list with any empty string elements removed.

func Contains

func Contains(list, value cty.Value) (cty.Value, error)

Contains determines whether a given list contains a given single value as one of its elements.

func Dirname

func Dirname(path cty.Value) (cty.Value, error)

Dirname takes a string containing a filesystem path and removes the last portion from it.

The underlying function implementation works only with the path string and does not access the filesystem itself. It is therefore unable to take into account filesystem features such as symlinks.

If the path is empty then the result is ".", representing the current working directory.

func Distinct

func Distinct(list cty.Value) (cty.Value, error)

Distinct takes a list and returns a new list with any duplicate elements removed.

func Element

func Element(list, index cty.Value) (cty.Value, error)

Element returns a single element from a given list at the given index. If index is greater than the length of the list then it is wrapped modulo the list length.

func File

func File(baseDir string, path cty.Value) (cty.Value, error)

File reads the contents of the file at the given path.

The file must contain valid UTF-8 bytes, or this function will return an error.

The underlying function implementation works relative to a particular base directory, so this wrapper takes a base directory string and uses it to construct the underlying function before calling it.

func FileBase64

func FileBase64(baseDir string, path cty.Value) (cty.Value, error)

FileBase64 reads the contents of the file at the given path.

The bytes from the file are encoded as base64 before returning.

The underlying function implementation works relative to a particular base directory, so this wrapper takes a base directory string and uses it to construct the underlying function before calling it.

func FileExists

func FileExists(baseDir string, path cty.Value) (cty.Value, error)

FileExists determines whether a file exists at the given path.

The underlying function implementation works relative to a particular base directory, so this wrapper takes a base directory string and uses it to construct the underlying function before calling it.

func Flatten

func Flatten(list cty.Value) (cty.Value, error)

Flatten takes a list and replaces any elements that are lists with a flattened sequence of the list contents.

func Floor

func Floor(num cty.Value) (cty.Value, error)

Floor returns the closest whole number lesser than or equal to the given value.

func Indent

func Indent(spaces, str cty.Value) (cty.Value, error)

Indent adds a given number of spaces to the beginnings of all but the first line in a given multi-line string.

func Index

func Index(list, value cty.Value) (cty.Value, error)

Index finds the element index for a given value in a list.

func Join

func Join(sep cty.Value, lists ...cty.Value) (cty.Value, error)

Join concatenates together the string elements of one or more lists with a given separator.

func Keys

func Keys(inputMap cty.Value) (cty.Value, error)

Keys takes a map and returns a sorted list of the map keys.

func Length

func Length(collection cty.Value) (cty.Value, error)

Length returns the number of elements in the given collection or number of Unicode characters in the given string.

func List

func List(args ...cty.Value) (cty.Value, error)

List takes any number of list arguments and returns a list containing those

values in the same order.

func Log

func Log(num, base cty.Value) (cty.Value, error)

Log returns returns the logarithm of a given number in a given base.

func Lookup

func Lookup(args ...cty.Value) (cty.Value, error)

Lookup performs a dynamic lookup into a map. There are two required arguments, map and key, plus an optional default, which is a value to return if no key is found in map.

func MakeFileExistsFunc

func MakeFileExistsFunc(baseDir string) function.Function

MakeFileExistsFunc constructs a function that takes a path and determines whether a file exists at that path

func MakeFileFunc

func MakeFileFunc(baseDir string, encBase64 bool) function.Function

MakeFileFunc constructs a function that takes a file path and returns the contents of that file, either directly as a string (where valid UTF-8 is required) or as a string containing base64 bytes.

func Map

func Map(args ...cty.Value) (cty.Value, error)

Map takes an even number of arguments and returns a map whose elements are constructed from consecutive pairs of arguments.

func Matchkeys

func Matchkeys(values, keys, searchset cty.Value) (cty.Value, error)

Matchkeys constructs a new list by taking a subset of elements from one list whose indexes match the corresponding indexes of values in another list.

func Md5

func Md5(str cty.Value) (cty.Value, error)

Md5 computes the MD5 hash of a given string and encodes it with hexadecimal digits.

func Merge

func Merge(maps ...cty.Value) (cty.Value, error)

Merge takes an arbitrary number of maps and returns a single map that contains a merged set of elements from all of the maps.

If more than one given map defines the same key then the one that is later in the argument sequence takes precedence.

func Pathexpand

func Pathexpand(path cty.Value) (cty.Value, error)

Pathexpand takes a string that might begin with a `~` segment, and if so it replaces that segment with the current user's home directory path.

The underlying function implementation works only with the path string and does not access the filesystem itself. It is therefore unable to take into account filesystem features such as symlinks.

If the leading segment in the path is not `~` then the given path is returned unmodified.

func Pow

func Pow(num, power cty.Value) (cty.Value, error)

Pow returns the logarithm of a given number in a given base.

func Replace

func Replace(str, substr, replace cty.Value) (cty.Value, error)

Replace searches a given string for another given substring, and replaces all occurences with a given replacement string.

func RsaDecrypt

func RsaDecrypt(ciphertext, privatekey cty.Value) (cty.Value, error)

RsaDecrypt decrypts an RSA-encrypted ciphertext, returning the corresponding cleartext.

func Sha1

func Sha1(str cty.Value) (cty.Value, error)

Sha1 computes the SHA1 hash of a given string and encodes it with hexadecimal digits.

func Sha256

func Sha256(str cty.Value) (cty.Value, error)

Sha256 computes the SHA256 hash of a given string and encodes it with hexadecimal digits.

func Sha512

func Sha512(str cty.Value) (cty.Value, error)

Sha512 computes the SHA512 hash of a given string and encodes it with hexadecimal digits.

func Signum

func Signum(num cty.Value) (cty.Value, error)

Signum determines the sign of a number, returning a number between -1 and 1 to represent the sign.

func Slice

func Slice(list, start, end cty.Value) (cty.Value, error)

Slice extracts some consecutive elements from within a list.

func Sort

func Sort(list cty.Value) (cty.Value, error)

Sort re-orders the elements of a given list of strings so that they are in ascending lexicographical order.

func Split

func Split(sep, str cty.Value) (cty.Value, error)

Split divides a given string by a given separator, returning a list of strings containing the characters between the separator sequences.

func TimeAdd

func TimeAdd(timestamp cty.Value, duration cty.Value) (cty.Value, error)

TimeAdd adds a duration to a timestamp, returning a new timestamp.

In the Terraform language, timestamps are conventionally represented as strings using RFC 3339 "Date and Time format" syntax. Timeadd requires the timestamp argument to be a string conforming to this syntax.

`duration` is a string representation of a time difference, consisting of sequences of number and unit pairs, like `"1.5h"` or `1h30m`. The accepted units are `ns`, `us` (or `µs`), `"ms"`, `"s"`, `"m"`, and `"h"`. The first number may be negative to indicate a negative duration, like `"-2h5m"`.

The result is a string, also in RFC 3339 format, representing the result of adding the given direction to the given timestamp.

func Timestamp

func Timestamp() (cty.Value, error)

Timestamp returns a string representation of the current date and time.

In the Terraform language, timestamps are conventionally represented as strings using RFC 3339 "Date and Time format" syntax, and so timestamp returns a string in this format.

func Title

func Title(str cty.Value) (cty.Value, error)

Title converts the first letter of each word in the given string to uppercase.

func Transpose

func Transpose(values cty.Value) (cty.Value, error)

Transpose takes a map of lists of strings and swaps the keys and values to produce a new map of lists of strings.

func TrimSpace

func TrimSpace(str cty.Value) (cty.Value, error)

TrimSpace removes any space characters from the start and end of the given string.

func URLEncode

func URLEncode(str cty.Value) (cty.Value, error)

URLEncode applies URL encoding to a given string.

This function identifies characters in the given string that would have a special meaning when included as a query string argument in a URL and escapes them using RFC 3986 "percent encoding".

If the given string contains non-ASCII characters, these are first encoded as UTF-8 and then percent encoding is applied separately to each UTF-8 byte.

func UUID

func UUID() (cty.Value, error)

UUID generates and returns a Type-4 UUID in the standard hexadecimal string format.

This is not a pure function: it will generate a different result for each call. It must therefore be registered as an impure function in the function table in the "lang" package.

func Values

func Values(values cty.Value) (cty.Value, error)

Values returns a list of the map values, in the order of the sorted keys. This function only works on flat maps.

func Zipmap

func Zipmap(keys, values cty.Value) (cty.Value, error)

Zipmap constructs a map from a list of keys and a corresponding list of values.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL