github.com/opentofu/opentofu@v1.7.1/internal/addrs/resource_phase.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package addrs
     7  
     8  import "fmt"
     9  
    10  // ResourceInstancePhase is a special kind of reference used only internally
    11  // during graph building to represent resource instances that are in a
    12  // non-primary state.
    13  //
    14  // Graph nodes can declare themselves referenceable via an instance phase
    15  // or can declare that they reference an instance phase in order to accomodate
    16  // secondary graph nodes dealing with, for example, destroy actions.
    17  //
    18  // This special reference type cannot be accessed directly by end-users, and
    19  // should never be shown in the UI.
    20  type ResourceInstancePhase struct {
    21  	referenceable
    22  	ResourceInstance ResourceInstance
    23  	Phase            ResourceInstancePhaseType
    24  }
    25  
    26  var _ Referenceable = ResourceInstancePhase{}
    27  
    28  // Phase returns a special "phase address" for the receving instance. See the
    29  // documentation of ResourceInstancePhase for the limited situations where this
    30  // is intended to be used.
    31  func (r ResourceInstance) Phase(rpt ResourceInstancePhaseType) ResourceInstancePhase {
    32  	return ResourceInstancePhase{
    33  		ResourceInstance: r,
    34  		Phase:            rpt,
    35  	}
    36  }
    37  
    38  // ContainingResource returns an address for the same phase of the resource
    39  // that this instance belongs to.
    40  func (rp ResourceInstancePhase) ContainingResource() ResourcePhase {
    41  	return rp.ResourceInstance.Resource.Phase(rp.Phase)
    42  }
    43  
    44  func (rp ResourceInstancePhase) String() string {
    45  	// We use a different separator here than usual to ensure that we'll
    46  	// never conflict with any non-phased resource instance string. This
    47  	// is intentionally something that would fail parsing with ParseRef,
    48  	// because this special address type should never be exposed in the UI.
    49  	return fmt.Sprintf("%s#%s", rp.ResourceInstance, rp.Phase)
    50  }
    51  
    52  func (rp ResourceInstancePhase) UniqueKey() UniqueKey {
    53  	return rp // A ResourceInstancePhase is its own UniqueKey
    54  }
    55  
    56  func (rp ResourceInstancePhase) uniqueKeySigil() {}
    57  
    58  // ResourceInstancePhaseType is an enumeration used with ResourceInstancePhase.
    59  type ResourceInstancePhaseType string
    60  
    61  const (
    62  	// ResourceInstancePhaseDestroy represents the "destroy" phase of a
    63  	// resource instance.
    64  	ResourceInstancePhaseDestroy ResourceInstancePhaseType = "destroy"
    65  
    66  	// ResourceInstancePhaseDestroyCBD is similar to ResourceInstancePhaseDestroy
    67  	// but is used for resources that have "create_before_destroy" set, thus
    68  	// requiring a different dependency ordering.
    69  	ResourceInstancePhaseDestroyCBD ResourceInstancePhaseType = "destroy-cbd"
    70  )
    71  
    72  func (rpt ResourceInstancePhaseType) String() string {
    73  	return string(rpt)
    74  }
    75  
    76  // ResourcePhase is a special kind of reference used only internally
    77  // during graph building to represent resources that are in a
    78  // non-primary state.
    79  //
    80  // Graph nodes can declare themselves referenceable via a resource phase
    81  // or can declare that they reference a resource phase in order to accomodate
    82  // secondary graph nodes dealing with, for example, destroy actions.
    83  //
    84  // Since resources (as opposed to instances) aren't actually phased, this
    85  // address type is used only as an approximation during initial construction
    86  // of the resource-oriented plan graph, under the assumption that resource
    87  // instances with ResourceInstancePhase addresses will be created in dynamic
    88  // subgraphs during the graph walk.
    89  //
    90  // This special reference type cannot be accessed directly by end-users, and
    91  // should never be shown in the UI.
    92  type ResourcePhase struct {
    93  	referenceable
    94  	Resource Resource
    95  	Phase    ResourceInstancePhaseType
    96  }
    97  
    98  var _ Referenceable = ResourcePhase{}
    99  
   100  // Phase returns a special "phase address" for the receving instance. See the
   101  // documentation of ResourceInstancePhase for the limited situations where this
   102  // is intended to be used.
   103  func (r Resource) Phase(rpt ResourceInstancePhaseType) ResourcePhase {
   104  	return ResourcePhase{
   105  		Resource: r,
   106  		Phase:    rpt,
   107  	}
   108  }
   109  
   110  func (rp ResourcePhase) String() string {
   111  	// We use a different separator here than usual to ensure that we'll
   112  	// never conflict with any non-phased resource instance string. This
   113  	// is intentionally something that would fail parsing with ParseRef,
   114  	// because this special address type should never be exposed in the UI.
   115  	return fmt.Sprintf("%s#%s", rp.Resource, rp.Phase)
   116  }
   117  
   118  func (rp ResourcePhase) UniqueKey() UniqueKey {
   119  	return rp // A ResourcePhase is its own UniqueKey
   120  }
   121  
   122  func (rp ResourcePhase) uniqueKeySigil() {}