Skip to content

Commit

Permalink
Fix type mismatch error in json unmarshal for float to struct (#1659)
Browse files Browse the repository at this point in the history
* fix for crash in lambda function cft yaml if code key is not present

* removed duplicate tag image tag

* bump up the version to 1.18.5

* added feature to parse cft template for ssm parameter

* bumped the version to 1.18.7

* bump up version to v1.18.8

* Sanitize the cft template file for aws:: words as it causes parser to fail

* Sanitize the cft template file for aws:: words as it causes parser to fail

* increment version

* Fix the int,float value to string in resource parameters

* updated version to 1.18.10
  • Loading branch information
nmoretenable committed Dec 21, 2023
1 parent 3aa1c57 commit 9ce8b18
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 6 deletions.
81 changes: 77 additions & 4 deletions pkg/iac-providers/cft/v1/sanitize-cft-template.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,18 @@ func (a *CFTV1) sanitizeCftTemplate(data []byte, isYAML bool) (map[string]interf

// sanitize Parameters
params, ok := templateFileMap[PARAMETERS]
var pMap map[string]interface{}
pMapconverted := make(map[string]interface{})
if ok {
pMap, ok := params.(map[string]interface{})
pMap, ok = params.(map[string]interface{})
if ok {
for pName := range pMap {
zap.S().Debug(fmt.Sprintf("inspecting parameter '%s'", pName))
inspectAndSanitizeParameters(pMap[pName])
resultMap, found := convertFloat64ToString(pMap[pName])
if found {
pMapconverted[pName] = resultMap
}
}
}
}
Expand All @@ -87,7 +93,7 @@ func (a *CFTV1) sanitizeCftTemplate(data []byte, isYAML bool) (map[string]interf
if ok {
for rName := range rMap {
zap.S().Debug("inspecting resource", zap.String("Resource Name", rName))
if shouldRemoveResource := inspectAndSanitizeResource(rMap[rName]); shouldRemoveResource {
if shouldRemoveResource := inspectAndSanitizeResource(rMap[rName], pMapconverted); shouldRemoveResource {
// we would remove any resource from the map for which goformation doesn't have a type defined
delete(rMap, rName)
}
Expand Down Expand Up @@ -181,7 +187,7 @@ func inspectAndSanitizeParameters(p interface{}) {
}
}

func inspectAndSanitizeResource(r interface{}) (shouldRemoveResource bool) {
func inspectAndSanitizeResource(r interface{}, pMap map[string]interface{}) (shouldRemoveResource bool) {
resMap, ok := r.(map[string]interface{})
if !ok {
zap.S().Debug("invalid data for 'Resource', should be of type map[string]interface{}")
Expand Down Expand Up @@ -238,8 +244,8 @@ func inspectAndSanitizeResource(r interface{}) (shouldRemoveResource bool) {
if val != nil {
propMap[propName] = val
}
findKeyAndReplace(propMap[propName], pMap)
}

inspectAndSanitizeResourceAttributes(resMap)
}
return
Expand Down Expand Up @@ -437,3 +443,70 @@ func examineStruct(t reflect.Type) map[string]reflect.StructField {
}
return m
}

func convertFloat64ToString(paramMap interface{}) (map[string]interface{}, bool) {
valMapNew := make(map[string]interface{})
foundfloat := false
if valMap, ok := paramMap.(map[string]interface{}); ok {
for paramName := range valMap {
var newBound []string
valToCheck := valMap[paramName]
switch val := valToCheck.(type) {
case int, float64, int32, float32, int8, int16, int64:
valToCheck = fmt.Sprintf("%v", val)
foundfloat = true
valMapNew[paramName] = valToCheck
}
if arrayValue, ok := valToCheck.([]interface{}); ok {
newBound = make([]string, len(arrayValue))
for i := range arrayValue {
switch val := arrayValue[i].(type) {
case int, float64, int32, float32, int8, int16, int64:
newBound[i] = fmt.Sprintf("%v", val)
foundfloat = true
}
}
if foundfloat {
valMapNew[paramName] = newBound
}
}
}
return valMapNew, foundfloat
}
return valMapNew, foundfloat
}

// findKeyAndReplace key in interface (recursively) and return value as interface
func findKeyAndReplace(obj interface{}, propValues map[string]interface{}) (interface{}, bool) {
// if the argument is not a map, ignore it
mobj, ok := obj.(map[string]interface{})
if !ok {
return nil, false
}
for k, v := range mobj {
// key match, return value
if val, ok := propValues[k]; ok {
if valMap, ok := val.(map[string]interface{}); ok {
if val2, ok := valMap["Default"]; ok {
mobj[k] = val2
}
return v, true
}
}
// if the value is a map, search recursively
if m, ok := v.(map[string]interface{}); ok {
if res, ok := findKeyAndReplace(m, propValues); ok {
return res, true
}
}
// if the value is an array, search recursively
if va, ok := v.([]interface{}); ok {
for _, a := range va {
if res, ok := findKeyAndReplace(a, propValues); ok {
return res, true
}
}
}
}
return nil, false
}
5 changes: 4 additions & 1 deletion pkg/mapper/iac-providers/cft/config/lambda-function.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type LambdaFunctionConfig struct {
VPCConfig []VPCConfigBlock `json:"vpc_config"`
Environment []EnvironmentBlock `json:"environment"`
KMSKeyARN string `json:"kms_key_arn"`
Tags map[string]string `json:"tags"`
}

// GetLambdaFunctionConfig returns config for LambdaFunction
Expand Down Expand Up @@ -110,7 +111,9 @@ func getServerlessConfig(sf *serverless.Function) []AWSResourceConfig {
Environment: environment,
KMSKeyARN: functions.GetVal(sf.KmsKeyArn),
}

if sf.Tags != nil {
cf.Tags = sf.Tags
}
cf = setServerlessCodePackage(cf, sf)

return []AWSResourceConfig{{
Expand Down
2 changes: 1 addition & 1 deletion pkg/version/version.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ package version
import "fmt"

// Terrascan The Terrascan version
const Terrascan = "1.18.9"
const Terrascan = "1.18.10"

// Get returns the terrascan version
func Get() string {
Expand Down

0 comments on commit 9ce8b18

Please sign in to comment.