55 "fmt"
66 "io"
77 "io/fs"
8- "log"
98 "reflect"
9+ "slices"
1010 "strings"
1111
1212 "github.com/aquasecurity/trivy/pkg/iac/scanners/terraformplan/tfjson/parser"
@@ -31,67 +31,53 @@ func PlanJSONHook(dfs fs.FS, input Input) (func(ctx *tfcontext.Context, blocks t
3131 return nil , fmt .Errorf ("unable to parse plan JSON: %w" , err )
3232 }
3333
34- //plan.PriorState
35-
3634 var _ = plan
3735 return func (ctx * tfcontext.Context , blocks terraform.Blocks , inputVars map [string ]cty.Value ) {
36+ // Do not recurse to child blocks.
37+ // TODO: Only load into the single parent context for the module.
3838 for _ , block := range blocks {
39- if block .InModule () {
40-
41- x := block .ModuleKey ()
42- y := block .ModuleBlock ().FullName ()
43- var _ , _ = x , y
44- fmt .Println (block .ModuleKey ())
39+ planMod := priorPlanModule (plan , block )
40+ if planMod == nil {
4541 continue
4642 }
47-
48- err = loadResourcesToContext (block .Context ().Parent (), plan .PriorState .Values .RootModule .Resources )
43+ err = loadResourcesToContext (block .Context ().Parent (), planMod .Resources )
4944 if err != nil {
45+ // TODO: Somehow handle this error
5046 panic (fmt .Sprintf ("unable to load resources to context: %v" , err ))
5147 }
5248 }
53-
54- // 'data' blocks are loaded into prior state
55- //plan.PriorState.Values.RootModule.Resources
56- for _ , resource := range plan .PriorState .Values .RootModule .Resources {
57- // TODO: Do index references exist here too?
58- // TODO: Handle submodule nested resources
59-
60- parts := strings .Split (resource .Address , "." )
61- if len (parts ) < 2 {
62- continue
63- }
64-
65- if parts [0 ] != "data" || strings .Contains (parts [1 ], "coder" ) {
66- continue
67- }
68-
69- val , err := toCtyValue (resource .AttributeValues )
70- if err != nil {
71- // TODO: Remove log
72- log .Printf ("unable to determine value of resource %q: %v" , resource .Address , err )
73- continue
74- }
75-
76- ctx .Set (val , parts ... )
77- }
78-
7949 }, nil
8050}
8151
82- func planResources (plan * tfjson.Plan , block * terraform.Block ) error {
52+ func priorPlanModule (plan * tfjson.Plan , block * terraform.Block ) * tfjson. StateModule {
8353 if ! block .InModule () {
84- return loadResourcesToContext ( block . Context (). Parent (), plan .PriorState .Values .RootModule . Resources )
54+ return plan .PriorState .Values .RootModule
8555 }
8656
87- var path []string
57+ var modPath []string
8858 mod := block .ModuleBlock ()
89-
9059 for {
91- path = append ([]string {mod .FullName ()}, path ... )
92- break
60+ modPath = append ([]string {mod .LocalName ()}, modPath ... )
61+ mod = mod .ModuleBlock ()
62+ if mod == nil {
63+ break
64+ }
9365 }
94- return nil
66+
67+ current := plan .PriorState .Values .RootModule
68+ for i := range modPath {
69+ idx := slices .IndexFunc (current .ChildModules , func (m * tfjson.StateModule ) bool {
70+ return m .Address == strings .Join (modPath [:i + 1 ], "." )
71+ })
72+ if idx == - 1 {
73+ // Maybe throw a diag here?
74+ return nil
75+ }
76+
77+ current = current .ChildModules [idx ]
78+ }
79+
80+ return current
9581}
9682
9783func loadResourcesToContext (ctx * tfcontext.Context , resources []* tfjson.StateResource ) error {
0 commit comments