diff --git a/mmv1/products/backupdr/BackupPlanAssociation.yaml b/mmv1/products/backupdr/BackupPlanAssociation.yaml index 043b493ea83a..c4e0ce8c5627 100644 --- a/mmv1/products/backupdr/BackupPlanAssociation.yaml +++ b/mmv1/products/backupdr/BackupPlanAssociation.yaml @@ -110,7 +110,7 @@ properties: output: true properties: - name: 'code' - type: String + type: Double description: The status code, which should be an enum value of [google.rpc.Code] - name: 'message' type: String diff --git a/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl b/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl index 1d77a3fb8f29..3f3c480883b2 100644 --- a/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl +++ b/mmv1/third_party/terraform/provider/provider_mmv1_resources.go.tmpl @@ -35,6 +35,8 @@ var handwrittenDatasources = map[string]*schema.Resource{ "google_apphub_discovered_service": apphub.DataSourceApphubDiscoveredService(), {{- if ne $.TargetVersionName "ga" }} "google_backup_dr_management_server": backupdr.DataSourceGoogleCloudBackupDRService(), + "google_backup_dr_backup_plan": backupdr.DataSourceGoogleCloudBackupDRBackupPlan(), + "google_backup_dr_backup_plan_association": backupdr.DataSourceGoogleCloudBackupDRBackupPlanAssociation(), {{- end }} "google_beyondcorp_app_connection": beyondcorp.DataSourceGoogleBeyondcorpAppConnection(), "google_beyondcorp_app_connector": beyondcorp.DataSourceGoogleBeyondcorpAppConnector(), diff --git a/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan.go b/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan.go new file mode 100644 index 000000000000..91e6bc82ff39 --- /dev/null +++ b/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan.go @@ -0,0 +1,50 @@ +package backupdr +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func DataSourceGoogleCloudBackupDRBackupPlan() *schema.Resource { + + dsSchema := tpgresource.DatasourceSchemaFromResourceSchema(ResourceBackupDRBackupPlan().Schema) + // Set 'Required' schema elements + tpgresource.AddRequiredFieldsToSchema(dsSchema, "backup_plan_id", "location") + + // Set 'Optional' schema elements + tpgresource.AddOptionalFieldsToSchema(dsSchema, "project") + return &schema.Resource{ + Read: dataSourceGoogleCloudBackupDRBackupPlanRead, + Schema: dsSchema, + } +} + +func dataSourceGoogleCloudBackupDRBackupPlanRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return err + } + + location, err := tpgresource.GetLocation(d, config) + if err != nil { + return err + } + + backup_plan_id := d.Get("backup_plan_id").(string) + + id := fmt.Sprintf("projects/%s/locations/%s/backupPlans/%s", project, location, backup_plan_id) + d.SetId(id) + err = resourceBackupDRBackupPlanRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil +} \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_association.go b/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_association.go new file mode 100644 index 000000000000..5d1cd585b892 --- /dev/null +++ b/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_association.go @@ -0,0 +1,50 @@ +package backupdr +import ( + "fmt" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" +) + +func DataSourceGoogleCloudBackupDRBackupPlanAssociation() *schema.Resource { + + dsSchema := tpgresource.DatasourceSchemaFromResourceSchema(ResourceBackupDRBackupPlanAssociation().Schema) + // Set 'Required' schema elements + tpgresource.AddRequiredFieldsToSchema(dsSchema, "backup_plan_association_id", "location") + + // Set 'Optional' schema elements + tpgresource.AddOptionalFieldsToSchema(dsSchema, "project") + return &schema.Resource{ + Read: dataSourceGoogleCloudBackupDRBackupPlanAssociationRead, + Schema: dsSchema, + } +} + +func dataSourceGoogleCloudBackupDRBackupPlanAssociationRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + + project, err := tpgresource.GetProject(d, config) + if err != nil { + return err + } + + location, err := tpgresource.GetLocation(d, config) + if err != nil { + return err + } + + backup_plan_association_id := d.Get("backup_plan_association_id").(string) + + id := fmt.Sprintf("projects/%s/locations/%s/backupPlanAssociations/%s", project, location, backup_plan_association_id) + d.SetId(id) + err = resourceBackupDRBackupPlanAssociationRead(d, meta) + if err != nil { + return err + } + + if d.Id() == "" { + return fmt.Errorf("%s not found", id) + } + + return nil +} \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_association_test.go.tmpl b/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_association_test.go.tmpl new file mode 100644 index 000000000000..9732d08fcfe4 --- /dev/null +++ b/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_association_test.go.tmpl @@ -0,0 +1,167 @@ +package backupdr_test +{{- if ne $.TargetVersionName "ga" }} + +import ( + "testing" + "fmt" + "strings" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-testing/terraform" + +) + +func TestAccDataSourceGoogleBackupDRBackupPlanAssociation_basic(t *testing.T) { + t.Parallel() + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccDataSourceGoogleBackupDRBackupPlanAssociation_basic(context), + Check: resource.ComposeTestCheckFunc( + acctest.CheckDataSourceStateMatchesResourceState("data.google_backup_dr_backup_plan_association.bpa", "google_backup_dr_backup_plan_association.bpa-data"), + ), + }, + }, + }) +} + +func testAccCheckBackupDRBackupPlanAssociationDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_backup_dr_backup_plan" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{"{{"}}BackupDRBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/locations/{{"{{"}}location{{"}}"}}/backupPlans/{{"{{"}}backup_plan_id{{"}}"}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("Backup Plan still exists at %s", url) + } + } + + return nil + } +} + + +func testAccDataSourceGoogleBackupDRBackupPlanAssociation_basic(context map[string]interface{}) string { + return acctest.Nprintf(` + resource "google_service_account" "default" { + account_id = "my-custom-sa" + display_name = "Custom SA for VM Instance" +} + +resource "google_compute_instance" "default" { + name = "test" + machine_type = "n2-standard-2" + zone = "us-central1-a" + tags = ["foo", "bar"] + boot_disk { + initialize_params { + image = "debian-cloud/debian-11" + labels = { + my_label = "value" + } + } + } + // Local SSD disk + scratch_disk { + interface = "NVME" + } + network_interface { + network = "default" + access_config { + // Ephemeral public IP + } + } + service_account { + # Google recommends custom service accounts that have cloud-platform scope and permissions granted via IAM Roles. + email = google_service_account.default.email + scopes = ["cloud-platform"] + } +} +resource "google_backup_dr_backup_vault" "my-backup-vault" { + location ="us-central1" + backup_vault_id = "bv-1" + description = "This is a second backup vault built by Terraform." + backup_minimum_enforced_retention_duration = "100000s" + labels = { + foo = "bar1" + bar = "baz1" + } + annotations = { + annotations1 = "bar1" + annotations2 = "baz1" + } + force_update = "true" + force_delete = "true" + allow_missing = "true" +} + + +resource "google_backup_dr_backup_plan" "foo" { + location = "us-central1" + backup_plan_id = "bp-test-tf" + resource_type= "compute.googleapis.com/Instance" + backup_vault = google_backup_dr_backup_vault.my-backup-vault.name + depends_on= [ google_backup_dr_backup_vault.my-backup-vault ] + backup_rules { + rule_id = "rule-1" + backup_retention_days = 5 + standard_schedule { + recurrence_type = "HOURLY" + hourly_frequency = 6 + time_zone = "UTC" + backup_window{ + start_hour_of_day = 0 + end_hour_of_day = 24 + } + } + } +} + +resource "google_backup_dr_backup_plan_association" "bpa" { + location = "us-central1" + backup_plan_association_id = "bpa-test-tf" + resource = google_compute_instance.default.id + backup_plan = google_backup_dr_backup_plan.foo.name + depends_on= [ google_backup_dr_backup_plan.foo ] + +} + +data "google_backup_dr_backup_plan_association" "bpa-data" { + location = "us-central1" + backup_plan_association_id="bpa-test-tf1" + depends_on= [ google_backup_dr_backup_plan_association.bpa ] + } +`, context) +} +{{- end }} \ No newline at end of file diff --git a/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_test.go.tmpl b/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_test.go.tmpl new file mode 100644 index 000000000000..0ff70e338702 --- /dev/null +++ b/mmv1/third_party/terraform/services/backupdr/data_source_backup_dr_backup_plan_test.go.tmpl @@ -0,0 +1,125 @@ +package backupdr_test +{{- if ne $.TargetVersionName "ga" }} + +import ( + "testing" + "fmt" + "strings" + "github.com/hashicorp/terraform-plugin-testing/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/tpgresource" + transport_tpg "github.com/hashicorp/terraform-provider-google/google/transport" + "github.com/hashicorp/terraform-plugin-testing/terraform" + +) + +func TestAccDataSourceGoogleBackupDRBackupPlan_basic(t *testing.T) { + t.Parallel() + context := map[string]interface{}{ + "random_suffix": acctest.RandString(t, 10), + } + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + Steps: []resource.TestStep{ + { + Config: testAccDataSourceGoogleBackupDRBackupPlan_basic(context), + Check: resource.ComposeTestCheckFunc( + acctest.CheckDataSourceStateMatchesResourceState("data.google_backup_dr_backup_plan.foo", "google_backup_dr_backup_plan.foo"), + ), + }, + }, + }) +} + +func testAccCheckBackupDRBackupPlanDestroyProducer(t *testing.T) func(s *terraform.State) error { + return func(s *terraform.State) error { + for name, rs := range s.RootModule().Resources { + if rs.Type != "google_backup_dr_backup_plan" { + continue + } + if strings.HasPrefix(name, "data.") { + continue + } + + config := acctest.GoogleProviderConfig(t) + + url, err := tpgresource.ReplaceVarsForTest(config, rs, "{{"{{"}}BackupDRBasePath{{"}}"}}projects/{{"{{"}}project{{"}}"}}/locations/{{"{{"}}location{{"}}"}}/backupPlans/{{"{{"}}backup_plan_id{{"}}"}}") + if err != nil { + return err + } + + billingProject := "" + + if config.BillingProject != "" { + billingProject = config.BillingProject + } + + _, err = transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: config.UserAgent, + }) + if err == nil { + return fmt.Errorf("Backup Plan still exists at %s", url) + } + } + + return nil + } +} + + +func testAccDataSourceGoogleBackupDRBackupPlan_basic(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_backup_dr_backup_vault" "my-backup-vault" { + project="nkuravi-consumer-billing-test" + location ="us-central1" + backup_vault_id = "bv-1" + description = "This is a second backup vault built by Terraform." + backup_minimum_enforced_retention_duration = "100000s" + labels = { + foo = "bar1" + bar = "baz1" + } + annotations = { + annotations1 = "bar1" + annotations2 = "baz1" + } + force_update = "true" + force_delete = "true" + allow_missing = "true" +} + + +resource "google_backup_dr_backup_plan" "foo" { + location = "us-central1" + backup_plan_id = "bp-test-tf1" + resource_type= "compute.googleapis.com/Instance" + backup_vault = google_backup_dr_backup_vault.my-backup-vault.name + depends_on=[ google_backup_dr_backup_vault.my-backup-vault ] + backup_rules { + rule_id = "rule-1" + backup_retention_days = 5 + standard_schedule { + recurrence_type = "HOURLY" + hourly_frequency = 6 + time_zone = "UTC" + backup_window{ + start_hour_of_day = 0 + end_hour_of_day = 24 + } + } + } +} + +data "google_backup_dr_backup_plan" "foo" { + location = "us-central1" + backup_plan_id="bp-test-tf1" + depends_on= [ google_backup_dr_backup_plan.foo ] + } +`, context) +} +{{- end }} \ No newline at end of file