Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1381,6 +1381,13 @@ API (for read pools, effective_availability_type may differ from availability_ty
Required: true,
Description: `The name of the instance from which the point in time should be restored.`,
},
{{- if ne $.TargetVersionName "ga" }}
"source_project": {
Type: schema.TypeString,
Optional: true,
Description: `The project ID of the source project`,
},
{{- end }}
"point_in_time": {
Type: schema.TypeString,
Optional: true,
Expand Down Expand Up @@ -1561,7 +1568,11 @@ func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{})
ReplicaConfiguration: expandReplicaConfiguration(d.Get("replica_configuration").([]interface{})),
}

cloneContext, cloneSource := expandCloneContext(d.Get("clone").([]interface{}))
cloneContext, cloneSourceInstance := expandCloneContext(d.Get("clone").([]interface{}))

{{- if ne $.TargetVersionName "ga" }}
cloneSourceProject := expandCloneSourceProject(d.Get("clone").([]interface{}))
{{- end }}
pointInTimeRestoreContext := expandPointInTimeRestoreContext(d.Get("point_in_time_restore_context").([]interface{}))

if valueI, ok := d.GetOk("settings.0.auto_upgrade_enabled"); ok && !(valueI.(bool)) {
Expand Down Expand Up @@ -1623,8 +1634,18 @@ func resourceSqlDatabaseInstanceCreate(d *schema.ResourceData, meta interface{})
RetryFunc: func() (operr error) {
if cloneContext != nil {
cloneContext.DestinationInstanceName = name
{{- if ne $.TargetVersionName "ga" }}
if cloneSourceProject != "" {
cloneContext.DestinationProject = project
cloneContext.DestinationNetwork = network
}
{{- end }}
clodeReq := sqladmin.InstancesCloneRequest{CloneContext: cloneContext}
op, operr = config.NewSqlAdminClient(userAgent).Instances.Clone(project, cloneSource, &clodeReq).Do()
{{- if ne $.TargetVersionName "ga" }}
op, operr = config.NewSqlAdminClient(userAgent).Instances.Clone(cloneSourceProject, cloneSourceInstance, &clodeReq).Do()
{{- else }}
op, operr = config.NewSqlAdminClient(userAgent).Instances.Clone(project, cloneSourceInstance, &clodeReq).Do()
{{- end }}
} else if pointInTimeRestoreContext != nil {
parent := fmt.Sprintf("projects/%s", project)
op, operr = config.NewSqlAdminClient(userAgent).Instances.PointInTimeRestore(parent, pointInTimeRestoreContext).Do()
Expand Down Expand Up @@ -1872,6 +1893,16 @@ func expandCloneContext(configured []interface{}) (*sqladmin.CloneContext, strin
}, _cloneConfiguration["source_instance_name"].(string)
}

{{- if ne $.TargetVersionName "ga" }}
func expandCloneSourceProject(configured []interface{}) (string) {
if len(configured) == 0 || configured[0] == nil {
return ""
}
_cloneConfiguration := configured[0].(map[string]interface{})
return _cloneConfiguration["source_project"].(string)
}
{{- end }}

func expandMaintenanceWindow(configured []interface{}) *sqladmin.MaintenanceWindow {
if len(configured) == 0 || configured[0] == nil {
return nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ fields:
- field: 'clone.preferred_zone'
- field: 'clone.source_instance_deletion_time'
- field: 'clone.source_instance_name'
{{- if ne $.TargetVersionName "ga" }}
- field: 'clone.source_project'
{{- end }}
- api_field: 'connectionName'
- api_field: 'databaseVersion'
- field: 'deletion_protection'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1718,6 +1718,49 @@ func TestAccSqlDatabaseInstance_basicClone(t *testing.T) {
})
}

{{- if ne $.TargetVersionName "ga" }}
func TestAccSqlDatabaseInstance_crossProjectClone(t *testing.T) {
t.Parallel()

context := map[string]interface{}{
"random_suffix": acctest.RandString(t, 10),
"orgId": envvar.GetTestOrgFromEnv(t),
"billingAccount": envvar.GetTestBillingAccountFromEnv(t),
"cloneSourceProject": envvar.GetTestProjectFromEnv(),
}

acctest.VcrTest(t, resource.TestCase{
PreCheck: func() { acctest.AccTestPreCheck(t) },
ProtoV5ProviderFactories: acctest.ProtoV5ProviderBetaFactories(t),
ExternalProviders: map[string]resource.ExternalProvider{
"time": {},
},
Steps: []resource.TestStep{
{
Config: testAccSqlDatabaseInstance_crossProjectClone(context),
},
{
ResourceName: "google_sql_database_instance.instance",
ImportState: true,
ImportStateVerify: true,
ImportStateIdFunc: testAccSqlDatabaseInstanceImportStateIdFunc("google_sql_database_instance.instance"),
ImportStateVerifyIgnore: []string{"deletion_protection", "clone"},
},
},
})
}
{{- end }}

func testAccSqlDatabaseInstanceImportStateIdFunc(resourceName string) resource.ImportStateIdFunc {
return func(s *terraform.State) (string, error) {
rs, ok := s.RootModule().Resources[resourceName]
if !ok {
return "", fmt.Errorf("Not found: %s", resourceName)
}
return fmt.Sprintf("%s/%s", rs.Primary.Attributes["project"], rs.Primary.Attributes["name"]), nil
}
}

func TestAccSqlDatabaseInstance_cloneWithSettings(t *testing.T) {
// Sqladmin client
acctest.SkipIfVcr(t)
Expand Down Expand Up @@ -8252,6 +8295,113 @@ data "google_sql_backup_run" "backup" {
`, context)
}

func testAccSqlDatabaseInstance_crossProjectClone(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_project" "project" {
provider = google-beta
name = "tf-test-cpc-%{random_suffix}"
project_id = "tf-test-cpc-%{random_suffix}"
org_id = "%{orgId}"
billing_account = "%{billingAccount}"
deletion_policy = "DELETE"
}

resource "time_sleep" "wait_60_seconds" {
create_duration = "60s"
depends_on = [google_project.project]
}

resource "google_project_service" "compute" {
provider = google-beta
project = google_project.project.project_id
service = "compute.googleapis.com"
depends_on = [time_sleep.wait_60_seconds]
}

resource "google_project_service" "servicenetworking" {
provider = google-beta
project = google_project.project.project_id
service = "servicenetworking.googleapis.com"
depends_on = [google_project_service.compute]
}

resource "time_sleep" "wait_300_seconds" {
create_duration = "300s"
depends_on = [google_project_service.servicenetworking]
}

resource "google_compute_network" "sql_network" {
provider = google-beta
name = "sql-network"
project = google_project.project.project_id
depends_on = [time_sleep.wait_300_seconds]
}

resource "google_compute_global_address" "sql_range" {
provider = google-beta
name = "sql-range"
purpose = "VPC_PEERING"
address_type = "INTERNAL"
prefix_length = 16
network = google_compute_network.sql_network.id
project = google_project.project.project_id
}

resource "google_service_networking_connection" "sql_vpc_connection" {
provider = google-beta
network = google_compute_network.sql_network.id
service = "servicenetworking.googleapis.com"
reserved_peering_ranges = [google_compute_global_address.sql_range.name]
depends_on = [google_project_service.servicenetworking]
deletion_policy = "ABANDON"
}

resource "google_sql_database_instance" "instance" {
provider = google-beta
name = "tf-test-cpc-%{random_suffix}"
database_version = "POSTGRES_11"
region = "us-central1"
project = google_project.project.project_id

settings {
tier = "db-custom-2-3840"
edition = "ENTERPRISE"
ip_configuration {
private_network = google_compute_network.sql_network.self_link
}
backup_configuration {
enabled = true
point_in_time_recovery_enabled = true
}
}

clone {
source_project = "%{cloneSourceProject}"
source_instance_name = google_sql_database_instance.source_instance.name
}

deletion_protection = false

// Ignore changes, since the most recent backup may change during the test
lifecycle{
ignore_changes = [clone[0].point_in_time]
}
depends_on = [google_service_networking_connection.sql_vpc_connection]
}

resource "google_sql_database_instance" "source_instance" {
provider = google-beta
name = "tf-test-source-%{random_suffix}"
database_version = "POSTGRES_11"
region = "us-central1"
deletion_protection = false
settings {
tier = "db-g1-small"
}
}
`, context)
}

func testAccSqlDatabaseInstance_cloneWithSettings(context map[string]interface{}) string {
return acctest.Nprintf(`
resource "google_sql_database_instance" "instance" {
Expand Down