44package resourcecontroller
55
66import (
7+ "context"
78 "encoding/json"
89 "fmt"
910 "log"
1011 "strconv"
1112 "strings"
1213 "time"
1314
15+ "github.com/IBM/go-sdk-core/v5/core"
1416 rc "github.com/IBM/platform-services-go-sdk/resourcecontrollerv2"
17+ "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
18+ "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry"
1519 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1620
1721 "github.com/IBM-Cloud/terraform-provider-ibm/ibm/conns"
@@ -22,12 +26,12 @@ import (
2226
2327func ResourceIBMResourceKey () * schema.Resource {
2428 return & schema.Resource {
25- Create : resourceIBMResourceKeyCreate ,
26- Read : resourceIBMResourceKeyRead ,
27- Update : resourceIBMResourceKeyUpdate ,
28- Delete : resourceIBMResourceKeyDelete ,
29- Exists : resourceIBMResourceKeyExists ,
30- Importer : & schema.ResourceImporter {},
29+ CreateContext : resourceIBMResourceKeyCreate ,
30+ ReadContext : resourceIBMResourceKeyRead ,
31+ UpdateContext : resourceIBMResourceKeyUpdate ,
32+ DeleteContext : resourceIBMResourceKeyDelete ,
33+ Exists : resourceIBMResourceKeyExists ,
34+ Importer : & schema.ResourceImporter {},
3135
3236 Timeouts : & schema.ResourceTimeout {
3337 Create : schema .DefaultTimeout (10 * time .Minute ),
@@ -215,10 +219,10 @@ func ResourceIBMResourceKeyValidator() *validate.ResourceValidator {
215219 return & ibmResourceKeyResourceValidator
216220}
217221
218- func resourceIBMResourceKeyCreate (d * schema.ResourceData , meta interface {}) error {
222+ func resourceIBMResourceKeyCreate (context context. Context , d * schema.ResourceData , meta interface {}) diag. Diagnostics {
219223 rsContClient , err := meta .(conns.ClientSession ).ResourceControllerV2API ()
220224 if err != nil {
221- return err
225+ return diag . FromErr ( err )
222226 }
223227 name := d .Get ("name" ).(string )
224228
@@ -232,7 +236,7 @@ func resourceIBMResourceKeyCreate(d *schema.ResourceData, meta interface{}) erro
232236 }
233237
234238 if instanceID == "" && aliasID == "" {
235- return fmt .Errorf ("[ERROR] Provide either `resource_instance_id` or `resource_alias_id`" )
239+ return diag . FromErr ( fmt .Errorf ("[ERROR] Provide either `resource_instance_id` or `resource_alias_id`" ) )
236240 }
237241
238242 keyParameters := rc.ResourceKeyPostParameters {}
@@ -251,19 +255,19 @@ func resourceIBMResourceKeyCreate(d *schema.ResourceData, meta interface{}) erro
251255
252256 resourceInstance , sourceCRN , err := getResourceInstanceAndCRN (d , meta )
253257 if err != nil {
254- return fmt .Errorf ("[ERROR] Error creating resource key when get instance and CRN: %s" , err )
258+ return diag . FromErr ( fmt .Errorf ("[ERROR] Error creating resource key when get instance and CRN: %s" , err ) )
255259 }
256260
257261 serviceID := resourceInstance .ResourceID
258262
259263 rsCatClient , err := meta .(conns.ClientSession ).ResourceCatalogAPI ()
260264 if err != nil {
261- return fmt .Errorf ("[ERROR] Error creating resource key when get ResourceCatalogAPI: %s" , err )
265+ return diag . FromErr ( fmt .Errorf ("[ERROR] Error creating resource key when get ResourceCatalogAPI: %s" , err ) )
262266 }
263267
264268 service , err := rsCatClient .ResourceCatalog ().Get (* serviceID , true )
265269 if err != nil {
266- return fmt .Errorf ("[ERROR] Error creating resource key when get service: %s" , err )
270+ return diag . FromErr ( fmt .Errorf ("[ERROR] Error creating resource key when get service: %s" , err ) )
267271 }
268272
269273 resourceKeyCreate := rc.CreateResourceKeyOptions {
@@ -275,7 +279,7 @@ func resourceIBMResourceKeyCreate(d *schema.ResourceData, meta interface{}) erro
275279 role := r .(string )
276280 serviceRole , err := getRoleFromName (role , service .Name , meta )
277281 if err != nil {
278- return fmt .Errorf ("[ERROR] Error creating resource key when get role: %s" , err )
282+ return diag . FromErr ( fmt .Errorf ("[ERROR] Error creating resource key when get role: %s" , err ) )
279283 }
280284 if role != "NONE" {
281285 keyParameters .SetProperty ("role_crn" , serviceRole .RoleID )
@@ -285,43 +289,80 @@ func resourceIBMResourceKeyCreate(d *schema.ResourceData, meta interface{}) erro
285289
286290 resourceKey , resp , err := rsContClient .CreateResourceKey (& resourceKeyCreate )
287291 if err != nil {
288- return fmt .Errorf ("[ERROR] Error creating resource key: %s with resp code: %s" , err , resp )
292+ return diag . FromErr ( fmt .Errorf ("[ERROR] Error creating resource key: %s with resp code: %s" , err , resp ) )
289293 }
290294
291295 d .SetId (* resourceKey .ID )
292296
293- return resourceIBMResourceKeyRead (d , meta )
297+ return resourceIBMResourceKeyRead (context , d , meta )
294298}
295299
296- func resourceIBMResourceKeyUpdate (d * schema.ResourceData , meta interface {}) error {
300+ func resourceIBMResourceKeyUpdate (context context. Context , d * schema.ResourceData , meta interface {}) diag. Diagnostics {
297301 return nil
298302}
299303
300- func resourceIBMResourceKeyRead (d * schema.ResourceData , meta interface {}) error {
304+ func resourceIBMResourceKeyRead (context context. Context , d * schema.ResourceData , meta interface {}) diag. Diagnostics {
301305 rsContClient , err := meta .(conns.ClientSession ).ResourceControllerV2API ()
302306 if err != nil {
303- return err
307+ return diag . FromErr ( err )
304308 }
305309 resourceKeyID := d .Id ()
306310 resourceKeyGet := rc.GetResourceKeyOptions {
307311 ID : & resourceKeyID ,
308312 }
309313
310- resourceKey , resp , err := rsContClient .GetResourceKey (& resourceKeyGet )
314+ var resp * core.DetailedResponse
315+ var resourceKey * rc.ResourceKey
316+ var (
317+ initialDelaySec = 2 // seconds
318+ maxDelaySec = 60 // max delay in seconds
319+
320+ )
321+
322+ err = retry .RetryContext (context , 5 * time .Minute , func () * retry.RetryError {
323+ retryCount := 0
324+
325+ return func () * retry.RetryError {
326+ // Calculate exponential delay
327+ delaySec := initialDelaySec * (1 << retryCount ) // equivalent to initialDelaySec * 2^retryCount
328+ if delaySec > maxDelaySec {
329+ delaySec = maxDelaySec
330+ }
331+ time .Sleep (time .Duration (delaySec ) * time .Second )
332+
333+ resourceKey , resp , err = rsContClient .GetResourceKey (& resourceKeyGet )
334+ if err != nil || resourceKey == nil {
335+ retryCount ++
336+ if resp != nil && resp .StatusCode == 404 {
337+ return retry .RetryableError (err )
338+ }
339+ return retry .NonRetryableError (err )
340+ }
341+ return nil
342+ }()
343+ })
344+ if conns .IsResourceTimeoutError (err ) {
345+ resourceKey , resp , err = rsContClient .GetResourceKey (& resourceKeyGet )
346+ }
311347 if err != nil || resourceKey == nil {
312- return fmt .Errorf ("[ERROR] Error retrieving resource key: %s with resp : %s" , err , resp )
348+ if resp != nil && resp .StatusCode == 404 {
349+ d .SetId ("" )
350+ return nil
351+ }
352+ return diag .FromErr (fmt .Errorf ("[ERROR] Error retrieving resource key: %s with resp : %s" , err , resp ))
313353 }
354+
314355 var credInterface map [string ]interface {}
315356 cred , _ := json .Marshal (resourceKey .Credentials )
316357 json .Unmarshal (cred , & credInterface )
317358 d .Set ("credentials" , flex .Flatten (credInterface ))
318359
319360 creds , err := json .Marshal (resourceKey .Credentials )
320361 if err != nil {
321- return fmt .Errorf ("[ERROR] Error marshalling resource key credentials: %s" , err )
362+ return diag . FromErr ( fmt .Errorf ("[ERROR] Error marshalling resource key credentials: %s" , err ) )
322363 }
323364 if err = d .Set ("credentials_json" , string (creds )); err != nil {
324- return fmt .Errorf ("[ERROR] Error setting the credentials json: %s" , err )
365+ return diag . FromErr ( fmt .Errorf ("[ERROR] Error setting the credentials json: %s" , err ) )
325366 }
326367 d .Set ("name" , * resourceKey .Name )
327368 d .Set ("status" , * resourceKey .State )
@@ -398,10 +439,10 @@ func resourceIBMResourceKeyRead(d *schema.ResourceData, meta interface{}) error
398439 return nil
399440}
400441
401- func resourceIBMResourceKeyDelete (d * schema.ResourceData , meta interface {}) error {
442+ func resourceIBMResourceKeyDelete (context context. Context , d * schema.ResourceData , meta interface {}) diag. Diagnostics {
402443 rsContClient , err := meta .(conns.ClientSession ).ResourceControllerV2API ()
403444 if err != nil {
404- return err
445+ return diag . FromErr ( err )
405446 }
406447
407448 resourceKeyID := d .Id ()
@@ -411,7 +452,7 @@ func resourceIBMResourceKeyDelete(d *schema.ResourceData, meta interface{}) erro
411452
412453 resp , err := rsContClient .DeleteResourceKey (& resourceKeyDelete )
413454 if err != nil {
414- return fmt .Errorf ("[ERROR] Error deleting resource key: %s with resp code: %s" , err , resp )
455+ return diag . FromErr ( fmt .Errorf ("[ERROR] Error deleting resource key: %s with resp code: %s" , err , resp ) )
415456 }
416457
417458 d .SetId ("" )
0 commit comments