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() {}