refactor ApplyResourceChange
Remove a bunch of indentation by returning early, and make sure we don't fail on non-fatal error without saving the applied value.
This commit is contained in:
parent
0a731167db
commit
7d05dee08d
|
@ -729,60 +729,76 @@ func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.A
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
plannedState := hcl2shim.FlatmapValueFromHCL2(plannedStateVal)
|
|
||||||
if newInstanceState != nil {
|
|
||||||
// here we use the planned state to check for unknown/zero containers values
|
|
||||||
// when normalizing the flatmap.
|
|
||||||
newInstanceState.Attributes = normalizeFlatmapContainers(plannedState, newInstanceState.Attributes, true)
|
|
||||||
}
|
|
||||||
|
|
||||||
newStateVal := cty.NullVal(block.ImpliedType())
|
newStateVal := cty.NullVal(block.ImpliedType())
|
||||||
|
|
||||||
// We keep the null val if we destroyed the resource, otherwise build the
|
// always return a nul value for destroy
|
||||||
// entire object, even if the new state was nil.
|
if newInstanceState == nil || destroy {
|
||||||
if !destroy {
|
newStateMP, err := msgpack.Marshal(newStateVal, block.ImpliedType())
|
||||||
newStateVal, err = schema.StateValueFromInstanceState(newInstanceState, block.ImpliedType())
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
resp.NewState = &proto.DynamicValue{
|
||||||
|
Msgpack: newStateMP,
|
||||||
|
}
|
||||||
|
return resp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// here we use the planned state to check for unknown/zero containers values
|
||||||
|
// when normalizing the flatmap.
|
||||||
|
plannedState := hcl2shim.FlatmapValueFromHCL2(plannedStateVal)
|
||||||
|
newInstanceState.Attributes = normalizeFlatmapContainers(plannedState, newInstanceState.Attributes, true)
|
||||||
|
|
||||||
|
// We keep the null val if we destroyed the resource, otherwise build the
|
||||||
|
// entire object, even if the new state was nil.
|
||||||
|
newStateVal, err = schema.StateValueFromInstanceState(newInstanceState, block.ImpliedType())
|
||||||
|
if err != nil {
|
||||||
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
newStateVal = copyMissingValues(newStateVal, plannedStateVal)
|
newStateVal = copyMissingValues(newStateVal, plannedStateVal)
|
||||||
|
|
||||||
if newInstanceState != nil {
|
// Cycle through the shims, to ensure that the plan will create an identical
|
||||||
prevVal := newStateVal
|
// value. Errors in this block are non-fatal (and should not happen, since
|
||||||
for i := 0; ; i++ {
|
// we've already shimmed this type), because we already have an applied value
|
||||||
// cycle through the shims, to ensure that the plan will create an
|
// and want to return that even if a later Plan may not agree.
|
||||||
// identical value
|
prevVal := newStateVal
|
||||||
shimmedState, err := res.ShimInstanceStateFromValue(prevVal)
|
for i := 0; ; i++ {
|
||||||
if err != nil {
|
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
shimmedState.Attributes = normalizeFlatmapContainers(shimmedState.Attributes, shimmedState.Attributes, false)
|
|
||||||
|
|
||||||
tmpVal, err := hcl2shim.HCL2ValueFromFlatmap(shimmedState.Attributes, block.ImpliedType())
|
shimmedState, err := res.ShimInstanceStateFromValue(prevVal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
log.Printf("[ERROR] failed to shim cty.Value: %s", err)
|
||||||
return resp, nil
|
break
|
||||||
}
|
}
|
||||||
|
shimmedState.Attributes = normalizeFlatmapContainers(shimmedState.Attributes, shimmedState.Attributes, false)
|
||||||
|
|
||||||
tmpVal = copyMissingValues(tmpVal, prevVal)
|
tmpVal, err := hcl2shim.HCL2ValueFromFlatmap(shimmedState.Attributes, block.ImpliedType())
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("[ERROR] failed to shim flatmap: %s", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
if tmpVal.RawEquals(prevVal) {
|
tmpVal = copyMissingValues(tmpVal, prevVal)
|
||||||
newStateVal = tmpVal
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
if i < 2 {
|
// If we have the same value before and after the shimming process, we
|
||||||
prevVal = tmpVal
|
// can be reasonably certain that PlanResourceChange will return the
|
||||||
continue
|
// same value.
|
||||||
}
|
if tmpVal.RawEquals(prevVal) {
|
||||||
|
newStateVal = tmpVal
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if i > 2 {
|
||||||
|
// This isn't fatal, since the value as actually applied.
|
||||||
log.Printf("[ERROR] hcl2shims failed to converge for value: %#v\n", newStateVal)
|
log.Printf("[ERROR] hcl2shims failed to converge for value: %#v\n", newStateVal)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The values are not the same, but we're only going to try this up to 3
|
||||||
|
// times before giving up. This should account for any empty nested values
|
||||||
|
// showing up a few levels deep.
|
||||||
|
prevVal = tmpVal
|
||||||
}
|
}
|
||||||
|
|
||||||
newStateVal = copyTimeoutValues(newStateVal, plannedStateVal)
|
newStateVal = copyTimeoutValues(newStateVal, plannedStateVal)
|
||||||
|
@ -796,15 +812,12 @@ func (s *GRPCProviderServer) ApplyResourceChange(_ context.Context, req *proto.A
|
||||||
Msgpack: newStateMP,
|
Msgpack: newStateMP,
|
||||||
}
|
}
|
||||||
|
|
||||||
if newInstanceState != nil {
|
meta, err := json.Marshal(newInstanceState.Meta)
|
||||||
meta, err := json.Marshal(newInstanceState.Meta)
|
if err != nil {
|
||||||
if err != nil {
|
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
||||||
resp.Diagnostics = convert.AppendProtoDiag(resp.Diagnostics, err)
|
return resp, nil
|
||||||
return resp, nil
|
|
||||||
}
|
|
||||||
resp.Private = meta
|
|
||||||
}
|
}
|
||||||
|
resp.Private = meta
|
||||||
return resp, nil
|
return resp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue