github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/states/instance_object.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  )
     9  
    10  // ResourceInstanceObject is the local representation of a specific remote
    11  // object associated with a resource instance. In practice not all remote
    12  // objects are actually remote in the sense of being accessed over the network,
    13  // but this is the most common case.
    14  //
    15  // It is not valid to mutate a ResourceInstanceObject once it has been created.
    16  // Instead, create a new object and replace the existing one.
    17  type ResourceInstanceObject struct {
    18  	// Value is the object-typed value representing the remote object within
    19  	// Terraform.
    20  	Value cty.Value
    21  
    22  	// Private is an opaque value set by the provider when this object was
    23  	// last created or updated. Terraform Core does not use this value in
    24  	// any way and it is not exposed anywhere in the user interface, so
    25  	// a provider can use it for retaining any necessary private state.
    26  	Private []byte
    27  
    28  	// Status represents the "readiness" of the object as of the last time
    29  	// it was updated.
    30  	Status ObjectStatus
    31  
    32  	// Dependencies is a set of absolute address to other resources this
    33  	// instance dependeded on when it was applied. This is used to construct
    34  	// the dependency relationships for an object whose configuration is no
    35  	// longer available, such as if it has been removed from configuration
    36  	// altogether, or is now deposed.
    37  	Dependencies []addrs.AbsResource
    38  
    39  	// DependsOn corresponds to the deprecated `depends_on` field in the state.
    40  	// This field contained the configuration `depends_on` values, and some of
    41  	// the references from within a single module.
    42  	DependsOn []addrs.Referenceable
    43  }
    44  
    45  // ObjectStatus represents the status of a RemoteObject.
    46  type ObjectStatus rune
    47  
    48  //go:generate go run golang.org/x/tools/cmd/stringer -type ObjectStatus
    49  
    50  const (
    51  	// ObjectReady is an object status for an object that is ready to use.
    52  	ObjectReady ObjectStatus = 'R'
    53  
    54  	// ObjectTainted is an object status representing an object that is in
    55  	// an unrecoverable bad state due to a partial failure during a create,
    56  	// update, or delete operation. Since it cannot be moved into the
    57  	// ObjectRead state, a tainted object must be replaced.
    58  	ObjectTainted ObjectStatus = 'T'
    59  
    60  	// ObjectPlanned is a special object status used only for the transient
    61  	// placeholder objects we place into state during the refresh and plan
    62  	// walks to stand in for objects that will be created during apply.
    63  	//
    64  	// Any object of this status must have a corresponding change recorded
    65  	// in the current plan, whose value must then be used in preference to
    66  	// the value stored in state when evaluating expressions. A planned
    67  	// object stored in state will be incomplete if any of its attributes are
    68  	// not yet known, and the plan must be consulted in order to "see" those
    69  	// unknown values, because the state is not able to represent them.
    70  	ObjectPlanned ObjectStatus = 'P'
    71  )
    72  
    73  // Encode marshals the value within the receiver to produce a
    74  // ResourceInstanceObjectSrc ready to be written to a state file.
    75  //
    76  // The given type must be the implied type of the resource type schema, and
    77  // the given value must conform to it. It is important to pass the schema
    78  // type and not the object's own type so that dynamically-typed attributes
    79  // will be stored correctly. The caller must also provide the version number
    80  // of the schema that the given type was derived from, which will be recorded
    81  // in the source object so it can be used to detect when schema migration is
    82  // required on read.
    83  //
    84  // The returned object may share internal references with the receiver and
    85  // so the caller must not mutate the receiver any further once once this
    86  // method is called.
    87  func (o *ResourceInstanceObject) Encode(ty cty.Type, schemaVersion uint64) (*ResourceInstanceObjectSrc, error) {
    88  	// Our state serialization can't represent unknown values, so we convert
    89  	// them to nulls here. This is lossy, but nobody should be writing unknown
    90  	// values here and expecting to get them out again later.
    91  	//
    92  	// We get unknown values here while we're building out a "planned state"
    93  	// during the plan phase, but the value stored in the plan takes precedence
    94  	// for expression evaluation. The apply step should never produce unknown
    95  	// values, but if it does it's the responsibility of the caller to detect
    96  	// and raise an error about that.
    97  	val := cty.UnknownAsNull(o.Value)
    98  
    99  	src, err := ctyjson.Marshal(val, ty)
   100  	if err != nil {
   101  		return nil, err
   102  	}
   103  
   104  	return &ResourceInstanceObjectSrc{
   105  		SchemaVersion: schemaVersion,
   106  		AttrsJSON:     src,
   107  		Private:       o.Private,
   108  		Status:        o.Status,
   109  		Dependencies:  o.Dependencies,
   110  	}, nil
   111  }
   112  
   113  // AsTainted returns a deep copy of the receiver with the status updated to
   114  // ObjectTainted.
   115  func (o *ResourceInstanceObject) AsTainted() *ResourceInstanceObject {
   116  	if o == nil {
   117  		// A nil object can't be tainted, but we'll allow this anyway to
   118  		// avoid a crash, since we presumably intend to eventually record
   119  		// the object has having been deleted anyway.
   120  		return nil
   121  	}
   122  	ret := o.DeepCopy()
   123  	ret.Status = ObjectTainted
   124  	return ret
   125  }