Skip to content

Commit ffdf9f2

Browse files
authored
actions: preserve unknown metadata in the json plan (#37611)
* actions: preserve unknown metadata in the json plan * copywrite headers
1 parent 1ac8497 commit ffdf9f2

File tree

4 files changed

+235
-67
lines changed

4 files changed

+235
-67
lines changed

internal/command/jsonformat/plan_test.go

Lines changed: 23 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ func TestRenderHuman_InvokeActionPlan(t *testing.T) {
3434
plan := Plan{
3535
ActionInvocations: []jsonplan.ActionInvocation{
3636
{
37-
Address: "action.test_action.action",
38-
Type: "test_action",
39-
Name: "action",
40-
ConfigValues: map[string]json.RawMessage{
41-
"attr": []byte("\"one\""),
42-
},
37+
Address: "action.test_action.action",
38+
Type: "test_action",
39+
Name: "action",
40+
ConfigValues: json.RawMessage("{\"attr\":\"one\"}"),
4341
ConfigSensitive: nil,
4442
ProviderName: "test",
4543
InvokeActionTrigger: new(jsonplan.InvokeActionTrigger),
@@ -95,12 +93,10 @@ func TestRenderHuman_InvokeActionPlanWithRefresh(t *testing.T) {
9593
plan := Plan{
9694
ActionInvocations: []jsonplan.ActionInvocation{
9795
{
98-
Address: "action.test_action.action",
99-
Type: "test_action",
100-
Name: "action",
101-
ConfigValues: map[string]json.RawMessage{
102-
"attr": []byte("\"one\""),
103-
},
96+
Address: "action.test_action.action",
97+
Type: "test_action",
98+
Name: "action",
99+
ConfigValues: json.RawMessage("{\"attr\":\"one\"}"),
104100
ConfigSensitive: nil,
105101
ProviderName: "test",
106102
InvokeActionTrigger: new(jsonplan.InvokeActionTrigger),
@@ -8483,7 +8479,7 @@ func TestResourceChange_actions(t *testing.T) {
84838479
TriggeringResourceAddress: triggeringResourceAddr.String(),
84848480
ActionTriggerEvent: "BeforeCreate",
84858481
},
8486-
ConfigValues: marshalConfigValues(cty.ObjectVal(map[string]cty.Value{
8482+
ConfigValues: marshalCtyJson(t, cty.ObjectVal(map[string]cty.Value{
84878483
"id": cty.StringVal("1D5F5E9E-F2E5-401B-9ED5-692A215AC67E"),
84888484
"disk": cty.ObjectVal(map[string]cty.Value{
84898485
"size": cty.StringVal("100"),
@@ -8527,7 +8523,7 @@ func TestResourceChange_actions(t *testing.T) {
85278523
TriggeringResourceAddress: triggeringResourceAddr.String(),
85288524
ActionTriggerEvent: "AfterCreate",
85298525
},
8530-
ConfigValues: marshalConfigValues(cty.ObjectVal(map[string]cty.Value{
8526+
ConfigValues: marshalCtyJson(t, cty.ObjectVal(map[string]cty.Value{
85318527
"id": cty.StringVal("1D5F5E9E-F2E5-401B-9ED5-692A215AC67E"),
85328528
"disk": cty.ObjectVal(map[string]cty.Value{
85338529
"size": cty.StringVal("100"),
@@ -8571,7 +8567,7 @@ func TestResourceChange_actions(t *testing.T) {
85718567
TriggeringResourceAddress: triggeringResourceAddr.String(),
85728568
ActionTriggerEvent: "BeforeCreate",
85738569
},
8574-
ConfigValues: marshalConfigValues(cty.ObjectVal(map[string]cty.Value{
8570+
ConfigValues: marshalCtyJson(t, cty.ObjectVal(map[string]cty.Value{
85758571
"id": cty.StringVal("first-block-and-action"),
85768572
})),
85778573
},
@@ -8586,7 +8582,7 @@ func TestResourceChange_actions(t *testing.T) {
85868582
TriggeringResourceAddress: triggeringResourceAddr.String(),
85878583
ActionTriggerEvent: "BeforeCreate",
85888584
},
8589-
ConfigValues: marshalConfigValues(cty.ObjectVal(map[string]cty.Value{
8585+
ConfigValues: marshalCtyJson(t, cty.ObjectVal(map[string]cty.Value{
85908586
"id": cty.StringVal("first-block-second-action"),
85918587
})),
85928588
},
@@ -8601,7 +8597,7 @@ func TestResourceChange_actions(t *testing.T) {
86018597
TriggeringResourceAddress: triggeringResourceAddr.String(),
86028598
ActionTriggerEvent: "AfterCreate",
86038599
},
8604-
ConfigValues: marshalConfigValues(cty.ObjectVal(map[string]cty.Value{
8600+
ConfigValues: marshalCtyJson(t, cty.ObjectVal(map[string]cty.Value{
86058601
"id": cty.StringVal("second-block-first-action"),
86068602
})),
86078603
},
@@ -8616,7 +8612,7 @@ func TestResourceChange_actions(t *testing.T) {
86168612
TriggeringResourceAddress: triggeringResourceAddr.String(),
86178613
ActionTriggerEvent: "AfterCreate",
86188614
},
8619-
ConfigValues: marshalConfigValues(cty.ObjectVal(map[string]cty.Value{
8615+
ConfigValues: marshalCtyJson(t, cty.ObjectVal(map[string]cty.Value{
86208616
"id": cty.StringVal("third-block-first-action"),
86218617
})),
86228618
},
@@ -8631,7 +8627,7 @@ func TestResourceChange_actions(t *testing.T) {
86318627
TriggeringResourceAddress: triggeringResourceAddr.String(),
86328628
ActionTriggerEvent: "BeforeCreate",
86338629
},
8634-
ConfigValues: marshalConfigValues(cty.ObjectVal(map[string]cty.Value{
8630+
ConfigValues: marshalCtyJson(t, cty.ObjectVal(map[string]cty.Value{
86358631
"id": cty.StringVal("fourth-block-first-action"),
86368632
})),
86378633
},
@@ -8739,23 +8735,6 @@ func TestResourceChange_actions(t *testing.T) {
87398735
})
87408736
}
87418737
}
8742-
func marshalConfigValues(value cty.Value) map[string]json.RawMessage {
8743-
// unmark our value to show all values
8744-
v, _ := value.UnmarkDeep()
8745-
8746-
if v == cty.NilVal || v.IsNull() {
8747-
return nil
8748-
}
8749-
8750-
ret := make(map[string]json.RawMessage)
8751-
it := value.ElementIterator()
8752-
for it.Next() {
8753-
k, v := it.Element()
8754-
vJSON, _ := ctyjson.Marshal(v, v.Type())
8755-
ret[k.AsString()] = json.RawMessage(vJSON)
8756-
}
8757-
return ret
8758-
}
87598738

87608739
func outputChange(name string, before, after cty.Value, sensitive bool) *plans.OutputChangeSrc {
87618740
addr := addrs.AbsOutputValue{
@@ -8931,3 +8910,11 @@ func marshalJson(t *testing.T, data interface{}) json.RawMessage {
89318910
}
89328911
return result
89338912
}
8913+
8914+
func marshalCtyJson(t *testing.T, data cty.Value) json.RawMessage {
8915+
result, err := ctyjson.Marshal(data, data.Type())
8916+
if err != nil {
8917+
t.Fatalf("failed to marshal json: %v", err)
8918+
}
8919+
return result
8920+
}

internal/command/jsonformat/structured/change.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,9 @@ func FromJsonViewsOutput(output viewsjson.Output) Change {
187187

188188
func FromJsonActionInvocation(actionInvocation jsonplan.ActionInvocation) Change {
189189
return Change{
190-
Before: unwrapAttributeValues(actionInvocation.ConfigValues),
191-
After: unwrapAttributeValues(actionInvocation.ConfigValues),
192-
Unknown: false,
190+
Before: unmarshalGeneric(actionInvocation.ConfigValues),
191+
After: unmarshalGeneric(actionInvocation.ConfigValues),
192+
Unknown: unmarshalGeneric(actionInvocation.ConfigUnknown),
193193
BeforeSensitive: unmarshalGeneric(actionInvocation.ConfigSensitive),
194194
AfterSensitive: unmarshalGeneric(actionInvocation.ConfigSensitive),
195195

internal/command/jsonplan/action_invocations.go

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,9 @@ type ActionInvocation struct {
2828
Name string `json:"name,omitempty"`
2929

3030
// ConfigValues is the JSON representation of the values in the config block of the action
31-
ConfigValues map[string]json.RawMessage `json:"config_values,omitempty"`
32-
ConfigSensitive json.RawMessage `json:"config_sensitive,omitempty"`
31+
ConfigValues json.RawMessage `json:"config_values,omitempty"`
32+
ConfigSensitive json.RawMessage `json:"config_sensitive,omitempty"`
33+
ConfigUnknown json.RawMessage `json:"config_unknown,omitempty"`
3334

3435
// ProviderName allows the property "type" to be interpreted unambiguously
3536
// in the unusual situation where a provider offers a type whose
@@ -93,24 +94,6 @@ func ActionInvocationCompare(a, b ActionInvocation) int {
9394
return 0
9495
}
9596

96-
func marshalConfigValues(value cty.Value) map[string]json.RawMessage {
97-
// unmark our value to show all values
98-
v, _ := value.UnmarkDeep()
99-
100-
if v == cty.NilVal || v.IsNull() {
101-
return nil
102-
}
103-
104-
ret := make(map[string]json.RawMessage)
105-
it := v.ElementIterator()
106-
for it.Next() {
107-
k, v := it.Element()
108-
vJSON, _ := ctyjson.Marshal(v, v.Type())
109-
ret[k.AsString()] = json.RawMessage(vJSON)
110-
}
111-
return ret
112-
}
113-
11497
func MarshalActionInvocations(actions []*plans.ActionInvocationInstanceSrc, schemas *terraform.Schemas) ([]ActionInvocation, error) {
11598
ret := make([]ActionInvocation, 0, len(actions))
11699
for _, action := range actions {
@@ -157,8 +140,12 @@ func MarshalActionInvocation(action *plans.ActionInvocationInstanceSrc, schemas
157140
return ai, fmt.Errorf("unsupported action trigger type: %T", at)
158141
}
159142

143+
var config []byte
144+
var sensitive []byte
145+
var unknown []byte
146+
160147
if actionDec.ConfigValue != cty.NilVal {
161-
_, pvms := actionDec.ConfigValue.UnmarkDeepWithPaths()
148+
unmarkedValue, pvms := actionDec.ConfigValue.UnmarkDeepWithPaths()
162149
sensitivePaths, otherMarks := marks.PathsWithMark(pvms, marks.Sensitive)
163150
ephemeralPaths, otherMarks := marks.PathsWithMark(otherMarks, marks.Ephemeral)
164151
if len(ephemeralPaths) > 0 {
@@ -168,19 +155,31 @@ func MarshalActionInvocation(action *plans.ActionInvocationInstanceSrc, schemas
168155
return ai, fmt.Errorf("action %s has config values with unsupported marks: %v", action.Addr, otherMarks)
169156
}
170157

171-
configValue := actionDec.ConfigValue
172-
if !configValue.IsWhollyKnown() {
173-
configValue = omitUnknowns(actionDec.ConfigValue)
158+
unknownValue := unknownAsBool(unmarkedValue)
159+
unknown, err = ctyjson.Marshal(unknownValue, unknownValue.Type())
160+
if err != nil {
161+
return ai, err
162+
}
163+
164+
configValue := omitUnknowns(unmarkedValue)
165+
config, err = ctyjson.Marshal(configValue, configValue.Type())
166+
if err != nil {
167+
return ai, err
174168
}
175-
cs := jsonstate.SensitiveAsBool(marks.MarkPaths(configValue, marks.Sensitive, sensitivePaths))
176-
configSensitive, err := ctyjson.Marshal(cs, cs.Type())
169+
170+
sensitivePaths = append(sensitivePaths, schema.ConfigSchema.SensitivePaths(unmarkedValue, nil)...)
171+
cs := jsonstate.SensitiveAsBool(marks.MarkPaths(unmarkedValue, marks.Sensitive, sensitivePaths))
172+
sensitive, err = ctyjson.Marshal(cs, cs.Type())
177173
if err != nil {
178174
return ai, err
179175
}
180176

181-
ai.ConfigValues = marshalConfigValues(configValue)
182-
ai.ConfigSensitive = configSensitive
183177
}
178+
179+
ai.ConfigValues = config
180+
ai.ConfigSensitive = sensitive
181+
ai.ConfigUnknown = unknown
182+
184183
return ai, nil
185184
}
186185

0 commit comments

Comments
 (0)