Skip to content

Commit a51cedd

Browse files
authored
refactor(terraform): sync funcs with Terraform (aquasecurity#6415)
1 parent 53517d6 commit a51cedd

File tree

17 files changed

+711
-906
lines changed

17 files changed

+711
-906
lines changed

.golangci.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ run:
9494
- ".*_test.go$"
9595
- "integration/*"
9696
- "examples/*"
97+
skip-dirs:
98+
- "pkg/iac/scanners/terraform/parser/funcs" # copies of Terraform functions
9799

98100
issues:
99101
exclude-rules:

pkg/iac/scanners/terraform/parser/funcs/cidr.go

Lines changed: 17 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ package funcs
44
import (
55
"fmt"
66
"math/big"
7-
"net"
87

98
"github.com/apparentlymart/go-cidr/cidr"
109
"github.com/zclconf/go-cty/cty"
@@ -25,13 +24,14 @@ var CidrHostFunc = function.New(&function.Spec{
2524
Type: cty.Number,
2625
},
2726
},
28-
Type: function.StaticReturnType(cty.String),
27+
Type: function.StaticReturnType(cty.String),
28+
RefineResult: refineNotNull,
2929
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
3030
var hostNum *big.Int
3131
if err := gocty.FromCtyValue(args[1], &hostNum); err != nil {
3232
return cty.UnknownVal(cty.String), err
3333
}
34-
_, network, err := net.ParseCIDR(args[0].AsString())
34+
_, network, err := ParseCIDR(args[0].AsString())
3535
if err != nil {
3636
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
3737
}
@@ -54,14 +54,19 @@ var CidrNetmaskFunc = function.New(&function.Spec{
5454
Type: cty.String,
5555
},
5656
},
57-
Type: function.StaticReturnType(cty.String),
57+
Type: function.StaticReturnType(cty.String),
58+
RefineResult: refineNotNull,
5859
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
59-
_, network, err := net.ParseCIDR(args[0].AsString())
60+
_, network, err := ParseCIDR(args[0].AsString())
6061
if err != nil {
6162
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
6263
}
6364

64-
return cty.StringVal(net.IP(network.Mask).String()), nil
65+
if network.IP.To4() == nil {
66+
return cty.UnknownVal(cty.String), fmt.Errorf("IPv6 addresses cannot have a netmask: %s", args[0].AsString())
67+
}
68+
69+
return cty.StringVal(IP(network.Mask).String()), nil
6570
},
6671
})
6772

@@ -82,7 +87,8 @@ var CidrSubnetFunc = function.New(&function.Spec{
8287
Type: cty.Number,
8388
},
8489
},
85-
Type: function.StaticReturnType(cty.String),
90+
Type: function.StaticReturnType(cty.String),
91+
RefineResult: refineNotNull,
8692
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
8793
var newbits int
8894
if err := gocty.FromCtyValue(args[1], &newbits); err != nil {
@@ -93,7 +99,7 @@ var CidrSubnetFunc = function.New(&function.Spec{
9399
return cty.UnknownVal(cty.String), err
94100
}
95101

96-
_, network, err := net.ParseCIDR(args[0].AsString())
102+
_, network, err := ParseCIDR(args[0].AsString())
97103
if err != nil {
98104
return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
99105
}
@@ -120,9 +126,10 @@ var CidrSubnetsFunc = function.New(&function.Spec{
120126
Name: "newbits",
121127
Type: cty.Number,
122128
},
123-
Type: function.StaticReturnType(cty.List(cty.String)),
129+
Type: function.StaticReturnType(cty.List(cty.String)),
130+
RefineResult: refineNotNull,
124131
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
125-
_, network, err := net.ParseCIDR(args[0].AsString())
132+
_, network, err := ParseCIDR(args[0].AsString())
126133
if err != nil {
127134
return cty.UnknownVal(cty.String), function.NewArgErrorf(0, "invalid CIDR expression: %s", err)
128135
}
@@ -186,27 +193,3 @@ var CidrSubnetsFunc = function.New(&function.Spec{
186193
return cty.ListVal(retVals), nil
187194
},
188195
})
189-
190-
// CidrHost calculates a full host IP address within a given IP network address prefix.
191-
func CidrHost(prefix, hostnum cty.Value) (cty.Value, error) {
192-
return CidrHostFunc.Call([]cty.Value{prefix, hostnum})
193-
}
194-
195-
// CidrNetmask converts an IPv4 address prefix given in CIDR notation into a subnet mask address.
196-
func CidrNetmask(prefix cty.Value) (cty.Value, error) {
197-
return CidrNetmaskFunc.Call([]cty.Value{prefix})
198-
}
199-
200-
// CidrSubnet calculates a subnet address within a given IP network address prefix.
201-
func CidrSubnet(prefix, newbits, netnum cty.Value) (cty.Value, error) {
202-
return CidrSubnetFunc.Call([]cty.Value{prefix, newbits, netnum})
203-
}
204-
205-
// CidrSubnets calculates a sequence of consecutive subnet prefixes that may
206-
// be of different prefix lengths under a common base prefix.
207-
func CidrSubnets(prefix cty.Value, newbits ...cty.Value) (cty.Value, error) {
208-
args := make([]cty.Value, len(newbits)+1)
209-
args[0] = prefix
210-
copy(args[1:], newbits)
211-
return CidrSubnetsFunc.Call(args)
212-
}

pkg/iac/scanners/terraform/parser/funcs/collection.go

Lines changed: 23 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ var LengthFunc = function.New(&function.Spec{
3333
return cty.Number, errors.New("argument must be a string, a collection type, or a structural type")
3434
}
3535
},
36+
RefineResult: refineNotNull,
3637
Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) {
3738
coll := args[0]
3839
collTy := args[0].Type()
@@ -69,7 +70,8 @@ var AllTrueFunc = function.New(&function.Spec{
6970
Type: cty.List(cty.Bool),
7071
},
7172
},
72-
Type: function.StaticReturnType(cty.Bool),
73+
Type: function.StaticReturnType(cty.Bool),
74+
RefineResult: refineNotNull,
7375
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
7476
result := cty.True
7577
for it := args[0].ElementIterator(); it.Next(); {
@@ -98,7 +100,8 @@ var AnyTrueFunc = function.New(&function.Spec{
98100
Type: cty.List(cty.Bool),
99101
},
100102
},
101-
Type: function.StaticReturnType(cty.Bool),
103+
Type: function.StaticReturnType(cty.Bool),
104+
RefineResult: refineNotNull,
102105
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
103106
result := cty.False
104107
var hasUnknown bool
@@ -147,6 +150,7 @@ var CoalesceFunc = function.New(&function.Spec{
147150
}
148151
return retType, nil
149152
},
153+
RefineResult: refineNotNull,
150154
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
151155
for _, argVal := range args {
152156
// We already know this will succeed because of the checks in our Type func above
@@ -179,7 +183,8 @@ var IndexFunc = function.New(&function.Spec{
179183
Type: cty.DynamicPseudoType,
180184
},
181185
},
182-
Type: function.StaticReturnType(cty.Number),
186+
Type: function.StaticReturnType(cty.Number),
187+
RefineResult: refineNotNull,
183188
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
184189
if !(args[0].Type().IsListType() || args[0].Type().IsTupleType()) {
185190
return cty.NilVal, errors.New("argument must be a list or tuple")
@@ -312,8 +317,8 @@ var LookupFunc = function.New(&function.Spec{
312317
return defaultVal.WithMarks(markses...), nil
313318
}
314319

315-
return cty.UnknownVal(cty.DynamicPseudoType).WithMarks(markses...), fmt.Errorf(
316-
"lookup failed to find '%s'", lookupKey)
320+
return cty.UnknownVal(cty.DynamicPseudoType), fmt.Errorf(
321+
"lookup failed to find key %s", redactIfSensitive(lookupKey, keyMarks))
317322
},
318323
})
319324

@@ -344,6 +349,7 @@ var MatchkeysFunc = function.New(&function.Spec{
344349
// the return type is based on args[0] (values)
345350
return args[0].Type(), nil
346351
},
352+
RefineResult: refineNotNull,
347353
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
348354
if !args[0].IsKnown() {
349355
return cty.UnknownVal(cty.List(retType.ElementType())), nil
@@ -353,7 +359,7 @@ var MatchkeysFunc = function.New(&function.Spec{
353359
return cty.ListValEmpty(retType.ElementType()), errors.New("length of keys and values should be equal")
354360
}
355361

356-
var output []cty.Value
362+
output := make([]cty.Value, 0)
357363
values := args[0]
358364

359365
// Keys and searchset must be the same type.
@@ -487,7 +493,8 @@ var SumFunc = function.New(&function.Spec{
487493
Type: cty.DynamicPseudoType,
488494
},
489495
},
490-
Type: function.StaticReturnType(cty.Number),
496+
Type: function.StaticReturnType(cty.Number),
497+
RefineResult: refineNotNull,
491498
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
492499

493500
if !args[0].CanIterateElements() {
@@ -528,6 +535,10 @@ var SumFunc = function.New(&function.Spec{
528535
if s.IsNull() {
529536
return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple of number values")
530537
}
538+
s, err = convert.Convert(s, cty.Number)
539+
if err != nil {
540+
return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple of number values")
541+
}
531542
for _, v := range arg[1:] {
532543
if v.IsNull() {
533544
return cty.NilVal, function.NewArgErrorf(0, "argument must be list, set, or tuple of number values")
@@ -552,7 +563,8 @@ var TransposeFunc = function.New(&function.Spec{
552563
Type: cty.Map(cty.List(cty.String)),
553564
},
554565
},
555-
Type: function.StaticReturnType(cty.Map(cty.List(cty.String))),
566+
Type: function.StaticReturnType(cty.Map(cty.List(cty.String))),
567+
RefineResult: refineNotNull,
556568
Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
557569
inputMap := args[0]
558570
if !inputMap.IsWhollyKnown() {
@@ -582,7 +594,7 @@ var TransposeFunc = function.New(&function.Spec{
582594
}
583595

584596
for outKey, outVal := range tmpMap {
585-
var values []cty.Value
597+
values := make([]cty.Value, 0)
586598
for _, v := range outVal {
587599
values = append(values, cty.StringVal(v))
588600
}
@@ -600,7 +612,7 @@ var TransposeFunc = function.New(&function.Spec{
600612
// ListFunc constructs a function that takes an arbitrary number of arguments
601613
// and returns a list containing those values in the same order.
602614
//
603-
// Deprecated: This function is deprecated in Terraform v0.12
615+
// This function is deprecated in Terraform v0.12
604616
var ListFunc = function.New(&function.Spec{
605617
Params: []function.Parameter{},
606618
VarParam: &function.Parameter{
@@ -621,7 +633,7 @@ var ListFunc = function.New(&function.Spec{
621633
// MapFunc constructs a function that takes an even number of arguments and
622634
// returns a map whose elements are constructed from consecutive pairs of arguments.
623635
//
624-
// Deprecated: This function is deprecated in Terraform v0.12
636+
// This function is deprecated in Terraform v0.12
625637
var MapFunc = function.New(&function.Spec{
626638
Params: []function.Parameter{},
627639
VarParam: &function.Parameter{
@@ -638,74 +650,3 @@ var MapFunc = function.New(&function.Spec{
638650
return cty.DynamicVal, fmt.Errorf("the \"map\" function was deprecated in Terraform v0.12 and is no longer available; use tomap({ ... }) syntax to write a literal map")
639651
},
640652
})
641-
642-
// Length returns the number of elements in the given collection or number of
643-
// Unicode characters in the given string.
644-
func Length(collection cty.Value) (cty.Value, error) {
645-
return LengthFunc.Call([]cty.Value{collection})
646-
}
647-
648-
// AllTrue returns true if all elements of the list are true. If the list is empty,
649-
// return true.
650-
func AllTrue(collection cty.Value) (cty.Value, error) {
651-
return AllTrueFunc.Call([]cty.Value{collection})
652-
}
653-
654-
// AnyTrue returns true if any element of the list is true. If the list is empty,
655-
// return false.
656-
func AnyTrue(collection cty.Value) (cty.Value, error) {
657-
return AnyTrueFunc.Call([]cty.Value{collection})
658-
}
659-
660-
// Coalesce takes any number of arguments and returns the first one that isn't empty.
661-
func Coalesce(args ...cty.Value) (cty.Value, error) {
662-
return CoalesceFunc.Call(args)
663-
}
664-
665-
// Index finds the element index for a given value in a list.
666-
func Index(list, value cty.Value) (cty.Value, error) {
667-
return IndexFunc.Call([]cty.Value{list, value})
668-
}
669-
670-
// List takes any number of list arguments and returns a list containing those
671-
//
672-
// values in the same order.
673-
func List(args ...cty.Value) (cty.Value, error) {
674-
return ListFunc.Call(args)
675-
}
676-
677-
// Lookup performs a dynamic lookup into a map.
678-
// There are two required arguments, map and key, plus an optional default,
679-
// which is a value to return if no key is found in map.
680-
func Lookup(args ...cty.Value) (cty.Value, error) {
681-
return LookupFunc.Call(args)
682-
}
683-
684-
// Map takes an even number of arguments and returns a map whose elements are constructed
685-
// from consecutive pairs of arguments.
686-
func Map(args ...cty.Value) (cty.Value, error) {
687-
return MapFunc.Call(args)
688-
}
689-
690-
// Matchkeys constructs a new list by taking a subset of elements from one list
691-
// whose indexes match the corresponding indexes of values in another list.
692-
func Matchkeys(values, keys, searchset cty.Value) (cty.Value, error) {
693-
return MatchkeysFunc.Call([]cty.Value{values, keys, searchset})
694-
}
695-
696-
// One returns either the first element of a one-element list, or null
697-
// if given a zero-element list..
698-
func One(list cty.Value) (cty.Value, error) {
699-
return OneFunc.Call([]cty.Value{list})
700-
}
701-
702-
// Sum adds numbers in a list, set, or tuple
703-
func Sum(list cty.Value) (cty.Value, error) {
704-
return SumFunc.Call([]cty.Value{list})
705-
}
706-
707-
// Transpose takes a map of lists of strings and swaps the keys and values to
708-
// produce a new map of lists of strings.
709-
func Transpose(values cty.Value) (cty.Value, error) {
710-
return TransposeFunc.Call([]cty.Value{values})
711-
}

0 commit comments

Comments
 (0)