Skip to content

Commit

Permalink
fix(cloudformation): infer type after resolving a function (#6406)
Browse files Browse the repository at this point in the history
  • Loading branch information
nikpivkin authored Mar 28, 2024
1 parent 5f69937 commit 6a2f6fd
Show file tree
Hide file tree
Showing 6 changed files with 67 additions and 8 deletions.
24 changes: 24 additions & 0 deletions pkg/iac/scanners/cloudformation/cftypes/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package cftypes

import "reflect"

type CfType string

const (
Expand All @@ -9,4 +11,26 @@ const (
Bool CfType = "bool"
Map CfType = "map"
List CfType = "list"
Unknown CfType = "unknown"
)

func TypeFromGoValue(value interface{}) CfType {
switch reflect.TypeOf(value).Kind() {
case reflect.String:
return String
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
return Int
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
return Int
case reflect.Float32, reflect.Float64:
return Float64
case reflect.Bool:
return Bool
case reflect.Map:
return Map
case reflect.Slice:
return List
default:
return Unknown
}
}
23 changes: 23 additions & 0 deletions pkg/iac/scanners/cloudformation/parser/fn_find_in_map_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,3 +98,26 @@ Resources:
nodeTypeProp := testRes.GetStringProperty("CacheNodeType", "")
assert.Equal(t, "cache.t2.micro", nodeTypeProp.Value())
}

func Test_InferType(t *testing.T) {
source := `---
Mappings:
ApiDB:
MultiAZ:
development: False
Resources:
ApiDB:
Type: AWS::RDS::DBInstance
Properties:
MultiAZ: !FindInMap [ApiDB, MultiAZ, development]
`

ctx := createTestFileContext(t, source)
require.NotNil(t, ctx)

testRes := ctx.GetResourceByLogicalID("ApiDB")
require.NotNil(t, testRes)

nodeTypeProp := testRes.GetBoolProperty("MultiAZ")
assert.False(t, nodeTypeProp.Value())
}
9 changes: 7 additions & 2 deletions pkg/iac/scanners/cloudformation/parser/intrinsics.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,13 @@ func ResolveIntrinsicFunc(property *Property) (*Property, bool) {

for funcName := range property.AsMap() {
if fn := intrinsicFuncs[funcName]; fn != nil {
//
return fn(property)
prop, resolved := fn(property)
if prop == nil || !resolved {
return prop, false
}

prop.inferType()
return prop, true
}
}
return property, false
Expand Down
8 changes: 8 additions & 0 deletions pkg/iac/scanners/cloudformation/parser/property.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,3 +425,11 @@ func convert(input interface{}) interface{} {
}
return input
}

func (p *Property) inferType() {
typ := cftypes.TypeFromGoValue(p.Inner.Value)
if typ == cftypes.Unknown {
return
}
p.Inner.Type = typ
}
7 changes: 2 additions & 5 deletions pkg/iac/scanners/cloudformation/parser/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,8 @@ func (r *Resource) GetProperty(path string) *Property {
first := pathParts[0]
property := &Property{}

for n, p := range r.properties() {
if n == first {
property = p
break
}
if p, exists := r.properties()[first]; exists {
property = p
}

if len(pathParts) == 1 || property.IsNil() {
Expand Down
4 changes: 3 additions & 1 deletion pkg/iac/scanners/cloudformation/parser/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,15 @@ func setPropertyValueFromYaml(node *yaml.Node, propertyData *PropertyInner) erro
if node.Content == nil {

switch node.Tag {

case "!!int":
propertyData.Type = cftypes.Int
propertyData.Value, _ = strconv.Atoi(node.Value)
case "!!bool":
propertyData.Type = cftypes.Bool
propertyData.Value, _ = strconv.ParseBool(node.Value)
case "!!float":
propertyData.Type = cftypes.Float64
propertyData.Value, _ = strconv.ParseFloat(node.Value, 64)
case "!!str", "!!string":
propertyData.Type = cftypes.String
propertyData.Value = node.Value
Expand Down

0 comments on commit 6a2f6fd

Please sign in to comment.