github.com/pulumi/terraform@v1.4.0/pkg/plans/changes_src.go (about) 1 package plans 2 3 import ( 4 "fmt" 5 6 "github.com/pulumi/terraform/pkg/addrs" 7 "github.com/pulumi/terraform/pkg/states" 8 "github.com/zclconf/go-cty/cty" 9 ) 10 11 // ResourceInstanceChangeSrc is a not-yet-decoded ResourceInstanceChange. 12 // Pass the associated resource type's schema type to method Decode to 13 // obtain a ResourceInstanceChange. 14 type ResourceInstanceChangeSrc struct { 15 // Addr is the absolute address of the resource instance that the change 16 // will apply to. 17 Addr addrs.AbsResourceInstance 18 19 // PrevRunAddr is the absolute address that this resource instance had at 20 // the conclusion of a previous run. 21 // 22 // This will typically be the same as Addr, but can be different if the 23 // previous resource instance was subject to a "moved" block that we 24 // handled in the process of creating this plan. 25 // 26 // For the initial creation of a resource instance there isn't really any 27 // meaningful "previous run address", but PrevRunAddr will still be set 28 // equal to Addr in that case in order to simplify logic elsewhere which 29 // aims to detect and react to the movement of instances between addresses. 30 PrevRunAddr addrs.AbsResourceInstance 31 32 // DeposedKey is the identifier for a deposed object associated with the 33 // given instance, or states.NotDeposed if this change applies to the 34 // current object. 35 // 36 // A Replace change for a resource with create_before_destroy set will 37 // create a new DeposedKey temporarily during replacement. In that case, 38 // DeposedKey in the plan is always states.NotDeposed, representing that 39 // the current object is being replaced with the deposed. 40 DeposedKey states.DeposedKey 41 42 // Provider is the address of the provider configuration that was used 43 // to plan this change, and thus the configuration that must also be 44 // used to apply it. 45 ProviderAddr addrs.AbsProviderConfig 46 47 // ChangeSrc is an embedded description of the not-yet-decoded change. 48 ChangeSrc 49 50 // ActionReason is an optional extra indication of why we chose the 51 // action recorded in Change.Action for this particular resource instance. 52 // 53 // This is an approximate mechanism only for the purpose of explaining the 54 // plan to end-users in the UI and is not to be used for any 55 // decision-making during the apply step; if apply behavior needs to vary 56 // depending on the "action reason" then the information for that decision 57 // must be recorded more precisely elsewhere for that purpose. 58 // 59 // See the field of the same name in ResourceInstanceChange for more 60 // details. 61 ActionReason ResourceInstanceChangeActionReason 62 63 // RequiredReplace is a set of paths that caused the change action to be 64 // Replace rather than Update. Always nil if the change action is not 65 // Replace. 66 RequiredReplace cty.PathSet 67 68 // Private allows a provider to stash any extra data that is opaque to 69 // Terraform that relates to this change. Terraform will save this 70 // byte-for-byte and return it to the provider in the apply call. 71 Private []byte 72 } 73 74 // Decode unmarshals the raw representation of the instance object being 75 // changed. Pass the implied type of the corresponding resource type schema 76 // for correct operation. 77 func (rcs *ResourceInstanceChangeSrc) Decode(ty cty.Type) (*ResourceInstanceChange, error) { 78 change, err := rcs.ChangeSrc.Decode(ty) 79 if err != nil { 80 return nil, err 81 } 82 prevRunAddr := rcs.PrevRunAddr 83 if prevRunAddr.Resource.Resource.Type == "" { 84 // Suggests an old caller that hasn't been properly updated to 85 // populate this yet. 86 prevRunAddr = rcs.Addr 87 } 88 return &ResourceInstanceChange{ 89 Addr: rcs.Addr, 90 PrevRunAddr: prevRunAddr, 91 DeposedKey: rcs.DeposedKey, 92 ProviderAddr: rcs.ProviderAddr, 93 Change: *change, 94 ActionReason: rcs.ActionReason, 95 RequiredReplace: rcs.RequiredReplace, 96 Private: rcs.Private, 97 }, nil 98 } 99 100 // DeepCopy creates a copy of the receiver where any pointers to nested mutable 101 // values are also copied, thus ensuring that future mutations of the receiver 102 // will not affect the copy. 103 // 104 // Some types used within a resource change are immutable by convention even 105 // though the Go language allows them to be mutated, such as the types from 106 // the addrs package. These are _not_ copied by this method, under the 107 // assumption that callers will behave themselves. 108 func (rcs *ResourceInstanceChangeSrc) DeepCopy() *ResourceInstanceChangeSrc { 109 if rcs == nil { 110 return nil 111 } 112 ret := *rcs 113 114 ret.RequiredReplace = cty.NewPathSet(ret.RequiredReplace.List()...) 115 116 if len(ret.Private) != 0 { 117 private := make([]byte, len(ret.Private)) 118 copy(private, ret.Private) 119 ret.Private = private 120 } 121 122 ret.ChangeSrc.Before = ret.ChangeSrc.Before.Copy() 123 ret.ChangeSrc.After = ret.ChangeSrc.After.Copy() 124 125 return &ret 126 } 127 128 func (rcs *ResourceInstanceChangeSrc) Moved() bool { 129 return !rcs.Addr.Equal(rcs.PrevRunAddr) 130 } 131 132 // OutputChangeSrc describes a change to an output value. 133 type OutputChangeSrc struct { 134 // Addr is the absolute address of the output value that the change 135 // will apply to. 136 Addr addrs.AbsOutputValue 137 138 // ChangeSrc is an embedded description of the not-yet-decoded change. 139 // 140 // For output value changes, the type constraint for the DynamicValue 141 // instances is always cty.DynamicPseudoType. 142 ChangeSrc 143 144 // Sensitive, if true, indicates that either the old or new value in the 145 // change is sensitive and so a rendered version of the plan in the UI 146 // should elide the actual values while still indicating the action of the 147 // change. 148 Sensitive bool 149 } 150 151 // Decode unmarshals the raw representation of the output value being 152 // changed. 153 func (ocs *OutputChangeSrc) Decode() (*OutputChange, error) { 154 change, err := ocs.ChangeSrc.Decode(cty.DynamicPseudoType) 155 if err != nil { 156 return nil, err 157 } 158 return &OutputChange{ 159 Addr: ocs.Addr, 160 Change: *change, 161 Sensitive: ocs.Sensitive, 162 }, nil 163 } 164 165 // DeepCopy creates a copy of the receiver where any pointers to nested mutable 166 // values are also copied, thus ensuring that future mutations of the receiver 167 // will not affect the copy. 168 // 169 // Some types used within a resource change are immutable by convention even 170 // though the Go language allows them to be mutated, such as the types from 171 // the addrs package. These are _not_ copied by this method, under the 172 // assumption that callers will behave themselves. 173 func (ocs *OutputChangeSrc) DeepCopy() *OutputChangeSrc { 174 if ocs == nil { 175 return nil 176 } 177 ret := *ocs 178 179 ret.ChangeSrc.Before = ret.ChangeSrc.Before.Copy() 180 ret.ChangeSrc.After = ret.ChangeSrc.After.Copy() 181 182 return &ret 183 } 184 185 // ChangeSrc is a not-yet-decoded Change. 186 type ChangeSrc struct { 187 // Action defines what kind of change is being made. 188 Action Action 189 190 // Before and After correspond to the fields of the same name in Change, 191 // but have not yet been decoded from the serialized value used for 192 // storage. 193 Before, After DynamicValue 194 195 // BeforeValMarks and AfterValMarks are stored path+mark combinations 196 // that might be discovered when encoding a change. Marks are removed 197 // to enable encoding (marked values cannot be marshalled), and so storing 198 // the path+mark combinations allow us to re-mark the value later 199 // when, for example, displaying the diff to the UI. 200 BeforeValMarks, AfterValMarks []cty.PathValueMarks 201 } 202 203 // Decode unmarshals the raw representations of the before and after values 204 // to produce a Change object. Pass the type constraint that the result must 205 // conform to. 206 // 207 // Where a ChangeSrc is embedded in some other struct, it's generally better 208 // to call the corresponding Decode method of that struct rather than working 209 // directly with its embedded Change. 210 func (cs *ChangeSrc) Decode(ty cty.Type) (*Change, error) { 211 var err error 212 before := cty.NullVal(ty) 213 after := cty.NullVal(ty) 214 215 if len(cs.Before) > 0 { 216 before, err = cs.Before.Decode(ty) 217 if err != nil { 218 return nil, fmt.Errorf("error decoding 'before' value: %s", err) 219 } 220 } 221 if len(cs.After) > 0 { 222 after, err = cs.After.Decode(ty) 223 if err != nil { 224 return nil, fmt.Errorf("error decoding 'after' value: %s", err) 225 } 226 } 227 228 return &Change{ 229 Action: cs.Action, 230 Before: before.MarkWithPaths(cs.BeforeValMarks), 231 After: after.MarkWithPaths(cs.AfterValMarks), 232 }, nil 233 }