@@ -517,9 +517,11 @@ func resourceContainerNodePoolCreate(d *schema.ResourceData, meta interface{}) e
517
517
operation , err = clusterNodePoolsCreateCall .Do ()
518
518
519
519
if err != nil {
520
- if tpgresource .IsFailedPreconditionError (err ) {
520
+ if tpgresource .IsFailedPreconditionError (err ) || tpgresource . IsQuotaError ( err ) {
521
521
// We get failed precondition errors if the cluster is updating
522
522
// while we try to add the node pool.
523
+ // We get quota errors if there the number of running concurrent
524
+ // operations reaches the quota.
523
525
return resource .RetryableError (err )
524
526
}
525
527
return resource .NonRetryableError (err )
@@ -722,9 +724,11 @@ func resourceContainerNodePoolDelete(d *schema.ResourceData, meta interface{}) e
722
724
operation , err = clusterNodePoolsDeleteCall .Do ()
723
725
724
726
if err != nil {
725
- if tpgresource .IsFailedPreconditionError (err ) {
727
+ if tpgresource .IsFailedPreconditionError (err ) || tpgresource . IsQuotaError ( err ) {
726
728
// We get failed precondition errors if the cluster is updating
727
729
// while we try to delete the node pool.
730
+ // We get quota errors if there the number of running concurrent
731
+ // operations reaches the quota.
728
732
return resource .RetryableError (err )
729
733
}
730
734
return resource .NonRetryableError (err )
@@ -1202,7 +1206,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1202
1206
timeout )
1203
1207
}
1204
1208
1205
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1209
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1206
1210
return err
1207
1211
}
1208
1212
log .Printf ("[INFO] Updated autoscaling in Node Pool %s" , d .Id ())
@@ -1240,7 +1244,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1240
1244
timeout )
1241
1245
}
1242
1246
1243
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1247
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1244
1248
return err
1245
1249
}
1246
1250
@@ -1294,7 +1298,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1294
1298
timeout )
1295
1299
}
1296
1300
1297
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1301
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1298
1302
return err
1299
1303
}
1300
1304
log .Printf ("[INFO] Updated tags for node pool %s" , name )
@@ -1331,7 +1335,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1331
1335
}
1332
1336
1333
1337
// Call update serially.
1334
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1338
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1335
1339
return err
1336
1340
}
1337
1341
@@ -1369,7 +1373,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1369
1373
}
1370
1374
1371
1375
// Call update serially.
1372
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1376
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1373
1377
return err
1374
1378
}
1375
1379
@@ -1401,7 +1405,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1401
1405
timeout )
1402
1406
}
1403
1407
1404
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1408
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1405
1409
return err
1406
1410
}
1407
1411
log .Printf ("[INFO] Updated image type in Node Pool %s" , d .Id ())
@@ -1435,7 +1439,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1435
1439
timeout )
1436
1440
}
1437
1441
1438
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1442
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1439
1443
return err
1440
1444
}
1441
1445
log .Printf ("[INFO] Updated workload_metadata_config for node pool %s" , name )
@@ -1468,7 +1472,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1468
1472
timeout )
1469
1473
}
1470
1474
1471
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1475
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1472
1476
return err
1473
1477
}
1474
1478
@@ -1501,7 +1505,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1501
1505
timeout )
1502
1506
}
1503
1507
1504
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1508
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1505
1509
return err
1506
1510
}
1507
1511
@@ -1532,7 +1536,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1532
1536
nodePoolInfo .location , "updating GKE node pool size" , userAgent ,
1533
1537
timeout )
1534
1538
}
1535
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1539
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1536
1540
return err
1537
1541
}
1538
1542
log .Printf ("[INFO] GKE node pool %s size has been updated to %d" , name , newSize )
@@ -1567,7 +1571,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1567
1571
nodePoolInfo .location , "updating GKE node pool management" , userAgent , timeout )
1568
1572
}
1569
1573
1570
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1574
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1571
1575
return err
1572
1576
}
1573
1577
log .Printf ("[INFO] Updated management in Node Pool %s" , name )
@@ -1594,7 +1598,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1594
1598
nodePoolInfo .project ,
1595
1599
nodePoolInfo .location , "updating GKE node pool version" , userAgent , timeout )
1596
1600
}
1597
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1601
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1598
1602
return err
1599
1603
}
1600
1604
log .Printf ("[INFO] Updated version in Node Pool %s" , name )
@@ -1619,7 +1623,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1619
1623
return ContainerOperationWait (config , op , nodePoolInfo .project , nodePoolInfo .location , "updating GKE node pool node locations" , userAgent , timeout )
1620
1624
}
1621
1625
1622
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1626
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1623
1627
return err
1624
1628
}
1625
1629
log .Printf ("[INFO] Updated node locations in Node Pool %s" , name )
@@ -1699,7 +1703,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1699
1703
// Wait until it's updated
1700
1704
return ContainerOperationWait (config , op , nodePoolInfo .project , nodePoolInfo .location , "updating GKE node pool upgrade settings" , userAgent , timeout )
1701
1705
}
1702
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1706
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1703
1707
return err
1704
1708
}
1705
1709
log .Printf ("[INFO] Updated upgrade settings in Node Pool %s" , name )
@@ -1730,7 +1734,7 @@ func nodePoolUpdate(d *schema.ResourceData, meta interface{}, nodePoolInfo *Node
1730
1734
timeout )
1731
1735
}
1732
1736
1733
- if err := tpgresource . RetryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1737
+ if err := retryWhileIncompatibleOperation (timeout , npLockKey , updateF ); err != nil {
1734
1738
return err
1735
1739
}
1736
1740
@@ -1781,3 +1785,21 @@ func containerNodePoolAwaitRestingState(config *transport_tpg.Config, name, proj
1781
1785
1782
1786
return state , err
1783
1787
}
1788
+
1789
+ // Retries an operation while the canonical error code is FAILED_PRECONDTION
1790
+ // or RESOURCE_EXHAUSTED which indicates there is an incompatible operation
1791
+ // already running on the cluster or there are the number of allowed
1792
+ // concurrent operations running on the cluster. These errors can be safely
1793
+ // retried until the incompatible operation completes, and the newly
1794
+ // requested operation can begin.
1795
+ func retryWhileIncompatibleOperation (timeout time.Duration , lockKey string , f func () error ) error {
1796
+ return resource .Retry (timeout , func () * resource.RetryError {
1797
+ if err := transport_tpg .LockedCall (lockKey , f ); err != nil {
1798
+ if tpgresource .IsFailedPreconditionError (err ) || tpgresource .IsQuotaError (err ) {
1799
+ return resource .RetryableError (err )
1800
+ }
1801
+ return resource .NonRetryableError (err )
1802
+ }
1803
+ return nil
1804
+ })
1805
+ }
0 commit comments