feat: Add IP Network to supported HCL Functions (#2426)
* Add IP Network to supported HCL Functions This patch adds CIDR functions from the `go-cty-funcs` package to supported HCL functions Signed-off-by: Oleh Neichev <oleg.neichev@gmail.com> * Test HCL CIDR Functions Signed-off-by: Oleh Neichev <oleg.neichev@gmail.com> --------- Signed-off-by: Oleh Neichev <oleg.neichev@gmail.com>
This commit is contained in:
parent
d10ef208b1
commit
3537f5f5c4
|
|
@ -24,22 +24,60 @@ map = {
|
|||
}
|
||||
can1 = can(hv.map.myVar)
|
||||
# true
|
||||
can2 = can(hv.map.notMyVar)
|
||||
can2 = can(hv.map.notMyVar)
|
||||
# false
|
||||
```
|
||||
#### cidrhost
|
||||
`cidrhost` calculates a full host IP address for a given host number within a given IP network address prefix.
|
||||
```
|
||||
cidrhost(prefix, hostnum)
|
||||
```
|
||||
```
|
||||
cidrhost("10.0.0.0/8", 2)
|
||||
# 10.0.0.2
|
||||
cidrhost("10.0.0.0/8", -2)
|
||||
# 10.255.255.254
|
||||
```
|
||||
#### cidrnetmask
|
||||
`cidrnetmask` converts an IPv4 address prefix given in CIDR notation into a subnet mask address.
|
||||
```
|
||||
cidrnetmask(prefix)
|
||||
```
|
||||
```
|
||||
cidrnetmask("10.0.0.0/16")
|
||||
# 255.255.0.0
|
||||
```
|
||||
#### cidrsubnet
|
||||
`cidrsubnet` calculates a subnet address within a given IP network address prefix.
|
||||
```
|
||||
cidrsubnet(prefix, newbits, netnum)
|
||||
```
|
||||
```
|
||||
cidrsubnet("10.0.0.0/8", 8, 2)
|
||||
# 10.2.0.0/16
|
||||
```
|
||||
#### cidrsubnets
|
||||
`cidrsubnets` calculates a sequence of consecutive IP address ranges within a particular CIDR prefix.
|
||||
```
|
||||
cidrsubnets(prefix, newbits...)
|
||||
```
|
||||
```
|
||||
cidrsubnets("10.0.0.0/8", 4, 4)
|
||||
# ["10.0.0.0/12", "10.16.0.0/12"]
|
||||
```
|
||||
#### ceil
|
||||
`ceil` returns the ceiling value of a given number
|
||||
```
|
||||
ceil(number)
|
||||
```
|
||||
```
|
||||
ceil(1)
|
||||
ceil(1)
|
||||
# 1
|
||||
ceil(1.1)
|
||||
ceil(1.1)
|
||||
# 2
|
||||
```
|
||||
#### chomp
|
||||
`chomp` removes newline characters at the end of a string.
|
||||
`chomp` removes newline characters at the end of a string.
|
||||
```
|
||||
chomp(string)
|
||||
```
|
||||
|
|
@ -66,7 +104,7 @@ coalesce([null, "value"]...)
|
|||
# value
|
||||
```
|
||||
#### coalescelist
|
||||
`coalescelist` takes any number of list arguments and returns the first one that isn't empty.
|
||||
`coalescelist` takes any number of list arguments and returns the first one that isn't empty.
|
||||
```
|
||||
coalescelist(list)
|
||||
```
|
||||
|
|
@ -89,7 +127,7 @@ compact(["", "val1", "val2"])
|
|||
# ["val1", "val2"]
|
||||
```
|
||||
#### concat
|
||||
`concat` takes one or more sequences (lists or tuples) and returns the single sequence that results from concatenating them together in order.
|
||||
`concat` takes one or more sequences (lists or tuples) and returns the single sequence that results from concatenating them together in order.
|
||||
```
|
||||
concat(list, list...)
|
||||
```
|
||||
|
|
@ -145,7 +183,7 @@ element(["val1","val2"], 1)
|
|||
```
|
||||
|
||||
#### chunklist
|
||||
`chunklist` splits a single list into fixed-size chunks, returning a list of lists.
|
||||
`chunklist` splits a single list into fixed-size chunks, returning a list of lists.
|
||||
```
|
||||
chunklist(list, size)
|
||||
```
|
||||
|
|
@ -154,7 +192,7 @@ chunklist(["a","b"], 1)
|
|||
# [["a"], ["b"]]
|
||||
```
|
||||
#### flatten
|
||||
`flatten` takes a list and replaces any elements that are lists with a flattened sequence of the list contents.
|
||||
`flatten` takes a list and replaces any elements that are lists with a flattened sequence of the list contents.
|
||||
```
|
||||
flatten(list)
|
||||
```
|
||||
|
|
@ -163,7 +201,7 @@ flatten([["a"], ["a","b"], ["c"]])
|
|||
# ["a","a","b","c"]
|
||||
```
|
||||
#### floor
|
||||
`floor` returns the closest whole number lesser than or equal to the given value.
|
||||
`floor` returns the closest whole number lesser than or equal to the given value.
|
||||
```
|
||||
floor(number)
|
||||
```
|
||||
|
|
@ -182,7 +220,7 @@ format(format, values)
|
|||
```
|
||||
format("Hello %s", "world")
|
||||
# Hello world
|
||||
```
|
||||
```
|
||||
#### formatdate
|
||||
`formatdate` reformats a timestamp given in RFC3339 syntax into another time syntax defined by a given format string.
|
||||
[Syntax details](https://pkg.go.dev/github.com/zclconf/go-cty/cty/function/stdlib#FormatDate)
|
||||
|
|
@ -215,7 +253,7 @@ formatlist("%s %s", "hello", ["World", "You"])
|
|||
]
|
||||
```
|
||||
#### indent
|
||||
`indent` adds a given number of spaces to the beginnings of all but the first line in a given multi-line string.
|
||||
`indent` adds a given number of spaces to the beginnings of all but the first line in a given multi-line string.
|
||||
```
|
||||
indent(number, string)
|
||||
```
|
||||
|
|
@ -239,7 +277,7 @@ int(6.2)
|
|||
```
|
||||
|
||||
#### join
|
||||
`join` concatenates together the string elements of one or more lists with a given separator.
|
||||
`join` concatenates together the string elements of one or more lists with a given separator.
|
||||
```
|
||||
join(listOfStrings, separator)
|
||||
```
|
||||
|
|
@ -249,7 +287,7 @@ join(" ", ["hello", "world"])
|
|||
```
|
||||
|
||||
#### jsondecode
|
||||
`jsondecode` parses the given JSON string and, if it is valid, returns the value it represents.
|
||||
`jsondecode` parses the given JSON string and, if it is valid, returns the value it represents.
|
||||
```
|
||||
jsonencode(string)
|
||||
```
|
||||
|
|
@ -260,7 +298,7 @@ jsonencode({"hello"="world"})
|
|||
```
|
||||
|
||||
#### jsonencode
|
||||
`jsonencode` returns a JSON serialization of the given value.
|
||||
`jsonencode` returns a JSON serialization of the given value.
|
||||
```
|
||||
jsondecode(string)
|
||||
```
|
||||
|
|
@ -275,13 +313,13 @@ jsondecode("{\"hello\": \"world\"}")
|
|||
```
|
||||
keys(map)
|
||||
```
|
||||
|
||||
|
||||
```
|
||||
keys({val1=1, val2=2, val3=3})
|
||||
# ["val1","val2","val3"]
|
||||
```
|
||||
#### length
|
||||
`length` returns the number of elements in the given __collection__.
|
||||
`length` returns the number of elements in the given __collection__.
|
||||
See `strlen` for strings
|
||||
```
|
||||
length(list)
|
||||
|
|
@ -292,7 +330,7 @@ length([1,2,3])
|
|||
# 3
|
||||
```
|
||||
#### log
|
||||
`log` returns returns the logarithm of a given number in a given base.
|
||||
`log` returns returns the logarithm of a given number in a given base.
|
||||
```
|
||||
log(number, base)
|
||||
```
|
||||
|
|
@ -302,7 +340,7 @@ log(1, 10)
|
|||
# 0
|
||||
```
|
||||
#### lookup
|
||||
`lookup` performs a dynamic lookup into a map. There are three required arguments, inputMap and key, plus a defaultValue, which is a value to return if the given key is not found in the inputMap.
|
||||
`lookup` performs a dynamic lookup into a map. There are three required arguments, inputMap and key, plus a defaultValue, which is a value to return if the given key is not found in the inputMap.
|
||||
```
|
||||
lookup(inputMap, key, defaultValue)
|
||||
```
|
||||
|
|
@ -325,7 +363,7 @@ lower("HELLO world")
|
|||
# hello world
|
||||
```
|
||||
#### max
|
||||
`max` returns the maximum number from the given numbers.
|
||||
`max` returns the maximum number from the given numbers.
|
||||
```
|
||||
max(numbers)
|
||||
```
|
||||
|
|
@ -346,7 +384,7 @@ merge({a="1"}, {a=[1,2], c="world"}, {d=40})
|
|||
|
||||
```
|
||||
#### min
|
||||
`min` returns the minimum number from the given numbers.
|
||||
`min` returns the minimum number from the given numbers.
|
||||
```
|
||||
min(numbers)
|
||||
```
|
||||
|
|
@ -355,7 +393,7 @@ min(1,128,70)
|
|||
# 1
|
||||
```
|
||||
#### parseint
|
||||
`parseint` parses a string argument and returns an integer of the specified base.
|
||||
`parseint` parses a string argument and returns an integer of the specified base.
|
||||
```
|
||||
parseint(string, base)
|
||||
```
|
||||
|
|
@ -366,7 +404,7 @@ parseint("11001", 2)
|
|||
# 25
|
||||
```
|
||||
#### pow
|
||||
`pow` returns the logarithm of a given number in a given base.
|
||||
`pow` returns the logarithm of a given number in a given base.
|
||||
```
|
||||
pow(number, power)
|
||||
```
|
||||
|
|
@ -388,7 +426,7 @@ range(1, 10, 3)
|
|||
# [1, 4, 7]
|
||||
```
|
||||
#### regex
|
||||
`regex` is a function that extracts one or more substrings from a given string by applying a regular expression pattern, describing the first match.
|
||||
`regex` is a function that extracts one or more substrings from a given string by applying a regular expression pattern, describing the first match.
|
||||
The return type depends on the composition of the capture groups (if any) in the pattern:
|
||||
|
||||
If there are no capture groups at all, the result is a single string representing the entire matched pattern.
|
||||
|
|
@ -396,7 +434,7 @@ The return type depends on the composition of the capture groups (if any) in the
|
|||
If none of the capture groups are named, the result is a tuple whose elements are the sub-groups in order and whose values are their sub-matches, or null if a particular sub-group was inside another group that didn't match.
|
||||
It is invalid to use both named and un-named capture groups together in the same pattern.
|
||||
|
||||
If the pattern doesn't match, this function returns an error. To test for a match, call `regexall` and check if the length of the result is greater than zero.
|
||||
If the pattern doesn't match, this function returns an error. To test for a match, call `regexall` and check if the length of the result is greater than zero.
|
||||
```
|
||||
regex(pattern, string)
|
||||
```
|
||||
|
|
@ -410,7 +448,7 @@ regex("[0-9]+", "v1.2.3")
|
|||
|
||||
The result type is always a list, whose element type is deduced from the pattern in the same way as the return type for Regex is decided.
|
||||
|
||||
If the pattern doesn't match at all, this function returns an empty list.
|
||||
If the pattern doesn't match at all, this function returns an empty list.
|
||||
```
|
||||
regexall(pattern, string)
|
||||
```
|
||||
|
|
@ -420,7 +458,7 @@ regexall("[0-9]+", "v1.2.3")
|
|||
# [1 2 3]
|
||||
```
|
||||
#### setintersection
|
||||
`setintersection` returns a new set containing the elements that exist in all of the given sets, which must have element types that can all be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.
|
||||
`setintersection` returns a new set containing the elements that exist in all of the given sets, which must have element types that can all be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.
|
||||
```
|
||||
setintersection(sets...)
|
||||
```
|
||||
|
|
@ -436,7 +474,7 @@ setproduct(sets...)
|
|||
```
|
||||
```
|
||||
setproduct(["host1", "host2"], ["stg.domain", "prod.domain"])
|
||||
###
|
||||
###
|
||||
[
|
||||
[
|
||||
"host1",
|
||||
|
|
@ -455,37 +493,37 @@ setproduct(["host1", "host2"], ["stg.domain", "prod.domain"])
|
|||
"prod.domain"
|
||||
],
|
||||
]
|
||||
```
|
||||
```
|
||||
#### setsubtract
|
||||
`setsubtract` returns a new set containing the elements from the first set that are not present in the second set. The sets must have element types that can both be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.
|
||||
`setsubtract` returns a new set containing the elements from the first set that are not present in the second set. The sets must have element types that can both be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.
|
||||
```
|
||||
setsubtract(sets...)
|
||||
```
|
||||
```
|
||||
setsubtract(["a", "b", "c"], ["a", "b"])
|
||||
###
|
||||
###
|
||||
["c"]
|
||||
```
|
||||
```
|
||||
#### setunion
|
||||
`setunion` returns a new set containing all of the elements from the given sets, which must have element types that can all be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.
|
||||
`setunion` returns a new set containing all of the elements from the given sets, which must have element types that can all be converted to some common type using the standard type unification rules. If conversion is not possible, an error is returned.
|
||||
```
|
||||
setunion(sets...)
|
||||
```
|
||||
|
||||
```
|
||||
setunion(["a", "b"], ["b", "c"], ["a", "d"])
|
||||
###
|
||||
###
|
||||
["a", "b", "c", "d"]
|
||||
```
|
||||
```
|
||||
#### signum
|
||||
`signum` determines the sign of a number, returning a number between -1 and 1 to represent the sign.
|
||||
`signum` determines the sign of a number, returning a number between -1 and 1 to represent the sign.
|
||||
```
|
||||
signum(number)
|
||||
```
|
||||
```
|
||||
signum(-182)
|
||||
# -1
|
||||
```
|
||||
```
|
||||
#### slice
|
||||
`slice` extracts some consecutive elements from within a list.
|
||||
startIndex is inclusive, endIndex is exclusive
|
||||
|
|
@ -497,7 +535,7 @@ slice([{"a" = "b"}, {"c" = "d"}, , {"e" = "f"}], 1, 1)
|
|||
# []
|
||||
slice([{"a" = "b"}, {"c" = "d"}, {"e" = "f"}], 1, 2)
|
||||
# [{"c" = "d"}]
|
||||
```
|
||||
```
|
||||
#### sort
|
||||
`sort` re-orders the elements of a given list of strings so that they are in ascending lexicographical order.
|
||||
```
|
||||
|
|
@ -506,25 +544,25 @@ sort(list)
|
|||
```
|
||||
sort(["1", "h", "r", "p", "word"])
|
||||
# ["1", "h", "p", "r", "word"]
|
||||
```
|
||||
```
|
||||
#### split
|
||||
`split` divides a given string by a given separator, returning a list of strings containing the characters between the separator sequences.
|
||||
`split` divides a given string by a given separator, returning a list of strings containing the characters between the separator sequences.
|
||||
```
|
||||
split(separatorString, string)
|
||||
```
|
||||
```
|
||||
split(".", "host.domain")
|
||||
# ["host", "domain"]
|
||||
```
|
||||
```
|
||||
#### strlen
|
||||
`strlen` is a Function that returns the length of the given string in characters.
|
||||
`strlen` is a Function that returns the length of the given string in characters.
|
||||
```
|
||||
strlen(string)
|
||||
```
|
||||
```
|
||||
strlen("yes")
|
||||
# 3
|
||||
```
|
||||
```
|
||||
#### strrev
|
||||
`strrev` is a Function that reverses the order of the characters in the given string.
|
||||
```
|
||||
|
|
@ -533,16 +571,16 @@ strrev(string)
|
|||
```
|
||||
strrev("yes")
|
||||
# "sey"
|
||||
```
|
||||
```
|
||||
#### substr
|
||||
`substr` is a Function that extracts a sequence of characters from another string and creates a new string.
|
||||
`substr` is a Function that extracts a sequence of characters from another string and creates a new string.
|
||||
```
|
||||
substr(string, offsetNumber, length)
|
||||
```
|
||||
```
|
||||
substr("host.domain", 0, 4)
|
||||
# "host"
|
||||
```
|
||||
```
|
||||
#### timeadd
|
||||
`timeadd` adds a duration to a timestamp, returning a new timestamp.
|
||||
Only units "inferior" or equal to `h` are supported.
|
||||
|
|
@ -553,7 +591,7 @@ substr(timestamp, duration)
|
|||
```
|
||||
timeadd("2024-01-01T00:00:00Z", "-2600h10m")
|
||||
# 2023-09-14T15:50:00Z
|
||||
```
|
||||
```
|
||||
#### trim
|
||||
`trim` removes the specified characters from the start and end of the given string.
|
||||
```
|
||||
|
|
@ -562,16 +600,16 @@ trim(string, string)
|
|||
```
|
||||
trim("Can you do that ? Yes ?", "?")
|
||||
# "Can you do that ? Yes"
|
||||
```
|
||||
```
|
||||
#### trimprefix
|
||||
`trimprefix` removes the specified prefix from the start of the given string.
|
||||
`trimprefix` removes the specified prefix from the start of the given string.
|
||||
```
|
||||
trimprefix(stringToTrim, trimmingString)
|
||||
```
|
||||
```
|
||||
trimprefix("please, do it", "please, ")
|
||||
# "do it"
|
||||
```
|
||||
```
|
||||
#### trimspace
|
||||
`trimspace` removes any space characters from the start and end of the given string.
|
||||
```
|
||||
|
|
@ -580,18 +618,18 @@ trimspace(string)
|
|||
```
|
||||
trimspace(" Hello World ")
|
||||
# "Hello World"
|
||||
```
|
||||
```
|
||||
#### trimsuffix
|
||||
`trimsuffix` removes the specified suffix from the end of the given string.
|
||||
`trimsuffix` removes the specified suffix from the end of the given string.
|
||||
```
|
||||
trimsuffix(stringToTrim, trimmingString)
|
||||
```
|
||||
```
|
||||
trimsuffix("Hello World", " World")
|
||||
# "Hello"
|
||||
```
|
||||
```
|
||||
#### try
|
||||
`try` is a variadic function that tries to evaluate all of is arguments in sequence until one succeeds, in which case it returns that result, or returns an error if none of them succeed.
|
||||
`try` is a variadic function that tries to evaluate all of is arguments in sequence until one succeeds, in which case it returns that result, or returns an error if none of them succeed.
|
||||
```
|
||||
try(expressions...)
|
||||
```
|
||||
|
|
@ -604,16 +642,16 @@ values {
|
|||
try(hv.map.do_not_exist, hv.map.world)
|
||||
}
|
||||
# "us"
|
||||
```
|
||||
```
|
||||
#### upper
|
||||
`upper` is a Function that converts a given string to uppercase.
|
||||
`upper` is a Function that converts a given string to uppercase.
|
||||
```
|
||||
upper(string)
|
||||
```
|
||||
```
|
||||
upper("up")
|
||||
# "UP"
|
||||
```
|
||||
```
|
||||
#### values
|
||||
`values` returns a list of the map values, in the order of the sorted keys. This function only works on flat maps.
|
||||
```
|
||||
|
|
@ -622,9 +660,9 @@ values(map)
|
|||
```
|
||||
values({"a" = 1,"b" = 2})
|
||||
# [1, 2]
|
||||
```
|
||||
```
|
||||
#### yamldecode
|
||||
`yamldecode` parses the given JSON string and, if it is valid, returns the value it represents.
|
||||
`yamldecode` parses the given JSON string and, if it is valid, returns the value it represents.
|
||||
```
|
||||
yamldecode(string)
|
||||
```
|
||||
|
|
@ -635,7 +673,7 @@ yamldecode("hello: world\narray: [1, 2, 3]")
|
|||
array = [1, 2, 3]
|
||||
hello = "world"
|
||||
}
|
||||
```
|
||||
```
|
||||
#### yamlencode
|
||||
`yamlencode` returns a JSON serialization of the given value.
|
||||
```
|
||||
|
|
@ -650,7 +688,7 @@ yamlencode({array = [1, 2, 3], hello = "world"})
|
|||
- 2
|
||||
- 3
|
||||
"hello": "world"
|
||||
```
|
||||
```
|
||||
#### zipmap
|
||||
`zipmap` constructs a map from a list of keys and a corresponding list of values.
|
||||
The lenght of each list must be equal
|
||||
|
|
@ -664,4 +702,4 @@ zipmap(["key1", "key2"], ["val1", "val2"])
|
|||
"key1" = "val1"
|
||||
"key2" = "val2"
|
||||
}
|
||||
```
|
||||
```
|
||||
|
|
|
|||
|
|
@ -1306,7 +1306,7 @@ domain: "dev.example.com"
|
|||
values {
|
||||
domain = "overdev.example.com"
|
||||
env = "dev"
|
||||
willBeOverriden = "override_me"
|
||||
willBeOverridden = "override_me"
|
||||
}
|
||||
```
|
||||
|
||||
|
|
@ -1319,7 +1319,7 @@ values {
|
|||
|
||||
```yaml
|
||||
# secrets.yml (assuming this one has been encrypted)
|
||||
willBeOverriden: overrided
|
||||
willBeOverridden: overridden
|
||||
```
|
||||
|
||||
```
|
||||
|
|
@ -1339,7 +1339,7 @@ releases:
|
|||
values:
|
||||
domain: "{{ .Values.domain }}" # == "overdev.example.com"
|
||||
env: "{{ .Values.env }}" # == "local"
|
||||
willBeOverriden: "{{ .Values.willBeOverriden }}" # == "overrided"
|
||||
willBeOverridden: "{{ .Values.willBeOverridden }}" # == "overridden"
|
||||
```
|
||||
## DAG-aware installation/deletion ordering with `needs`
|
||||
|
||||
|
|
|
|||
2
go.mod
2
go.mod
|
|
@ -14,6 +14,7 @@ require (
|
|||
github.com/golang/mock v1.6.0
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/gosuri/uitable v0.0.4
|
||||
github.com/hashicorp/go-cty-funcs v0.1.0
|
||||
github.com/hashicorp/go-getter/v2 v2.2.3
|
||||
github.com/hashicorp/hcl/v2 v2.24.0
|
||||
github.com/helmfile/chartify v0.26.2
|
||||
|
|
@ -145,6 +146,7 @@ require (
|
|||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/antchfx/jsonquery v1.3.6 // indirect
|
||||
github.com/antchfx/xpath v1.3.5 // indirect
|
||||
github.com/apparentlymart/go-cidr v1.1.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
||||
|
|
|
|||
4
go.sum
4
go.sum
|
|
@ -133,6 +133,8 @@ github.com/antchfx/jsonquery v1.3.6/go.mod h1:fGzSGJn9Y826Qd3pC8Wx45avuUwpkePsAC
|
|||
github.com/antchfx/xpath v1.3.2/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
|
||||
github.com/antchfx/xpath v1.3.5 h1:PqbXLC3TkfeZyakF5eeh3NTWEbYl4VHNVeufANzDbKQ=
|
||||
github.com/antchfx/xpath v1.3.5/go.mod h1:i54GszH55fYfBmoZXapTHN8T8tkcHfRgLyVwwqzXNcs=
|
||||
github.com/apparentlymart/go-cidr v1.1.0 h1:2mAhrMoF+nhXqxTzSZMUzDHkLjmIHC+Zzn4tdgBZjnU=
|
||||
github.com/apparentlymart/go-cidr v1.1.0/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/araddon/dateparse v0.0.0-20210429162001-6b43995a97de h1:FxWPpzIjnTlhPwqqXc4/vE0f7GvRjuAsbW+HOIe8KnA=
|
||||
|
|
@ -445,6 +447,8 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY
|
|||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-cty-funcs v0.1.0 h1:TRO/6x1unvTPpotTgrTU7qlcbd99JBLt+vmF6dMF6lY=
|
||||
github.com/hashicorp/go-cty-funcs v0.1.0/go.mod h1:crc3afXAsjGOJ+12LNX8PImH+ejyxOjnjvsUteKcFIw=
|
||||
github.com/hashicorp/go-getter/v2 v2.2.3 h1:6CVzhT0KJQHqd9b0pK3xSP0CM/Cv+bVhk+jcaRJ2pGk=
|
||||
github.com/hashicorp/go-getter/v2 v2.2.3/go.mod h1:hp5Yy0GMQvwWVUmwLs3ygivz1JSLI323hdIE9J9m7TY=
|
||||
github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k=
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package hcllang
|
|||
|
||||
import (
|
||||
"dario.cat/mergo"
|
||||
"github.com/hashicorp/go-cty-funcs/cidr"
|
||||
"github.com/hashicorp/hcl/v2/ext/tryfunc"
|
||||
ctyyaml "github.com/zclconf/go-cty-yaml"
|
||||
"github.com/zclconf/go-cty/cty/function"
|
||||
|
|
@ -14,6 +15,10 @@ func HCLFunctions(additionnalFunctions map[string]function.Function) (map[string
|
|||
"can": tryfunc.CanFunc,
|
||||
"ceil": stdlib.CeilFunc,
|
||||
"chomp": stdlib.ChompFunc,
|
||||
"cidrhost": cidr.HostFunc,
|
||||
"cidrnetmask": cidr.NetmaskFunc,
|
||||
"cidrsubnet": cidr.SubnetFunc,
|
||||
"cidrsubnets": cidr.SubnetsFunc,
|
||||
"coalesce": stdlib.CoalesceFunc,
|
||||
"coalescelist": stdlib.CoalesceListFunc,
|
||||
"compact": stdlib.CompactFunc,
|
||||
|
|
|
|||
|
|
@ -545,3 +545,26 @@ func TestHCL_ValuesOverride_TransitiveDependencies(t *testing.T) {
|
|||
t.Errorf("Expected full_path=override/path (overridden), got %v", actual["full_path"])
|
||||
}
|
||||
}
|
||||
|
||||
// TestHCL_CIDRFunctions tests that HCL CIDR functions work correctly
|
||||
func TestHCL_CIDRFunctions(t *testing.T) {
|
||||
l := newHCLLoader()
|
||||
l.AddFiles([]string{"testdata/cidr.hcl"})
|
||||
|
||||
actual, err := l.HCLRender()
|
||||
if err != nil {
|
||||
t.Fatalf("Render error: %s", err.Error())
|
||||
}
|
||||
|
||||
expected := map[string]any{
|
||||
"host": "10.0.0.2",
|
||||
"host_neg": "10.255.255.254",
|
||||
"netmask": "255.255.0.0",
|
||||
"subnet": "10.2.0.0/16",
|
||||
"subnets": []any{"10.0.0.0/12", "10.16.0.0/12"},
|
||||
}
|
||||
|
||||
if diff := cmp.Diff(expected, actual); diff != "" {
|
||||
t.Error(diff)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
values {
|
||||
host = cidrhost("10.0.0.0/8", 2)
|
||||
host_neg = cidrhost("10.0.0.0/8", -2)
|
||||
netmask = cidrnetmask("10.0.0.0/16")
|
||||
subnet = cidrsubnet("10.0.0.0/8", 8, 2)
|
||||
subnets = cidrsubnets("10.0.0.0/8", 4, 4)
|
||||
}
|
||||
Loading…
Reference in New Issue