From ba4cbdcce3b4f5fbfe3249b5f162ac8fa338faae Mon Sep 17 00:00:00 2001 From: Modular Magician Date: Tue, 12 Mar 2024 17:10:17 +0000 Subject: [PATCH] Add data source for AppHub discovered workload (#10107) * Add data source for Apphub discovered workload * Add data source for Apphub discovered workload * Add data source for Apphub Discovered Workload * Resolved comments * Resolved comments * Resolved comments * Resolved comments * Add tests and documentation for data source discovered workload * Resolved comments and added tests * Resolved comments * Added modifications in tests, data source and documentation * Added modifications in tests, data source and documentation * Added modifications in tests, data source and documentation * Verified tests * Tests Verification * Tests Verification * Updated logic to obtain workload_uri * Updated logic to obtain workload_uri * Resolved comments * Resolved comments * Add billing account and shorten service project name * Add header * Change the project name to start with tf-test * Resolved comments * Lint changes * Removing two sleeps * Removing two sleeps * Modifying documentation * Resolved tests * Resolved comments * Resolved comments * logic modification * Update Retry logic * Update Retry logic * Resolved tests * Adding workload_uri description * Adding workload_uri description [upstream:a6ceb9e3c35210af4ecfaee801958eb7b79ac377] Signed-off-by: Modular Magician --- .changelog/10107.txt | 3 + google/provider/provider_mmv1_resources.go | 1 + .../data_source_apphub_discovered_workload.go | 164 ++++++++++++++++++ ..._source_apphub_discovered_workload_test.go | 147 ++++++++++++++++ .../apphub_discovered_workload.html.markdown | 50 ++++++ 5 files changed, 365 insertions(+) create mode 100644 .changelog/10107.txt create mode 100644 google/services/apphub/data_source_apphub_discovered_workload.go create mode 100644 google/services/apphub/data_source_apphub_discovered_workload_test.go create mode 100644 website/docs/d/apphub_discovered_workload.html.markdown diff --git a/.changelog/10107.txt b/.changelog/10107.txt new file mode 100644 index 00000000000..41234b7d845 --- /dev/null +++ b/.changelog/10107.txt @@ -0,0 +1,3 @@ +```release-note:new-datasource +`google_apphub_discovered_workload` +``` \ No newline at end of file diff --git a/google/provider/provider_mmv1_resources.go b/google/provider/provider_mmv1_resources.go index 81d3339ab44..b9ad9d045bd 100644 --- a/google/provider/provider_mmv1_resources.go +++ b/google/provider/provider_mmv1_resources.go @@ -137,6 +137,7 @@ var handwrittenDatasources = map[string]*schema.Resource{ "google_alloydb_locations": alloydb.DataSourceAlloydbLocations(), "google_alloydb_supported_database_flags": alloydb.DataSourceAlloydbSupportedDatabaseFlags(), "google_artifact_registry_repository": artifactregistry.DataSourceArtifactRegistryRepository(), + "google_apphub_discovered_workload": apphub.DataSourceApphubDiscoveredWorkload(), "google_app_engine_default_service_account": appengine.DataSourceGoogleAppEngineDefaultServiceAccount(), "google_apphub_discovered_service": apphub.DataSourceApphubDiscoveredService(), "google_beyondcorp_app_connection": beyondcorp.DataSourceGoogleBeyondcorpAppConnection(), diff --git a/google/services/apphub/data_source_apphub_discovered_workload.go b/google/services/apphub/data_source_apphub_discovered_workload.go new file mode 100644 index 00000000000..5b7d0944cb0 --- /dev/null +++ b/google/services/apphub/data_source_apphub_discovered_workload.go @@ -0,0 +1,164 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package apphub + +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 DataSourceApphubDiscoveredWorkload() *schema.Resource { + return &schema.Resource{ + Read: dataSourceApphubDiscoveredWorkloadRead, + Schema: map[string]*schema.Schema{ + "project": { + Type: schema.TypeString, + Optional: true, + }, + "location": { + Type: schema.TypeString, + Required: true, + }, + "workload_uri": { + Type: schema.TypeString, + Required: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + "workload_reference": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "uri": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "workload_properties": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "gcp_project": { + Type: schema.TypeString, + Computed: true, + }, + "location": { + Type: schema.TypeString, + Computed: true, + }, + "zone": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + }, + } +} + +func dataSourceApphubDiscoveredWorkloadRead(d *schema.ResourceData, meta interface{}) error { + config := meta.(*transport_tpg.Config) + userAgent, err := tpgresource.GenerateUserAgentString(d, config.UserAgent) + if err != nil { + return err + } + + url, err := tpgresource.ReplaceVars(d, config, fmt.Sprintf("{{ApphubBasePath}}projects/{{project}}/locations/{{location}}/discoveredWorkloads:lookup?uri={{workload_uri}}")) + if err != nil { + return err + } + + billingProject := "" + + // err == nil indicates that the billing_project value was found + if bp, err := tpgresource.GetBillingProject(d, config); err == nil { + billingProject = bp + } + + res, err := transport_tpg.SendRequest(transport_tpg.SendRequestOptions{ + Config: config, + Method: "GET", + Project: billingProject, + RawURL: url, + UserAgent: userAgent, + }) + + if err != nil { + return transport_tpg.HandleDataSourceNotFoundError(err, d, fmt.Sprintf("ApphubDiscoveredWorkload %q", d.Id()), url) + } + + if err := d.Set("name", flattenApphubDiscoveredWorkloadName(res["discoveredWorkload"].(map[string]interface{})["name"], d, config)); err != nil { + return fmt.Errorf("Error setting workload name: %s", err) + } + + if err := d.Set("workload_reference", flattenApphubDiscoveredWorkloadReference(res["discoveredWorkload"].(map[string]interface{})["workloadReference"], d, config)); err != nil { + return fmt.Errorf("Error setting service reference: %s", err) + } + + if err := d.Set("workload_properties", flattenApphubDiscoveredWorkloadProperties(res["discoveredWorkload"].(map[string]interface{})["workloadProperties"], d, config)); err != nil { + return fmt.Errorf("Error setting workload properties: %s", err) + } + + d.SetId(res["discoveredWorkload"].(map[string]interface{})["name"].(string)) + + return nil + +} + +func flattenApphubDiscoveredWorkloadReference(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["uri"] = flattenApphubDiscoveredWorkloadDataUri(original["uri"], d, config) + return []interface{}{transformed} +} + +func flattenApphubDiscoveredWorkloadProperties(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + if v == nil { + return nil + } + original := v.(map[string]interface{}) + if len(original) == 0 { + return nil + } + transformed := make(map[string]interface{}) + transformed["gcp_project"] = flattenApphubDiscoveredWorkloadDataGcpProject(original["gcpProject"], d, config) + transformed["location"] = flattenApphubDiscoveredWorkloadDataLocation(original["location"], d, config) + transformed["zone"] = flattenApphubDiscoveredWorkloadDataZone(original["zone"], d, config) + return []interface{}{transformed} +} + +func flattenApphubDiscoveredWorkloadName(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenApphubDiscoveredWorkloadDataUri(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenApphubDiscoveredWorkloadDataGcpProject(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenApphubDiscoveredWorkloadDataLocation(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} + +func flattenApphubDiscoveredWorkloadDataZone(v interface{}, d *schema.ResourceData, config *transport_tpg.Config) interface{} { + return v +} diff --git a/google/services/apphub/data_source_apphub_discovered_workload_test.go b/google/services/apphub/data_source_apphub_discovered_workload_test.go new file mode 100644 index 00000000000..8efa4f43f01 --- /dev/null +++ b/google/services/apphub/data_source_apphub_discovered_workload_test.go @@ -0,0 +1,147 @@ +// Copyright (c) HashiCorp, Inc. +// SPDX-License-Identifier: MPL-2.0 +package apphub_test + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-provider-google/google/acctest" + "github.com/hashicorp/terraform-provider-google/google/envvar" +) + +func TestAccDataSourceApphubDiscoveredWorkload_basic(t *testing.T) { + t.Parallel() + + context := map[string]interface{}{ + "org_id": envvar.GetTestOrgFromEnv(t), + "random_suffix": acctest.RandString(t, 10), + "billing_account": envvar.GetTestBillingAccountFromEnv(t), + } + + acctest.VcrTest(t, resource.TestCase{ + PreCheck: func() { acctest.AccTestPreCheck(t) }, + ProtoV5ProviderFactories: acctest.ProtoV5ProviderFactories(t), + ExternalProviders: map[string]resource.ExternalProvider{ + "time": {}, + }, + Steps: []resource.TestStep{ + { + Config: testDataSourceApphubDiscoveredWorkload_basic(context), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttrSet("data.google_apphub_discovered_workload.catalog-workload", "name"), + ), + }, + }, + }) +} + +func testDataSourceApphubDiscoveredWorkload_basic(context map[string]interface{}) string { + return acctest.Nprintf(` +resource "google_project" "service_project" { + project_id ="tf-test-ah-%{random_suffix}" + name = "Service Project" + org_id = "%{org_id}" + billing_account = "%{billing_account}" +} + +# Enable Compute API +resource "google_project_service" "compute_service_project" { + project = google_project.service_project.project_id + service = "compute.googleapis.com" +} + +resource "time_sleep" "wait_120s" { + depends_on = [google_project_service.compute_service_project] + create_duration = "120s" +} + +resource "google_apphub_service_project_attachment" "service_project_attachment" { + service_project_attachment_id = google_project.service_project.project_id + depends_on = [time_sleep.wait_120s] +} + +data "google_apphub_discovered_workload" "catalog-workload" { + location = "us-central1" + workload_uri = "${replace(google_compute_region_instance_group_manager.mig.instance_group, "https://www.googleapis.com/compute/v1", "//compute.googleapis.com")}" + depends_on = [time_sleep.wait_120s_for_resource_ingestion] +} + +# VPC network +resource "google_compute_network" "ilb_network" { + name = "l7-ilb-network-%{random_suffix}" + project = google_project.service_project.project_id + auto_create_subnetworks = false + depends_on = [time_sleep.wait_120s] +} + +# backend subnet +resource "google_compute_subnetwork" "ilb_subnet" { + name = "l7-ilb-subnetwork-%{random_suffix}" + project = google_project.service_project.project_id + ip_cidr_range = "10.0.1.0/24" + region = "us-central1" + network = google_compute_network.ilb_network.id +} + +resource "time_sleep" "wait_120s_for_resource_ingestion" { + depends_on = [google_compute_region_instance_group_manager.mig] + create_duration = "120s" +} + +# instance template +resource "google_compute_instance_template" "instance_template" { + name = "l7-ilb-mig-template-%{random_suffix}" + project = google_project.service_project.project_id + machine_type = "e2-small" + tags = ["http-server"] + network_interface { + network = google_compute_network.ilb_network.id + subnetwork = google_compute_subnetwork.ilb_subnet.id + access_config { + # add external ip to fetch packages + } + } + disk { + source_image = "debian-cloud/debian-10" + auto_delete = true + boot = true + } + # install nginx and serve a simple web page + metadata = { + startup-script = <<-EOF1 + #! /bin/bash + set -euo pipefail + export DEBIAN_FRONTEND=noninteractive + apt-get update + apt-get install -y nginx-light jq + NAME=$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/hostname") + IP=$(curl -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/ip") + METADATA=$(curl -f -H "Metadata-Flavor: Google" "http://metadata.google.internal/computeMetadata/v1/instance/attributes/?recursive=True" | jq 'del(.["startup-script"])') + cat < /var/www/html/index.html +
+      Name: $NAME
+      IP: $IP
+      Metadata: $METADATA
+      
+ EOF + EOF1 + } + lifecycle { + create_before_destroy = true + } +} + +resource "google_compute_region_instance_group_manager" "mig" { + name = "l7-ilb-mig1-%{random_suffix}" + project = google_project.service_project.project_id + region = "us-central1" + version { + instance_template = google_compute_instance_template.instance_template.id + name = "primary" + } + base_instance_name = "vm" + target_size = 2 +} +`, context) +} diff --git a/website/docs/d/apphub_discovered_workload.html.markdown b/website/docs/d/apphub_discovered_workload.html.markdown new file mode 100644 index 00000000000..d9fc574eaff --- /dev/null +++ b/website/docs/d/apphub_discovered_workload.html.markdown @@ -0,0 +1,50 @@ +--- +subcategory: "Apphub" +description: |- + Get information about a discovered workload. +--- + +# google\_apphub\_discovered_workload + +Get information about a discovered workload from its uri. + + +## Example Usage + + +```hcl +data "google_apphub_discovered_workload" "my-workload" { + location = "us-central1" + workload_uri = "my-workload-uri" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `project` - The host project of the discovered workload. +* `workload_uri` - (Required) The uri of the workload (instance group managed by the Instance Group Manager). Example: "//compute.googleapis.com/projects/1/regions/us-east1/instanceGroups/id1" +* `location` - (Required) The location of the discovered workload. + +## Attributes Reference + +In addition to the arguments listed above, the following computed attributes are exported: + +* `name` - Resource name of a Workload. Format: "projects/{host-project-id}/locations/{location}/applications/{application-id}/workloads/{workload-id}". + +* `workload_reference` - Reference to an underlying networking resource that can comprise a Workload. Structure is [documented below](#nested_workload_reference) + +The `workload_reference` block supports: + +* `uri` - The underlying resource URI. + +* `workload_properties` - Properties of an underlying compute resource that can comprise a Workload. Structure is [documented below](#nested_workload_properties) + +The `workload_properties` block supports: + +* `gcp_project` - The service project identifier that the underlying cloud resource resides in. + +* `location` - The location that the underlying resource resides in. + +* `zone` - The location that the underlying resource resides in if it is zonal.