github.com/aquasecurity/trivy-iac@v0.8.1-0.20240127024015-3d8e412cf0ab/pkg/scanners/cloudformation/parser/fn_sub.go (about) 1 package parser 2 3 import ( 4 "fmt" 5 "strconv" 6 "strings" 7 8 "github.com/aquasecurity/trivy-iac/pkg/scanners/cloudformation/cftypes" 9 ) 10 11 func ResolveSub(property *Property) (resolved *Property, success bool) { 12 if !property.isFunction() { 13 return property, true 14 } 15 16 refValue := property.AsMap()["Fn::Sub"] 17 18 if refValue.IsString() { 19 return resolveStringSub(refValue, property), true 20 } 21 22 if refValue.IsList() { 23 return resolveMapSub(refValue, property) 24 } 25 26 return property, false 27 } 28 29 func resolveMapSub(refValue *Property, original *Property) (*Property, bool) { 30 refValues := refValue.AsList() 31 if len(refValues) != 2 { 32 return abortIntrinsic(original, "Fn::Sub with list expects 2 values, returning original property") 33 } 34 35 workingString := refValues[0].AsString() 36 components := refValues[1].AsMap() 37 38 for k, v := range components { 39 replacement := "[failed to resolve]" 40 switch v.Type() { 41 case cftypes.Map: 42 resolved, _ := ResolveIntrinsicFunc(v) 43 replacement = resolved.AsString() 44 case cftypes.String: 45 replacement = v.AsString() 46 case cftypes.Int: 47 replacement = strconv.Itoa(v.AsInt()) 48 case cftypes.Bool: 49 replacement = fmt.Sprintf("%v", v.AsBool()) 50 case cftypes.List: 51 var parts []string 52 for _, p := range v.AsList() { 53 parts = append(parts, p.String()) 54 } 55 replacement = fmt.Sprintf("[%s]", strings.Join(parts, ", ")) 56 } 57 workingString = strings.ReplaceAll(workingString, fmt.Sprintf("${%s}", k), replacement) 58 } 59 60 return original.deriveResolved(cftypes.String, workingString), true 61 } 62 63 func resolveStringSub(refValue *Property, original *Property) *Property { 64 workingString := refValue.AsString() 65 66 for k, param := range pseudoParameters { 67 workingString = strings.ReplaceAll(workingString, fmt.Sprintf("${%s}", k), fmt.Sprintf("%v", param.getRawValue())) 68 } 69 70 return original.deriveResolved(cftypes.String, workingString) 71 }