Skip to content

Commit e6d90bd

Browse files
authored
fix: rewrite onlyDataResources (#9263)
1 parent d37f6d8 commit e6d90bd

File tree

2 files changed

+144
-10
lines changed

2 files changed

+144
-10
lines changed

provisioner/terraform/executor.go

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -264,18 +264,21 @@ func (e *executor) plan(ctx, killCtx context.Context, env, vars []string, logr l
264264
}, nil
265265
}
266266

267-
func onlyDataResources(sm *tfjson.StateModule) *tfjson.StateModule {
268-
sm2 := *sm
269-
sm2.Resources = make([]*tfjson.StateResource, 0, len(sm.Resources))
267+
func onlyDataResources(sm tfjson.StateModule) tfjson.StateModule {
268+
filtered := sm
269+
filtered.Resources = []*tfjson.StateResource{}
270270
for _, r := range sm.Resources {
271271
if r.Mode == "data" {
272-
sm2.Resources = append(sm2.Resources, r)
272+
filtered.Resources = append(filtered.Resources, r)
273273
}
274274
}
275+
276+
filtered.ChildModules = []*tfjson.StateModule{}
275277
for _, c := range sm.ChildModules {
276-
sm2.ChildModules = append(sm2.ChildModules, onlyDataResources(c))
278+
filteredChild := onlyDataResources(*c)
279+
filtered.ChildModules = append(filtered.ChildModules, &filteredChild)
277280
}
278-
return &sm2
281+
return filtered
279282
}
280283

281284
// planResources must only be called while the lock is held.
@@ -300,10 +303,9 @@ func (e *executor) planResources(ctx, killCtx context.Context, planfilePath stri
300303
// We don't want all prior resources, because Quotas (and
301304
// future features) would never know which resources are getting
302305
// deleted by a stop.
303-
modules = append(
304-
modules,
305-
onlyDataResources(plan.PriorState.Values.RootModule),
306-
)
306+
307+
filtered := onlyDataResources(*plan.PriorState.Values.RootModule)
308+
modules = append(modules, &filtered)
307309
}
308310
modules = append(modules, plan.PlannedValues.RootModule)
309311

provisioner/terraform/executor_internal_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
package terraform
22

33
import (
4+
"encoding/json"
45
"testing"
56

7+
tfjson "github.com/hashicorp/terraform-json"
68
"github.com/stretchr/testify/require"
79

810
"github.com/coder/coder/v2/provisionersdk/proto"
@@ -41,3 +43,133 @@ From standing in the English rain`))
4143
}
4244
require.Equal(t, expected, logr.logs)
4345
}
46+
47+
func TestOnlyDataResources(t *testing.T) {
48+
t.Parallel()
49+
50+
tests := []struct {
51+
name string
52+
stateMod *tfjson.StateModule
53+
expected *tfjson.StateModule
54+
}{
55+
{
56+
name: "empty state module",
57+
stateMod: &tfjson.StateModule{},
58+
expected: &tfjson.StateModule{},
59+
},
60+
{
61+
name: "only data resources",
62+
stateMod: &tfjson.StateModule{
63+
Resources: []*tfjson.StateResource{
64+
{Name: "cat", Type: "coder_parameter", Mode: "data", Address: "cat-address"},
65+
{Name: "cow", Type: "foobaz", Mode: "data", Address: "cow-address"},
66+
},
67+
ChildModules: []*tfjson.StateModule{
68+
{
69+
Resources: []*tfjson.StateResource{
70+
{Name: "child-cat", Type: "coder_parameter", Mode: "data", Address: "child-cat-address"},
71+
{Name: "child-dog", Type: "foobar", Mode: "data", Address: "child-dog-address"},
72+
},
73+
Address: "child-module-1",
74+
},
75+
},
76+
Address: "fake-module",
77+
},
78+
expected: &tfjson.StateModule{
79+
Resources: []*tfjson.StateResource{
80+
{Name: "cat", Type: "coder_parameter", Mode: "data", Address: "cat-address"},
81+
{Name: "cow", Type: "foobaz", Mode: "data", Address: "cow-address"},
82+
},
83+
ChildModules: []*tfjson.StateModule{
84+
{
85+
Resources: []*tfjson.StateResource{
86+
{Name: "child-cat", Type: "coder_parameter", Mode: "data", Address: "child-cat-address"},
87+
{Name: "child-dog", Type: "foobar", Mode: "data", Address: "child-dog-address"},
88+
},
89+
Address: "child-module-1",
90+
},
91+
},
92+
Address: "fake-module",
93+
},
94+
},
95+
{
96+
name: "only non-data resources",
97+
stateMod: &tfjson.StateModule{
98+
Resources: []*tfjson.StateResource{
99+
{Name: "cat", Type: "coder_parameter", Mode: "foobar", Address: "cat-address"},
100+
{Name: "cow", Type: "foobaz", Mode: "foo", Address: "cow-address"},
101+
},
102+
ChildModules: []*tfjson.StateModule{
103+
{
104+
Resources: []*tfjson.StateResource{
105+
{Name: "child-cat", Type: "coder_parameter", Mode: "foobar", Address: "child-cat-address"},
106+
{Name: "child-dog", Type: "foobar", Mode: "foobaz", Address: "child-dog-address"},
107+
},
108+
Address: "child-module-1",
109+
},
110+
},
111+
Address: "fake-module",
112+
},
113+
expected: &tfjson.StateModule{
114+
Address: "fake-module",
115+
ChildModules: []*tfjson.StateModule{
116+
{Address: "child-module-1"},
117+
},
118+
},
119+
},
120+
{
121+
name: "mixed resources",
122+
stateMod: &tfjson.StateModule{
123+
Resources: []*tfjson.StateResource{
124+
{Name: "cat", Type: "coder_parameter", Mode: "data", Address: "cat-address"},
125+
{Name: "dog", Type: "foobar", Mode: "magic", Address: "dog-address"},
126+
{Name: "cow", Type: "foobaz", Mode: "data", Address: "cow-address"},
127+
},
128+
ChildModules: []*tfjson.StateModule{
129+
{
130+
Resources: []*tfjson.StateResource{
131+
{Name: "child-cat", Type: "coder_parameter", Mode: "data", Address: "child-cat-address"},
132+
{Name: "child-dog", Type: "foobar", Mode: "data", Address: "child-dog-address"},
133+
{Name: "child-cow", Type: "foobaz", Mode: "magic", Address: "child-cow-address"},
134+
},
135+
Address: "child-module-1",
136+
},
137+
},
138+
Address: "fake-module",
139+
},
140+
expected: &tfjson.StateModule{
141+
Resources: []*tfjson.StateResource{
142+
{Name: "cat", Type: "coder_parameter", Mode: "data", Address: "cat-address"},
143+
{Name: "cow", Type: "foobaz", Mode: "data", Address: "cow-address"},
144+
},
145+
ChildModules: []*tfjson.StateModule{
146+
{
147+
Resources: []*tfjson.StateResource{
148+
{Name: "child-cat", Type: "coder_parameter", Mode: "data", Address: "child-cat-address"},
149+
{Name: "child-dog", Type: "foobar", Mode: "data", Address: "child-dog-address"},
150+
},
151+
Address: "child-module-1",
152+
},
153+
},
154+
Address: "fake-module",
155+
},
156+
},
157+
}
158+
159+
for _, tt := range tests {
160+
tt := tt
161+
162+
t.Run(tt.name, func(t *testing.T) {
163+
t.Parallel()
164+
165+
filtered := onlyDataResources(*tt.stateMod)
166+
167+
expected, err := json.Marshal(tt.expected)
168+
require.NoError(t, err)
169+
got, err := json.Marshal(filtered)
170+
require.NoError(t, err)
171+
172+
require.Equal(t, string(expected), string(got))
173+
})
174+
}
175+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy