github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/states/instance_object_src.go (about) 1 package states 2 3 import ( 4 "github.com/zclconf/go-cty/cty" 5 ctyjson "github.com/zclconf/go-cty/cty/json" 6 7 "github.com/hashicorp/terraform/addrs" 8 "github.com/hashicorp/terraform/configs/hcl2shim" 9 ) 10 11 // ResourceInstanceObjectSrc is a not-fully-decoded version of 12 // ResourceInstanceObject. Decoding of it can be completed by first handling 13 // any schema migration steps to get to the latest schema version and then 14 // calling method Decode with the implied type of the latest schema. 15 type ResourceInstanceObjectSrc struct { 16 // SchemaVersion is the resource-type-specific schema version number that 17 // was current when either AttrsJSON or AttrsFlat was encoded. Migration 18 // steps are required if this is less than the current version number 19 // reported by the corresponding provider. 20 SchemaVersion uint64 21 22 // AttrsJSON is a JSON-encoded representation of the object attributes, 23 // encoding the value (of the object type implied by the associated resource 24 // type schema) that represents this remote object in Terraform Language 25 // expressions, and is compared with configuration when producing a diff. 26 // 27 // This is retained in JSON format here because it may require preprocessing 28 // before decoding if, for example, the stored attributes are for an older 29 // schema version which the provider must upgrade before use. If the 30 // version is current, it is valid to simply decode this using the 31 // type implied by the current schema, without the need for the provider 32 // to perform an upgrade first. 33 // 34 // When writing a ResourceInstanceObject into the state, AttrsJSON should 35 // always be conformant to the current schema version and the current 36 // schema version should be recorded in the SchemaVersion field. 37 AttrsJSON []byte 38 39 // AttrsFlat is a legacy form of attributes used in older state file 40 // formats, and in the new state format for objects that haven't yet been 41 // upgraded. This attribute is mutually exclusive with Attrs: for any 42 // ResourceInstanceObject, only one of these attributes may be populated 43 // and the other must be nil. 44 // 45 // An instance object with this field populated should be upgraded to use 46 // Attrs at the earliest opportunity, since this legacy flatmap-based 47 // format will be phased out over time. AttrsFlat should not be used when 48 // writing new or updated objects to state; instead, callers must follow 49 // the recommendations in the AttrsJSON documentation above. 50 AttrsFlat map[string]string 51 52 // These fields all correspond to the fields of the same name on 53 // ResourceInstanceObject. 54 Private []byte 55 Status ObjectStatus 56 Dependencies []addrs.AbsResource 57 // deprecated 58 DependsOn []addrs.Referenceable 59 } 60 61 // Decode unmarshals the raw representation of the object attributes. Pass the 62 // implied type of the corresponding resource type schema for correct operation. 63 // 64 // Before calling Decode, the caller must check that the SchemaVersion field 65 // exactly equals the version number of the schema whose implied type is being 66 // passed, or else the result is undefined. 67 // 68 // The returned object may share internal references with the receiver and 69 // so the caller must not mutate the receiver any further once once this 70 // method is called. 71 func (os *ResourceInstanceObjectSrc) Decode(ty cty.Type) (*ResourceInstanceObject, error) { 72 var val cty.Value 73 var err error 74 if os.AttrsFlat != nil { 75 // Legacy mode. We'll do our best to unpick this from the flatmap. 76 val, err = hcl2shim.HCL2ValueFromFlatmap(os.AttrsFlat, ty) 77 if err != nil { 78 return nil, err 79 } 80 } else { 81 val, err = ctyjson.Unmarshal(os.AttrsJSON, ty) 82 if err != nil { 83 return nil, err 84 } 85 } 86 87 return &ResourceInstanceObject{ 88 Value: val, 89 Status: os.Status, 90 Dependencies: os.Dependencies, 91 DependsOn: os.DependsOn, 92 Private: os.Private, 93 }, nil 94 } 95 96 // CompleteUpgrade creates a new ResourceInstanceObjectSrc by copying the 97 // metadata from the receiver and writing in the given new schema version 98 // and attribute value that are presumed to have resulted from upgrading 99 // from an older schema version. 100 func (os *ResourceInstanceObjectSrc) CompleteUpgrade(newAttrs cty.Value, newType cty.Type, newSchemaVersion uint64) (*ResourceInstanceObjectSrc, error) { 101 new := os.DeepCopy() 102 new.AttrsFlat = nil // We always use JSON after an upgrade, even if the source used flatmap 103 104 // This is the same principle as ResourceInstanceObject.Encode, but 105 // avoiding a decode/re-encode cycle because we don't have type info 106 // available for the "old" attributes. 107 newAttrs = cty.UnknownAsNull(newAttrs) 108 src, err := ctyjson.Marshal(newAttrs, newType) 109 if err != nil { 110 return nil, err 111 } 112 113 new.AttrsJSON = src 114 new.SchemaVersion = newSchemaVersion 115 return new, nil 116 }