@@ -3,12 +3,13 @@ package kms
33import (
44 "context"
55 "fmt"
6+ "log"
67 "strings"
78
9+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
810 "github.com/oracle/terraform-provider-oci/internal/client"
911 "github.com/oracle/terraform-provider-oci/internal/tfresource"
1012
11- "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1213 oci_kms "github.com/oracle/oci-go-sdk/v65/keymanagement"
1314)
1415
@@ -20,7 +21,6 @@ func KmsVaultReplicationResource() *schema.Resource {
2021 Timeouts : tfresource .DefaultTimeout ,
2122 Create : createKmsVaultReplica ,
2223 Read : readKmsVaultReplica ,
23- Update : updateKmsVaultReplica ,
2424 Delete : deleteKmsVaultReplica ,
2525 Schema : map [string ]* schema.Schema {
2626 // Required
@@ -32,7 +32,10 @@ func KmsVaultReplicationResource() *schema.Resource {
3232 "replica_region" : {
3333 Type : schema .TypeString ,
3434 Required : true ,
35+ ForceNew : true ,
3536 },
37+
38+ // Optional
3639 "replica_vault_metadata" : {
3740 Type : schema .TypeList ,
3841 Optional : true ,
@@ -67,6 +70,18 @@ func KmsVaultReplicationResource() *schema.Resource {
6770 },
6871
6972 // Computed
73+ "crypto_endpoint" : {
74+ Type : schema .TypeString ,
75+ Computed : true ,
76+ },
77+ "management_endpoint" : {
78+ Type : schema .TypeString ,
79+ Computed : true ,
80+ },
81+ "vault_replica_status" : {
82+ Type : schema .TypeString ,
83+ Computed : true ,
84+ },
7085 },
7186 }
7287}
@@ -87,14 +102,6 @@ func readKmsVaultReplica(d *schema.ResourceData, m interface{}) error {
87102 return tfresource .ReadResource (sync )
88103}
89104
90- func updateKmsVaultReplica (d * schema.ResourceData , m interface {}) error {
91- sync := & KmsVaultReplicaResourceCrud {}
92- sync .D = d
93- sync .Client = m .(* client.OracleClients ).KmsVaultClient ()
94-
95- return tfresource .UpdateResource (d , sync )
96- }
97-
98105func deleteKmsVaultReplica (d * schema.ResourceData , m interface {}) error {
99106 sync := & KmsVaultReplicaResourceCrud {}
100107 sync .D = d
@@ -106,134 +113,148 @@ func deleteKmsVaultReplica(d *schema.ResourceData, m interface{}) error {
106113type KmsVaultReplicaResourceCrud struct {
107114 tfresource.BaseCrud
108115 Client * oci_kms.KmsVaultClient
109- Res * oci_kms.ListVaultReplicasResponse
116+ Res * oci_kms.VaultReplicaSummary
110117 DisableNotFoundRetries bool
111118}
112119
113120func (s * KmsVaultReplicaResourceCrud ) ID () string {
114- return * s .Res .OpcRequestId
115- }
116-
117- func (s * KmsVaultReplicaResourceCrud ) Create () error {
118- replicaRegionStr := ""
119- if replicaRegion , ok := s .D .GetOkExists ("replica_region" ); ok {
120- tmp := replicaRegion .(string )
121- replicaRegionStr = tmp
122- }
121+ log .Printf ("[INFO] ID()" )
123122
124- vaultIdStr := ""
123+ vaultIdStr := "vault_id "
125124 if vaultId , ok := s .D .GetOkExists ("vault_id" ); ok {
126125 tmp := vaultId .(string )
127126 vaultIdStr = tmp
128127 }
128+ replicaRegionStr := * s .Res .Region
129129
130- return s .createVaultReplicaHelper (vaultIdStr , replicaRegionStr )
130+ log .Printf ("[INFO] ID() Setting ID: %s" , fmt .Sprintf ("%s:%s" , vaultIdStr , replicaRegionStr ))
131+ return fmt .Sprintf ("%s:%s" , vaultIdStr , replicaRegionStr )
131132}
132133
133- func (s * KmsVaultReplicaResourceCrud ) Get () error {
134- request := oci_kms.ListVaultReplicasRequest {}
134+ func (s * KmsVaultReplicaResourceCrud ) Create () error {
135+ log .Printf ("[INFO] Create()" )
136+ request := oci_kms.CreateVaultReplicaRequest {}
135137
136138 if vaultId , ok := s .D .GetOkExists ("vault_id" ); ok {
137139 tmp := vaultId .(string )
138140 request .VaultId = & tmp
139141 }
140142
141- request .RequestMetadata .RetryPolicy = tfresource .GetRetryPolicy (s .DisableNotFoundRetries , "kms" )
142-
143- response , err := s .Client .ListVaultReplicas (context .Background (), request )
144- if err != nil {
145- return err
143+ if replicaRegion , ok := s .D .GetOkExists ("replica_region" ); ok {
144+ tmp := replicaRegion .(string )
145+ request .ReplicaRegion = & tmp
146146 }
147147
148- s .Res = & response
149- return nil
150- }
151-
152- func (s * KmsVaultReplicaResourceCrud ) Update () error {
148+ if replicaVaultMetadata , ok := s .D .GetOkExists ("replica_vault_metadata" ); ok {
149+ if tmpList := replicaVaultMetadata .([]interface {}); len (tmpList ) > 0 {
150+ fieldKeyFormat := fmt .Sprintf ("%s.%d.%%s" , "replica_vault_metadata" , 0 )
151+ replicaExternalVaultMetadata := oci_kms.ReplicaExternalVaultMetadata {}
153152
154- // Update is only supported for the change in replica region. All others are a forceNew
155- if s .D .HasChange ("replica_region" ) {
153+ if privateEndpointId , ok := s .D .GetOkExists (fmt .Sprintf (fieldKeyFormat , "private_endpoint_id" )); ok {
154+ tmp := privateEndpointId .(string )
155+ replicaExternalVaultMetadata .PrivateEndpointId = & tmp
156+ }
156157
157- oldRaw , newRaw := s .D .GetChange ("replica_region" )
158- oldReplicaRegionName := oldRaw .(string )
159- newReplicaRegionName := newRaw .(string )
158+ if idcsAccountNameUrl , ok := s .D .GetOkExists (fmt .Sprintf (fieldKeyFormat , "idcs_account_name_url" )); ok {
159+ tmp := idcsAccountNameUrl .(string )
160+ replicaExternalVaultMetadata .IdcsAccountNameUrl = & tmp
161+ }
160162
161- vaultIdStr := ""
162- if vaultId , ok := s .D .GetOkExists ("vault_id" ); ok {
163- tmp := vaultId .(string )
164- vaultIdStr = tmp
163+ request .ReplicaVaultMetadata = & replicaExternalVaultMetadata
165164 }
165+ }
166166
167- // delete replica in the old region for the primary vault
168- err := s .deleteVaultReplicaHelper (vaultIdStr , oldReplicaRegionName )
169- if err != nil {
170- return err
171- }
167+ request .RequestMetadata .RetryPolicy = tfresource .GetRetryPolicy (s .DisableNotFoundRetries , "kms" )
168+
169+ log .Printf ("[INFO] Create() Sending Create Replica Request" )
170+ _ , err := s .Client .CreateVaultReplica (context .Background (), request )
171+ if err != nil {
172+ return err
173+ }
172174
173- // Create replica in the new region for the primary vault after deletion is completed
174- return s .createVaultReplicaHelper (vaultIdStr , newReplicaRegionName )
175+ log .Printf ("[INFO] Create() Waiting for Replica Creation" )
176+ retentionPolicyFunc := func () bool { return s .Res .Status == oci_kms .VaultReplicaSummaryStatusCreated }
177+ waitErr := tfresource .WaitForResourceCondition (s , retentionPolicyFunc , s .D .Timeout (schema .TimeoutCreate ))
178+ if waitErr != nil {
179+ return waitErr
175180 }
181+ log .Printf ("[INFO] Create() Replica Creation Completed" )
182+
176183 return nil
177184}
178185
179- func (s * KmsVaultReplicaResourceCrud ) Delete () error {
180- replicaRegionStr := ""
181- if replicaRegion , ok := s .D .GetOkExists ("replica_region" ); ok {
182- tmp := replicaRegion .(string )
183- replicaRegionStr = tmp
184- }
186+ func (s * KmsVaultReplicaResourceCrud ) Get () error {
187+ log .Printf ("[INFO] Get()" )
188+
189+ request := oci_kms.ListVaultReplicasRequest {}
190+
191+ /*
192+ *The Vault ID is only present in the config and not in the Response so we need to check
193+ * if Vault ID is available in the state/config then use that else extract it from the ID
194+ * We can't always use the ID as it is only set after resource creation or provided during import
195+ */
196+ vaultIdStr := "vault_id"
197+ replicaRegionStr := "replica_region"
185198
186- vaultIdStr := ""
187199 if vaultId , ok := s .D .GetOkExists ("vault_id" ); ok {
188200 tmp := vaultId .(string )
189201 vaultIdStr = tmp
202+ request .VaultId = & tmp
190203 }
191-
192- return s .deleteVaultReplicaHelper (vaultIdStr , replicaRegionStr )
193- }
194-
195- func (s * KmsVaultReplicaResourceCrud ) createVaultReplicaHelper (vaultId string , replicaRegion string ) error {
196- request := oci_kms.CreateVaultReplicaRequest {}
197-
198- if len (strings .TrimSpace (vaultId )) != 0 {
199- request .VaultId = & vaultId
200- }
201-
202- if len (strings .TrimSpace (replicaRegion )) != 0 {
203- request .ReplicaRegion = & replicaRegion
204+ if replicaRegion , ok := s .D .GetOkExists ("replica_region" ); ok {
205+ tmp := replicaRegion .(string )
206+ replicaRegionStr = tmp
204207 }
205-
206- if replicaVaultMetadata , ok := s .D .GetOkExists ("replica_vault_metadata" ); ok {
207- if tmpList := replicaVaultMetadata .([]interface {}); len (tmpList ) > 0 {
208- fieldKeyFormat := fmt .Sprintf ("%s.%d.%%s" , "replica_vault_metadata" , 0 )
209- tmp , err := s .mapToReplicaVaultMetadata (fieldKeyFormat )
210- if err != nil {
211- return err
212- }
213- request .ReplicaVaultMetadata = & tmp
208+ // If the Vault ID or Replica Region String didn't get updated from state/config, use ID
209+ if vaultIdStr == "vault_id" || replicaRegionStr == "replica_region" {
210+ log .Printf ("[INFO] Get() Vault ID or Replica Region String didn't get updated from state/config, using Resource ID" )
211+ parts := strings .Split (s .D .Id (), ":" )
212+ if len (parts ) > 1 {
213+ vaultId := parts [0 ]
214+ request .VaultId = & vaultId
215+ replicaRegionStr = parts [1 ]
216+ } else {
217+ log .Fatalf ("[ERROR] Get() unable to parse current ID: %s. The expected format of the ID is \" {vault_id}:{replica_region}\" " , s .D .Id ())
214218 }
215219 }
216220
217221 request .RequestMetadata .RetryPolicy = tfresource .GetRetryPolicy (s .DisableNotFoundRetries , "kms" )
218222
219- _ , err := s .Client .CreateVaultReplica (context .Background (), request )
223+ log .Printf ("[INFO] Get() Calling List Vault Replicas" )
224+ response , err := s .Client .ListVaultReplicas (context .Background (), request )
220225 if err != nil {
221226 return err
222227 }
223228
224- retentionPolicyFunc := func () bool { return s .Res .Items [0 ].Status == oci_kms .VaultReplicaSummaryStatusCreated }
225- return tfresource .WaitForResourceCondition (s , retentionPolicyFunc , s .D .Timeout (schema .TimeoutCreate ))
229+ vaultReplicaSummaryRes := oci_kms.VaultReplicaSummary {Status : oci_kms .VaultReplicaSummaryStatusDeleted }
230+ for _ , vaultReplicaSummary := range response .Items {
231+ vaultReplicaRegion := * (vaultReplicaSummary .Region )
232+ if vaultReplicaRegion == replicaRegionStr {
233+ vaultReplicaSummaryRes = vaultReplicaSummary
234+ }
235+ }
236+ s .Res = & vaultReplicaSummaryRes
237+ // Explicitly Call VoidState to Remove Deleted Vault Replica from State
238+ if s .Res .Status == oci_kms .VaultReplicaSummaryStatusDeleted {
239+ log .Printf ("[INFO] VoidState() as no resource is found, removing from state" )
240+ s .VoidState ()
241+ }
242+
243+ return nil
226244}
227245
228- func (s * KmsVaultReplicaResourceCrud ) deleteVaultReplicaHelper (vaultId string , replicaRegion string ) error {
246+ func (s * KmsVaultReplicaResourceCrud ) Delete () error {
247+ log .Printf ("[INFO] Delete()" )
229248 request := oci_kms.DeleteVaultReplicaRequest {}
230249
231- if len (strings .TrimSpace (vaultId )) != 0 {
232- request .VaultId = & vaultId
250+ if vaultId , ok := s .D .GetOkExists ("vault_id" ); ok {
251+ tmp := vaultId .(string )
252+ request .VaultId = & tmp
233253 }
234254
235- if len (strings .TrimSpace (replicaRegion )) != 0 {
236- request .ReplicaRegion = & replicaRegion
255+ if replicaRegion , ok := s .D .GetOkExists ("replica_region" ); ok {
256+ tmp := replicaRegion .(string )
257+ request .ReplicaRegion = & tmp
237258 }
238259
239260 request .RequestMetadata .RetryPolicy = tfresource .GetRetryPolicy (s .DisableNotFoundRetries , "kms" )
@@ -243,60 +264,71 @@ func (s *KmsVaultReplicaResourceCrud) deleteVaultReplicaHelper(vaultId string, r
243264 return err
244265 }
245266
246- retentionPolicyFunc := func () bool {
247- return (len (s .Res .Items ) == 0 || s .Res .Items [0 ].Status == oci_kms .VaultReplicaSummaryStatusDeleted )
267+ retentionPolicyFunc := func () bool { return s .Res == nil || s .Res .Status == oci_kms .VaultReplicaSummaryStatusDeleted }
268+ waitErr := tfresource .WaitForResourceCondition (s , retentionPolicyFunc , s .D .Timeout (schema .TimeoutDelete ))
269+ if waitErr != nil {
270+ return waitErr
248271 }
249- return tfresource .WaitForResourceCondition (s , retentionPolicyFunc , s .D .Timeout (schema .TimeoutDelete ))
272+
273+ return nil
250274}
251275
252276func (s * KmsVaultReplicaResourceCrud ) SetData () error {
277+ log .Printf ("[INFO] SetData()" )
278+
279+ parts := strings .Split (s .D .Id (), ":" )
280+ if len (parts ) > 1 {
281+ vaultId := parts [0 ]
282+ s .D .Set ("vault_id" , & vaultId )
283+ }
284+
285+ if s .Res .CryptoEndpoint != nil {
286+ s .D .Set ("crypto_endpoint" , * s .Res .CryptoEndpoint )
287+ }
288+
289+ if s .Res .ManagementEndpoint != nil {
290+ s .D .Set ("management_endpoint" , * s .Res .ManagementEndpoint )
291+ }
292+
293+ if s .Res .Region != nil {
294+ s .D .Set ("replica_region" , * s .Res .Region )
295+ }
296+
297+ s .D .Set ("vault_replica_status" , s .Res .Status )
298+
253299 return nil
254300}
255301
256- // Necessary to have. Otherwise cause "Could not set resource state" error from setState() in crud helper
302+ // State Necessary to have. Otherwise, cause "Could not set resource state, sync did not have a valid .Res.State, .Resource.State, or .WorkRequest.State " error from setState() in crud_helper
257303func (s * KmsVaultReplicaResourceCrud ) State () oci_kms.VaultReplicaSummaryStatusEnum {
258- if len (s .Res .Items ) > 0 {
259- return s .Res .Items [0 ].Status
260- }
261- return ""
304+ log .Printf ("[INFO] State()" )
305+ return s .Res .Status
262306}
263307
264308func (s * KmsVaultReplicaResourceCrud ) CreatedPending () []string {
309+ log .Printf ("[INFO] CreatedPending()" )
265310 return []string {
266311 string (oci_kms .VaultReplicaSummaryStatusCreating ),
267312 }
268313}
269314
270315func (s * KmsVaultReplicaResourceCrud ) CreatedTarget () []string {
316+ log .Printf ("[INFO] CreatedTarget()" )
271317 return []string {
272318 string (oci_kms .VaultReplicaSummaryStatusCreated ),
273319 }
274320}
275321
276322func (s * KmsVaultReplicaResourceCrud ) DeletedPending () []string {
323+ log .Printf ("[INFO] DeletedPending()" )
277324 return []string {
278325 string (oci_kms .VaultReplicaSummaryStatusDeleting ),
279326 }
280327}
281328
282329func (s * KmsVaultReplicaResourceCrud ) DeletedTarget () []string {
330+ log .Printf ("[INFO] DeletedTarget()" )
283331 return []string {
284332 string (oci_kms .VaultReplicaSummaryStatusDeleted ),
285333 }
286334}
287-
288- func (s * KmsVaultReplicaResourceCrud ) mapToReplicaVaultMetadata (fieldKeyFormat string ) (oci_kms.ReplicaExternalVaultMetadata , error ) {
289- result := oci_kms.ReplicaExternalVaultMetadata {}
290-
291- if privateEndpointId , ok := s .D .GetOkExists (fmt .Sprintf (fieldKeyFormat , "private_endpoint_id" )); ok {
292- tmp := privateEndpointId .(string )
293- result .PrivateEndpointId = & tmp
294- }
295-
296- if idcsAccountNameUrl , ok := s .D .GetOkExists (fmt .Sprintf (fieldKeyFormat , "idcs_account_name_url" )); ok {
297- tmp := idcsAccountNameUrl .(string )
298- result .IdcsAccountNameUrl = & tmp
299- }
300-
301- return result , nil
302- }
0 commit comments