@@ -296,6 +296,48 @@ If not set, defaults to 14 days.`,
296296 Description : `User-defined labels for the alloydb cluster.` ,
297297 Elem : & schema.Schema {Type : schema .TypeString },
298298 },
299+ "restore_backup_source" : {
300+ Type : schema .TypeList ,
301+ Optional : true ,
302+ ForceNew : true ,
303+ Description : `The source when restoring from a backup. Conflicts with 'restore_continuous_backup_source', both can't be set together.` ,
304+ MaxItems : 1 ,
305+ Elem : & schema.Resource {
306+ Schema : map [string ]* schema.Schema {
307+ "backup_name" : {
308+ Type : schema .TypeString ,
309+ Required : true ,
310+ ForceNew : true ,
311+ Description : `The name of the backup that this cluster is restored from.` ,
312+ },
313+ },
314+ },
315+ ConflictsWith : []string {"restore_continuous_backup_source" },
316+ },
317+ "restore_continuous_backup_source" : {
318+ Type : schema .TypeList ,
319+ Optional : true ,
320+ ForceNew : true ,
321+ Description : `The source when restoring via point in time recovery (PITR). Conflicts with 'restore_backup_source', both can't be set together.` ,
322+ MaxItems : 1 ,
323+ Elem : & schema.Resource {
324+ Schema : map [string ]* schema.Schema {
325+ "cluster" : {
326+ Type : schema .TypeString ,
327+ Required : true ,
328+ ForceNew : true ,
329+ Description : `The name of the source cluster that this cluster is restored from.` ,
330+ },
331+ "point_in_time" : {
332+ Type : schema .TypeString ,
333+ Required : true ,
334+ ForceNew : true ,
335+ Description : `The point in time that this cluster is restored to, in RFC 3339 format.` ,
336+ },
337+ },
338+ },
339+ ConflictsWith : []string {"restore_backup_source" },
340+ },
299341 "backup_source" : {
300342 Type : schema .TypeList ,
301343 Computed : true ,
@@ -469,6 +511,18 @@ func resourceAlloydbClusterCreate(d *schema.ResourceData, meta interface{}) erro
469511 } else if v , ok := d .GetOkExists ("initial_user" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (initialUserProp )) && (ok || ! reflect .DeepEqual (v , initialUserProp )) {
470512 obj ["initialUser" ] = initialUserProp
471513 }
514+ restoreBackupSourceProp , err := expandAlloydbClusterRestoreBackupSource (d .Get ("restore_backup_source" ), d , config )
515+ if err != nil {
516+ return err
517+ } else if v , ok := d .GetOkExists ("restore_backup_source" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (restoreBackupSourceProp )) && (ok || ! reflect .DeepEqual (v , restoreBackupSourceProp )) {
518+ obj ["restoreBackupSource" ] = restoreBackupSourceProp
519+ }
520+ restoreContinuousBackupSourceProp , err := expandAlloydbClusterRestoreContinuousBackupSource (d .Get ("restore_continuous_backup_source" ), d , config )
521+ if err != nil {
522+ return err
523+ } else if v , ok := d .GetOkExists ("restore_continuous_backup_source" ); ! tpgresource .IsEmptyValue (reflect .ValueOf (restoreContinuousBackupSourceProp )) && (ok || ! reflect .DeepEqual (v , restoreContinuousBackupSourceProp )) {
524+ obj ["restoreContinuousBackupSource" ] = restoreContinuousBackupSourceProp
525+ }
472526 continuousBackupConfigProp , err := expandAlloydbClusterContinuousBackupConfig (d .Get ("continuous_backup_config" ), d , config )
473527 if err != nil {
474528 return err
@@ -501,6 +555,39 @@ func resourceAlloydbClusterCreate(d *schema.ResourceData, meta interface{}) erro
501555 billingProject = bp
502556 }
503557
558+ // Read the restore variables from obj and remove them, since they do not map to anything in the cluster
559+ var backupSource interface {}
560+ var continuousBackupSource interface {}
561+ if val , ok := obj ["restoreBackupSource" ]; ok {
562+ backupSource = val
563+ delete (obj , "restoreBackupSource" )
564+ }
565+ if val , ok := obj ["restoreContinuousBackupSource" ]; ok {
566+ continuousBackupSource = val
567+ delete (obj , "restoreContinuousBackupSource" )
568+ }
569+
570+ restoreClusterRequestBody := make (map [string ]interface {})
571+ if backupSource != nil {
572+ // If restoring from a backup, set the backupSource
573+ restoreClusterRequestBody ["backup_source" ] = backupSource
574+ } else if continuousBackupSource != nil {
575+ // Otherwise if restoring via PITR, set the continuousBackupSource
576+ restoreClusterRequestBody ["continuous_backup_source" ] = continuousBackupSource
577+ }
578+
579+ if backupSource != nil || continuousBackupSource != nil {
580+ // Use restore API if this is a restore instead of a create cluster call
581+ url = strings .Replace (url , "clusters?clusterId" , "clusters:restore?clusterId" , 1 )
582+
583+ // Copy obj which contains the cluster into a cluster map
584+ cluster := make (map [string ]interface {})
585+ for k , v := range obj {
586+ cluster [k ] = v
587+ }
588+ restoreClusterRequestBody ["cluster" ] = cluster
589+ obj = restoreClusterRequestBody
590+ }
504591 res , err := transport_tpg .SendRequest (transport_tpg.SendRequestOptions {
505592 Config : config ,
506593 Method : "POST" ,
@@ -1337,6 +1424,63 @@ func expandAlloydbClusterInitialUserPassword(v interface{}, d tpgresource.Terraf
13371424 return v , nil
13381425}
13391426
1427+ func expandAlloydbClusterRestoreBackupSource (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
1428+ l := v .([]interface {})
1429+ if len (l ) == 0 || l [0 ] == nil {
1430+ return nil , nil
1431+ }
1432+ raw := l [0 ]
1433+ original := raw .(map [string ]interface {})
1434+ transformed := make (map [string ]interface {})
1435+
1436+ transformedBackupName , err := expandAlloydbClusterRestoreBackupSourceBackupName (original ["backup_name" ], d , config )
1437+ if err != nil {
1438+ return nil , err
1439+ } else if val := reflect .ValueOf (transformedBackupName ); val .IsValid () && ! tpgresource .IsEmptyValue (val ) {
1440+ transformed ["backupName" ] = transformedBackupName
1441+ }
1442+
1443+ return transformed , nil
1444+ }
1445+
1446+ func expandAlloydbClusterRestoreBackupSourceBackupName (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
1447+ return v , nil
1448+ }
1449+
1450+ func expandAlloydbClusterRestoreContinuousBackupSource (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
1451+ l := v .([]interface {})
1452+ if len (l ) == 0 || l [0 ] == nil {
1453+ return nil , nil
1454+ }
1455+ raw := l [0 ]
1456+ original := raw .(map [string ]interface {})
1457+ transformed := make (map [string ]interface {})
1458+
1459+ transformedCluster , err := expandAlloydbClusterRestoreContinuousBackupSourceCluster (original ["cluster" ], d , config )
1460+ if err != nil {
1461+ return nil , err
1462+ } else if val := reflect .ValueOf (transformedCluster ); val .IsValid () && ! tpgresource .IsEmptyValue (val ) {
1463+ transformed ["cluster" ] = transformedCluster
1464+ }
1465+
1466+ transformedPointInTime , err := expandAlloydbClusterRestoreContinuousBackupSourcePointInTime (original ["point_in_time" ], d , config )
1467+ if err != nil {
1468+ return nil , err
1469+ } else if val := reflect .ValueOf (transformedPointInTime ); val .IsValid () && ! tpgresource .IsEmptyValue (val ) {
1470+ transformed ["pointInTime" ] = transformedPointInTime
1471+ }
1472+
1473+ return transformed , nil
1474+ }
1475+
1476+ func expandAlloydbClusterRestoreContinuousBackupSourceCluster (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
1477+ return v , nil
1478+ }
1479+
1480+ func expandAlloydbClusterRestoreContinuousBackupSourcePointInTime (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
1481+ return v , nil
1482+ }
1483+
13401484func expandAlloydbClusterContinuousBackupConfig (v interface {}, d tpgresource.TerraformResourceData , config * transport_tpg.Config ) (interface {}, error ) {
13411485 l := v .([]interface {})
13421486 if len (l ) == 0 || l [0 ] == nil {
0 commit comments