jsonplan: move action invocation marshalling to separate function

This commit is contained in:
Daniel Schmidt 2025-08-18 14:17:50 +02:00
parent b1574c6acb
commit 0313b1471d

View file

@ -94,64 +94,70 @@ func marshalConfigValues(value cty.Value) map[string]json.RawMessage {
func MarshalActionInvocations(actions []*plans.ActionInvocationInstanceSrc, schemas *terraform.Schemas) ([]ActionInvocation, error) {
ret := make([]ActionInvocation, 0, len(actions))
for _, action := range actions {
schema := schemas.ActionTypeConfig(
action.ProviderAddr.Provider,
action.Addr.Action.Action.Type,
)
if schema.ConfigSchema == nil {
return ret, fmt.Errorf("no schema found for %s (in provider %s)", action.Addr.Action.Action.Type, action.ProviderAddr.Provider)
}
actionDec, err := action.Decode(&schema)
ai, err := MarshalActionInvocation(action, schemas)
if err != nil {
return ret, fmt.Errorf("failed to decode action %s: %w", action.Addr, err)
}
ai := ActionInvocation{
Address: action.Addr.String(),
Type: action.Addr.Action.Action.Type,
Name: action.Addr.Action.Action.Name,
ProviderName: action.ProviderAddr.Provider.String(),
}
switch at := action.ActionTrigger.(type) {
case plans.LifecycleActionTrigger:
ai.LifecycleActionTrigger = &LifecycleActionTrigger{
TriggeringResourceAddress: at.TriggeringResourceAddr.String(),
ActionTriggerEvent: at.TriggerEvent().String(),
ActionTriggerBlockIndex: at.ActionTriggerBlockIndex,
ActionsListIndex: at.ActionsListIndex,
}
default:
return ret, fmt.Errorf("unsupported action trigger type: %T", at)
}
if actionDec.ConfigValue != cty.NilVal {
// TODO: Support sensitive and ephemeral values in action invocations.
_, pvms := actionDec.ConfigValue.UnmarkDeepWithPaths()
sensitivePaths, otherMarks := marks.PathsWithMark(pvms, marks.Sensitive)
if len(sensitivePaths) > 0 {
return ret, fmt.Errorf("action %s has sensitive config values, which are not supported in action invocations", action.Addr)
}
ephemeralPaths, otherMarks := marks.PathsWithMark(otherMarks, marks.Ephemeral)
if len(ephemeralPaths) > 0 {
return ret, fmt.Errorf("action %s has ephemeral config values, which are not supported in action invocations", action.Addr)
}
if len(otherMarks) > 0 {
return ret, fmt.Errorf("action %s has config values with unsupported marks: %v", action.Addr, otherMarks)
}
if actionDec.ConfigValue.IsWhollyKnown() {
ai.ConfigValues = marshalConfigValues(actionDec.ConfigValue)
} else {
knowns := omitUnknowns(actionDec.ConfigValue)
ai.ConfigValues = marshalConfigValues(knowns)
}
return nil, err
}
ret = append(ret, ai)
}
return ret, nil
}
func MarshalActionInvocation(action *plans.ActionInvocationInstanceSrc, schemas *terraform.Schemas) (ActionInvocation, error) {
ai := ActionInvocation{
Address: action.Addr.String(),
Type: action.Addr.Action.Action.Type,
Name: action.Addr.Action.Action.Name,
ProviderName: action.ProviderAddr.Provider.String(),
}
schema := schemas.ActionTypeConfig(
action.ProviderAddr.Provider,
action.Addr.Action.Action.Type,
)
if schema.ConfigSchema == nil {
return ai, fmt.Errorf("no schema found for %s (in provider %s)", action.Addr.Action.Action.Type, action.ProviderAddr.Provider)
}
actionDec, err := action.Decode(&schema)
if err != nil {
return ai, fmt.Errorf("failed to decode action %s: %w", action.Addr, err)
}
switch at := action.ActionTrigger.(type) {
case plans.LifecycleActionTrigger:
ai.LifecycleActionTrigger = &LifecycleActionTrigger{
TriggeringResourceAddress: at.TriggeringResourceAddr.String(),
ActionTriggerEvent: at.TriggerEvent().String(),
ActionTriggerBlockIndex: at.ActionTriggerBlockIndex,
ActionsListIndex: at.ActionsListIndex,
}
default:
return ai, fmt.Errorf("unsupported action trigger type: %T", at)
}
if actionDec.ConfigValue != cty.NilVal {
// TODO: Support sensitive and ephemeral values in action invocations.
_, pvms := actionDec.ConfigValue.UnmarkDeepWithPaths()
sensitivePaths, otherMarks := marks.PathsWithMark(pvms, marks.Sensitive)
if len(sensitivePaths) > 0 {
return ai, fmt.Errorf("action %s has sensitive config values, which are not supported in action invocations", action.Addr)
}
ephemeralPaths, otherMarks := marks.PathsWithMark(otherMarks, marks.Ephemeral)
if len(ephemeralPaths) > 0 {
return ai, fmt.Errorf("action %s has ephemeral config values, which are not supported in action invocations", action.Addr)
}
if len(otherMarks) > 0 {
return ai, fmt.Errorf("action %s has config values with unsupported marks: %v", action.Addr, otherMarks)
}
if actionDec.ConfigValue.IsWhollyKnown() {
ai.ConfigValues = marshalConfigValues(actionDec.ConfigValue)
} else {
knowns := omitUnknowns(actionDec.ConfigValue)
ai.ConfigValues = marshalConfigValues(knowns)
}
}
return ai, nil
}